From b79fd65a83e6563393807efbc44be3e2bdb16537 Mon Sep 17 00:00:00 2001 From: Josh Haberman Date: Tue, 11 Sep 2018 10:59:08 -0700 Subject: WIP. --- upb/def.c | 1469 ++++++++++++------------------------------------------------- 1 file changed, 293 insertions(+), 1176 deletions(-) (limited to 'upb/def.c') diff --git a/upb/def.c b/upb/def.c index 0c154e6..2e53cf7 100644 --- a/upb/def.c +++ b/upb/def.c @@ -4,9 +4,82 @@ #include #include #include -#include "upb/structdefs.int.h" #include "upb/handlers.h" +struct upb_fielddef { + 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; + char *unresolved_name; + } sub; + union { + const upb_oneofdef *oneof; + } + uint32_t number_; + uint32_t selector_base; /* Used to index into a upb::Handlers table. */ + bool is_extension_; + bool lazy_; + bool packed_; + upb_descriptortype_t type_; + upb_label_t label_; +}; + +struct upb_msgdef { + 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. Built lazily. */ + upb_inttable *itof; /* int to field */ + upb_strtable *ntof; /* name to field/oneof */ + + /* Is this a map-entry message? */ + bool map_entry; + + /* TODO(haberman): proper extension ranges (there can be multiple). */ +}; + +struct upb_enumdef { + upb_strtable ntoi; + upb_inttable iton; + int32_t defaultval; +}; + +struct upb_oneofdef { + const upb_msgdef *parent; + const char *name; + upb_strtable *ntof; + upb_inttable *itof; +}; + +struct upb_symtab { + upb_arena arena; + upb_strtable symtab; +}; + +struct upb_filedef { + const char *name; + const char *package; + const char *phpprefix; + const char *phpnamespace; + upb_syntax_t syntax; + + upb_inttable defs; + upb_inttable deps; +}; + typedef struct { size_t len; char str[1]; /* Null-terminated string data follows. */ @@ -66,186 +139,24 @@ static bool upb_isident(const char *str, size_t len, bool full, upb_status *s) { return !start; } -static bool upb_isoneof(const upb_refcounted *def) { - return def->vtbl == &upb_oneofdef_vtbl; -} - -static bool upb_isfield(const upb_refcounted *def) { - return def->vtbl == &upb_fielddef_vtbl; -} - -static const upb_oneofdef *upb_trygetoneof(const upb_refcounted *def) { - return upb_isoneof(def) ? (const upb_oneofdef*)def : NULL; -} - -static const upb_fielddef *upb_trygetfield(const upb_refcounted *def) { - return upb_isfield(def) ? (const upb_fielddef*)def : NULL; -} - - -/* upb_def ********************************************************************/ - -upb_deftype_t upb_def_type(const upb_def *d) { return d->type; } - -const char *upb_def_fullname(const upb_def *d) { return d->fullname; } - -const char *upb_def_name(const upb_def *d) { - const char *p; - - if (d->fullname == NULL) { - return NULL; - } else if ((p = strrchr(d->fullname, '.')) == NULL) { - /* No '.' in the name, return the full string. */ - return d->fullname; - } else { - /* Return one past the last '.'. */ - return p + 1; - } -} - -bool upb_def_setfullname(upb_def *def, const char *fullname, upb_status *s) { - UPB_ASSERT(!upb_def_isfrozen(def)); - if (!upb_isident(fullname, strlen(fullname), true, s)) { - return false; - } - - fullname = upb_gstrdup(fullname); - if (!fullname) { - upb_upberr_setoom(s); - return false; - } - - upb_gfree((void*)def->fullname); - def->fullname = fullname; +static bool upb_isoneof(const void *def) { + UPB_UNUSED(def); return true; } -const upb_filedef *upb_def_file(const upb_def *d) { return d->file; } - -static bool upb_def_init(upb_def *def, upb_deftype_t type, - const struct upb_refcounted_vtbl *vtbl, - const void *owner) { - if (!upb_refcounted_init(upb_def_upcast_mutable(def), vtbl, owner)) return false; - def->type = type; - def->fullname = NULL; - def->came_from_user = false; - def->file = NULL; +static bool upb_isfield(const void *def) { + UPB_UNUSED(def); return true; } -static void upb_def_uninit(upb_def *def) { - upb_gfree((void*)def->fullname); -} - -static const char *msgdef_name(const upb_msgdef *m) { - const char *name = upb_def_fullname(upb_msgdef_upcast(m)); - return name ? name : "(anonymous)"; +static const upb_oneofdef *upb_trygetoneof(const void *def) { + return upb_isoneof(def) ? (const upb_oneofdef*)def : NULL; } -static bool upb_validate_field(upb_fielddef *f, upb_status *s) { - if (upb_fielddef_name(f) == NULL || upb_fielddef_number(f) == 0) { - upb_status_seterrmsg(s, "fielddef must have name and number set"); - return false; - } - - if (!f->type_is_set_) { - upb_status_seterrmsg(s, "fielddef type was not initialized"); - return false; - } - - if (upb_fielddef_lazy(f) && - upb_fielddef_descriptortype(f) != UPB_DESCRIPTOR_TYPE_MESSAGE) { - upb_status_seterrmsg(s, - "only length-delimited submessage fields may be lazy"); - return false; - } - - if (upb_fielddef_hassubdef(f)) { - const upb_def *subdef; - - if (f->subdef_is_symbolic) { - upb_status_seterrf(s, "field '%s.%s' has not been resolved", - msgdef_name(f->msg.def), upb_fielddef_name(f)); - return false; - } - - subdef = upb_fielddef_subdef(f); - if (subdef == NULL) { - upb_status_seterrf(s, "field %s.%s is missing required subdef", - msgdef_name(f->msg.def), upb_fielddef_name(f)); - return false; - } - - if (!upb_def_isfrozen(subdef) && !subdef->came_from_user) { - upb_status_seterrf(s, - "subdef of field %s.%s is not frozen or being frozen", - msgdef_name(f->msg.def), upb_fielddef_name(f)); - return false; - } - } - - if (upb_fielddef_type(f) == UPB_TYPE_ENUM) { - bool has_default_name = upb_fielddef_enumhasdefaultstr(f); - bool has_default_number = upb_fielddef_enumhasdefaultint32(f); - - /* Previously verified by upb_validate_enumdef(). */ - UPB_ASSERT(upb_enumdef_numvals(upb_fielddef_enumsubdef(f)) > 0); - - /* We've already validated that we have an associated enumdef and that it - * has at least one member, so at least one of these should be true. - * Because if the user didn't set anything, we'll pick up the enum's - * default, but if the user *did* set something we should at least pick up - * the one they set (int32 or string). */ - UPB_ASSERT(has_default_name || has_default_number); - - if (!has_default_name) { - upb_status_seterrf(s, - "enum default for field %s.%s (%d) is not in the enum", - msgdef_name(f->msg.def), upb_fielddef_name(f), - upb_fielddef_defaultint32(f)); - return false; - } - - if (!has_default_number) { - upb_status_seterrf(s, - "enum default for field %s.%s (%s) is not in the enum", - msgdef_name(f->msg.def), upb_fielddef_name(f), - upb_fielddef_defaultstr(f, NULL)); - return false; - } - - /* Lift the effective numeric default into the field's default slot, in case - * we were only getting it "by reference" from the enumdef. */ - upb_fielddef_setdefaultint32(f, upb_fielddef_defaultint32(f)); - } - - /* Ensure that MapEntry submessages only appear as repeated fields, not - * optional/required (singular) fields. */ - if (upb_fielddef_type(f) == UPB_TYPE_MESSAGE && - upb_fielddef_msgsubdef(f) != NULL) { - const upb_msgdef *subdef = upb_fielddef_msgsubdef(f); - if (upb_msgdef_mapentry(subdef) && !upb_fielddef_isseq(f)) { - upb_status_seterrf(s, - "Field %s refers to mapentry message but is not " - "a repeated field", - upb_fielddef_name(f) ? upb_fielddef_name(f) : - "(unnamed)"); - return false; - } - } - - return true; +static const upb_fielddef *upb_trygetfield(const void *def) { + return upb_isfield(def) ? (const upb_fielddef*)def : NULL; } -static bool upb_validate_enumdef(const upb_enumdef *e, upb_status *s) { - if (upb_enumdef_numvals(e) == 0) { - upb_status_seterrf(s, "enum %s has no members (must have at least one)", - upb_enumdef_fullname(e)); - return false; - } - - return true; -} /* All submessage fields are lower than all other fields. * Secondly, fields are increasing in order. */ @@ -291,11 +202,7 @@ static bool assign_msg_indices(upb_msgdef *m, upb_status *s) { !upb_msg_field_done(&j); upb_msg_field_next(&j), i++) { upb_fielddef *f = upb_msg_iter_field(&j); - UPB_ASSERT(f->msg.def == m); - if (!upb_validate_field(f, s)) { - upb_gfree(fields); - return false; - } + UPB_ASSERT(f->msgdef == m); if (upb_fielddef_issubmsg(f)) { m->submsg_field_count++; } @@ -365,6 +272,7 @@ static bool assign_msg_indices(upb_msgdef *m, upb_status *s) { return true; } +#if 0 bool _upb_def_validate(upb_def *const*defs, size_t n, upb_status *s) { size_t i; @@ -416,73 +324,20 @@ err: UPB_ASSERT(!(s && upb_ok(s))); return false; } - -bool upb_def_freeze(upb_def *const* defs, size_t n, upb_status *s) { - /* Def graph contains FieldDefs between each MessageDef, so double the - * limit. */ - const size_t maxdepth = UPB_MAX_MESSAGE_DEPTH * 2; - - if (!_upb_def_validate(defs, n, s)) { - return false; - } - - - /* Validation all passed; freeze the objects. */ - return upb_refcounted_freeze((upb_refcounted *const*)defs, n, s, maxdepth); -} +#endif /* upb_enumdef ****************************************************************/ -static void visitenum(const upb_refcounted *r, upb_refcounted_visit *visit, - void *closure) { - const upb_enumdef *e = (const upb_enumdef*)r; - const upb_def *def = upb_enumdef_upcast(e); - if (upb_def_file(def)) { - visit(r, upb_filedef_upcast(upb_def_file(def)), closure); - } -} - -static void freeenum(upb_refcounted *r) { - upb_enumdef *e = (upb_enumdef*)r; - upb_inttable_iter i; - upb_inttable_begin(&i, &e->iton); - for( ; !upb_inttable_done(&i); upb_inttable_next(&i)) { - /* To clean up the upb_gstrdup() from upb_enumdef_addval(). */ - upb_gfree(upb_value_getcstr(upb_inttable_iter_value(&i))); - } - upb_strtable_uninit(&e->ntoi); - upb_inttable_uninit(&e->iton); - upb_def_uninit(upb_enumdef_upcast_mutable(e)); - upb_gfree(e); -} - -const struct upb_refcounted_vtbl upb_enumdef_vtbl = {&visitenum, &freeenum}; - -upb_enumdef *upb_enumdef_new(const void *owner) { - upb_enumdef *e = upb_gmalloc(sizeof(*e)); - if (!e) return NULL; - - if (!upb_def_init(upb_enumdef_upcast_mutable(e), UPB_DEF_ENUM, - &upb_enumdef_vtbl, owner)) { - goto err2; - } +#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 e; - -err1: - upb_strtable_uninit(&e->ntoi); -err2: - upb_gfree(e); - return NULL; -} - -bool upb_enumdef_freeze(upb_enumdef *e, upb_status *status) { - upb_def *d = upb_enumdef_upcast_mutable(e); - return upb_def_freeze(&d, 1, status); + return true; } +#endif const char *upb_enumdef_fullname(const upb_enumdef *e) { return upb_def_fullname(upb_enumdef_upcast(e)); @@ -492,11 +347,7 @@ const char *upb_enumdef_name(const upb_enumdef *e) { return upb_def_name(upb_enumdef_upcast(e)); } -bool upb_enumdef_setfullname(upb_enumdef *e, const char *fullname, - upb_status *s) { - return upb_def_setfullname(upb_enumdef_upcast_mutable(e), fullname, s); -} - +#if 0 bool upb_enumdef_addval(upb_enumdef *e, const char *name, int32_t num, upb_status *status) { char *name2; @@ -531,12 +382,14 @@ bool upb_enumdef_addval(upb_enumdef *e, const char *name, int32_t num, return true; } +#endif int32_t upb_enumdef_default(const upb_enumdef *e) { UPB_ASSERT(upb_enumdef_iton(e, e->defaultval)); return e->defaultval; } +#if 0 bool upb_enumdef_setdefault(upb_enumdef *e, int32_t val, upb_status *s) { UPB_ASSERT(!upb_enumdef_isfrozen(e)); if (!upb_enumdef_iton(e, val)) { @@ -546,6 +399,7 @@ bool upb_enumdef_setdefault(upb_enumdef *e, int32_t val, upb_status *s) { e->defaultval = val; return true; } +#endif int upb_enumdef_numvals(const upb_enumdef *e) { return upb_strtable_count(&e->ntoi); @@ -588,110 +442,19 @@ int32_t upb_enum_iter_number(upb_enum_iter *iter) { static void upb_fielddef_init_default(upb_fielddef *f); -static void upb_fielddef_uninit_default(upb_fielddef *f) { - if (f->type_is_set_ && f->default_is_string && f->defaultval.bytes) - freestr(f->defaultval.bytes); -} - const char *upb_fielddef_fullname(const upb_fielddef *e) { return upb_def_fullname(upb_fielddef_upcast(e)); } -static void visitfield(const upb_refcounted *r, upb_refcounted_visit *visit, - void *closure) { - const upb_fielddef *f = (const upb_fielddef*)r; - const upb_def *def = upb_fielddef_upcast(f); - if (upb_fielddef_containingtype(f)) { - visit(r, upb_msgdef_upcast2(upb_fielddef_containingtype(f)), closure); - } - if (upb_fielddef_containingoneof(f)) { - visit(r, upb_oneofdef_upcast(upb_fielddef_containingoneof(f)), closure); - } - if (upb_fielddef_subdef(f)) { - visit(r, upb_def_upcast(upb_fielddef_subdef(f)), closure); - } - if (upb_def_file(def)) { - visit(r, upb_filedef_upcast(upb_def_file(def)), closure); - } -} - -static void freefield(upb_refcounted *r) { - upb_fielddef *f = (upb_fielddef*)r; - upb_fielddef_uninit_default(f); - if (f->subdef_is_symbolic) - upb_gfree(f->sub.name); - upb_def_uninit(upb_fielddef_upcast_mutable(f)); - upb_gfree(f); -} - -static const char *enumdefaultstr(const upb_fielddef *f) { - const upb_enumdef *e; - UPB_ASSERT(f->type_is_set_ && f->type_ == UPB_TYPE_ENUM); - e = upb_fielddef_enumsubdef(f); - if (f->default_is_string && f->defaultval.bytes) { - /* Default was explicitly set as a string. */ - str_t *s = f->defaultval.bytes; - return s->str; - } else if (e) { - if (!f->default_is_string) { - /* Default was explicitly set as an integer; look it up in enumdef. */ - const char *name = upb_enumdef_iton(e, f->defaultval.sint); - if (name) { - return name; - } - } else { - /* Default is completely unset; pull enumdef default. */ - if (upb_enumdef_numvals(e) > 0) { - const char *name = upb_enumdef_iton(e, upb_enumdef_default(e)); - UPB_ASSERT(name); - return name; - } - } - } - return NULL; -} - -static bool enumdefaultint32(const upb_fielddef *f, int32_t *val) { - const upb_enumdef *e; - UPB_ASSERT(f->type_is_set_ && f->type_ == UPB_TYPE_ENUM); - e = upb_fielddef_enumsubdef(f); - if (!f->default_is_string) { - /* Default was explicitly set as an integer. */ - *val = f->defaultval.sint; - return true; - } else if (e) { - if (f->defaultval.bytes) { - /* Default was explicitly set as a str; try to lookup corresponding int. */ - str_t *s = f->defaultval.bytes; - if (upb_enumdef_ntoiz(e, s->str, val)) { - return true; - } - } else { - /* Default is unset; try to pull in enumdef default. */ - if (upb_enumdef_numvals(e) > 0) { - *val = upb_enumdef_default(e); - return true; - } - } - } - return false; -} - -const struct upb_refcounted_vtbl upb_fielddef_vtbl = {visitfield, freefield}; - +#if 0 upb_fielddef *upb_fielddef_new(const void *o) { upb_fielddef *f = upb_gmalloc(sizeof(*f)); if (!f) return NULL; - if (!upb_def_init(upb_fielddef_upcast_mutable(f), UPB_DEF_FIELD, - &upb_fielddef_vtbl, o)) { - upb_gfree(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->msg_is_symbolic = false; f->label_ = UPB_LABEL_OPTIONAL; f->type_ = UPB_TYPE_INT32; f->number_ = 0; @@ -712,13 +475,9 @@ upb_fielddef *upb_fielddef_new(const void *o) { f->intfmt = UPB_INTFMT_VARIABLE; return f; } - -bool upb_fielddef_typeisset(const upb_fielddef *f) { - return f->type_is_set_; -} +#endif upb_fieldtype_t upb_fielddef_type(const upb_fielddef *f) { - UPB_ASSERT(f->type_is_set_); return f->type_; } @@ -798,60 +557,16 @@ size_t upb_fielddef_getjsonname(const upb_fielddef *f, char *buf, size_t len) { } const upb_msgdef *upb_fielddef_containingtype(const upb_fielddef *f) { - return f->msg_is_symbolic ? NULL : f->msg.def; + return f->msgdef; } const upb_oneofdef *upb_fielddef_containingoneof(const upb_fielddef *f) { return f->oneof; } -upb_msgdef *upb_fielddef_containingtype_mutable(upb_fielddef *f) { - return (upb_msgdef*)upb_fielddef_containingtype(f); -} - -const char *upb_fielddef_containingtypename(upb_fielddef *f) { - return f->msg_is_symbolic ? f->msg.name : NULL; -} - -static void release_containingtype(upb_fielddef *f) { - if (f->msg_is_symbolic) upb_gfree(f->msg.name); -} - -bool upb_fielddef_setcontainingtypename(upb_fielddef *f, const char *name, - upb_status *s) { - char *name_copy; - UPB_ASSERT(!upb_fielddef_isfrozen(f)); - if (upb_fielddef_containingtype(f)) { - upb_status_seterrmsg(s, "field has already been added to a message."); - return false; - } - /* TODO: validate name (upb_isident() doesn't quite work atm because this name - * may have a leading "."). */ - - name_copy = upb_gstrdup(name); - if (!name_copy) { - upb_upberr_setoom(s); - return false; - } - - release_containingtype(f); - f->msg.name = name_copy; - f->msg_is_symbolic = true; - return true; -} - -bool upb_fielddef_setname(upb_fielddef *f, const char *name, upb_status *s) { - if (upb_fielddef_containingtype(f) || upb_fielddef_containingoneof(f)) { - upb_status_seterrmsg(s, "Already added to message or oneof"); - return false; - } - return upb_def_setfullname(upb_fielddef_upcast_mutable(f), name, s); -} - -static void chkdefaulttype(const upb_fielddef *f, upb_fieldtype_t type) { +static void chkdefaulttype(const upb_fielddef *f, int ctype) { UPB_UNUSED(f); - UPB_UNUSED(type); - UPB_ASSERT(f->type_is_set_ && upb_fielddef_type(f) == type); + UPB_UNUSED(ctype); } int64_t upb_fielddef_defaultint64(const upb_fielddef *f) { @@ -860,15 +575,8 @@ int64_t upb_fielddef_defaultint64(const upb_fielddef *f) { } int32_t upb_fielddef_defaultint32(const upb_fielddef *f) { - if (f->type_is_set_ && upb_fielddef_type(f) == UPB_TYPE_ENUM) { - int32_t val; - bool ok = enumdefaultint32(f, &val); - UPB_ASSERT(ok); - return val; - } else { - chkdefaulttype(f, UPB_TYPE_INT32); - return f->defaultval.sint; - } + chkdefaulttype(f, UPB_TYPE_INT32); + return f->defaultval.sint; } uint64_t upb_fielddef_defaultuint64(const upb_fielddef *f) { @@ -943,10 +651,6 @@ static void upb_fielddef_init_default(upb_fielddef *f) { } } -const upb_def *upb_fielddef_subdef(const upb_fielddef *f) { - return f->subdef_is_symbolic ? NULL : f->sub.def; -} - const upb_msgdef *upb_fielddef_msgsubdef(const upb_fielddef *f) { const upb_def *def = upb_fielddef_subdef(f); return def ? upb_dyncast_msgdef(def) : NULL; @@ -957,10 +661,6 @@ const upb_enumdef *upb_fielddef_enumsubdef(const upb_fielddef *f) { return def ? upb_dyncast_enumdef(def) : NULL; } -upb_def *upb_fielddef_subdef_mutable(upb_fielddef *f) { - return (upb_def*)upb_fielddef_subdef(f); -} - const char *upb_fielddef_subdefname(const upb_fielddef *f) { if (f->subdef_is_symbolic) { return f->sub.name; @@ -985,306 +685,24 @@ bool upb_fielddef_setnumber(upb_fielddef *f, uint32_t number, upb_status *s) { return true; } -void upb_fielddef_settype(upb_fielddef *f, upb_fieldtype_t type) { - UPB_ASSERT(!upb_fielddef_isfrozen(f)); - UPB_ASSERT(upb_fielddef_checktype(type)); - upb_fielddef_uninit_default(f); - f->type_ = type; - f->type_is_set_ = true; - upb_fielddef_init_default(f); -} - -void upb_fielddef_setdescriptortype(upb_fielddef *f, int type) { - UPB_ASSERT(!upb_fielddef_isfrozen(f)); - switch (type) { - case UPB_DESCRIPTOR_TYPE_DOUBLE: - upb_fielddef_settype(f, UPB_TYPE_DOUBLE); - break; - case UPB_DESCRIPTOR_TYPE_FLOAT: - upb_fielddef_settype(f, UPB_TYPE_FLOAT); - break; - case UPB_DESCRIPTOR_TYPE_INT64: - case UPB_DESCRIPTOR_TYPE_SFIXED64: - case UPB_DESCRIPTOR_TYPE_SINT64: - upb_fielddef_settype(f, UPB_TYPE_INT64); - break; - case UPB_DESCRIPTOR_TYPE_UINT64: - case UPB_DESCRIPTOR_TYPE_FIXED64: - upb_fielddef_settype(f, UPB_TYPE_UINT64); - break; - case UPB_DESCRIPTOR_TYPE_INT32: - case UPB_DESCRIPTOR_TYPE_SFIXED32: - case UPB_DESCRIPTOR_TYPE_SINT32: - upb_fielddef_settype(f, UPB_TYPE_INT32); - break; - case UPB_DESCRIPTOR_TYPE_UINT32: - case UPB_DESCRIPTOR_TYPE_FIXED32: - upb_fielddef_settype(f, UPB_TYPE_UINT32); - break; - case UPB_DESCRIPTOR_TYPE_BOOL: - upb_fielddef_settype(f, UPB_TYPE_BOOL); - break; - case UPB_DESCRIPTOR_TYPE_STRING: - upb_fielddef_settype(f, UPB_TYPE_STRING); - break; - case UPB_DESCRIPTOR_TYPE_BYTES: - upb_fielddef_settype(f, UPB_TYPE_BYTES); - break; - case UPB_DESCRIPTOR_TYPE_GROUP: - case UPB_DESCRIPTOR_TYPE_MESSAGE: - upb_fielddef_settype(f, UPB_TYPE_MESSAGE); - break; - case UPB_DESCRIPTOR_TYPE_ENUM: - upb_fielddef_settype(f, UPB_TYPE_ENUM); - break; - default: UPB_ASSERT(false); - } - - if (type == UPB_DESCRIPTOR_TYPE_FIXED64 || - type == UPB_DESCRIPTOR_TYPE_FIXED32 || - type == UPB_DESCRIPTOR_TYPE_SFIXED64 || - type == UPB_DESCRIPTOR_TYPE_SFIXED32) { - upb_fielddef_setintfmt(f, UPB_INTFMT_FIXED); - } else if (type == UPB_DESCRIPTOR_TYPE_SINT64 || - type == UPB_DESCRIPTOR_TYPE_SINT32) { - upb_fielddef_setintfmt(f, UPB_INTFMT_ZIGZAG); - } else { - upb_fielddef_setintfmt(f, UPB_INTFMT_VARIABLE); - } - - upb_fielddef_settagdelim(f, type == UPB_DESCRIPTOR_TYPE_GROUP); -} - upb_descriptortype_t upb_fielddef_descriptortype(const upb_fielddef *f) { - switch (upb_fielddef_type(f)) { - case UPB_TYPE_FLOAT: return UPB_DESCRIPTOR_TYPE_FLOAT; - case UPB_TYPE_DOUBLE: return UPB_DESCRIPTOR_TYPE_DOUBLE; - case UPB_TYPE_BOOL: return UPB_DESCRIPTOR_TYPE_BOOL; - case UPB_TYPE_STRING: return UPB_DESCRIPTOR_TYPE_STRING; - case UPB_TYPE_BYTES: return UPB_DESCRIPTOR_TYPE_BYTES; - case UPB_TYPE_ENUM: return UPB_DESCRIPTOR_TYPE_ENUM; - case UPB_TYPE_INT32: - switch (upb_fielddef_intfmt(f)) { - case UPB_INTFMT_VARIABLE: return UPB_DESCRIPTOR_TYPE_INT32; - case UPB_INTFMT_FIXED: return UPB_DESCRIPTOR_TYPE_SFIXED32; - case UPB_INTFMT_ZIGZAG: return UPB_DESCRIPTOR_TYPE_SINT32; - } - case UPB_TYPE_INT64: - switch (upb_fielddef_intfmt(f)) { - case UPB_INTFMT_VARIABLE: return UPB_DESCRIPTOR_TYPE_INT64; - case UPB_INTFMT_FIXED: return UPB_DESCRIPTOR_TYPE_SFIXED64; - case UPB_INTFMT_ZIGZAG: return UPB_DESCRIPTOR_TYPE_SINT64; - } - case UPB_TYPE_UINT32: - switch (upb_fielddef_intfmt(f)) { - case UPB_INTFMT_VARIABLE: return UPB_DESCRIPTOR_TYPE_UINT32; - case UPB_INTFMT_FIXED: return UPB_DESCRIPTOR_TYPE_FIXED32; - case UPB_INTFMT_ZIGZAG: return -1; - } - case UPB_TYPE_UINT64: - switch (upb_fielddef_intfmt(f)) { - case UPB_INTFMT_VARIABLE: return UPB_DESCRIPTOR_TYPE_UINT64; - case UPB_INTFMT_FIXED: return UPB_DESCRIPTOR_TYPE_FIXED64; - case UPB_INTFMT_ZIGZAG: return -1; - } - case UPB_TYPE_MESSAGE: - return upb_fielddef_istagdelim(f) ? - UPB_DESCRIPTOR_TYPE_GROUP : UPB_DESCRIPTOR_TYPE_MESSAGE; - } - return 0; -} - -void upb_fielddef_setisextension(upb_fielddef *f, bool is_extension) { - UPB_ASSERT(!upb_fielddef_isfrozen(f)); - f->is_extension_ = is_extension; -} - -void upb_fielddef_setlazy(upb_fielddef *f, bool lazy) { - UPB_ASSERT(!upb_fielddef_isfrozen(f)); - f->lazy_ = lazy; -} - -void upb_fielddef_setpacked(upb_fielddef *f, bool packed) { - UPB_ASSERT(!upb_fielddef_isfrozen(f)); - f->packed_ = packed; + return f->type; } -void upb_fielddef_setlabel(upb_fielddef *f, upb_label_t label) { - UPB_ASSERT(!upb_fielddef_isfrozen(f)); - UPB_ASSERT(upb_fielddef_checklabel(label)); - f->label_ = label; -} - -void upb_fielddef_setintfmt(upb_fielddef *f, upb_intfmt_t fmt) { - UPB_ASSERT(!upb_fielddef_isfrozen(f)); - UPB_ASSERT(upb_fielddef_checkintfmt(fmt)); - f->intfmt = fmt; -} - -void upb_fielddef_settagdelim(upb_fielddef *f, bool tag_delim) { - UPB_ASSERT(!upb_fielddef_isfrozen(f)); - f->tagdelim = tag_delim; - f->tagdelim = tag_delim; -} - -static bool checksetdefault(upb_fielddef *f, upb_fieldtype_t type) { - if (!f->type_is_set_ || upb_fielddef_isfrozen(f) || - upb_fielddef_type(f) != type) { - UPB_ASSERT(false); - return false; - } - if (f->default_is_string) { - str_t *s = f->defaultval.bytes; - UPB_ASSERT(s || type == UPB_TYPE_ENUM); - if (s) freestr(s); - } - f->default_is_string = false; - return true; -} - -void upb_fielddef_setdefaultint64(upb_fielddef *f, int64_t value) { - if (checksetdefault(f, UPB_TYPE_INT64)) - f->defaultval.sint = value; -} - -void upb_fielddef_setdefaultint32(upb_fielddef *f, int32_t value) { - if ((upb_fielddef_type(f) == UPB_TYPE_ENUM && - checksetdefault(f, UPB_TYPE_ENUM)) || - checksetdefault(f, UPB_TYPE_INT32)) { - f->defaultval.sint = value; - } -} - -void upb_fielddef_setdefaultuint64(upb_fielddef *f, uint64_t value) { - if (checksetdefault(f, UPB_TYPE_UINT64)) - f->defaultval.uint = value; -} - -void upb_fielddef_setdefaultuint32(upb_fielddef *f, uint32_t value) { - if (checksetdefault(f, UPB_TYPE_UINT32)) - f->defaultval.uint = value; -} - -void upb_fielddef_setdefaultbool(upb_fielddef *f, bool value) { - if (checksetdefault(f, UPB_TYPE_BOOL)) - f->defaultval.uint = value; -} - -void upb_fielddef_setdefaultfloat(upb_fielddef *f, float value) { - if (checksetdefault(f, UPB_TYPE_FLOAT)) - f->defaultval.flt = value; -} - -void upb_fielddef_setdefaultdouble(upb_fielddef *f, double value) { - if (checksetdefault(f, UPB_TYPE_DOUBLE)) - f->defaultval.dbl = value; -} - -bool upb_fielddef_setdefaultstr(upb_fielddef *f, const void *str, size_t len, - upb_status *s) { - str_t *str2; - UPB_ASSERT(upb_fielddef_isstring(f) || f->type_ == UPB_TYPE_ENUM); - if (f->type_ == UPB_TYPE_ENUM && !upb_isident(str, len, false, s)) - return false; - - if (f->default_is_string) { - str_t *s = f->defaultval.bytes; - UPB_ASSERT(s || f->type_ == UPB_TYPE_ENUM); - if (s) freestr(s); - } else { - UPB_ASSERT(f->type_ == UPB_TYPE_ENUM); - } - - str2 = newstr(str, len); - f->defaultval.bytes = str2; - f->default_is_string = true; - return true; -} - -void upb_fielddef_setdefaultcstr(upb_fielddef *f, const char *str, - upb_status *s) { - UPB_ASSERT(f->type_is_set_); - upb_fielddef_setdefaultstr(f, str, str ? strlen(str) : 0, s); -} - -bool upb_fielddef_enumhasdefaultint32(const upb_fielddef *f) { - int32_t val; - UPB_ASSERT(f->type_is_set_ && f->type_ == UPB_TYPE_ENUM); - return enumdefaultint32(f, &val); -} - -bool upb_fielddef_enumhasdefaultstr(const upb_fielddef *f) { - UPB_ASSERT(f->type_is_set_ && f->type_ == UPB_TYPE_ENUM); - return enumdefaultstr(f) != NULL; -} - -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; - } -} - -static void release_subdef(upb_fielddef *f) { - if (f->subdef_is_symbolic) { - upb_gfree(f->sub.name); - } else if (f->sub.def) { - upb_unref2(f->sub.def, f); - } -} - -bool upb_fielddef_setsubdef(upb_fielddef *f, const upb_def *subdef, - upb_status *s) { - UPB_ASSERT(!upb_fielddef_isfrozen(f)); - UPB_ASSERT(upb_fielddef_hassubdef(f)); - if (subdef && !upb_subdef_typecheck(f, subdef, s)) return false; - release_subdef(f); - f->sub.def = subdef; - f->subdef_is_symbolic = false; - if (f->sub.def) upb_ref2(f->sub.def, f); - return true; -} - -bool upb_fielddef_setmsgsubdef(upb_fielddef *f, const upb_msgdef *subdef, - upb_status *s) { - return upb_fielddef_setsubdef(f, upb_msgdef_upcast(subdef), s); -} - -bool upb_fielddef_setenumsubdef(upb_fielddef *f, const upb_enumdef *subdef, - upb_status *s) { - return upb_fielddef_setsubdef(f, upb_enumdef_upcast(subdef), s); -} - -bool upb_fielddef_setsubdefname(upb_fielddef *f, const char *name, - upb_status *s) { - char *name_copy; - UPB_ASSERT(!upb_fielddef_isfrozen(f)); - if (!upb_fielddef_hassubdef(f)) { - upb_status_seterrmsg(s, "field type does not accept a subdef"); - return false; - } - - name_copy = upb_gstrdup(name); - if (!name_copy) { - upb_upberr_setoom(s); +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; } - - /* TODO: validate name (upb_isident() doesn't quite work atm because this name - * may have a leading "."). */ - release_subdef(f); - f->sub.name = name_copy; - f->subdef_is_symbolic = true; - return true; } bool upb_fielddef_issubmsg(const upb_fielddef *f) { @@ -1343,66 +761,6 @@ static const char *kValueFullMessageName = "google.protobuf.Value"; static const char *kListValueFullMessageName = "google.protobuf.ListValue"; static const char *kStructFullMessageName = "google.protobuf.Struct"; -static void visitmsg(const upb_refcounted *r, upb_refcounted_visit *visit, - void *closure) { - upb_msg_oneof_iter o; - const upb_msgdef *m = (const upb_msgdef*)r; - const upb_def *def = upb_msgdef_upcast(m); - upb_msg_field_iter i; - for(upb_msg_field_begin(&i, m); - !upb_msg_field_done(&i); - upb_msg_field_next(&i)) { - upb_fielddef *f = upb_msg_iter_field(&i); - visit(r, upb_fielddef_upcast2(f), closure); - } - for(upb_msg_oneof_begin(&o, m); - !upb_msg_oneof_done(&o); - upb_msg_oneof_next(&o)) { - upb_oneofdef *f = upb_msg_iter_oneof(&o); - visit(r, upb_oneofdef_upcast(f), closure); - } - if (upb_def_file(def)) { - visit(r, upb_filedef_upcast(upb_def_file(def)), closure); - } -} - -static void freemsg(upb_refcounted *r) { - upb_msgdef *m = (upb_msgdef*)r; - upb_strtable_uninit(&m->ntof); - upb_inttable_uninit(&m->itof); - upb_def_uninit(upb_msgdef_upcast_mutable(m)); - upb_gfree(m); -} - -const struct upb_refcounted_vtbl upb_msgdef_vtbl = {visitmsg, freemsg}; - -upb_msgdef *upb_msgdef_new(const void *owner) { - upb_msgdef *m = upb_gmalloc(sizeof(*m)); - if (!m) return NULL; - - if (!upb_def_init(upb_msgdef_upcast_mutable(m), UPB_DEF_MSG, &upb_msgdef_vtbl, - owner)) { - goto err2; - } - - if (!upb_inttable_init(&m->itof, UPB_CTYPE_PTR)) goto err2; - if (!upb_strtable_init(&m->ntof, UPB_CTYPE_PTR)) goto err1; - m->map_entry = false; - m->syntax = UPB_SYNTAX_PROTO2; - return m; - -err1: - upb_inttable_uninit(&m->itof); -err2: - upb_gfree(m); - return NULL; -} - -bool upb_msgdef_freeze(upb_msgdef *m, upb_status *status) { - upb_def *d = upb_msgdef_upcast_mutable(m); - return upb_def_freeze(&d, 1, status); -} - const char *upb_msgdef_fullname(const upb_msgdef *m) { return upb_def_fullname(upb_msgdef_upcast(m)); } @@ -1411,20 +769,6 @@ const char *upb_msgdef_name(const upb_msgdef *m) { return upb_def_name(upb_msgdef_upcast(m)); } -bool upb_msgdef_setfullname(upb_msgdef *m, const char *fullname, - upb_status *s) { - return upb_def_setfullname(upb_msgdef_upcast_mutable(m), fullname, s); -} - -bool upb_msgdef_setsyntax(upb_msgdef *m, upb_syntax_t syntax) { - if (syntax != UPB_SYNTAX_PROTO2 && syntax != UPB_SYNTAX_PROTO3) { - return false; - } - - m->syntax = syntax; - return true; -} - upb_syntax_t upb_msgdef_syntax(const upb_msgdef *m) { return m->syntax; } @@ -1449,17 +793,6 @@ static bool check_field_add(const upb_msgdef *m, const upb_fielddef *f, return true; } -static void add_field(upb_msgdef *m, upb_fielddef *f, const void *ref_donor) { - release_containingtype(f); - f->msg.def = m; - f->msg_is_symbolic = false; - upb_inttable_insert(&m->itof, upb_fielddef_number(f), upb_value_ptr(f)); - upb_strtable_insert(&m->ntof, upb_fielddef_name(f), upb_value_ptr(f)); - upb_ref2(f, m); - upb_ref2(m, f); - if (ref_donor) upb_fielddef_unref(f, ref_donor); -} - bool upb_msgdef_addfield(upb_msgdef *m, upb_fielddef *f, const void *ref_donor, upb_status *s) { /* TODO: extensions need to have a separate namespace, because proto2 allows a @@ -1590,11 +923,6 @@ int upb_msgdef_numoneofs(const upb_msgdef *m) { return upb_strtable_count(&m->ntof) - upb_inttable_count(&m->itof); } -void upb_msgdef_setmapentry(upb_msgdef *m, bool map_entry) { - UPB_ASSERT(!upb_msgdef_isfrozen(m)); - m->map_entry = map_entry; -} - bool upb_msgdef_mapentry(const upb_msgdef *m) { return m->map_entry; } @@ -1668,80 +996,8 @@ void upb_msg_oneof_iter_setdone(upb_msg_oneof_iter *iter) { /* upb_oneofdef ***************************************************************/ -static void visitoneof(const upb_refcounted *r, upb_refcounted_visit *visit, - void *closure) { - const upb_oneofdef *o = (const upb_oneofdef*)r; - upb_oneof_iter i; - for (upb_oneof_begin(&i, o); !upb_oneof_done(&i); upb_oneof_next(&i)) { - const upb_fielddef *f = upb_oneof_iter_field(&i); - visit(r, upb_fielddef_upcast2(f), closure); - } - if (o->parent) { - visit(r, upb_msgdef_upcast2(o->parent), closure); - } -} - -static void freeoneof(upb_refcounted *r) { - upb_oneofdef *o = (upb_oneofdef*)r; - upb_strtable_uninit(&o->ntof); - upb_inttable_uninit(&o->itof); - upb_gfree((void*)o->name); - upb_gfree(o); -} - -const struct upb_refcounted_vtbl upb_oneofdef_vtbl = {visitoneof, freeoneof}; - -upb_oneofdef *upb_oneofdef_new(const void *owner) { - upb_oneofdef *o = upb_gmalloc(sizeof(*o)); - - if (!o) { - return NULL; - } - - o->parent = NULL; - o->name = NULL; - - if (!upb_refcounted_init(upb_oneofdef_upcast_mutable(o), &upb_oneofdef_vtbl, - owner)) { - goto err2; - } - - if (!upb_inttable_init(&o->itof, UPB_CTYPE_PTR)) goto err2; - if (!upb_strtable_init(&o->ntof, UPB_CTYPE_PTR)) goto err1; - - return o; - -err1: - upb_inttable_uninit(&o->itof); -err2: - upb_gfree(o); - return NULL; -} - const char *upb_oneofdef_name(const upb_oneofdef *o) { return o->name; } -bool upb_oneofdef_setname(upb_oneofdef *o, const char *name, upb_status *s) { - UPB_ASSERT(!upb_oneofdef_isfrozen(o)); - if (upb_oneofdef_containingtype(o)) { - upb_status_seterrmsg(s, "oneof already added to a message"); - return false; - } - - if (!upb_isident(name, strlen(name), true, s)) { - return false; - } - - name = upb_gstrdup(name); - if (!name) { - upb_status_seterrmsg(s, "One of memory"); - return false; - } - - upb_gfree((void*)o->name); - o->name = name; - return true; -} - const upb_msgdef *upb_oneofdef_containingtype(const upb_oneofdef *o) { return o->parent; } @@ -1818,7 +1074,6 @@ bool upb_oneofdef_addfield(upb_oneofdef *o, upb_fielddef *f, } } - release_containingtype(f); f->oneof = o; upb_inttable_insert(&o->itof, upb_fielddef_number(f), upb_value_ptr(f)); upb_strtable_insert(&o->ntof, upb_fielddef_name(f), upb_value_ptr(f)); @@ -1864,35 +1119,6 @@ void upb_oneof_iter_setdone(upb_oneof_iter *iter) { /* upb_filedef ****************************************************************/ -static void visitfiledef(const upb_refcounted *r, upb_refcounted_visit *visit, - void *closure) { - const upb_filedef *f = (const upb_filedef*)r; - size_t i; - - for(i = 0; i < upb_filedef_defcount(f); i++) { - visit(r, upb_def_upcast(upb_filedef_def(f, i)), closure); - } -} - -static void freefiledef(upb_refcounted *r) { - upb_filedef *f = (upb_filedef*)r; - size_t i; - - for(i = 0; i < upb_filedef_depcount(f); i++) { - upb_filedef_unref(upb_filedef_dep(f, i), f); - } - - upb_inttable_uninit(&f->defs); - upb_inttable_uninit(&f->deps); - upb_gfree((void*)f->name); - upb_gfree((void*)f->package); - upb_gfree((void*)f->phpprefix); - upb_gfree((void*)f->phpnamespace); - upb_gfree(f); -} - -const struct upb_refcounted_vtbl upb_filedef_vtbl = {visitfiledef, freefiledef}; - upb_filedef *upb_filedef_new(const void *owner) { upb_filedef *f = upb_gmalloc(sizeof(*f)); @@ -1906,11 +1132,6 @@ upb_filedef *upb_filedef_new(const void *owner) { f->phpnamespace = NULL; f->syntax = UPB_SYNTAX_PROTO2; - if (!upb_refcounted_init(upb_filedef_upcast_mutable(f), &upb_filedef_vtbl, - owner)) { - goto err; - } - if (!upb_inttable_init(&f->defs, UPB_CTYPE_CONSTPTR)) { goto err; } @@ -1978,122 +1199,8 @@ const upb_filedef *upb_filedef_dep(const upb_filedef *f, size_t i) { } } -bool upb_filedef_setname(upb_filedef *f, const char *name, upb_status *s) { - name = upb_gstrdup(name); - if (!name) { - upb_upberr_setoom(s); - return false; - } - upb_gfree((void*)f->name); - f->name = name; - return true; -} - -bool upb_filedef_setpackage(upb_filedef *f, const char *package, - upb_status *s) { - if (!upb_isident(package, strlen(package), true, s)) return false; - package = upb_gstrdup(package); - if (!package) { - upb_upberr_setoom(s); - return false; - } - upb_gfree((void*)f->package); - f->package = package; - return true; -} - -bool upb_filedef_setphpprefix(upb_filedef *f, const char *phpprefix, - upb_status *s) { - phpprefix = upb_gstrdup(phpprefix); - if (!phpprefix) { - upb_upberr_setoom(s); - return false; - } - upb_gfree((void*)f->phpprefix); - f->phpprefix = phpprefix; - return true; -} - -bool upb_filedef_setphpnamespace(upb_filedef *f, const char *phpnamespace, - upb_status *s) { - phpnamespace = upb_gstrdup(phpnamespace); - if (!phpnamespace) { - upb_upberr_setoom(s); - return false; - } - upb_gfree((void*)f->phpnamespace); - f->phpnamespace = phpnamespace; - return true; -} - -bool upb_filedef_setsyntax(upb_filedef *f, upb_syntax_t syntax, - upb_status *s) { - UPB_UNUSED(s); - if (syntax != UPB_SYNTAX_PROTO2 && - syntax != UPB_SYNTAX_PROTO3) { - upb_status_seterrmsg(s, "Unknown syntax value."); - return false; - } - f->syntax = syntax; - - { - /* Set all messages in this file to match. */ - size_t i; - for (i = 0; i < upb_filedef_defcount(f); i++) { - /* Casting const away is safe since all defs in mutable filedef must - * also be mutable. */ - upb_def *def = (upb_def*)upb_filedef_def(f, i); - - upb_msgdef *m = upb_dyncast_msgdef_mutable(def); - if (m) { - m->syntax = syntax; - } - } - } - - return true; -} - -bool upb_filedef_adddef(upb_filedef *f, upb_def *def, const void *ref_donor, - upb_status *s) { - if (def->file) { - upb_status_seterrmsg(s, "Def is already part of another filedef."); - return false; - } - - if (upb_inttable_push(&f->defs, upb_value_constptr(def))) { - def->file = f; - upb_ref2(def, f); - upb_ref2(f, def); - if (ref_donor) upb_def_unref(def, ref_donor); - if (def->type == UPB_DEF_MSG) { - upb_downcast_msgdef_mutable(def)->syntax = f->syntax; - } - return true; - } else { - upb_upberr_setoom(s); - return false; - } -} - -bool upb_filedef_adddep(upb_filedef *f, const upb_filedef *dep) { - if (upb_inttable_push(&f->deps, upb_value_constptr(dep))) { - /* Regular ref instead of ref2 because files can't form cycles. */ - upb_filedef_ref(dep, f); - return true; - } else { - return false; - } -} - void upb_symtab_free(upb_symtab *s) { - upb_strtable_iter i; - upb_strtable_begin(&i, &s->symtab); - for (; !upb_strtable_done(&i); upb_strtable_next(&i)) { - const upb_def *def = upb_value_getptr(upb_strtable_iter_value(&i)); - upb_def_unref(def, s); - } - upb_strtable_uninit(&s->symtab); + upb_arena_uninit(&s->arena); upb_gfree(s); } @@ -2103,7 +1210,17 @@ upb_symtab *upb_symtab_new() { return NULL; } - upb_strtable_init(&s->symtab, UPB_CTYPE_PTR); + 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; + +err1: + upb_arena_uninit(&s->arena); +err2: + upb_gfree(s); return s; } @@ -2153,77 +1270,7 @@ const upb_def *upb_symtab_resolve(const upb_symtab *s, const char *base, return ret; } -/* TODO(haberman): we need a lot more testing of error conditions. */ -static bool symtab_add(upb_symtab *s, upb_def *const*defs, size_t n, - void *ref_donor, upb_refcounted *freeze_also, - upb_status *status) { - size_t i; - size_t add_n; - size_t freeze_n; - upb_strtable_iter iter; - upb_refcounted **add_objs = NULL; - upb_def **add_defs = NULL; - size_t add_objs_size; - upb_strtable addtab; - - if (n == 0 && !freeze_also) { - return true; - } - - if (!upb_strtable_init(&addtab, UPB_CTYPE_PTR)) { - upb_status_seterrmsg(status, "out of memory"); - return false; - } - - /* Add new defs to our "add" set. */ - for (i = 0; i < n; i++) { - upb_def *def = defs[i]; - const char *fullname; - upb_fielddef *f; - - if (upb_def_isfrozen(def)) { - upb_status_seterrmsg(status, "added defs must be mutable"); - goto err; - } - UPB_ASSERT(!upb_def_isfrozen(def)); - fullname = upb_def_fullname(def); - if (!fullname) { - upb_status_seterrmsg( - status, "Anonymous defs cannot be added to a symtab"); - goto err; - } - - f = upb_dyncast_fielddef_mutable(def); - - if (f) { - if (!upb_fielddef_containingtypename(f)) { - upb_status_seterrmsg(status, - "Standalone fielddefs must have a containing type " - "(extendee) name set"); - goto err; - } - } else { - if (upb_strtable_lookup(&addtab, fullname, NULL)) { - upb_status_seterrf(status, "Conflicting defs named '%s'", fullname); - goto err; - } - if (upb_strtable_lookup(&s->symtab, fullname, NULL)) { - upb_status_seterrf(status, "Symtab already has a def named '%s'", - fullname); - goto err; - } - if (!upb_strtable_insert(&addtab, fullname, upb_value_ptr(def))) - goto oom_err; - upb_def_donateref(def, ref_donor, s); - } - - if (upb_dyncast_fielddef_mutable(def)) { - /* TODO(haberman): allow adding extensions attached to files. */ - upb_status_seterrf(status, "Can't add extensions to symtab.\n"); - goto err; - } - } - +#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)) { @@ -2258,132 +1305,202 @@ static bool symtab_add(upb_symtab *s, upb_def *const*defs, size_t n, } } } +#endif - /* We need an array of the defs in addtab, for passing to - * upb_refcounted_freeze(). */ - add_objs_size = upb_strtable_count(&addtab); - if (freeze_also) { - add_objs_size++; - } +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)); + upb_stringview name = google_protobuf_OneofDescriptorProto_name(oneof_proto); + upb_value o_ptr = upb_value_ptr(o); - add_defs = upb_gmalloc(sizeof(void*) * add_objs_size); - if (add_defs == NULL) goto oom_err; - upb_strtable_begin(&iter, &addtab); - for (add_n = 0; !upb_strtable_done(&iter); upb_strtable_next(&iter)) { - add_defs[add_n++] = upb_value_getptr(upb_strtable_iter_value(&iter)); - } + CHK(o); + CHK(upb_inttable_init2(&o->itof, UPB_CTYPE_PTR, alloc)); + CHK(upb_strtable_init2(&o->ntof, UPB_CTYPE_PTR, alloc)); - /* Validate defs. */ - if (!_upb_def_validate(add_defs, add_n, status)) { - goto err; + o->index = upb_strtable_count(&m->ntof); + o->name = upb_strdup2(name.data, name.size, alloc); + o->parent = m; + + CHK(upb_strtable_insert3(&m->ntof, name.data, name.size, o_ptr, 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; + const upb_array *arr; + + CHK(f); + + f->msgdef = m; + + 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_; +} + +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)); + const google_protobuf_MessageOptions *options; + const upb_array *arr; + + CHK(m); + CHK(upb_inttable_init2(&m->itof, UPB_CTYPE_PTR, alloc)); + CHK(upb_strtable_init2(&m->ntof, UPB_CTYPE_PTR, alloc)); + + m->map_entry = false; + + options = google_protobuf_DescriptorProto_options(msg_proto); + + if (options) { + m->map_entry = google_protobuf_MessageOptions_map_entry(options); } - /* Cheat a little and give the array a new type. - * This is probably undefined behavior, but this code will be deleted soon. */ - add_objs = (upb_refcounted**)add_defs; + arr = google_protobuf_DescriptorProto_oneof_decl(msg_proto); - freeze_n = add_n; - if (freeze_also) { - add_objs[freeze_n++] = freeze_also; + 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)); } - if (!upb_refcounted_freeze(add_objs, freeze_n, status, - UPB_MAX_MESSAGE_DEPTH * 2)) { - goto err; + 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)); } - /* This must be delayed until all errors have been detected, since error - * recovery code uses this table to cleanup defs. */ - upb_strtable_uninit(&addtab); - - /* TODO(haberman) we don't properly handle errors after this point (like - * OOM in upb_strtable_insert() below). */ - for (i = 0; i < add_n; i++) { - upb_def *def = (upb_def*)add_objs[i]; - const char *name = upb_def_fullname(def); - bool success; - success = upb_strtable_insert(&s->symtab, name, upb_value_ptr(def)); - UPB_ASSERT(success); + 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_gfree(add_defs); - return true; -oom_err: - upb_status_seterrmsg(status, "out of memory"); -err: { - /* We need to donate the refs back. */ - upb_strtable_begin(&iter, &addtab); - for (; !upb_strtable_done(&iter); upb_strtable_next(&iter)) { - upb_def *def = upb_value_getptr(upb_strtable_iter_value(&iter)); - upb_def_donateref(def, s, ref_donor); - } + 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_strtable_uninit(&addtab); - upb_gfree(add_defs); - UPB_ASSERT(!upb_ok(status)); - return false; + + return true; } -bool upb_symtab_add(upb_symtab *s, upb_def *const*defs, size_t n, - void *ref_donor, upb_status *status) { - return symtab_add(s, defs, n, ref_donor, NULL, status); +static char* strviewdup(upb_symtab *symtab, upb_stringview view) { + if (view.size == 0) { + return NULL; + } + return upb_strdup2(view.data, view.size, upb_arena_alloc(&symtab->arena)); } -bool upb_symtab_addfile(upb_symtab *s, upb_filedef *file, upb_status *status) { - size_t n; +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; + 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_def **defs; - bool ret; - n = upb_filedef_defcount(file); - if (n == 0) { - return true; - } - defs = upb_gmalloc(sizeof(*defs) * n); + upb_arena_init(&tmparena); + upb_strtable_init2(&addtab, UPB_CTYPE_PTR, upb_arena_alloc(&tmparena)); + file_proto = + google_protobuf_FileDescriptorProto_parsenew(serialized, &tmparena); - if (defs == NULL) { - upb_status_seterrmsg(status, "Out of memory"); - return false; - } - for (i = 0; i < n; i++) { - defs[i] = upb_filedef_mutabledef(file, i); + if (!file_proto || !file) goto err; + + file->name = + strviewdup(s, google_protobuf_FileDescriptorProto_name(file_proto)); + file->package = + strviewdup(s, google_protobuf_FileDescriptorProto_package(file_proto)); + file->phpprefix = NULL; + file->phpnamespace = NULL; + + 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)); } - ret = symtab_add(s, defs, n, NULL, upb_filedef_upcast_mutable(file), status); + arr = google_protobuf_FileDescriptorProto_message_type(file_proto); - upb_gfree(defs); - return ret; -} + 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; + } -/* Iteration. */ + arr = google_protobuf_FileDescriptorProto_enum_type(file_proto); -static void advance_to_matching(upb_symtab_iter *iter) { - if (iter->type == UPB_DEF_ANY) - return; + 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; + } - while (!upb_strtable_done(&iter->iter) && - iter->type != upb_symtab_iter_def(iter)->type) { - upb_strtable_next(&iter->iter); + /* Now that all names are in the table, resolve references. */ + upb_strtable_begin(&iter, &addtab); + for (; !upb_strtable_done(&iter); upb_strtable_next(&iter)) { } -} -void upb_symtab_begin(upb_symtab_iter *iter, const upb_symtab *s, - upb_deftype_t type) { - upb_strtable_begin(&iter->iter, &s->symtab); - iter->type = type; - advance_to_matching(iter); -} + /* Success; add addtab to symtab. */ + upb_strtable_begin(&iter, &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); + upb_value value = upb_strtable_iter_value(&iter); + upb_strtable_insert3(&s->symtab, key, keylen, value, alloc); + } -void upb_symtab_next(upb_symtab_iter *iter) { - upb_strtable_next(&iter->iter); - advance_to_matching(iter); -} + return true; -bool upb_symtab_done(const upb_symtab_iter *iter) { - return upb_strtable_done(&iter->iter); +err: + upb_arena_uninit(&tmparena); + return false; } -const upb_def *upb_symtab_iter_def(const upb_symtab_iter *iter) { - return upb_value_getptr(upb_strtable_iter_value(&iter->iter)); +bool upb_symtab_addset(upb_symtab *s, const char *buf, size_t len, + upb_status *status) { + return true; } -- cgit v1.2.3 From 336402b4d7251d37239d2f7ff8259174525baa38 Mon Sep 17 00:00:00 2001 From: Joshua Haberman Date: Mon, 10 Dec 2018 10:18:48 -0800 Subject: WIP, core library compiles now. --- BUILD | 33 +-- CMakeLists.txt | 216 +------------- upb/bindings/lua/def.c | 780 ++++++------------------------------------------- upb/def.c | 722 ++++++++++++++++++++++++++------------------- upb/def.h | 13 +- upb/handlers.c | 4 +- upb/json/parser.c | 126 ++++---- upb/json/parser.h | 3 +- upb/json/parser.rl | 20 +- upb/json/printer.c | 2 +- upb/msg.h | 9 + upb/pb/textprinter.c | 4 +- upb/structdefs.int.h | 196 ------------- 13 files changed, 602 insertions(+), 1526 deletions(-) delete mode 100644 upb/structdefs.int.h (limited to 'upb/def.c') diff --git a/BUILD b/BUILD index 96418f1..df05e06 100644 --- a/BUILD +++ b/BUILD @@ -27,7 +27,6 @@ cc_library( "upb/port_undef.inc", "upb/refcounted.c", "upb/sink.c", - "upb/structdefs.int.h", "upb/structs.int.h", "upb/table.c", "upb/table.int.h", @@ -429,13 +428,6 @@ proto_library( ], ) -genrule( - name = "copy_google_descriptor_pb", - srcs = [":google_descriptor_proto"], - outs = ["generated/google/protobuf/descriptor.pb"], - cmd = "cp $< $@", -) - genrule( name = "generate_descriptor_c", srcs = ["google/protobuf/descriptor.proto"], @@ -462,16 +454,16 @@ genrule( cmd = "cp $< $@", ) -genrule( - name = "generated_json_test_proto_upbdefs", - srcs = ["generated/tests/json/test.proto.pb"], - outs = [ - "generated/tests/json/test.upbdefs.h", - "generated/tests/json/test.upbdefs.c", - ], - cmd = "UPBC=$$PWD/$(location :lua_upbc); INFILE=$$PWD/$<; cd $(GENDIR)/generated && $$UPBC --generate-upbdefs $$INFILE", - tools = [":lua_upbc"], -) +#genrule( +# name = "generated_json_test_proto_upbdefs", +# srcs = ["generated/tests/json/test.proto.pb"], +# outs = [ +# "generated/tests/json/test.upbdefs.h", +# "generated/tests/json/test.upbdefs.c", +# ], +# cmd = "UPBC=$$PWD/$(location :lua_upbc); INFILE=$$PWD/$<; cd $(GENDIR)/generated && $$UPBC --generate-upbdefs $$INFILE", +# tools = [":lua_upbc"], +#) genrule( name = "generate_json_ragel", @@ -488,11 +480,6 @@ generated_file_staleness_test( "google/protobuf/descriptor.upb.c", "google/protobuf/descriptor.upb.h", "tests/json/test.proto.pb", - "tests/json/test.upbdefs.c", - "tests/json/test.upbdefs.h", - "upb/descriptor/descriptor.pb", - "upb/descriptor/descriptor.upbdefs.c", - "upb/descriptor/descriptor.upbdefs.h", "upb/json/parser.c", "upb/pb/compile_decoder_x64.h", ], diff --git a/CMakeLists.txt b/CMakeLists.txt index 4fb3b53..26ac066 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -57,209 +57,6 @@ elseif(UNIX) set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--build-id") endif() -<<<<<<< HEAD -FIND_PACKAGE(Lua) -if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/third_party/protobuf/Makefile.am") - set(PROTOBUF_FOUND TRUE) -endif() -find_program(RAGEL NAMES ragel) - -if(LUA_FOUND) - include_directories(${LUA_INCLUDE_DIR}) - - add_library(upb_c SHARED - upb/bindings/lua/upb.c - upb/bindings/lua/def.c - upb/bindings/lua/msg.c - ) - target_link_libraries(upb_c LINK_PRIVATE - upbpb_pic - upbdef_pic - upbhandlers_pic upb_pic ) - - add_library(pb_c SHARED - upb/bindings/lua/upb/pb.c - ) - target_link_libraries(pb_c LINK_PRIVATE upb_c upbpb_pic) - - set_target_properties(upb_c - PROPERTIES - LIBRARY_OUTPUT_DIRECTORY "upb/bindings/lua" - PREFIX "" - SUFFIX ".so") - set_target_properties(pb_c - PROPERTIES - LIBRARY_OUTPUT_DIRECTORY "upb/bindings/lua/upb" - PREFIX "" - SUFFIX ".so") - - add_custom_command( - OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/tools/upbc - DEPENDS ${CMAKE_SOURCE_DIR}/tools/upbc - ${CMAKE_SOURCE_DIR}/tools/upbc.lua - ${CMAKE_SOURCE_DIR}/tools/make_c_api.lua - ${CMAKE_SOURCE_DIR}/upb/bindings/lua/upb.lua - ${CMAKE_SOURCE_DIR}/upb/bindings/lua/upb/pb.lua - upb_c - pb_c - COMMAND ${CMAKE_COMMAND} -E copy - ${CMAKE_SOURCE_DIR}/tools/upbc - ${CMAKE_SOURCE_DIR}/tools/upbc.lua - ${CMAKE_SOURCE_DIR}/tools/make_c_api.lua - ${CMAKE_CURRENT_BINARY_DIR}/tools) - add_custom_command( - OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/lua/upb.lua - DEPENDS ${CMAKE_SOURCE_DIR}/upb/bindings/lua/upb.lua - COMMAND ${CMAKE_COMMAND} -E copy - ${CMAKE_SOURCE_DIR}/upb/bindings/lua/upb.lua - ${CMAKE_CURRENT_BINARY_DIR}/upb/bindings/lua) - add_custom_command( - OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/lua/upb/pb.lua - DEPENDS ${CMAKE_SOURCE_DIR}/upb/bindings/lua/upb/pb.lua - COMMAND ${CMAKE_COMMAND} -E copy - ${CMAKE_SOURCE_DIR}/upb/bindings/lua/upb/pb.lua - ${CMAKE_CURRENT_BINARY_DIR}/upb/bindings/lua/upb) - - add_custom_command( - OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/upb/pb/compile_decoder_x64.h - DEPENDS upb/pb/compile_decoder_x64.dasc - COMMAND - cd ${CMAKE_CURRENT_SOURCE_DIR} && - lua third_party/dynasm/dynasm.lua - -c upb/pb/compile_decoder_x64.dasc - > ${CMAKE_CURRENT_BINARY_DIR}/upb/pb/compile_decoder_x64.h - ) - - add_custom_target( - genfiles2 ALL - DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/upb/pb/compile_decoder_x64.h - ) - - add_test( - NAME testlua - COMMAND lua ${CMAKE_SOURCE_DIR}/tests/bindings/lua/test_upb.lua - ${CMAKE_SOURCE_DIR}/tests/bindings/lua/test_upb.pb.lua - ) - set_property(TEST testlua PROPERTY ENVIRONMENT - LUA_PATH=${CMAKE_SOURCE_DIR}/third_party/lunit/?.lua$${CMAKE_SOURCE_DIR}/upb/bindings/lua/?.lua - LUA_CPATH=${CMAKE_BINARY_DIR}/upb/bindings/lua/?.so - ) - set_tests_properties(testlua - PROPERTIES - DEPENDS "upb_c;pb_c" - ) - enable_testing() -endif() - -if(LUA_FOUND AND PROTOBUF_FOUND) - set(protobuf_BUILD_TESTS OFF CACHE BOOL "enable tests for proto2" FORCE) - set(protobuf_BUILD_SHARED_LIBS OFF CACHE BOOL "enable shared libs for proto2" FORCE) - set(protobuf_BUILD_CONFORMANCE ON CACHE BOOL "Build conformance tests" FORCE) - add_subdirectory(third_party/protobuf/cmake) - - add_custom_target( - upbc ALL - DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/tools/make_c_api.lua - ${CMAKE_CURRENT_SOURCE_DIR}/tools/upbc.lua - ${CMAKE_CURRENT_BINARY_DIR}/tools/upbc - ${CMAKE_CURRENT_BINARY_DIR}/lua/upb.lua - ${CMAKE_CURRENT_BINARY_DIR}/lua/upb/pb.lua - ) - - add_custom_command( - OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/conformance.upb.h - ${CMAKE_CURRENT_BINARY_DIR}/google/protobuf/test_messages_proto3.upb.h - ${CMAKE_CURRENT_BINARY_DIR}/google/protobuf/test_messages_proto3.upb.c - ${CMAKE_CURRENT_BINARY_DIR}/google/protobuf/any.upb.c - ${CMAKE_CURRENT_BINARY_DIR}/google/protobuf/duration.upb.c - ${CMAKE_CURRENT_BINARY_DIR}/google/protobuf/field_mask.upb.c - ${CMAKE_CURRENT_BINARY_DIR}/google/protobuf/struct.upb.c - ${CMAKE_CURRENT_BINARY_DIR}/google/protobuf/timestamp.upb.c - ${CMAKE_CURRENT_BINARY_DIR}/google/protobuf/wrappers.upb.c - ${CMAKE_CURRENT_BINARY_DIR}/conformance.upb.c - DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/tools/upbc - ${CMAKE_CURRENT_SOURCE_DIR}/third_party/protobuf/conformance/conformance.proto - COMMAND protoc --include_imports - ${CMAKE_CURRENT_SOURCE_DIR}/third_party/protobuf/conformance/conformance.proto - ${CMAKE_CURRENT_SOURCE_DIR}/third_party/protobuf/src/google/protobuf/test_messages_proto3.proto - -I${CMAKE_CURRENT_SOURCE_DIR}/third_party/protobuf/conformance - -I${CMAKE_CURRENT_SOURCE_DIR}/third_party/protobuf/src - -o${CMAKE_CURRENT_BINARY_DIR}/conformance.pb && - tools/upbc ${CMAKE_CURRENT_BINARY_DIR}/conformance.pb - ) - - add_custom_command( - OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/google/protobuf/descriptor.upb.h - ${CMAKE_CURRENT_BINARY_DIR}/google/protobuf/descriptor.upb.c - DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/tools/upbc - ${CMAKE_CURRENT_SOURCE_DIR}/google/protobuf/descriptor.proto - COMMAND protoc - ${CMAKE_CURRENT_SOURCE_DIR}/google/protobuf/descriptor.proto - -I${CMAKE_CURRENT_SOURCE_DIR} - -o${CMAKE_CURRENT_BINARY_DIR}/descriptor.pb && - tools/upbc ${CMAKE_CURRENT_BINARY_DIR}/descriptor.pb - ) - - add_custom_target( - genfiles ALL - DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/conformance.upb.h - ${CMAKE_CURRENT_BINARY_DIR}/google/protobuf/descriptor.upb.h - ) - - add_executable(conformance_upb - tests/conformance_upb.c - ${CMAKE_CURRENT_BINARY_DIR}/conformance.upb.c - ${CMAKE_CURRENT_BINARY_DIR}/google/protobuf/test_messages_proto3.upb.c - ${CMAKE_CURRENT_BINARY_DIR}/google/protobuf/any.upb.c - ${CMAKE_CURRENT_BINARY_DIR}/google/protobuf/duration.upb.c - ${CMAKE_CURRENT_BINARY_DIR}/google/protobuf/field_mask.upb.c - ${CMAKE_CURRENT_BINARY_DIR}/google/protobuf/struct.upb.c - ${CMAKE_CURRENT_BINARY_DIR}/google/protobuf/timestamp.upb.c - ${CMAKE_CURRENT_BINARY_DIR}/google/protobuf/wrappers.upb.c - ) - target_link_libraries(conformance_upb LINK_PRIVATE - upb - ) - - add_custom_target( - conformance - DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/conformance_upb - ${CMAKE_CURRENT_BINARY_DIR}/third_party/protobuf/cmake/conformance_test_runner - COMMAND ${CMAKE_CURRENT_BINARY_DIR}/third_party/protobuf/cmake/conformance_test_runner ${CMAKE_CURRENT_BINARY_DIR}/conformance_upb - ) - -endif() - -if (RAGEL) - add_custom_command( - OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/upb/json/parser.c - DEPENDS upb/json/parser.rl - COMMAND cd ${CMAKE_CURRENT_SOURCE_DIR} && RAGEL -C -o ${CMAKE_CURRENT_BINARY_DIR}/upb/json/parser.c upb/json/parser.rl - ) -endif() - -configure_file(tools/copy_genfiles.sh.in tools/copy_genfiles.sh) - -set(UPB_SRCS - upb/decode.c - upb/encode.c - upb/msg.c - upb/table.c - upb/upb.c -) - -set (UPBDEF_SRCS - upb/def.c - upb/msgfactory.c -) - -set(UPBHANDLERS_SRCS - upb/sink.c - upb/handlers.c -) - -set(UPBPB_SRCS -======= enable_testing() add_library(upb @@ -290,15 +87,7 @@ add_library(upb upb/refcounted.h upb/sink.h upb/upb.h) -add_library(upb_descriptor - upb/descriptor/descriptor.upbdefs.c - upb/descriptor/reader.c - upb/descriptor/descriptor.upbdefs.h - upb/descriptor/reader.h) -target_link_libraries(upb_descriptor - upb) add_library(upb_pb ->>>>>>> cmake-mac-fixes upb/pb/compile_decoder.c upb/pb/decoder.c upb/pb/decoder.int.h @@ -308,11 +97,9 @@ add_library(upb_pb upb/pb/varint.int.h upb/pb/decoder.h upb/pb/encoder.h - upb/pb/glue.h upb/pb/textprinter.h) target_link_libraries(upb_pb - upb - upb_descriptor) + upb) add_library(upb_json upb/json/parser.c upb/json/printer.c @@ -369,7 +156,6 @@ add_executable(test_cpp add_test(NAME test_cpp COMMAND test_cpp) target_link_libraries(test_cpp upb - upb_descriptor upb_pb upb_test) add_executable(test_table 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 +#include #include #include +#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 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 @@ -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 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 +#include #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_ */ -- cgit v1.2.3 From 0fed529ea1795d728a7ec75c3f06d95e4ba3bd8d Mon Sep 17 00:00:00 2001 From: Joshua Haberman Date: Wed, 12 Dec 2018 06:35:03 -0800 Subject: WIP, more progress on refactoring. --- CMakeLists.txt | 1 - upb/def.c | 647 +++++++++++++++++++++++++-------------------------------- upb/def.h | 30 +-- 3 files changed, 281 insertions(+), 397 deletions(-) (limited to 'upb/def.c') diff --git a/CMakeLists.txt b/CMakeLists.txt index 26ac066..e3d30c2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -72,7 +72,6 @@ add_library(upb upb/port_undef.inc upb/refcounted.c upb/sink.c - upb/structdefs.int.h upb/structs.int.h upb/table.c upb/table.int.h diff --git a/upb/def.c b/upb/def.c index 3167222..33ad70e 100644 --- a/upb/def.c +++ b/upb/def.c @@ -13,8 +13,8 @@ typedef struct { char str[1]; /* Null-terminated string data follows. */ } str_t; -static str_t *newstr(const char *data, size_t len) { - str_t *ret = upb_gmalloc(sizeof(*ret) + len); +static str_t *newstr(upb_alloc *alloc, const char *data, size_t len) { + str_t *ret = upb_malloc(alloc, sizeof(*ret) + len); if (!ret) return NULL; ret->len = len; memcpy(ret->str, data, len); @@ -22,9 +22,9 @@ static str_t *newstr(const char *data, size_t len) { return ret; } -static void freestr(str_t *s) { upb_gfree(s); } - struct upb_fielddef { + const upb_filedef *file; + const upb_msgdef *msgdef; const char *full_name; union { int64_t sint; @@ -34,11 +34,11 @@ struct upb_fielddef { bool boolean; str_t *str; } defaultval; - const upb_msgdef *msgdef; const upb_oneofdef *oneof; union { const upb_msgdef *msgdef; const upb_enumdef *enumdef; + const google_protobuf_FieldDescriptorProto *unresolved; } sub; uint32_t number_; uint32_t index_; @@ -60,6 +60,11 @@ struct upb_msgdef { upb_inttable itof; upb_strtable ntof; + const upb_fielddef *fields; + const upb_oneofdef *oneofs; + int field_count; + int oneof_count; + /* Is this a map-entry message? */ bool map_entry; upb_wellknowntype_t well_known_type; @@ -68,6 +73,7 @@ struct upb_msgdef { }; struct upb_enumdef { + const upb_filedef *file; const char *full_name; upb_strtable ntoi; upb_inttable iton; @@ -76,7 +82,7 @@ struct upb_enumdef { struct upb_oneofdef { const upb_msgdef *parent; - const char *name; + const char *full_name; uint32_t index; upb_strtable ntof; upb_inttable itof; @@ -89,13 +95,15 @@ struct upb_filedef { const char *phpnamespace; upb_syntax_t syntax; - const upb_msgdef **msgs; - const upb_enumdef **enums; const upb_filedef **deps; - - int msgcount; - int enumcount; - int depcount; + const upb_msgdef *msgs; + const upb_enumdef *enums; + const upb_fielddef *exts; + + int dep_count; + int msg_count; + int enum_count; + int ext_count; }; /* Inside a symtab we store tagged pointers to specific def types. */ @@ -422,60 +430,11 @@ const char *upb_enumdef_name(const upb_enumdef *e) { return shortdefname(e->full_name); } -#if 0 -bool upb_enumdef_addval(upb_enumdef *e, const char *name, int32_t num, - upb_status *status) { - char *name2; - - if (!upb_isident(name, strlen(name), false, status)) { - return false; - } - - if (upb_enumdef_ntoiz(e, name, NULL)) { - upb_status_seterrf(status, "name '%s' is already defined", name); - return false; - } - - if (!upb_strtable_insert(&e->ntoi, name, upb_value_int32(num))) { - upb_status_seterrmsg(status, "out of memory"); - return false; - } - - if (!upb_inttable_lookup(&e->iton, num, NULL)) { - name2 = upb_gstrdup(name); - if (!name2 || !upb_inttable_insert(&e->iton, num, upb_value_cstr(name2))) { - upb_status_seterrmsg(status, "out of memory"); - upb_strtable_remove(&e->ntoi, name, NULL); - return false; - } - } - - if (upb_enumdef_numvals(e) == 1) { - bool ok = upb_enumdef_setdefault(e, num, NULL); - UPB_ASSERT(ok); - } - - return true; -} -#endif - int32_t upb_enumdef_default(const upb_enumdef *e) { UPB_ASSERT(upb_enumdef_iton(e, e->defaultval)); return e->defaultval; } -#if 0 -bool upb_enumdef_setdefault(upb_enumdef *e, int32_t val, upb_status *s) { - UPB_ASSERT(!upb_enumdef_isfrozen(e)); - if (!upb_enumdef_iton(e, val)) { - upb_status_seterrf(s, "number '%d' is not in the enum.", val); - return false; - } - e->defaultval = val; - return true; -} -#endif - int upb_enumdef_numvals(const upb_enumdef *e) { return upb_strtable_count(&e->ntoi); } @@ -744,96 +703,6 @@ upb_syntax_t upb_msgdef_syntax(const upb_msgdef *m) { return m->file->syntax; } -#if 0 -/* Helper: check that the field |f| is safe to add to msgdef |m|. Set an error - * on status |s| and return false if not. */ -static bool check_field_add(const upb_msgdef *m, const upb_fielddef *f, - upb_status *s) { - if (upb_fielddef_containingtype(f) != NULL) { - upb_status_seterrmsg(s, "fielddef already belongs to a message"); - return false; - return true; -} - -bool upb_msgdef_addfield(upb_msgdef *m, upb_fielddef *f, const void *ref_donor, - upb_status *s) { - /* TODO: extensions need to have a separate namespace, because proto2 allows a - * top-level extension (ie. one not in any package) to have the same name as a - * field from the message. - * - * This also implies that there needs to be a separate lookup-by-name method - * for extensions. It seems desirable for iteration to return both extensions - * and non-extensions though. - * - * We also need to validate that the field number is in an extension range iff - * it is an extension. - * - * This method is idempotent. Check if |f| is already part of this msgdef and - * return immediately if so. */ - if (upb_fielddef_containingtype(f) == m) { - if (ref_donor) upb_fielddef_unref(f, ref_donor); - return true; - } - - /* Check constraints for all fields before performing any action. */ - if (!check_field_add(m, f, s)) { - return false; - } else if (upb_fielddef_containingoneof(f) != NULL) { - /* Fields in a oneof can only be added by adding the oneof to the msgdef. */ - upb_status_seterrmsg(s, "fielddef is part of a oneof"); - return false; - } - - /* Constraint checks ok, perform the action. */ - add_field(m, f, ref_donor); - return true; -} - -bool upb_msgdef_addoneof(upb_msgdef *m, upb_oneofdef *o, const void *ref_donor, - upb_status *s) { - upb_oneof_iter it; - - /* Check various conditions that would prevent this oneof from being added. */ - if (upb_oneofdef_containingtype(o)) { - upb_status_seterrmsg(s, "oneofdef already belongs to a message"); - return false; - } else if (upb_oneofdef_name(o) == NULL) { - upb_status_seterrmsg(s, "oneofdef name was not set"); - return false; - } else if (upb_strtable_lookup(&m->ntof, upb_oneofdef_name(o), NULL)) { - upb_status_seterrmsg(s, "name conflicts with existing field or oneof"); - return false; - } - - /* Check that all of the oneof's fields do not conflict with names or numbers - * of fields already in the message. */ - for (upb_oneof_begin(&it, o); !upb_oneof_done(&it); upb_oneof_next(&it)) { - const upb_fielddef *f = upb_oneof_iter_field(&it); - if (!check_field_add(m, f, s)) { - return false; - } - } - - /* Everything checks out -- commit now. */ - - /* Add oneof itself first. */ - o->parent = m; - upb_strtable_insert(&m->ntof, upb_oneofdef_name(o), upb_value_ptr(o)); - upb_ref2(o, m); - upb_ref2(m, o); - - /* Add each field of the oneof directly to the msgdef. */ - for (upb_oneof_begin(&it, o); !upb_oneof_done(&it); upb_oneof_next(&it)) { - upb_fielddef *f = upb_oneof_iter_field(&it); - add_field(m, f, NULL); - } - - if (ref_donor) upb_oneofdef_unref(o, ref_donor); - - return true; -} -#endif - const upb_fielddef *upb_msgdef_itof(const upb_msgdef *m, uint32_t i) { upb_value val; return upb_inttable_lookup32(&m->itof, i, &val) ? @@ -949,7 +818,9 @@ void upb_msg_oneof_iter_setdone(upb_msg_oneof_iter *iter) { /* upb_oneofdef ***************************************************************/ -const char *upb_oneofdef_name(const upb_oneofdef *o) { return o->name; } +const char *upb_oneofdef_name(const upb_oneofdef *o) { + return shortdefname(o->full_name); +} const upb_msgdef *upb_oneofdef_containingtype(const upb_oneofdef *o) { return o->parent; @@ -963,79 +834,6 @@ uint32_t upb_oneofdef_index(const upb_oneofdef *o) { return o->index; } -#if 0 -bool upb_oneofdef_addfield(upb_oneofdef *o, upb_fielddef *f, - const void *ref_donor, - upb_status *s) { - /* This method is idempotent. Check if |f| is already part of this oneofdef - * and return immediately if so. */ - if (upb_fielddef_containingoneof(f) == o) { - return true; - } - - /* The field must have an OPTIONAL label. */ - if (upb_fielddef_label(f) != UPB_LABEL_OPTIONAL) { - upb_status_seterrmsg(s, "fields in oneof must have OPTIONAL label"); - return false; - } - - /* Check that no field with this name or number exists already in the oneof. - * Also check that the field is not already part of a oneof. */ - 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_oneofdef_itof(o, upb_fielddef_number(f)) || - upb_oneofdef_ntofz(o, upb_fielddef_name(f))) { - upb_status_seterrmsg(s, "duplicate field name or number"); - return false; - } else if (upb_fielddef_containingoneof(f) != NULL) { - upb_status_seterrmsg(s, "fielddef already belongs to a oneof"); - return false; - } - - /* We allow adding a field to the oneof either if the field is not part of a - * msgdef, or if it is and we are also part of the same msgdef. */ - if (o->parent == NULL) { - /* If we're not in a msgdef, the field cannot be either. Otherwise we would - * need to magically add this oneof to a msgdef to remain consistent, which - * is surprising behavior. */ - if (upb_fielddef_containingtype(f) != NULL) { - upb_status_seterrmsg(s, "fielddef already belongs to a message, but " - "oneof does not"); - return false; - } - } else { - /* If we're in a msgdef, the user can add fields that either aren't in any - * msgdef (in which case they're added to our msgdef) or already a part of - * our msgdef. */ - if (upb_fielddef_containingtype(f) != NULL && - upb_fielddef_containingtype(f) != o->parent) { - upb_status_seterrmsg(s, "fielddef belongs to a different message " - "than oneof"); - return false; - } - } - - /* Commit phase. First add the field to our parent msgdef, if any, because - * that may fail; then add the field to our own tables. */ - - if (o->parent != NULL && upb_fielddef_containingtype(f) == NULL) { - if (!upb_msgdef_addfield((upb_msgdef*)o->parent, f, NULL, s)) { - return false; - } - } - - f->oneof = o; - upb_inttable_insert(&o->itof, upb_fielddef_number(f), upb_value_ptr(f)); - upb_strtable_insert(&o->ntof, upb_fielddef_name(f), upb_value_ptr(f)); - upb_ref2(f, o); - upb_ref2(o, f); - if (ref_donor) upb_fielddef_unref(f, ref_donor); - - return true; -} -#endif - const upb_fielddef *upb_oneofdef_ntof(const upb_oneofdef *o, const char *name, size_t length) { upb_value val; @@ -1092,27 +890,27 @@ upb_syntax_t upb_filedef_syntax(const upb_filedef *f) { } int upb_filedef_msgcount(const upb_filedef *f) { - return f->msgcount; + return f->msg_count; } int upb_filedef_depcount(const upb_filedef *f) { - return f->depcount; + return f->dep_count; } int upb_filedef_enumcount(const upb_filedef *f) { - return f->enumcount; + return f->enum_count; } const upb_filedef *upb_filedef_dep(const upb_filedef *f, int i) { - return i < 0 || i >= f->depcount ? NULL : f->deps[i]; + return i < 0 || i >= f->dep_count ? NULL : f->deps[i]; } const upb_msgdef *upb_filedef_msg(const upb_filedef *f, int i) { - return i < 0 || i >= f->msgcount ? NULL : f->msgs[i]; + return i < 0 || i >= f->msg_count ? NULL : &f->msgs[i]; } const upb_enumdef *upb_filedef_enum(const upb_filedef *f, int i) { - return i < 0 || i >= f->enumcount ? NULL : f->enums[i]; + return i < 0 || i >= f->enum_count ? NULL : &f->enums[i]; } void upb_symtab_free(upb_symtab *s) { @@ -1159,68 +957,6 @@ const upb_enumdef *upb_symtab_lookupenum(const upb_symtab *s, const char *sym) { 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, - const char *base, const char *sym) { - if(strlen(sym) == 0) return NULL; - if(sym[0] == '.') { - /* Symbols starting with '.' are absolute, so we do a single lookup. - * Slice to omit the leading '.' */ - upb_value v; - return upb_strtable_lookup(t, sym + 1, &v) ? upb_value_getptr(v) : NULL; - } else { - /* Remove components from base until we find an entry or run out. - * TODO: This branch is totally broken, but currently not used. */ - (void)base; - UPB_ASSERT(false); - return NULL; - } -} - -const upb_def *upb_symtab_resolve(const upb_symtab *s, const char *base, - const char *sym) { - upb_def *ret = upb_resolvename(&s->syms, base, sym); - return ret; -} - - /* Now using the table, resolve symbolic references for subdefs. */ - upb_strtable_begin(&iter, &addtab); - for (; !upb_strtable_done(&iter); upb_strtable_next(&iter)) { - const char *base; - upb_def *def = upb_value_getptr(upb_strtable_iter_value(&iter)); - upb_msgdef *m = upb_dyncast_msgdef_mutable(def); - upb_msg_field_iter j; - - if (!m) continue; - /* Type names are resolved relative to the message in which they appear. */ - base = upb_msgdef_fullname(m); - - for(upb_msg_field_begin(&j, m); - !upb_msg_field_done(&j); - upb_msg_field_next(&j)) { - upb_fielddef *f = upb_msg_iter_field(&j); - const char *name = upb_fielddef_subdefname(f); - if (name && !upb_fielddef_subdef(f)) { - /* Try the lookup in the current set of to-be-added defs first. If not - * there, try existing defs. */ - upb_def *subdef = upb_resolvename(&addtab, base, name); - if (subdef == NULL) { - subdef = upb_resolvename(&s->syms, base, name); - } - if (subdef == NULL) { - upb_status_seterrf( - status, "couldn't resolve name '%s' in message '%s'", name, base); - goto err; - } else if (!upb_fielddef_setsubdef(f, subdef, status)) { - goto err; - } - } - } - } -#endif - /* Code to build defs from descriptor protos. *********************************/ @@ -1234,7 +970,7 @@ const upb_def *upb_symtab_resolve(const upb_symtab *s, const char *base, typedef struct { const upb_symtab *symtab; - const upb_filedef *file; /* File we are building. */ + 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. */ @@ -1250,7 +986,7 @@ static bool symtab_add(const symtab_addctx *ctx, const char *name, 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); + upb_status_seterrf(ctx->status, "duplicate symbol '%s'", name); return false; } @@ -1258,28 +994,75 @@ static bool symtab_add(const symtab_addctx *ctx, const char *name, return true; } +/* Given a symbol and the base symbol inside which it is defined, find the + * symbol's definition in t. */ +static bool resolvename(const upb_strtable *t, const upb_fielddef *f, + const char *base, upb_stringview sym, + upb_deftype_t type, upb_status *status, + const void **def) { + if(sym.size == 0) return NULL; + if(sym.data[0] == '.') { + /* Symbols starting with '.' are absolute, so we do a single lookup. + * Slice to omit the leading '.' */ + upb_value v; + if (!upb_strtable_lookup2(t, sym.data + 1, sym.size - 1, &v)) { + return false; + } + + *def = unpack_def(v, type); + + if (!*def) { + upb_status_seterrf(status, + "type mismatch when resolving field %s, name %s", + f->full_name, sym.data); + return false; + } + + return true; + } else { + /* Remove components from base until we find an entry or run out. + * TODO: This branch is totally broken, but currently not used. */ + (void)base; + UPB_ASSERT(false); + return false; + } +} + +const void *symtab_resolve(const symtab_addctx *ctx, const upb_fielddef *f, + const char *base, upb_stringview sym, + upb_deftype_t type) { + const void *ret; + if (!resolvename(ctx->addtab, f, base, sym, type, ctx->status, &ret) && + !resolvename(&ctx->symtab->syms, f, base, sym, type, ctx->status, &ret)) { + if (upb_ok(ctx->status)) { + upb_status_seterrf(ctx->status, "couldn't resolve name '%s'", sym.data); + } + return false; + } + return ret; +} + static bool create_oneofdef( const symtab_addctx *ctx, upb_msgdef *m, const google_protobuf_OneofDescriptorProto *oneof_proto) { - upb_oneofdef *o = upb_malloc(ctx->alloc, sizeof(*o)); + upb_oneofdef *o; upb_stringview name = google_protobuf_OneofDescriptorProto_name(oneof_proto); - upb_value o_ptr = upb_value_ptr(o); - 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, ctx->alloc); + o = (upb_oneofdef*)&m->oneofs[m->oneof_count++]; o->parent = m; - - CHK_OOM(upb_strtable_insert3(&m->ntof, name.data, name.size, o_ptr, + o->full_name = makefullname(m->full_name, name); + CHK_OOM(symtab_add(ctx, o->full_name, pack_def(o, UPB_DEFTYPE_ONEOF))); + CHK_OOM(upb_strtable_insert3(&m->ntof, name.data, name.size, upb_value_ptr(o), ctx->alloc)); + CHK_OOM(upb_inttable_init2(&o->itof, UPB_CTYPE_PTR, ctx->alloc)); + CHK_OOM(upb_strtable_init2(&o->ntof, UPB_CTYPE_PTR, ctx->alloc)); + return true; } -static bool parse_default(const char *str, size_t len, upb_fielddef *f) { +static bool parse_default(const symtab_addctx *ctx, const char *str, size_t len, + upb_fielddef *f) { char *end; switch (upb_fielddef_type(f)) { case UPB_TYPE_INT32: { @@ -1332,11 +1115,11 @@ static bool parse_default(const char *str, size_t len, upb_fielddef *f) { } } case UPB_TYPE_STRING: - f->defaultval.str = newstr(str, len); + f->defaultval.str = newstr(ctx->alloc, str, len); break; case UPB_TYPE_BYTES: /* XXX: need to interpret the C-escaped value. */ - f->defaultval.str = newstr(str, len); + f->defaultval.str = newstr(ctx->alloc, str, len); case UPB_TYPE_MESSAGE: /* Should not have a default value. */ return false; @@ -1348,17 +1131,48 @@ 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)); + upb_fielddef *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 *full_name; const char *shortname; - - CHK_OOM(f); - memset(f, 0, sizeof(*f)); + int oneof_index; name = google_protobuf_FieldDescriptorProto_name(field_proto); + CHK(upb_isident(name, false, ctx->status)); + full_name = makefullname(prefix, name); + shortname = shortdefname(full_name); + + if (m) { + /* direct message field. */ + f = (upb_fielddef*)&m->fields[m->field_count++]; + f->msgdef = m; + f->is_extension_ = false; + + if (!upb_strtable_insert3(&m->ntof, name.data, name.size, packed_v, alloc)) { + upb_status_seterrf(ctx->status, "duplicate field 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; + } + } else { + /* extension field. */ + f = (upb_fielddef*)&ctx->file->exts[ctx->file->ext_count]; + f->is_extension_ = true; + CHK_OOM(symtab_add(ctx, full_name, pack_def(f, UPB_DEFTYPE_FIELD))); + } + + f->full_name = full_name; + f->file = ctx->file; + 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); + f->oneof = NULL; /* TODO(haberman): use hazzers. */ if (name.size == 0 || f->number_ == 0) { @@ -1366,27 +1180,42 @@ static bool create_fielddef( return false; } - CHK(upb_isident(name, false, ctx->status)); + /* We can't resolve the subdef or (in the case of extensions) the containing + * message yet, because it may not have been defined yet. We stash a pointer + * to the field_proto until later when we can properly resolve it. */ + f->sub.unresolved = field_proto; - 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 (m) { + /* XXX: need hazzers. */ + oneof_index = google_protobuf_FieldDescriptorProto_oneof_index(field_proto); + if (oneof_index) { + if (upb_fielddef_label(f) != UPB_LABEL_OPTIONAL) { + upb_status_seterrf(ctx->status, + "fields in oneof must have OPTIONAL label (%s)", + f->full_name); + return false; + } + + if (oneof_index >= m->oneof_count) { + upb_status_seterrf(ctx->status, "oneof_index out of range (%s)", + f->full_name); + return false; + } + f->oneof = &m->oneofs[oneof_index]; + } else { + f->oneof = NULL; + } + } 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)); + CHK(parse_default(ctx, defaultval.data, defaultval.size, f)); } options = google_protobuf_FieldDescriptorProto_options(field_proto); @@ -1396,32 +1225,13 @@ static bool create_fielddef( 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)); + upb_enumdef *e; const upb_array *arr; upb_stringview name; size_t i; @@ -1429,13 +1239,15 @@ static bool create_enumdef( name = google_protobuf_EnumDescriptorProto_name(enum_proto); CHK(upb_isident(name, false, ctx->status)); + e = (upb_enumdef*)&ctx->file->enums[ctx->file->enum_count++]; e->full_name = makefullname(prefix, name); - e->defaultval = 0; + CHK_OOM(symtab_add(ctx, e->full_name, pack_def(e, UPB_DEFTYPE_ENUM))); - 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)); + e->defaultval = 0; + arr = google_protobuf_EnumDescriptorProto_value(enum_proto); for (i = 0; i < upb_array_size(arr); i++) { @@ -1446,6 +1258,11 @@ static bool create_enumdef( int32_t num = google_protobuf_EnumValueDescriptorProto_number(value); upb_value v = upb_value_int32(num); + if (upb_strtable_lookup(&e->ntoi, name2, NULL)) { + upb_status_seterrf(ctx->status, "duplicate enum label '%s'", name2); + return false; + } + CHK_OOM(name2 && upb_strtable_insert(&e->ntoi, name2, v)); if (!upb_inttable_lookup(&e->iton, num, NULL)) { @@ -1458,21 +1275,23 @@ static bool create_enumdef( 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)); + upb_msgdef *m; const google_protobuf_MessageOptions *options; const upb_array *arr; - size_t i; + size_t i, n; upb_stringview name; - 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 = (upb_msgdef*)&ctx->file->msgs[ctx->file->msg_count++]; m->full_name = makefullname(prefix, name); + CHK_OOM(symtab_add(ctx, m->full_name, pack_def(m, UPB_DEFTYPE_MSG))); + + CHK_OOM(upb_inttable_init2(&m->itof, UPB_CTYPE_PTR, ctx->alloc)); + CHK_OOM(upb_strtable_init2(&m->ntof, UPB_CTYPE_PTR, ctx->alloc)); + + m->file = ctx->file; m->map_entry = false; options = google_protobuf_DescriptorProto_options(msg_proto); @@ -1482,15 +1301,16 @@ static bool create_msgdef(const symtab_addctx *ctx, const char *prefix, } arr = google_protobuf_DescriptorProto_oneof_decl(msg_proto); - - for (i = 0; i < upb_array_size(arr); i++) { + m->oneof_count = 0; + n = upb_array_size(arr); + m->oneofs = upb_malloc(ctx->alloc, sizeof(*m->oneofs) * n); + for (i = 0; i < n; i++) { const google_protobuf_OneofDescriptorProto *oneof_proto = 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 = upb_msgval_getptr(upb_array_get(arr, i)); @@ -1499,12 +1319,10 @@ static bool create_msgdef(const symtab_addctx *ctx, const char *prefix, 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 = upb_msgval_getptr(upb_array_get(arr, i)); @@ -1512,7 +1330,6 @@ static bool create_msgdef(const symtab_addctx *ctx, const char *prefix, } arr = google_protobuf_DescriptorProto_nested_type(msg_proto); - for (i = 0; i < upb_array_size(arr); i++) { const google_protobuf_DescriptorProto *msg_proto2 = upb_msgval_getptr(upb_array_get(arr, i)); @@ -1529,15 +1346,96 @@ static char* strviewdup(const symtab_addctx *ctx, upb_stringview view) { return upb_strdup2(view.data, view.size, ctx->alloc); } +typedef struct { + int msg_count; + int enum_count; + int ext_count; +} decl_counts; + +static void count_types_in_msg( + const google_protobuf_DescriptorProto *msg_proto, + decl_counts *counts) { + const upb_array *arr; + size_t i; + + arr = google_protobuf_DescriptorProto_nested_type(msg_proto); + for (i = 0; i < upb_array_size(arr); i++) { + count_types_in_msg(upb_msgval_getptr(upb_array_get(arr, i)), counts); + } + + arr = google_protobuf_DescriptorProto_enum_type(msg_proto); + counts->enum_count += upb_array_size(arr); + arr = google_protobuf_DescriptorProto_extension(msg_proto); + counts->ext_count += upb_array_size(arr); +} + +static void count_types_in_file( + const google_protobuf_FileDescriptorProto *file_proto, + decl_counts *counts) { + const upb_array *arr; + size_t i; + + arr = google_protobuf_FileDescriptorProto_message_type(file_proto); + for (i = 0; i < upb_array_size(arr); i++) { + count_types_in_msg(upb_msgval_getptr(upb_array_get(arr, i)), counts); + } + + arr = google_protobuf_FileDescriptorProto_enum_type(file_proto); + counts->enum_count += upb_array_size(arr); + arr = google_protobuf_FileDescriptorProto_extension(file_proto); + counts->ext_count += upb_array_size(arr); +} + +static bool resolve_fielddef(const symtab_addctx *ctx, const char *prefix, + upb_fielddef *f) { + upb_stringview name; + if (f->is_extension_) { + name = google_protobuf_FieldDescriptorProto_extendee(f->sub.unresolved); + f->msgdef = symtab_resolve(ctx, f, prefix, name, UPB_DEFTYPE_MSG); + CHK(f->msgdef); + } + + name = google_protobuf_FieldDescriptorProto_type_name(f->sub.unresolved); + if (upb_fielddef_issubmsg(f)) { + f->sub.msgdef = symtab_resolve(ctx, f, prefix, name, UPB_DEFTYPE_MSG); + CHK(f->sub.msgdef); + } else if (f->type_ == UPB_DESCRIPTOR_TYPE_ENUM) { + f->sub.enumdef = symtab_resolve(ctx, f, prefix, name, UPB_DEFTYPE_ENUM); + CHK(f->sub.enumdef); + + if (!upb_enumdef_iton(f->sub.enumdef, f->defaultval.sint)) { + upb_status_seterrf(ctx->status, + "enum field %s has default (%d) not in the enum", + f->full_name, f->defaultval.sint); + return false; + } + } + + return true; +} + 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_strtable_iter iter; + upb_alloc *alloc = ctx->alloc; const upb_array *arr; size_t i, n; + int j; + decl_counts counts; upb_stringview syntax, package; + count_types_in_file(file_proto, &counts); + + file->msgs = upb_malloc(alloc, sizeof(*file->msgs) * counts.msg_count); + file->enums = upb_malloc(alloc, sizeof(*file->enums) * counts.enum_count); + file->exts = upb_malloc(alloc, sizeof(*file->exts) * counts.ext_count); + + /* We increment these as defs are added. */ + file->msg_count = 0; + file->enum_count = 0; + file->ext_count = 0; + package = google_protobuf_FileDescriptorProto_package(file_proto); CHK(upb_isident(package, true, ctx->status)); @@ -1559,9 +1457,7 @@ static bool build_filedef( } /* Read options. */ - file_options_proto = google_protobuf_FileDescriptorProto_options(file_proto); - if (file_options_proto) { file->phpprefix = strviewdup( ctx, google_protobuf_FileOptions_php_class_prefix(file_options_proto)); @@ -1569,11 +1465,10 @@ static bool build_filedef( ctx, google_protobuf_FileOptions_php_namespace(file_options_proto)); } - /* Resolve dependencies. */ - + /* Verify dependencies. */ arr = google_protobuf_FileDescriptorProto_dependency(file_proto); n = upb_array_size(arr); - file->deps = upb_malloc(ctx->alloc, sizeof(*file->deps) * n) ; + file->deps = upb_malloc(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)); @@ -1589,7 +1484,6 @@ static bool build_filedef( } /* 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 = @@ -1598,7 +1492,6 @@ static bool build_filedef( } /* 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 = @@ -1606,9 +1499,27 @@ static bool build_filedef( CHK(create_enumdef(ctx, file->package, enum_proto)); } + /* Create extensions. */ + arr = google_protobuf_FileDescriptorProto_extension(file_proto); + n = upb_array_size(arr); + file->exts = upb_malloc(alloc, sizeof(*file->exts) * n); + CHK_OOM(file->exts); + for (i = 0; i < n; i++) { + const google_protobuf_FieldDescriptorProto *field_proto = + upb_msgval_getptr(upb_array_get(arr, i)); + CHK(create_fielddef(ctx, file->package, NULL, field_proto)); + } + /* Now that all names are in the table, resolve references. */ - upb_strtable_begin(&iter, ctx->addtab); - for (; !upb_strtable_done(&iter); upb_strtable_next(&iter)) { + for (i = 0; i < file->ext_count; i++) { + CHK(resolve_fielddef(ctx, file->package, (upb_fielddef*)&file->exts[i])); + } + + for (i = 0; i < file->msg_count; i++) { + const upb_msgdef *m = &file->msgs[i]; + for (j = 0; i < m->field_count; i++) { + CHK(resolve_fielddef(ctx, m->full_name, (upb_fielddef*)&m->fields[j])); + } } return true; diff --git a/upb/def.h b/upb/def.h index 4a7342e..78ae9b3 100644 --- a/upb/def.h +++ b/upb/def.h @@ -54,9 +54,7 @@ UPB_DECLARE_TYPE(upb::SymbolTable, upb_symtab) /* A upb_fielddef describes a single field in a message. It is most often * found as a part of a upb_msgdef, but can also stand alone to represent - * an extension. - * - * Its base class is upb::Def (use upb::upcast() to convert). */ + * an extension. */ class upb::FieldDef { public: typedef upb_fieldtype_t Type; @@ -232,9 +230,7 @@ typedef upb_strtable_iter upb_msg_oneof_iter; #ifdef __cplusplus -/* Structure that describes a single .proto message type. - * - * Its base class is upb::Def (use upb::upcast() to convert). */ +/* Structure that describes a single .proto message type. */ class upb::MessageDef { public: const char* full_name() const; @@ -439,8 +435,6 @@ typedef upb_strtable_iter upb_enum_iter; #ifdef __cplusplus -/* Class that represents an enum. Its base class is upb::Def (convert with - * upb::upcast()). */ class upb::EnumDef { public: const char* full_name() const; @@ -642,12 +636,6 @@ class upb::FileDef { /* Syntax for the file. Defaults to proto2. */ upb_syntax_t syntax() const; - /* Get the list of defs from the file. These are returned in the order that - * they were added to the FileDef. */ - int def_count() const; - const Def* def(int index) const; - Def* def(int index); - /* Get the list of dependencies from the file. These are returned in the * order that they were added to the FileDef. */ int dependency_count() const; @@ -688,7 +676,6 @@ class upb::SymbolTable { /* Finds an entry in the symbol table with this exact name. If not found, * returns NULL. */ - const Def* Lookup(const char *sym) const; const MessageDef* LookupMessage(const char *sym) const; const EnumDef* LookupEnum(const char *sym) const; @@ -731,9 +718,6 @@ inline SymbolTable* SymbolTable::New() { inline void SymbolTable::Free(SymbolTable* s) { upb_symtab_free(s); } -inline const Def* SymbolTable::Lookup(const char *sym) const { - return upb_symtab_lookup(this, sym); -} inline const MessageDef *SymbolTable::LookupMessage(const char *sym) const { return upb_symtab_lookupmsg(this, sym); } @@ -750,10 +734,6 @@ UPB_INLINE const char* upb_safecstr(const std::string& str) { /* Inline C++ wrappers. */ namespace upb { -inline Def::Type Def::def_type() const { return upb_def_type(this); } -inline const char* Def::full_name() const { return upb_def_fullname(this); } -inline const char* Def::name() const { return upb_def_name(this); } - inline const char* FieldDef::full_name() const { return upb_fielddef_fullname(this); } @@ -1017,12 +997,6 @@ inline const char* FileDef::phpnamespace() const { inline int FileDef::def_count() const { return upb_filedef_defcount(this); } -inline const Def* FileDef::def(int index) const { - return upb_filedef_def(this, index); -} -inline Def* FileDef::def(int index) { - return const_cast(upb_filedef_def(this, index)); -} inline int FileDef::dependency_count() const { return upb_filedef_depcount(this); } -- cgit v1.2.3 From 7ff8413a0317566d67b5b4abcb6ee2b72e9d465b Mon Sep 17 00:00:00 2001 From: Joshua Haberman Date: Thu, 13 Dec 2018 05:40:33 -0800 Subject: Ported some tests. --- BUILD | 26 ++- CMakeLists.txt | 10 +- google/protobuf/descriptor.pb | Bin 0 -> 7493 bytes tests/pb/test_decoder.cc | 102 +--------- tests/pb/test_decoder.proto | 86 ++++++++ tests/pb/test_encoder.cc | 28 ++- tests/test_def.c | 453 ------------------------------------------ upb/def.c | 15 +- upb/def.h | 16 +- 9 files changed, 145 insertions(+), 591 deletions(-) create mode 100644 google/protobuf/descriptor.pb create mode 100644 tests/pb/test_decoder.proto delete mode 100644 tests/test_def.c (limited to 'upb/def.c') diff --git a/BUILD b/BUILD index df05e06..4d4168f 100644 --- a/BUILD +++ b/BUILD @@ -157,15 +157,6 @@ cc_test( ], ) -cc_test( - name = "test_def", - srcs = ["tests/test_def.c"], - deps = [ - ":upb_pb", - ":upb_test", - ], -) - cc_test( name = "test_handlers", srcs = ["tests/test_handlers.c"], @@ -187,7 +178,7 @@ cc_test( cc_test( name = "test_encoder", srcs = ["tests/pb/test_encoder.cc"], - data = ["upb/descriptor/descriptor.pb"], + data = ["google/protobuf/descriptor.pb"], deps = [ ":upb_cc_bindings", ":upb_pb", @@ -413,6 +404,20 @@ py_binary( srcs = ["tools/make_cmakelists.py"], ) +proto_library( + name = "descriptor_proto", + srcs = [ + "google/protobuf/descriptor.proto", + ], +) + +genrule( + name = "copy_upb_descriptor_pb", + srcs = [":descriptor_proto"], + outs = ["generated/google/protobuf/descriptor.pb"], + cmd = "cp $< $@", +) + genrule( name = "gen_cmakelists", outs = ["generated/CMakeLists.txt"], @@ -477,6 +482,7 @@ generated_file_staleness_test( name = "test_generated_files", outs = [ "CMakeLists.txt", + "google/protobuf/descriptor.pb", "google/protobuf/descriptor.upb.c", "google/protobuf/descriptor.upb.h", "tests/json/test.proto.pb", diff --git a/CMakeLists.txt b/CMakeLists.txt index e3d30c2..54082a5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -120,12 +120,6 @@ add_test(NAME test_varint COMMAND test_varint) target_link_libraries(test_varint upb_pb upb_test) -add_executable(test_def - tests/test_def.c) -add_test(NAME test_def COMMAND test_def) -target_link_libraries(test_def - upb_pb - upb_test) add_executable(test_handlers tests/test_handlers.c) add_test(NAME test_handlers COMMAND test_handlers) @@ -144,8 +138,8 @@ add_test(NAME test_encoder COMMAND test_encoder) add_custom_command( TARGET test_encoder POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy - ${CMAKE_SOURCE_DIR}/upb/descriptor/descriptor.pb - ${CMAKE_CURRENT_BINARY_DIR}/upb/descriptor/descriptor.pb) + ${CMAKE_SOURCE_DIR}/google/protobuf/descriptor.pb + ${CMAKE_CURRENT_BINARY_DIR}/google/protobuf/descriptor.pb) target_link_libraries(test_encoder upb_cc_bindings upb_pb diff --git a/google/protobuf/descriptor.pb b/google/protobuf/descriptor.pb new file mode 100644 index 0000000..0a74c99 Binary files /dev/null and b/google/protobuf/descriptor.pb differ diff --git a/tests/pb/test_decoder.cc b/tests/pb/test_decoder.cc index 49544b2..a931779 100644 --- a/tests/pb/test_decoder.cc +++ b/tests/pb/test_decoder.cc @@ -399,107 +399,8 @@ void reg_str(upb_handlers *h, uint32_t num) { ASSERT(h->SetStringHandler(f, UpbBind(value_string, new uint32_t(num)))); } -void AddField(upb_descriptortype_t descriptor_type, const std::string& name, - uint32_t fn, bool repeated, upb::MessageDef* md) { - // TODO: Fluent interface? ie. - // ASSERT(md->AddField(upb::BuildFieldDef() - // .SetName("f_message") - // .SetNumber(UPB_DESCRIPTOR_TYPE_MESSAGE) - // .SetDescriptorType(UPB_DESCRIPTOR_TYPE_MESSAGE) - // .SetMessageSubdef(md.get()))); - upb::reffed_ptr f = upb::FieldDef::New(); - ASSERT(f->set_name(name, NULL)); - ASSERT(f->set_number(fn, NULL)); - f->set_label(repeated ? UPB_LABEL_REPEATED : UPB_LABEL_OPTIONAL); - f->set_descriptor_type(descriptor_type); - ASSERT(md->AddField(f.get(), NULL)); -} - -void AddFieldsForType(upb_descriptortype_t descriptor_type, - const char* basename, upb::MessageDef* md) { - const upb_descriptortype_t t = descriptor_type; - AddField(t, std::string("f_") + basename, t, false, md); - AddField(t, std::string("r_") + basename, rep_fn(t), true, md); -} - -upb::reffed_ptr NewMessageDef() { - upb::reffed_ptr md = upb::MessageDef::New(); - - md->set_full_name("DecoderTest", NULL); - - AddFieldsForType(UPB_DESCRIPTOR_TYPE_DOUBLE, "double", md.get()); - AddFieldsForType(UPB_DESCRIPTOR_TYPE_FLOAT, "float", md.get()); - AddFieldsForType(UPB_DESCRIPTOR_TYPE_INT64, "int64", md.get()); - AddFieldsForType(UPB_DESCRIPTOR_TYPE_UINT64, "uint64", md.get()); - AddFieldsForType(UPB_DESCRIPTOR_TYPE_INT32, "int32", md.get()); - AddFieldsForType(UPB_DESCRIPTOR_TYPE_FIXED64, "fixed64", md.get()); - AddFieldsForType(UPB_DESCRIPTOR_TYPE_FIXED32, "fixed32", md.get()); - AddFieldsForType(UPB_DESCRIPTOR_TYPE_BOOL, "bool", md.get()); - AddFieldsForType(UPB_DESCRIPTOR_TYPE_STRING, "string", md.get()); - AddFieldsForType(UPB_DESCRIPTOR_TYPE_BYTES, "bytes", md.get()); - AddFieldsForType(UPB_DESCRIPTOR_TYPE_UINT32, "uint32", md.get()); - AddFieldsForType(UPB_DESCRIPTOR_TYPE_SFIXED32, "sfixed32", md.get()); - AddFieldsForType(UPB_DESCRIPTOR_TYPE_SFIXED64, "sfixed64", md.get()); - AddFieldsForType(UPB_DESCRIPTOR_TYPE_SINT32, "sint32", md.get()); - AddFieldsForType(UPB_DESCRIPTOR_TYPE_SINT64, "sint64", md.get()); - - AddField(UPB_DESCRIPTOR_TYPE_STRING, "nop_field", 40, false, md.get()); - - upb::reffed_ptr f = upb::FieldDef::New(); - ASSERT(f->set_name("f_message", NULL)); - ASSERT(f->set_number(UPB_DESCRIPTOR_TYPE_MESSAGE, NULL)); - f->set_descriptor_type(UPB_DESCRIPTOR_TYPE_MESSAGE); - ASSERT(f->set_message_subdef(md.get(), NULL)); - ASSERT(md->AddField(f.get(), NULL)); - - f = upb::FieldDef::New(); - ASSERT(f->set_name("r_message", NULL)); - ASSERT(f->set_number(rep_fn(UPB_DESCRIPTOR_TYPE_MESSAGE), NULL)); - f->set_label(UPB_LABEL_REPEATED); - f->set_descriptor_type(UPB_DESCRIPTOR_TYPE_MESSAGE); - ASSERT(f->set_message_subdef(md.get(), NULL)); - ASSERT(md->AddField(f.get(), NULL)); - - f = upb::FieldDef::New(); - ASSERT(f->set_name("f_group", NULL)); - ASSERT(f->set_number(UPB_DESCRIPTOR_TYPE_GROUP, NULL)); - f->set_descriptor_type(UPB_DESCRIPTOR_TYPE_GROUP); - ASSERT(f->set_message_subdef(md.get(), NULL)); - ASSERT(md->AddField(f.get(), NULL)); - - f = upb::FieldDef::New(); - ASSERT(f->set_name("r_group", NULL)); - ASSERT(f->set_number(rep_fn(UPB_DESCRIPTOR_TYPE_GROUP), NULL)); - f->set_label(UPB_LABEL_REPEATED); - f->set_descriptor_type(UPB_DESCRIPTOR_TYPE_GROUP); - ASSERT(f->set_message_subdef(md.get(), NULL)); - ASSERT(md->AddField(f.get(), NULL)); - - upb::reffed_ptr e = upb::EnumDef::New(); - ASSERT(e->AddValue("FOO", 1, NULL)); - ASSERT(e->Freeze(NULL)); - - f = upb::FieldDef::New(); - ASSERT(f->set_name("f_enum", NULL)); - ASSERT(f->set_number(UPB_DESCRIPTOR_TYPE_ENUM, NULL)); - f->set_descriptor_type(UPB_DESCRIPTOR_TYPE_ENUM); - ASSERT(f->set_enum_subdef(e.get(), NULL)); - ASSERT(md->AddField(f.get(), NULL)); - - f = upb::FieldDef::New(); - ASSERT(f->set_name("r_enum", NULL)); - ASSERT(f->set_number(rep_fn(UPB_DESCRIPTOR_TYPE_ENUM), NULL)); - f->set_label(UPB_LABEL_REPEATED); - f->set_descriptor_type(UPB_DESCRIPTOR_TYPE_ENUM); - ASSERT(f->set_enum_subdef(e.get(), NULL)); - ASSERT(md->AddField(f.get(), NULL)); - - ASSERT(md->Freeze(NULL)); - - return md; -} - upb::reffed_ptr NewHandlers(TestMode mode) { + upb::reffed_ptr h(upb::Handlers::New(NewMessageDef().get())); if (mode == ALL_HANDLERS) { @@ -1277,6 +1178,7 @@ upb::reffed_ptr method = void run_tests(bool use_jit) { upb::reffed_ptr method; upb::reffed_ptr handlers; + upb::SymbolTable symtab; handlers = NewHandlers(test_mode); global_handlers = handlers.get(); diff --git a/tests/pb/test_decoder.proto b/tests/pb/test_decoder.proto new file mode 100644 index 0000000..8197dea --- /dev/null +++ b/tests/pb/test_decoder.proto @@ -0,0 +1,86 @@ + +syntax = "proto2"; + +enum TestEnum { + FOO = 1; +} + +message DecoderTest { + optional double f_double = 1; + optional float f_float = 2; + optional int64 f_int64 = 3; + optional uint64 f_uint64 = 4; + optional int32 f_int32 = 5; + optional fixed64 f_fixed64 = 6; + optional fixed32 f_fixed32 = 7; + optional bool f_bool = 8; + optional string f_string = 9; + optional DecoderTest f_message = 11; + optional bytes f_bytes = 12; + optional uint32 f_uint32 = 13; + optional TestEnum f_enum = 14; + optional sfixed32 f_sfixed32 = 15; + optional sfixed64 f_sfixed64 = 16; + optional sint32 f_sint32 = 17; + optional sint64 f_sint64 = 18; + + optional string nop_field = 40; + + repeated double r_double = 536869912; + repeated float r_float = 536869913; + repeated int64 r_int64 = 536869914; + repeated uint64 r_uint64 = 536869915; + repeated int32 r_int32 = 536869916; + repeated fixed64 r_fixed64 = 536869917; + repeated fixed32 r_fixed32 = 536869918; + repeated bool r_bool = 536869919; + repeated string r_string = 536869920; + repeated DecoderTest r_message = 536869922; + repeated bytes r_bytes = 536869923; + repeated uint32 r_uint32 = 536869924; + repeated TestEnum r_enum = 536869925; + repeated sfixed32 r_sfixed32 = 536869926; + repeated sfixed64 r_sfixed64 = 536869927; + repeated sint32 r_sint32 = 536869928; + repeated sint64 r_sint64 = 536869929; + + optional group F_group = 10 { + optional double f_double = 1; + optional float f_float = 2; + optional int64 f_int64 = 3; + optional uint64 f_uint64 = 4; + optional int32 f_int32 = 5; + optional fixed64 f_fixed64 = 6; + optional fixed32 f_fixed32 = 7; + optional bool f_bool = 8; + optional string f_string = 9; + optional DecoderTest f_message = 11; + optional bytes f_bytes = 12; + optional uint32 f_uint32 = 13; + optional TestEnum f_enum = 14; + optional sfixed32 f_sfixed32 = 15; + optional sfixed64 f_sfixed64 = 16; + optional sint32 f_sint32 = 17; + optional sint64 f_sint64 = 18; + } + + optional group R_group = 536869921 { + optional double f_double = 1; + optional float f_float = 2; + optional int64 f_int64 = 3; + optional uint64 f_uint64 = 4; + optional int32 f_int32 = 5; + optional fixed64 f_fixed64 = 6; + optional fixed32 f_fixed32 = 7; + optional bool f_bool = 8; + optional string f_string = 9; + optional DecoderTest f_message = 11; + optional bytes f_bytes = 12; + optional uint32 f_uint32 = 13; + optional TestEnum f_enum = 14; + optional sfixed32 f_sfixed32 = 15; + optional sfixed64 f_sfixed64 = 16; + optional sint32 f_sint32 = 17; + optional sint64 f_sint64 = 18; + } +} diff --git a/tests/pb/test_encoder.cc b/tests/pb/test_encoder.cc index 6c20e27..78a779f 100644 --- a/tests/pb/test_encoder.cc +++ b/tests/pb/test_encoder.cc @@ -2,10 +2,9 @@ #include "tests/test_util.h" #include "tests/upb_test.h" #include "upb/bindings/stdc++/string.h" -#include "upb/descriptor/descriptor.upbdefs.h" +#include "google/protobuf/descriptor.upb.h" #include "upb/pb/decoder.h" #include "upb/pb/encoder.h" -#include "upb/pb/glue.h" std::string read_string(const char *filename) { size_t len; @@ -18,16 +17,30 @@ std::string read_string(const char *filename) { } void test_pb_roundtrip() { - upb::reffed_ptr md( - upbdefs::google::protobuf::FileDescriptorSet::get()); + std::string input = read_string("google/protobuf/descriptor.pb"); + upb::SymbolTable* symtab = upb::SymbolTable::New(); + upb::Arena arena; + google_protobuf_FileDescriptorSet *set = + google_protobuf_FileDescriptorSet_parsenew( + upb_stringview_make(input.c_str(), input.size()), &arena); + ASSERT(set); + const upb_array *arr = google_protobuf_FileDescriptorSet_file(set); + const google_protobuf_FileDescriptorProto *file_proto = + static_cast( + upb_msgval_getptr(upb_array_get(arr, 0))); + upb::Status status; + bool ok = symtab->AddFile(file_proto, &status); + ASSERT(ok); + const upb::MessageDef *md = + symtab->LookupMessage("google.protobuf.FileDescriptorSet"); + ASSERT(md); upb::reffed_ptr encoder_handlers( - upb::pb::Encoder::NewHandlers(md.get())); + upb::pb::Encoder::NewHandlers(md)); upb::reffed_ptr method( upb::pb::DecoderMethod::New( upb::pb::DecoderMethodOptions(encoder_handlers.get()))); upb::InlinedEnvironment<512> env; - std::string input = read_string("upb/descriptor/descriptor.pb"); std::string output; upb::StringSink string_sink(&output); upb::pb::Encoder* encoder = @@ -35,9 +48,10 @@ void test_pb_roundtrip() { string_sink.input()); upb::pb::Decoder* decoder = upb::pb::Decoder::Create(&env, method.get(), encoder->input()); - bool ok = upb::BufferSource::PutBuffer(input, decoder->input()); + ok = upb::BufferSource::PutBuffer(input, decoder->input()); ASSERT(ok); ASSERT(input == output); + upb::SymbolTable::Free(symtab); } extern "C" { diff --git a/tests/test_def.c b/tests/test_def.c deleted file mode 100644 index d82fddb..0000000 --- a/tests/test_def.c +++ /dev/null @@ -1,453 +0,0 @@ -/* -** Test of defs and symtab. There should be far more tests of edge conditions -** (like attempts to link defs that don't have required properties set). -*/ - -#include "tests/test_util.h" -#include "upb/def.h" -#include "upb/pb/glue.h" -#include "upb_test.h" -#include -#include - -const char *descriptor_file; - -static void test_empty_symtab() { - upb_symtab *s = upb_symtab_new(); - upb_symtab_iter i; - for (upb_symtab_begin(&i, s, UPB_DEF_ANY); !upb_symtab_done(&i); - upb_symtab_next(&i)) { - ASSERT(false); /* Should not get here. */ - } - upb_symtab_free(s); -} - -static void test_noreftracking() { - /* Reftracking is not required; clients can pass UPB_UNTRACKED_REF for owner. */ - upb_msgdef *md = upb_msgdef_new(UPB_UNTRACKED_REF); - upb_msgdef_ref(md, UPB_UNTRACKED_REF); - - /* Clients can mix tracked and untracked refs. */ - upb_msgdef_ref(md, &md); - - upb_msgdef_unref(md, UPB_UNTRACKED_REF); - upb_msgdef_unref(md, UPB_UNTRACKED_REF); - - /* Call some random function on the messagedef to test that it is alive. */ - ASSERT(!upb_msgdef_isfrozen(md)); - - upb_msgdef_unref(md, &md); -} - -static upb_symtab *load_test_proto() { - upb_symtab *s = upb_symtab_new(); - upb_status status = UPB_STATUS_INIT; - size_t len; - char *data = upb_readfile(descriptor_file, &len); - upb_filedef **files, **files_ptr; - ASSERT(s); - ASSERT(data); - files = upb_loaddescriptor(data, len, &files, &status); - ASSERT(files); - free(data); - - files_ptr = files; - while (*files_ptr) { - bool ok; - ASSERT(!upb_filedef_isfrozen(*files_ptr)); - ok = upb_symtab_addfile(s, *files_ptr, &status); - ASSERT(ok); - ASSERT(upb_filedef_isfrozen(*files_ptr)); - upb_filedef_unref(*files_ptr, &files); - files_ptr++; - } - - upb_gfree(files); - - return s; -} - -static void test_cycles() { - bool ok; - upb_symtab *s = load_test_proto(); - const upb_msgdef *m; - const upb_fielddef *f; - const upb_def *def; - const upb_def *def2; - - /* Test cycle detection by making a cyclic def's main refcount go to zero - * and then be incremented to one again. */ - def = upb_symtab_lookup(s, "A"); - upb_def_ref(def, &def); - ASSERT(def); - ASSERT(upb_def_isfrozen(def)); - upb_symtab_free(s); - - /* Message A has only one subfield: "optional B b = 1". */ - m = upb_downcast_msgdef(def); - f = upb_msgdef_itof(m, 1); - ASSERT(f); - ASSERT(upb_fielddef_hassubdef(f)); - ASSERT(upb_msgdef_ntofz(m, "b") == f); - ASSERT(upb_msgdef_ntof(m, "b", 1) == f); - def2 = upb_fielddef_subdef(f); - ASSERT(upb_downcast_msgdef(def2)); - ok = strcmp(upb_def_fullname(def2), "B") == 0; - ASSERT(ok); - - upb_def_ref(def2, &def2); - upb_def_unref(def, &def); - - /* We know "def" is still alive because it's reachable from def2. */ - ok = strcmp(upb_def_fullname(def), "A") == 0; - ASSERT(ok); - upb_def_unref(def2, &def2); -} - -static void test_symbol_resolution() { - upb_status s = UPB_STATUS_INIT; - upb_def *defs[2]; - upb_msgdef *m1; - upb_msgdef *m2; - upb_msgdef *m3; - upb_fielddef *m3_field1; - upb_fielddef *m3_field2; - - upb_symtab *symtab = upb_symtab_new(&symtab); - ASSERT(symtab); - - /* m1 has name "A.B.C" and no fields. We'll add it to the symtab now. */ - m1 = upb_msgdef_new(&m1); - ASSERT(m1); - ASSERT_STATUS(upb_msgdef_setfullname(m1, "A.B.C", &s), &s); - ASSERT_STATUS(upb_symtab_add(symtab, (upb_def**)&m1, 1, - NULL, &s), &s); - - /* m2 has name "D.E" and no fields. We'll add it in the same batch as m3 - * below. */ - m2 = upb_msgdef_new(&m2); - ASSERT(m2); - ASSERT_STATUS(upb_msgdef_setfullname(m2, "D.E", &s), &s); - - /* m3 has name "F.G" and two fields, of type A.B.C and D.E respectively. We'll - * add it in the same batch as m2 above. */ - m3 = upb_msgdef_new(&m3); - ASSERT(m3); - ASSERT_STATUS(upb_msgdef_setfullname(m3, "F.G", &s), &s); - m3_field1 = upb_fielddef_new(&m3_field1); - ASSERT_STATUS(upb_fielddef_setname(m3_field1, "field1", &s), &s); - ASSERT_STATUS(upb_fielddef_setnumber(m3_field1, 1, &s), &s); - upb_fielddef_setlabel(m3_field1, UPB_LABEL_OPTIONAL); - upb_fielddef_settype(m3_field1, UPB_TYPE_MESSAGE); - ASSERT_STATUS(upb_fielddef_setsubdefname(m3_field1, ".A.B.C", &s), &s); - ASSERT_STATUS(upb_msgdef_addfield(m3, m3_field1, NULL, &s), &s); - - m3_field2 = upb_fielddef_new(&m3_field2); - ASSERT_STATUS(upb_fielddef_setname(m3_field2, "field2", &s), &s); - ASSERT_STATUS(upb_fielddef_setnumber(m3_field2, 2, &s), &s); - upb_fielddef_setlabel(m3_field2, UPB_LABEL_OPTIONAL); - upb_fielddef_settype(m3_field2, UPB_TYPE_MESSAGE); - ASSERT_STATUS(upb_fielddef_setsubdefname(m3_field2, ".D.E", &s), &s); - ASSERT_STATUS(upb_msgdef_addfield(m3, m3_field2, NULL, &s), &s); - - defs[0] = upb_msgdef_upcast_mutable(m2); - defs[1] = upb_msgdef_upcast_mutable(m3); - ASSERT_STATUS(upb_symtab_add(symtab, defs, 2, NULL, &s), &s); - - upb_fielddef_unref(m3_field2, &m3_field2); - upb_fielddef_unref(m3_field1, &m3_field1); - upb_msgdef_unref(m3, &m3); - upb_msgdef_unref(m2, &m2); - upb_msgdef_unref(m1, &m1); - upb_symtab_free(symtab); -} - -static void test_fielddef_unref() { - bool ok; - upb_symtab *s = load_test_proto(); - const upb_msgdef *md = upb_symtab_lookupmsg(s, "A"); - const upb_fielddef *f = upb_msgdef_itof(md, 1); - upb_fielddef_ref(f, &f); - - /* Unref symtab; now fielddef is the only thing keeping the msgdef alive. */ - upb_symtab_free(s); - /* Check that md is still alive. */ - ok = strcmp(upb_msgdef_fullname(md), "A") == 0; - ASSERT(ok); - - /* Check that unref of fielddef frees the whole remaining graph. */ - upb_fielddef_unref(f, &f); -} - -static void test_fielddef() { - /* Test that we don't leak an unresolved subdef name. */ - upb_fielddef *f1 = upb_fielddef_new(&f1); - upb_fielddef_settype(f1, UPB_TYPE_MESSAGE); - ASSERT(upb_fielddef_setsubdefname(f1, "YO", NULL)); - upb_fielddef_unref(f1, &f1); -} - -static upb_fielddef *newfield( - const char *name, int32_t num, uint8_t type, uint8_t label, - const char *type_name, void *owner) { - upb_fielddef *f = upb_fielddef_new(owner); - ASSERT(upb_fielddef_setname(f, name, NULL)); - ASSERT(upb_fielddef_setnumber(f, num, NULL)); - upb_fielddef_settype(f, type); - upb_fielddef_setlabel(f, label); - if (type_name) { - ASSERT(upb_fielddef_setsubdefname(f, type_name, NULL)); - } - return f; -} - -static upb_msgdef *upb_msgdef_newnamed(const char *name, void *owner) { - upb_msgdef *m = upb_msgdef_new(owner); - upb_msgdef_setfullname(m, name, NULL); - return m; -} - -static void test_replacement_fails() { - bool ok; - upb_symtab *s = upb_symtab_new(&s); - upb_status status = UPB_STATUS_INIT; - upb_def *newdefs[2]; - - upb_msgdef *m = upb_msgdef_newnamed("MyMessage", &s); - upb_msgdef *m2 = upb_msgdef_newnamed("MyMessage", &s); - - newdefs[0] = upb_msgdef_upcast_mutable(m); - newdefs[1] = upb_msgdef_upcast_mutable(m2); - ok = upb_symtab_add(s, newdefs, 2, &s, &status); - ASSERT(ok == false); - upb_status_clear(&status); - - /* Adding just one is ok. */ - ASSERT_STATUS(upb_symtab_add(s, newdefs, 1, &s, &status), &status); - - /* Adding a conflicting one is not ok. */ - newdefs[0] = upb_msgdef_upcast_mutable(m2); - ok = upb_symtab_add(s, newdefs, 1, &s, &status); - ASSERT(ok == false); - - upb_symtab_free(s); -} - -static void test_freeze_free() { - bool ok; - - /* Test that freeze frees defs that were only being kept alive by virtue of - * sharing a group with other defs that are being frozen. */ - upb_msgdef *m1 = upb_msgdef_newnamed("M1", &m1); - upb_msgdef *m2 = upb_msgdef_newnamed("M2", &m2); - upb_msgdef *m3 = upb_msgdef_newnamed("M3", &m3); - upb_msgdef *m4 = upb_msgdef_newnamed("M4", &m4); - upb_fielddef *f = upb_fielddef_new(&f); - - /* Freeze M4 and make M1 point to it. */ - upb_def_freeze((upb_def*const*)&m4, 1, NULL); - - upb_fielddef_settype(f, UPB_TYPE_MESSAGE); - ASSERT(upb_fielddef_setnumber(f, 1, NULL)); - ASSERT(upb_fielddef_setname(f, "foo", NULL)); - ASSERT(upb_fielddef_setmsgsubdef(f, m4, NULL)); - - ASSERT(upb_msgdef_addfield(m1, f, &f, NULL)); - - /* After this unref, M1 is the only thing keeping M4 alive. */ - upb_msgdef_unref(m4, &m4); - - /* Force M1/M2/M3 into a single mutable refcounting group. */ - f = upb_fielddef_new(&f); - upb_fielddef_settype(f, UPB_TYPE_MESSAGE); - ASSERT(upb_fielddef_setnumber(f, 1, NULL)); - ASSERT(upb_fielddef_setname(f, "foo", NULL)); - - ASSERT(upb_fielddef_setmsgsubdef(f, m1, NULL)); - ASSERT(upb_fielddef_setmsgsubdef(f, m2, NULL)); - ASSERT(upb_fielddef_setmsgsubdef(f, m3, NULL)); - - /* Make M3 cyclic with itself. */ - ASSERT(upb_msgdef_addfield(m3, f, &f, NULL)); - - /* These will be kept alive since they are in the same refcounting group as - * M3, which still has a ref. Note: this behavior is not guaranteed by the - * API, but true in practice with its current implementation. */ - upb_msgdef_unref(m1, &m1); - upb_msgdef_unref(m2, &m2); - - /* Test that they are still alive (NOT allowed by the API). */ - ok = strcmp("M1", upb_msgdef_fullname(m1)) == 0; - ASSERT(ok); - ok = strcmp("M2", upb_msgdef_fullname(m2)) == 0; - ASSERT(ok); - - /* Freeze M3. If the test leaked no memory, then freeing m1 and m2 was - * successful. */ - ASSERT(upb_def_freeze((upb_def*const*)&m3, 1, NULL)); - - upb_msgdef_unref(m3, &m3); -} - -static void test_partial_freeze() { - /* Test that freeze of only part of the graph correctly adjusts objects that - * point to the newly-frozen objects. */ - upb_msgdef *m1 = upb_msgdef_newnamed("M1", &m1); - upb_msgdef *m2 = upb_msgdef_newnamed("M2", &m2); - upb_msgdef *m3 = upb_msgdef_newnamed("M3", &m3); - upb_fielddef *f1 = upb_fielddef_new(&f1); - upb_fielddef *f2 = upb_fielddef_new(&f2); - upb_def *defs[2]; - defs[0] = upb_msgdef_upcast_mutable(m1); - defs[1] = upb_msgdef_upcast_mutable(m2); - - upb_fielddef_settype(f1, UPB_TYPE_MESSAGE); - ASSERT(upb_fielddef_setnumber(f1, 1, NULL)); - ASSERT(upb_fielddef_setname(f1, "f1", NULL)); - ASSERT(upb_fielddef_setmsgsubdef(f1, m1, NULL)); - - upb_fielddef_settype(f2, UPB_TYPE_MESSAGE); - ASSERT(upb_fielddef_setnumber(f2, 2, NULL)); - ASSERT(upb_fielddef_setname(f2, "f2", NULL)); - ASSERT(upb_fielddef_setmsgsubdef(f2, m2, NULL)); - - ASSERT(upb_msgdef_addfield(m3, f1, &f1, NULL)); - ASSERT(upb_msgdef_addfield(m3, f2, &f2, NULL)); - - /* Freeze M1 and M2, which should cause the group to be split - * and m3 (left mutable) to take references on m1 and m2. */ - ASSERT(upb_def_freeze(defs, 2, NULL)); - - ASSERT(upb_msgdef_isfrozen(m1)); - ASSERT(upb_msgdef_isfrozen(m2)); - ASSERT(!upb_msgdef_isfrozen(m3)); - - upb_msgdef_unref(m1, &m1); - upb_msgdef_unref(m2, &m2); - upb_msgdef_unref(m3, &m3); -} - -static void test_descriptor_flags() { - upb_msgdef *m = upb_msgdef_new(&m); - upb_status s = UPB_STATUS_INIT; - - ASSERT(upb_msgdef_mapentry(m) == false); - upb_msgdef_setfullname(m, "TestMessage", &s); - ASSERT(upb_ok(&s)); - upb_msgdef_setmapentry(m, true); - ASSERT(upb_msgdef_mapentry(m) == true); - upb_msgdef_unref(m, &m); -} - -static void test_mapentry_check() { - upb_status s = UPB_STATUS_INIT; - upb_msgdef *m = upb_msgdef_new(&m); - upb_fielddef *f = upb_fielddef_new(&f); - upb_symtab *symtab = upb_symtab_new(&symtab); - upb_msgdef *subm = upb_msgdef_new(&subm); - upb_def *defs[2]; - - upb_msgdef_setfullname(m, "TestMessage", &s); - upb_fielddef_setname(f, "field1", &s); - upb_fielddef_setnumber(f, 1, &s); - upb_fielddef_setlabel(f, UPB_LABEL_OPTIONAL); - upb_fielddef_settype(f, UPB_TYPE_MESSAGE); - upb_fielddef_setsubdefname(f, ".MapEntry", &s); - upb_msgdef_addfield(m, f, &f, &s); - ASSERT(upb_ok(&s)); - - upb_msgdef_setfullname(subm, "MapEntry", &s); - upb_msgdef_setmapentry(subm, true); - - defs[0] = upb_msgdef_upcast_mutable(m); - defs[1] = upb_msgdef_upcast_mutable(subm); - upb_symtab_add(symtab, defs, 2, NULL, &s); - /* Should not have succeeded: non-repeated field pointing to a MapEntry. */ - ASSERT(!upb_ok(&s)); - - upb_status_clear(&s); - upb_fielddef_setlabel(f, UPB_LABEL_REPEATED); - upb_symtab_add(symtab, defs, 2, NULL, &s); - ASSERT(upb_ok(&s)); - - upb_symtab_free(symtab); - upb_msgdef_unref(subm, &subm); - upb_msgdef_unref(m, &m); -} - -static void test_oneofs() { - upb_status s = UPB_STATUS_INIT; - bool ok = true; - upb_def *subm_defs[1]; - upb_symtab *symtab = upb_symtab_new(&symtab); - upb_msgdef *subm = upb_msgdef_newnamed("SubMessage", &symtab); - upb_msgdef *m = upb_msgdef_newnamed("TestMessage", &symtab); - upb_oneofdef *o = upb_oneofdef_new(&o); - const upb_oneofdef *lookup_o; - const upb_fielddef *lookup_field; - upb_def *defs[1]; - - ASSERT(symtab != NULL); - - /* Create a test message for fields to refer to. */ - upb_msgdef_addfield(subm, newfield("field1", 1, UPB_TYPE_INT32, - UPB_LABEL_OPTIONAL, NULL, &symtab), - &symtab, NULL); - subm_defs[0] = upb_msgdef_upcast_mutable(subm); - ASSERT_STATUS(upb_symtab_add(symtab, subm_defs, 1, &symtab, &s), &s); - - ASSERT(upb_msgdef_numoneofs(m) == 0); - - ASSERT(upb_oneofdef_numfields(o) == 0); - ASSERT(upb_oneofdef_name(o) == NULL); - - ok = upb_oneofdef_setname(o, "test_oneof", &s); - ASSERT_STATUS(ok, &s); - - ok = upb_oneofdef_addfield(o, newfield("field1", 1, UPB_TYPE_INT32, - UPB_LABEL_OPTIONAL, NULL, &symtab), - &symtab, NULL); - ASSERT_STATUS(ok, &s); - ok = upb_oneofdef_addfield(o, newfield("field2", 2, UPB_TYPE_MESSAGE, - UPB_LABEL_OPTIONAL, ".SubMessage", - &symtab), - &symtab, NULL); - ASSERT_STATUS(ok, &s); - - ok = upb_msgdef_addoneof(m, o, NULL, &s); - ASSERT_STATUS(ok, &s); - - defs[0] = upb_msgdef_upcast_mutable(m); - ASSERT_STATUS(upb_symtab_add(symtab, defs, 1, &symtab, &s), &s); - - ASSERT(upb_msgdef_numoneofs(m) == 1); - lookup_o = upb_msgdef_ntooz(m, "test_oneof"); - ASSERT(lookup_o == o); - - lookup_field = upb_oneofdef_ntofz(o, "field1"); - ASSERT(lookup_field != NULL && upb_fielddef_number(lookup_field) == 1); - - upb_symtab_free(symtab); - upb_oneofdef_unref(o, &o); -} - -int run_tests(int argc, char *argv[]) { - if (argc < 2) { - fprintf(stderr, "Usage: test_def \n"); - return 1; - } - descriptor_file = argv[1]; - test_empty_symtab(); - test_cycles(); - test_symbol_resolution(); - test_fielddef(); - test_fielddef_unref(); - test_replacement_fails(); - test_freeze_free(); - test_partial_freeze(); - test_noreftracking(); - test_descriptor_flags(); - test_mapentry_check(); - test_oneofs(); - return 0; -} diff --git a/upb/def.c b/upb/def.c index 33ad70e..9a4d766 100644 --- a/upb/def.c +++ b/upb/def.c @@ -1359,14 +1359,21 @@ static void count_types_in_msg( size_t i; arr = google_protobuf_DescriptorProto_nested_type(msg_proto); - for (i = 0; i < upb_array_size(arr); i++) { - count_types_in_msg(upb_msgval_getptr(upb_array_get(arr, i)), counts); + if (arr) { + for (i = 0; i < upb_array_size(arr); i++) { + count_types_in_msg(upb_msgval_getptr(upb_array_get(arr, i)), counts); + } } arr = google_protobuf_DescriptorProto_enum_type(msg_proto); - counts->enum_count += upb_array_size(arr); + if (arr) { + counts->enum_count += upb_array_size(arr); + } + arr = google_protobuf_DescriptorProto_extension(msg_proto); - counts->ext_count += upb_array_size(arr); + if (arr) { + counts->ext_count += upb_array_size(arr); + } } static void count_types_in_file( diff --git a/upb/def.h b/upb/def.h index 78ae9b3..4fe6d04 100644 --- a/upb/def.h +++ b/upb/def.h @@ -564,8 +564,6 @@ class upb::OneofDef { upb_oneof_iter iter_; }; - iterator begin(); - iterator end(); const_iterator begin() const; const_iterator end() const; @@ -682,7 +680,8 @@ class upb::SymbolTable { /* TODO: iteration? */ /* Adds the given serialized FileDescriptorProto to the pool. */ - bool AddFile(const char *file, size_t len, Status *status); + bool AddFile(const google_protobuf_FileDescriptorProto *file_proto, + Status *status); /* Adds the given serialized FileDescriptorSet to the pool. */ bool AddSet(const char *set, size_t len, Status *status); @@ -703,6 +702,7 @@ 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); +int upb_symtab_filecount(const upb_symtab *s); bool upb_symtab_addfile(upb_symtab *s, const google_protobuf_FileDescriptorProto* file, upb_status *status); @@ -721,6 +721,10 @@ inline void SymbolTable::Free(SymbolTable* s) { inline const MessageDef *SymbolTable::LookupMessage(const char *sym) const { return upb_symtab_lookupmsg(this, sym); } +inline bool SymbolTable::AddFile( + const google_protobuf_FileDescriptorProto *file_proto, Status *status) { + return upb_symtab_addfile(this, file_proto, status); +} } /* namespace upb */ #endif @@ -767,9 +771,6 @@ inline const MessageDef* FieldDef::containing_type() const { inline const OneofDef* FieldDef::containing_oneof() const { return upb_fielddef_containingoneof(this); } -inline void FieldDef::clear_json_name() { - upb_fielddef_clearjsonname(this); -} inline bool FieldDef::IsSubMessage() const { return upb_fielddef_issubmsg(this); } @@ -994,9 +995,6 @@ inline const char* FileDef::phpprefix() const { inline const char* FileDef::phpnamespace() const { return upb_filedef_phpnamespace(this); } -inline int FileDef::def_count() const { - return upb_filedef_defcount(this); -} inline int FileDef::dependency_count() const { return upb_filedef_depcount(this); } -- cgit v1.2.3 From cf0a89ed69561d73210056566272b27844a95782 Mon Sep 17 00:00:00 2001 From: Joshua Haberman Date: Thu, 13 Dec 2018 07:41:56 -0800 Subject: Updated to use the new array accessors. --- upb/bindings/lua/def.c | 14 ++---- upb/def.c | 133 +++++++++++++++++++++---------------------------- 2 files changed, 63 insertions(+), 84 deletions(-) (limited to 'upb/def.c') diff --git a/upb/bindings/lua/def.c b/upb/bindings/lua/def.c index 1fde212..00b75c9 100644 --- a/upb/bindings/lua/def.c +++ b/upb/bindings/lua/def.c @@ -634,10 +634,9 @@ static int lupb_symtab_gc(lua_State *L) { * 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_arena *arena; - size_t i; - upb_array *file_arr; + size_t i, n, len; + const google_protobuf_FileDescriptorProto *const *files; google_protobuf_FileDescriptorSet *set; upb_symtab *s = lupb_symtab_check(L, 1); const char *str = luaL_checklstring(L, 2, &len); @@ -652,12 +651,9 @@ static int lupb_symtab_add(lua_State *L) { luaL_argerror(L, 2, "failed to parse descriptor"); } - file_arr = (upb_array*)google_protobuf_FileDescriptorSet_file(set); - for (i = 0; i < upb_array_size(file_arr); i++) { - upb_msgval entry = upb_array_get(file_arr, i); - google_protobuf_FileDescriptorProto *file = - (void *)upb_msgval_getmsg(entry); - CHK(upb_symtab_addfile(s, file, &status)); + files = google_protobuf_FileDescriptorSet_file(set, &n); + for (i = 0; i < n; i++) { + CHK(upb_symtab_addfile(s, files[i], &status)); } return 0; diff --git a/upb/def.c b/upb/def.c index 9a4d766..8029c92 100644 --- a/upb/def.c +++ b/upb/def.c @@ -1232,9 +1232,9 @@ static bool create_enumdef( const symtab_addctx *ctx, const char *prefix, const google_protobuf_EnumDescriptorProto *enum_proto) { upb_enumdef *e; - const upb_array *arr; + const google_protobuf_EnumValueDescriptorProto *const *values; upb_stringview name; - size_t i; + size_t i, n; name = google_protobuf_EnumDescriptorProto_name(enum_proto); CHK(upb_isident(name, false, ctx->status)); @@ -1248,11 +1248,10 @@ static bool create_enumdef( e->defaultval = 0; - arr = google_protobuf_EnumDescriptorProto_value(enum_proto); + values = google_protobuf_EnumDescriptorProto_value(enum_proto, &n); - for (i = 0; i < upb_array_size(arr); i++) { - const google_protobuf_EnumValueDescriptorProto *value = - upb_msgval_getptr(upb_array_get(arr, i)); + for (i = 0; i < n; i++) { + const google_protobuf_EnumValueDescriptorProto *value = values[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); @@ -1277,7 +1276,10 @@ static bool create_msgdef(const symtab_addctx *ctx, const char *prefix, const google_protobuf_DescriptorProto *msg_proto) { upb_msgdef *m; const google_protobuf_MessageOptions *options; - const upb_array *arr; + const google_protobuf_OneofDescriptorProto *const *oneofs; + const google_protobuf_FieldDescriptorProto *const *fields; + const google_protobuf_EnumDescriptorProto *const *enums; + const google_protobuf_DescriptorProto *const *msgs; size_t i, n; upb_stringview name; @@ -1300,21 +1302,16 @@ static bool create_msgdef(const symtab_addctx *ctx, const char *prefix, m->map_entry = google_protobuf_MessageOptions_map_entry(options); } - arr = google_protobuf_DescriptorProto_oneof_decl(msg_proto); + oneofs = google_protobuf_DescriptorProto_oneof_decl(msg_proto, &n); m->oneof_count = 0; - n = upb_array_size(arr); m->oneofs = upb_malloc(ctx->alloc, sizeof(*m->oneofs) * n); for (i = 0; i < n; i++) { - const google_protobuf_OneofDescriptorProto *oneof_proto = - upb_msgval_getptr(upb_array_get(arr, i)); - CHK(create_oneofdef(ctx, m, oneof_proto)); + CHK(create_oneofdef(ctx, m, oneofs[i])); } - arr = google_protobuf_DescriptorProto_field(msg_proto); - for (i = 0; i < upb_array_size(arr); i++) { - const google_protobuf_FieldDescriptorProto *field_proto = - upb_msgval_getptr(upb_array_get(arr, i)); - CHK(create_fielddef(ctx, m->full_name, m, field_proto)); + fields = google_protobuf_DescriptorProto_field(msg_proto, &n); + for (i = 0; i < n; i++) { + CHK(create_fielddef(ctx, m->full_name, m, fields[i])); } CHK(assign_msg_indices(m, ctx->status)); @@ -1322,18 +1319,14 @@ static bool create_msgdef(const symtab_addctx *ctx, const char *prefix, /* 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 = - upb_msgval_getptr(upb_array_get(arr, i)); - CHK(create_enumdef(ctx, m->full_name, enum_proto)); + enums = google_protobuf_DescriptorProto_enum_type(msg_proto, &n); + for (i = 0; i < n; i++) { + CHK(create_enumdef(ctx, m->full_name, enums[i])); } - arr = google_protobuf_DescriptorProto_nested_type(msg_proto); - for (i = 0; i < upb_array_size(arr); i++) { - const google_protobuf_DescriptorProto *msg_proto2 = - upb_msgval_getptr(upb_array_get(arr, i)); - CHK(create_msgdef(ctx, m->full_name, msg_proto2)); + msgs = google_protobuf_DescriptorProto_nested_type(msg_proto, &n); + for (i = 0; i < n; i++) { + CHK(create_msgdef(ctx, m->full_name, msgs[i])); } return true; @@ -1352,45 +1345,39 @@ typedef struct { int ext_count; } decl_counts; -static void count_types_in_msg( - const google_protobuf_DescriptorProto *msg_proto, - decl_counts *counts) { - const upb_array *arr; - size_t i; +static void count_types_in_msg(const google_protobuf_DescriptorProto *msg_proto, + decl_counts *counts) { + const google_protobuf_DescriptorProto *const *msgs; + size_t i, n; - arr = google_protobuf_DescriptorProto_nested_type(msg_proto); - if (arr) { - for (i = 0; i < upb_array_size(arr); i++) { - count_types_in_msg(upb_msgval_getptr(upb_array_get(arr, i)), counts); - } + msgs = google_protobuf_DescriptorProto_nested_type(msg_proto, &n); + for (i = 0; i < n; i++) { + count_types_in_msg(msgs[i], counts); } - arr = google_protobuf_DescriptorProto_enum_type(msg_proto); - if (arr) { - counts->enum_count += upb_array_size(arr); - } + google_protobuf_DescriptorProto_enum_type(msg_proto, &n); + counts->enum_count += n; - arr = google_protobuf_DescriptorProto_extension(msg_proto); - if (arr) { - counts->ext_count += upb_array_size(arr); - } + google_protobuf_DescriptorProto_extension(msg_proto, &n); + counts->ext_count += n; } static void count_types_in_file( const google_protobuf_FileDescriptorProto *file_proto, decl_counts *counts) { - const upb_array *arr; - size_t i; + const google_protobuf_DescriptorProto *const *msgs; + size_t i, n; - arr = google_protobuf_FileDescriptorProto_message_type(file_proto); - for (i = 0; i < upb_array_size(arr); i++) { - count_types_in_msg(upb_msgval_getptr(upb_array_get(arr, i)), counts); + msgs = google_protobuf_FileDescriptorProto_message_type(file_proto, &n); + for (i = 0; i < n; i++) { + count_types_in_msg(msgs[i], counts); } - arr = google_protobuf_FileDescriptorProto_enum_type(file_proto); - counts->enum_count += upb_array_size(arr); - arr = google_protobuf_FileDescriptorProto_extension(file_proto); - counts->ext_count += upb_array_size(arr); + google_protobuf_FileDescriptorProto_enum_type(file_proto, &n); + counts->enum_count += n; + + google_protobuf_FileDescriptorProto_extension(file_proto, &n); + counts->ext_count += n; } static bool resolve_fielddef(const symtab_addctx *ctx, const char *prefix, @@ -1424,11 +1411,13 @@ static bool resolve_fielddef(const symtab_addctx *ctx, const char *prefix, 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_alloc *alloc = ctx->alloc; - const upb_array *arr; + const google_protobuf_FileOptions *file_options_proto; + const google_protobuf_DescriptorProto *const *msgs; + const google_protobuf_EnumDescriptorProto *const *enums; + const google_protobuf_FieldDescriptorProto *const *exts; + const upb_stringview* strs; size_t i, n; - int j; decl_counts counts; upb_stringview syntax, package; @@ -1473,12 +1462,12 @@ static bool build_filedef( } /* Verify dependencies. */ - arr = google_protobuf_FileDescriptorProto_dependency(file_proto); - n = upb_array_size(arr); + strs = google_protobuf_FileDescriptorProto_dependency(file_proto, &n); file->deps = upb_malloc(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_stringview dep_name = strs[i]; upb_value v; if (!upb_strtable_lookup2(&ctx->symtab->files, dep_name.data, dep_name.size, &v)) { @@ -1491,30 +1480,23 @@ static bool build_filedef( } /* 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 = - upb_msgval_getptr(upb_array_get(arr, i)); - CHK(create_msgdef(ctx, file->package, msg_proto)); + msgs = google_protobuf_FileDescriptorProto_message_type(file_proto, &n); + for (i = 0; i < n; i++) { + CHK(create_msgdef(ctx, file->package, msgs[i])); } /* 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 = - upb_msgval_getptr(upb_array_get(arr, i)); - CHK(create_enumdef(ctx, file->package, enum_proto)); + enums = google_protobuf_FileDescriptorProto_enum_type(file_proto, &n); + for (i = 0; i < n; i++) { + CHK(create_enumdef(ctx, file->package, enums[i])); } /* Create extensions. */ - arr = google_protobuf_FileDescriptorProto_extension(file_proto); - n = upb_array_size(arr); + exts = google_protobuf_FileDescriptorProto_extension(file_proto, &n); file->exts = upb_malloc(alloc, sizeof(*file->exts) * n); CHK_OOM(file->exts); for (i = 0; i < n; i++) { - const google_protobuf_FieldDescriptorProto *field_proto = - upb_msgval_getptr(upb_array_get(arr, i)); - CHK(create_fielddef(ctx, file->package, NULL, field_proto)); + CHK(create_fielddef(ctx, file->package, NULL, exts[i])); } /* Now that all names are in the table, resolve references. */ @@ -1524,6 +1506,7 @@ static bool build_filedef( for (i = 0; i < file->msg_count; i++) { const upb_msgdef *m = &file->msgs[i]; + int j; for (j = 0; i < m->field_count; i++) { CHK(resolve_fielddef(ctx, m->full_name, (upb_fielddef*)&m->fields[j])); } -- cgit v1.2.3 From e2c2121f20bb8e90830f11d562e19d7244a14a5b Mon Sep 17 00:00:00 2001 From: Joshua Haberman Date: Thu, 13 Dec 2018 10:55:26 -0800 Subject: Use some hazzers in def.c. --- upb/def.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) (limited to 'upb/def.c') diff --git a/upb/def.c b/upb/def.c index ab8a8b7..e9acd43 100644 --- a/upb/def.c +++ b/upb/def.c @@ -1133,7 +1133,7 @@ static bool create_fielddef( upb_alloc *alloc = ctx->alloc; upb_fielddef *f; const google_protobuf_FieldOptions *options; - upb_stringview defaultval, name; + upb_stringview name; upb_value packed_v = pack_def(f, UPB_DEFTYPE_FIELD); upb_value v = upb_value_constptr(f); const char *full_name; @@ -1220,17 +1220,20 @@ static bool create_fielddef( f->oneof = NULL; } - defaultval = google_protobuf_FieldDescriptorProto_default_value(field_proto); - - if (defaultval.data) { + if (google_protobuf_FieldDescriptorProto_has_default_value(field_proto)) { + upb_stringview defaultval = + google_protobuf_FieldDescriptorProto_default_value(field_proto); CHK(parse_default(ctx, defaultval.data, defaultval.size, f)); } - options = google_protobuf_FieldDescriptorProto_options(field_proto); - if (options) { + if (google_protobuf_FieldDescriptorProto_has_options(field_proto)) { + options = google_protobuf_FieldDescriptorProto_options(field_proto); f->lazy_ = google_protobuf_FieldOptions_lazy(options); f->packed_ = google_protobuf_FieldOptions_packed(options); + } else { + f->lazy_ = false; + f->packed_ = false; } return true; -- cgit v1.2.3 From 380558922b661499f4eb43b0463b5a73e5fe87b7 Mon Sep 17 00:00:00 2001 From: Joshua Haberman Date: Sat, 15 Dec 2018 16:17:48 -0800 Subject: test_encoder passes! Other tests still need to be fixed. --- google/protobuf/descriptor.upb.h | 172 +++++++++++------------ tests/pb/test_encoder.cc | 7 +- upb/def.c | 289 ++++++++++++++++++++------------------- upb/generated_util.h | 6 +- upb/msg.h | 3 + upb/upb.c | 1 + upb/upb.h | 1 + upbc/generator.cc | 2 +- upbc/message_layout.cc | 4 +- 9 files changed, 251 insertions(+), 234 deletions(-) (limited to 'upb/def.c') diff --git a/google/protobuf/descriptor.upb.h b/google/protobuf/descriptor.upb.h index 8ed3fbe..421e41e 100644 --- a/google/protobuf/descriptor.upb.h +++ b/google/protobuf/descriptor.upb.h @@ -160,22 +160,22 @@ UPB_INLINE char *google_protobuf_FileDescriptorProto_serialize(const google_prot return upb_encode(msg, &google_protobuf_FileDescriptorProto_msginit, arena, len); } -UPB_INLINE bool google_protobuf_FileDescriptorProto_has_name(const google_protobuf_FileDescriptorProto *msg) { return _upb_has_field(msg, 0); } +UPB_INLINE bool google_protobuf_FileDescriptorProto_has_name(const google_protobuf_FileDescriptorProto *msg) { return _upb_has_field(msg, 1); } UPB_INLINE upb_stringview google_protobuf_FileDescriptorProto_name(const google_protobuf_FileDescriptorProto *msg) { return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(4, 8)); } -UPB_INLINE bool google_protobuf_FileDescriptorProto_has_package(const google_protobuf_FileDescriptorProto *msg) { return _upb_has_field(msg, 1); } +UPB_INLINE bool google_protobuf_FileDescriptorProto_has_package(const google_protobuf_FileDescriptorProto *msg) { return _upb_has_field(msg, 2); } UPB_INLINE upb_stringview google_protobuf_FileDescriptorProto_package(const google_protobuf_FileDescriptorProto *msg) { return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(12, 24)); } UPB_INLINE upb_stringview const* google_protobuf_FileDescriptorProto_dependency(const google_protobuf_FileDescriptorProto *msg, size_t *len) { return (upb_stringview const*)_upb_array_accessor(msg, UPB_SIZE(36, 72), len); } UPB_INLINE const google_protobuf_DescriptorProto* const* google_protobuf_FileDescriptorProto_message_type(const google_protobuf_FileDescriptorProto *msg, size_t *len) { return (const google_protobuf_DescriptorProto* const*)_upb_array_accessor(msg, UPB_SIZE(40, 80), len); } UPB_INLINE const google_protobuf_EnumDescriptorProto* const* google_protobuf_FileDescriptorProto_enum_type(const google_protobuf_FileDescriptorProto *msg, size_t *len) { return (const google_protobuf_EnumDescriptorProto* const*)_upb_array_accessor(msg, UPB_SIZE(44, 88), len); } UPB_INLINE const google_protobuf_ServiceDescriptorProto* const* google_protobuf_FileDescriptorProto_service(const google_protobuf_FileDescriptorProto *msg, size_t *len) { return (const google_protobuf_ServiceDescriptorProto* const*)_upb_array_accessor(msg, UPB_SIZE(48, 96), len); } UPB_INLINE const google_protobuf_FieldDescriptorProto* const* google_protobuf_FileDescriptorProto_extension(const google_protobuf_FileDescriptorProto *msg, size_t *len) { return (const google_protobuf_FieldDescriptorProto* const*)_upb_array_accessor(msg, UPB_SIZE(52, 104), len); } -UPB_INLINE bool google_protobuf_FileDescriptorProto_has_options(const google_protobuf_FileDescriptorProto *msg) { return _upb_has_field(msg, 3); } +UPB_INLINE bool google_protobuf_FileDescriptorProto_has_options(const google_protobuf_FileDescriptorProto *msg) { return _upb_has_field(msg, 4); } UPB_INLINE const google_protobuf_FileOptions* google_protobuf_FileDescriptorProto_options(const google_protobuf_FileDescriptorProto *msg) { return UPB_FIELD_AT(msg, const google_protobuf_FileOptions*, UPB_SIZE(28, 56)); } -UPB_INLINE bool google_protobuf_FileDescriptorProto_has_source_code_info(const google_protobuf_FileDescriptorProto *msg) { return _upb_has_field(msg, 4); } +UPB_INLINE bool google_protobuf_FileDescriptorProto_has_source_code_info(const google_protobuf_FileDescriptorProto *msg) { return _upb_has_field(msg, 5); } UPB_INLINE const google_protobuf_SourceCodeInfo* google_protobuf_FileDescriptorProto_source_code_info(const google_protobuf_FileDescriptorProto *msg) { return UPB_FIELD_AT(msg, const google_protobuf_SourceCodeInfo*, UPB_SIZE(32, 64)); } UPB_INLINE int32_t const* google_protobuf_FileDescriptorProto_public_dependency(const google_protobuf_FileDescriptorProto *msg, size_t *len) { return (int32_t const*)_upb_array_accessor(msg, UPB_SIZE(56, 112), len); } UPB_INLINE int32_t const* google_protobuf_FileDescriptorProto_weak_dependency(const google_protobuf_FileDescriptorProto *msg, size_t *len) { return (int32_t const*)_upb_array_accessor(msg, UPB_SIZE(60, 120), len); } -UPB_INLINE bool google_protobuf_FileDescriptorProto_has_syntax(const google_protobuf_FileDescriptorProto *msg) { return _upb_has_field(msg, 2); } +UPB_INLINE bool google_protobuf_FileDescriptorProto_has_syntax(const google_protobuf_FileDescriptorProto *msg) { return _upb_has_field(msg, 3); } UPB_INLINE upb_stringview google_protobuf_FileDescriptorProto_syntax(const google_protobuf_FileDescriptorProto *msg) { return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(20, 40)); } UPB_INLINE void google_protobuf_FileDescriptorProto_set_name(google_protobuf_FileDescriptorProto *msg, upb_stringview value) { UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(4, 8)) = value; } @@ -213,14 +213,14 @@ UPB_INLINE char *google_protobuf_DescriptorProto_serialize(const google_protobuf return upb_encode(msg, &google_protobuf_DescriptorProto_msginit, arena, len); } -UPB_INLINE bool google_protobuf_DescriptorProto_has_name(const google_protobuf_DescriptorProto *msg) { return _upb_has_field(msg, 0); } +UPB_INLINE bool google_protobuf_DescriptorProto_has_name(const google_protobuf_DescriptorProto *msg) { return _upb_has_field(msg, 1); } UPB_INLINE upb_stringview google_protobuf_DescriptorProto_name(const google_protobuf_DescriptorProto *msg) { return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(4, 8)); } UPB_INLINE const google_protobuf_FieldDescriptorProto* const* google_protobuf_DescriptorProto_field(const google_protobuf_DescriptorProto *msg, size_t *len) { return (const google_protobuf_FieldDescriptorProto* const*)_upb_array_accessor(msg, UPB_SIZE(16, 32), len); } UPB_INLINE const google_protobuf_DescriptorProto* const* google_protobuf_DescriptorProto_nested_type(const google_protobuf_DescriptorProto *msg, size_t *len) { return (const google_protobuf_DescriptorProto* const*)_upb_array_accessor(msg, UPB_SIZE(20, 40), len); } UPB_INLINE const google_protobuf_EnumDescriptorProto* const* google_protobuf_DescriptorProto_enum_type(const google_protobuf_DescriptorProto *msg, size_t *len) { return (const google_protobuf_EnumDescriptorProto* const*)_upb_array_accessor(msg, UPB_SIZE(24, 48), len); } UPB_INLINE const google_protobuf_DescriptorProto_ExtensionRange* const* google_protobuf_DescriptorProto_extension_range(const google_protobuf_DescriptorProto *msg, size_t *len) { return (const google_protobuf_DescriptorProto_ExtensionRange* const*)_upb_array_accessor(msg, UPB_SIZE(28, 56), len); } UPB_INLINE const google_protobuf_FieldDescriptorProto* const* google_protobuf_DescriptorProto_extension(const google_protobuf_DescriptorProto *msg, size_t *len) { return (const google_protobuf_FieldDescriptorProto* const*)_upb_array_accessor(msg, UPB_SIZE(32, 64), len); } -UPB_INLINE bool google_protobuf_DescriptorProto_has_options(const google_protobuf_DescriptorProto *msg) { return _upb_has_field(msg, 1); } +UPB_INLINE bool google_protobuf_DescriptorProto_has_options(const google_protobuf_DescriptorProto *msg) { return _upb_has_field(msg, 2); } UPB_INLINE const google_protobuf_MessageOptions* google_protobuf_DescriptorProto_options(const google_protobuf_DescriptorProto *msg) { return UPB_FIELD_AT(msg, const google_protobuf_MessageOptions*, UPB_SIZE(12, 24)); } UPB_INLINE const google_protobuf_OneofDescriptorProto* const* google_protobuf_DescriptorProto_oneof_decl(const google_protobuf_DescriptorProto *msg, size_t *len) { return (const google_protobuf_OneofDescriptorProto* const*)_upb_array_accessor(msg, UPB_SIZE(36, 72), len); } UPB_INLINE const google_protobuf_DescriptorProto_ReservedRange* const* google_protobuf_DescriptorProto_reserved_range(const google_protobuf_DescriptorProto *msg, size_t *len) { return (const google_protobuf_DescriptorProto_ReservedRange* const*)_upb_array_accessor(msg, UPB_SIZE(40, 80), len); } @@ -260,11 +260,11 @@ UPB_INLINE char *google_protobuf_DescriptorProto_ExtensionRange_serialize(const return upb_encode(msg, &google_protobuf_DescriptorProto_ExtensionRange_msginit, arena, len); } -UPB_INLINE bool google_protobuf_DescriptorProto_ExtensionRange_has_start(const google_protobuf_DescriptorProto_ExtensionRange *msg) { return _upb_has_field(msg, 0); } +UPB_INLINE bool google_protobuf_DescriptorProto_ExtensionRange_has_start(const google_protobuf_DescriptorProto_ExtensionRange *msg) { return _upb_has_field(msg, 1); } UPB_INLINE int32_t google_protobuf_DescriptorProto_ExtensionRange_start(const google_protobuf_DescriptorProto_ExtensionRange *msg) { return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(4, 4)); } -UPB_INLINE bool google_protobuf_DescriptorProto_ExtensionRange_has_end(const google_protobuf_DescriptorProto_ExtensionRange *msg) { return _upb_has_field(msg, 1); } +UPB_INLINE bool google_protobuf_DescriptorProto_ExtensionRange_has_end(const google_protobuf_DescriptorProto_ExtensionRange *msg) { return _upb_has_field(msg, 2); } UPB_INLINE int32_t google_protobuf_DescriptorProto_ExtensionRange_end(const google_protobuf_DescriptorProto_ExtensionRange *msg) { return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(8, 8)); } -UPB_INLINE bool google_protobuf_DescriptorProto_ExtensionRange_has_options(const google_protobuf_DescriptorProto_ExtensionRange *msg) { return _upb_has_field(msg, 2); } +UPB_INLINE bool google_protobuf_DescriptorProto_ExtensionRange_has_options(const google_protobuf_DescriptorProto_ExtensionRange *msg) { return _upb_has_field(msg, 3); } UPB_INLINE const google_protobuf_ExtensionRangeOptions* google_protobuf_DescriptorProto_ExtensionRange_options(const google_protobuf_DescriptorProto_ExtensionRange *msg) { return UPB_FIELD_AT(msg, const google_protobuf_ExtensionRangeOptions*, UPB_SIZE(12, 16)); } UPB_INLINE void google_protobuf_DescriptorProto_ExtensionRange_set_start(google_protobuf_DescriptorProto_ExtensionRange *msg, int32_t value) { UPB_FIELD_AT(msg, int32_t, UPB_SIZE(4, 4)) = value; } @@ -286,9 +286,9 @@ UPB_INLINE char *google_protobuf_DescriptorProto_ReservedRange_serialize(const g return upb_encode(msg, &google_protobuf_DescriptorProto_ReservedRange_msginit, arena, len); } -UPB_INLINE bool google_protobuf_DescriptorProto_ReservedRange_has_start(const google_protobuf_DescriptorProto_ReservedRange *msg) { return _upb_has_field(msg, 0); } +UPB_INLINE bool google_protobuf_DescriptorProto_ReservedRange_has_start(const google_protobuf_DescriptorProto_ReservedRange *msg) { return _upb_has_field(msg, 1); } UPB_INLINE int32_t google_protobuf_DescriptorProto_ReservedRange_start(const google_protobuf_DescriptorProto_ReservedRange *msg) { return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(4, 4)); } -UPB_INLINE bool google_protobuf_DescriptorProto_ReservedRange_has_end(const google_protobuf_DescriptorProto_ReservedRange *msg) { return _upb_has_field(msg, 1); } +UPB_INLINE bool google_protobuf_DescriptorProto_ReservedRange_has_end(const google_protobuf_DescriptorProto_ReservedRange *msg) { return _upb_has_field(msg, 2); } UPB_INLINE int32_t google_protobuf_DescriptorProto_ReservedRange_end(const google_protobuf_DescriptorProto_ReservedRange *msg) { return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(8, 8)); } UPB_INLINE void google_protobuf_DescriptorProto_ReservedRange_set_start(google_protobuf_DescriptorProto_ReservedRange *msg, int32_t value) { UPB_FIELD_AT(msg, int32_t, UPB_SIZE(4, 4)) = value; } @@ -329,25 +329,25 @@ UPB_INLINE char *google_protobuf_FieldDescriptorProto_serialize(const google_pro return upb_encode(msg, &google_protobuf_FieldDescriptorProto_msginit, arena, len); } -UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_name(const google_protobuf_FieldDescriptorProto *msg) { return _upb_has_field(msg, 4); } +UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_name(const google_protobuf_FieldDescriptorProto *msg) { return _upb_has_field(msg, 5); } UPB_INLINE upb_stringview google_protobuf_FieldDescriptorProto_name(const google_protobuf_FieldDescriptorProto *msg) { return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(32, 32)); } -UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_extendee(const google_protobuf_FieldDescriptorProto *msg) { return _upb_has_field(msg, 5); } +UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_extendee(const google_protobuf_FieldDescriptorProto *msg) { return _upb_has_field(msg, 6); } UPB_INLINE upb_stringview google_protobuf_FieldDescriptorProto_extendee(const google_protobuf_FieldDescriptorProto *msg) { return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(40, 48)); } -UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_number(const google_protobuf_FieldDescriptorProto *msg) { return _upb_has_field(msg, 2); } +UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_number(const google_protobuf_FieldDescriptorProto *msg) { return _upb_has_field(msg, 3); } UPB_INLINE int32_t google_protobuf_FieldDescriptorProto_number(const google_protobuf_FieldDescriptorProto *msg) { return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(24, 24)); } -UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_label(const google_protobuf_FieldDescriptorProto *msg) { return _upb_has_field(msg, 0); } +UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_label(const google_protobuf_FieldDescriptorProto *msg) { return _upb_has_field(msg, 1); } UPB_INLINE google_protobuf_FieldDescriptorProto_Label google_protobuf_FieldDescriptorProto_label(const google_protobuf_FieldDescriptorProto *msg) { return UPB_FIELD_AT(msg, google_protobuf_FieldDescriptorProto_Label, UPB_SIZE(8, 8)); } -UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_type(const google_protobuf_FieldDescriptorProto *msg) { return _upb_has_field(msg, 1); } +UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_type(const google_protobuf_FieldDescriptorProto *msg) { return _upb_has_field(msg, 2); } UPB_INLINE google_protobuf_FieldDescriptorProto_Type google_protobuf_FieldDescriptorProto_type(const google_protobuf_FieldDescriptorProto *msg) { return UPB_FIELD_AT(msg, google_protobuf_FieldDescriptorProto_Type, UPB_SIZE(16, 16)); } -UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_type_name(const google_protobuf_FieldDescriptorProto *msg) { return _upb_has_field(msg, 6); } +UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_type_name(const google_protobuf_FieldDescriptorProto *msg) { return _upb_has_field(msg, 7); } UPB_INLINE upb_stringview google_protobuf_FieldDescriptorProto_type_name(const google_protobuf_FieldDescriptorProto *msg) { return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(48, 64)); } -UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_default_value(const google_protobuf_FieldDescriptorProto *msg) { return _upb_has_field(msg, 7); } +UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_default_value(const google_protobuf_FieldDescriptorProto *msg) { return _upb_has_field(msg, 8); } UPB_INLINE upb_stringview google_protobuf_FieldDescriptorProto_default_value(const google_protobuf_FieldDescriptorProto *msg) { return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(56, 80)); } -UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_options(const google_protobuf_FieldDescriptorProto *msg) { return _upb_has_field(msg, 9); } +UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_options(const google_protobuf_FieldDescriptorProto *msg) { return _upb_has_field(msg, 10); } UPB_INLINE const google_protobuf_FieldOptions* google_protobuf_FieldDescriptorProto_options(const google_protobuf_FieldDescriptorProto *msg) { return UPB_FIELD_AT(msg, const google_protobuf_FieldOptions*, UPB_SIZE(72, 112)); } -UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_oneof_index(const google_protobuf_FieldDescriptorProto *msg) { return _upb_has_field(msg, 3); } +UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_oneof_index(const google_protobuf_FieldDescriptorProto *msg) { return _upb_has_field(msg, 4); } UPB_INLINE int32_t google_protobuf_FieldDescriptorProto_oneof_index(const google_protobuf_FieldDescriptorProto *msg) { return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(28, 28)); } -UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_json_name(const google_protobuf_FieldDescriptorProto *msg) { return _upb_has_field(msg, 8); } +UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_json_name(const google_protobuf_FieldDescriptorProto *msg) { return _upb_has_field(msg, 9); } UPB_INLINE upb_stringview google_protobuf_FieldDescriptorProto_json_name(const google_protobuf_FieldDescriptorProto *msg) { return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(64, 96)); } UPB_INLINE void google_protobuf_FieldDescriptorProto_set_name(google_protobuf_FieldDescriptorProto *msg, upb_stringview value) { UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(32, 32)) = value; } @@ -376,9 +376,9 @@ UPB_INLINE char *google_protobuf_OneofDescriptorProto_serialize(const google_pro return upb_encode(msg, &google_protobuf_OneofDescriptorProto_msginit, arena, len); } -UPB_INLINE bool google_protobuf_OneofDescriptorProto_has_name(const google_protobuf_OneofDescriptorProto *msg) { return _upb_has_field(msg, 0); } +UPB_INLINE bool google_protobuf_OneofDescriptorProto_has_name(const google_protobuf_OneofDescriptorProto *msg) { return _upb_has_field(msg, 1); } UPB_INLINE upb_stringview google_protobuf_OneofDescriptorProto_name(const google_protobuf_OneofDescriptorProto *msg) { return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(4, 8)); } -UPB_INLINE bool google_protobuf_OneofDescriptorProto_has_options(const google_protobuf_OneofDescriptorProto *msg) { return _upb_has_field(msg, 1); } +UPB_INLINE bool google_protobuf_OneofDescriptorProto_has_options(const google_protobuf_OneofDescriptorProto *msg) { return _upb_has_field(msg, 2); } UPB_INLINE const google_protobuf_OneofOptions* google_protobuf_OneofDescriptorProto_options(const google_protobuf_OneofDescriptorProto *msg) { return UPB_FIELD_AT(msg, const google_protobuf_OneofOptions*, UPB_SIZE(12, 24)); } UPB_INLINE void google_protobuf_OneofDescriptorProto_set_name(google_protobuf_OneofDescriptorProto *msg, upb_stringview value) { UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(4, 8)) = value; } @@ -399,10 +399,10 @@ UPB_INLINE char *google_protobuf_EnumDescriptorProto_serialize(const google_prot return upb_encode(msg, &google_protobuf_EnumDescriptorProto_msginit, arena, len); } -UPB_INLINE bool google_protobuf_EnumDescriptorProto_has_name(const google_protobuf_EnumDescriptorProto *msg) { return _upb_has_field(msg, 0); } +UPB_INLINE bool google_protobuf_EnumDescriptorProto_has_name(const google_protobuf_EnumDescriptorProto *msg) { return _upb_has_field(msg, 1); } UPB_INLINE upb_stringview google_protobuf_EnumDescriptorProto_name(const google_protobuf_EnumDescriptorProto *msg) { return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(4, 8)); } UPB_INLINE const google_protobuf_EnumValueDescriptorProto* const* google_protobuf_EnumDescriptorProto_value(const google_protobuf_EnumDescriptorProto *msg, size_t *len) { return (const google_protobuf_EnumValueDescriptorProto* const*)_upb_array_accessor(msg, UPB_SIZE(16, 32), len); } -UPB_INLINE bool google_protobuf_EnumDescriptorProto_has_options(const google_protobuf_EnumDescriptorProto *msg) { return _upb_has_field(msg, 1); } +UPB_INLINE bool google_protobuf_EnumDescriptorProto_has_options(const google_protobuf_EnumDescriptorProto *msg) { return _upb_has_field(msg, 2); } UPB_INLINE const google_protobuf_EnumOptions* google_protobuf_EnumDescriptorProto_options(const google_protobuf_EnumDescriptorProto *msg) { return UPB_FIELD_AT(msg, const google_protobuf_EnumOptions*, UPB_SIZE(12, 24)); } UPB_INLINE const google_protobuf_EnumDescriptorProto_EnumReservedRange* const* google_protobuf_EnumDescriptorProto_reserved_range(const google_protobuf_EnumDescriptorProto *msg, size_t *len) { return (const google_protobuf_EnumDescriptorProto_EnumReservedRange* const*)_upb_array_accessor(msg, UPB_SIZE(20, 40), len); } UPB_INLINE upb_stringview const* google_protobuf_EnumDescriptorProto_reserved_name(const google_protobuf_EnumDescriptorProto *msg, size_t *len) { return (upb_stringview const*)_upb_array_accessor(msg, UPB_SIZE(24, 48), len); } @@ -431,9 +431,9 @@ UPB_INLINE char *google_protobuf_EnumDescriptorProto_EnumReservedRange_serialize return upb_encode(msg, &google_protobuf_EnumDescriptorProto_EnumReservedRange_msginit, arena, len); } -UPB_INLINE bool google_protobuf_EnumDescriptorProto_EnumReservedRange_has_start(const google_protobuf_EnumDescriptorProto_EnumReservedRange *msg) { return _upb_has_field(msg, 0); } +UPB_INLINE bool google_protobuf_EnumDescriptorProto_EnumReservedRange_has_start(const google_protobuf_EnumDescriptorProto_EnumReservedRange *msg) { return _upb_has_field(msg, 1); } UPB_INLINE int32_t google_protobuf_EnumDescriptorProto_EnumReservedRange_start(const google_protobuf_EnumDescriptorProto_EnumReservedRange *msg) { return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(4, 4)); } -UPB_INLINE bool google_protobuf_EnumDescriptorProto_EnumReservedRange_has_end(const google_protobuf_EnumDescriptorProto_EnumReservedRange *msg) { return _upb_has_field(msg, 1); } +UPB_INLINE bool google_protobuf_EnumDescriptorProto_EnumReservedRange_has_end(const google_protobuf_EnumDescriptorProto_EnumReservedRange *msg) { return _upb_has_field(msg, 2); } UPB_INLINE int32_t google_protobuf_EnumDescriptorProto_EnumReservedRange_end(const google_protobuf_EnumDescriptorProto_EnumReservedRange *msg) { return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(8, 8)); } UPB_INLINE void google_protobuf_EnumDescriptorProto_EnumReservedRange_set_start(google_protobuf_EnumDescriptorProto_EnumReservedRange *msg, int32_t value) { UPB_FIELD_AT(msg, int32_t, UPB_SIZE(4, 4)) = value; } @@ -454,11 +454,11 @@ UPB_INLINE char *google_protobuf_EnumValueDescriptorProto_serialize(const google return upb_encode(msg, &google_protobuf_EnumValueDescriptorProto_msginit, arena, len); } -UPB_INLINE bool google_protobuf_EnumValueDescriptorProto_has_name(const google_protobuf_EnumValueDescriptorProto *msg) { return _upb_has_field(msg, 1); } +UPB_INLINE bool google_protobuf_EnumValueDescriptorProto_has_name(const google_protobuf_EnumValueDescriptorProto *msg) { return _upb_has_field(msg, 2); } UPB_INLINE upb_stringview google_protobuf_EnumValueDescriptorProto_name(const google_protobuf_EnumValueDescriptorProto *msg) { return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(8, 8)); } -UPB_INLINE bool google_protobuf_EnumValueDescriptorProto_has_number(const google_protobuf_EnumValueDescriptorProto *msg) { return _upb_has_field(msg, 0); } +UPB_INLINE bool google_protobuf_EnumValueDescriptorProto_has_number(const google_protobuf_EnumValueDescriptorProto *msg) { return _upb_has_field(msg, 1); } UPB_INLINE int32_t google_protobuf_EnumValueDescriptorProto_number(const google_protobuf_EnumValueDescriptorProto *msg) { return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(4, 4)); } -UPB_INLINE bool google_protobuf_EnumValueDescriptorProto_has_options(const google_protobuf_EnumValueDescriptorProto *msg) { return _upb_has_field(msg, 2); } +UPB_INLINE bool google_protobuf_EnumValueDescriptorProto_has_options(const google_protobuf_EnumValueDescriptorProto *msg) { return _upb_has_field(msg, 3); } UPB_INLINE const google_protobuf_EnumValueOptions* google_protobuf_EnumValueDescriptorProto_options(const google_protobuf_EnumValueDescriptorProto *msg) { return UPB_FIELD_AT(msg, const google_protobuf_EnumValueOptions*, UPB_SIZE(16, 24)); } UPB_INLINE void google_protobuf_EnumValueDescriptorProto_set_name(google_protobuf_EnumValueDescriptorProto *msg, upb_stringview value) { UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(8, 8)) = value; } @@ -480,10 +480,10 @@ UPB_INLINE char *google_protobuf_ServiceDescriptorProto_serialize(const google_p return upb_encode(msg, &google_protobuf_ServiceDescriptorProto_msginit, arena, len); } -UPB_INLINE bool google_protobuf_ServiceDescriptorProto_has_name(const google_protobuf_ServiceDescriptorProto *msg) { return _upb_has_field(msg, 0); } +UPB_INLINE bool google_protobuf_ServiceDescriptorProto_has_name(const google_protobuf_ServiceDescriptorProto *msg) { return _upb_has_field(msg, 1); } UPB_INLINE upb_stringview google_protobuf_ServiceDescriptorProto_name(const google_protobuf_ServiceDescriptorProto *msg) { return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(4, 8)); } UPB_INLINE const google_protobuf_MethodDescriptorProto* const* google_protobuf_ServiceDescriptorProto_method(const google_protobuf_ServiceDescriptorProto *msg, size_t *len) { return (const google_protobuf_MethodDescriptorProto* const*)_upb_array_accessor(msg, UPB_SIZE(16, 32), len); } -UPB_INLINE bool google_protobuf_ServiceDescriptorProto_has_options(const google_protobuf_ServiceDescriptorProto *msg) { return _upb_has_field(msg, 1); } +UPB_INLINE bool google_protobuf_ServiceDescriptorProto_has_options(const google_protobuf_ServiceDescriptorProto *msg) { return _upb_has_field(msg, 2); } UPB_INLINE const google_protobuf_ServiceOptions* google_protobuf_ServiceDescriptorProto_options(const google_protobuf_ServiceDescriptorProto *msg) { return UPB_FIELD_AT(msg, const google_protobuf_ServiceOptions*, UPB_SIZE(12, 24)); } UPB_INLINE void google_protobuf_ServiceDescriptorProto_set_name(google_protobuf_ServiceDescriptorProto *msg, upb_stringview value) { UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(4, 8)) = value; } @@ -506,17 +506,17 @@ UPB_INLINE char *google_protobuf_MethodDescriptorProto_serialize(const google_pr return upb_encode(msg, &google_protobuf_MethodDescriptorProto_msginit, arena, len); } -UPB_INLINE bool google_protobuf_MethodDescriptorProto_has_name(const google_protobuf_MethodDescriptorProto *msg) { return _upb_has_field(msg, 2); } +UPB_INLINE bool google_protobuf_MethodDescriptorProto_has_name(const google_protobuf_MethodDescriptorProto *msg) { return _upb_has_field(msg, 3); } UPB_INLINE upb_stringview google_protobuf_MethodDescriptorProto_name(const google_protobuf_MethodDescriptorProto *msg) { return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(4, 8)); } -UPB_INLINE bool google_protobuf_MethodDescriptorProto_has_input_type(const google_protobuf_MethodDescriptorProto *msg) { return _upb_has_field(msg, 3); } +UPB_INLINE bool google_protobuf_MethodDescriptorProto_has_input_type(const google_protobuf_MethodDescriptorProto *msg) { return _upb_has_field(msg, 4); } UPB_INLINE upb_stringview google_protobuf_MethodDescriptorProto_input_type(const google_protobuf_MethodDescriptorProto *msg) { return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(12, 24)); } -UPB_INLINE bool google_protobuf_MethodDescriptorProto_has_output_type(const google_protobuf_MethodDescriptorProto *msg) { return _upb_has_field(msg, 4); } +UPB_INLINE bool google_protobuf_MethodDescriptorProto_has_output_type(const google_protobuf_MethodDescriptorProto *msg) { return _upb_has_field(msg, 5); } UPB_INLINE upb_stringview google_protobuf_MethodDescriptorProto_output_type(const google_protobuf_MethodDescriptorProto *msg) { return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(20, 40)); } -UPB_INLINE bool google_protobuf_MethodDescriptorProto_has_options(const google_protobuf_MethodDescriptorProto *msg) { return _upb_has_field(msg, 5); } +UPB_INLINE bool google_protobuf_MethodDescriptorProto_has_options(const google_protobuf_MethodDescriptorProto *msg) { return _upb_has_field(msg, 6); } UPB_INLINE const google_protobuf_MethodOptions* google_protobuf_MethodDescriptorProto_options(const google_protobuf_MethodDescriptorProto *msg) { return UPB_FIELD_AT(msg, const google_protobuf_MethodOptions*, UPB_SIZE(28, 56)); } -UPB_INLINE bool google_protobuf_MethodDescriptorProto_has_client_streaming(const google_protobuf_MethodDescriptorProto *msg) { return _upb_has_field(msg, 0); } +UPB_INLINE bool google_protobuf_MethodDescriptorProto_has_client_streaming(const google_protobuf_MethodDescriptorProto *msg) { return _upb_has_field(msg, 1); } UPB_INLINE bool google_protobuf_MethodDescriptorProto_client_streaming(const google_protobuf_MethodDescriptorProto *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(1, 1)); } -UPB_INLINE bool google_protobuf_MethodDescriptorProto_has_server_streaming(const google_protobuf_MethodDescriptorProto *msg) { return _upb_has_field(msg, 1); } +UPB_INLINE bool google_protobuf_MethodDescriptorProto_has_server_streaming(const google_protobuf_MethodDescriptorProto *msg) { return _upb_has_field(msg, 2); } UPB_INLINE bool google_protobuf_MethodDescriptorProto_server_streaming(const google_protobuf_MethodDescriptorProto *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(2, 2)); } UPB_INLINE void google_protobuf_MethodDescriptorProto_set_name(google_protobuf_MethodDescriptorProto *msg, upb_stringview value) { UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(4, 8)) = value; } @@ -541,41 +541,41 @@ UPB_INLINE char *google_protobuf_FileOptions_serialize(const google_protobuf_Fil return upb_encode(msg, &google_protobuf_FileOptions_msginit, arena, len); } -UPB_INLINE bool google_protobuf_FileOptions_has_java_package(const google_protobuf_FileOptions *msg) { return _upb_has_field(msg, 10); } +UPB_INLINE bool google_protobuf_FileOptions_has_java_package(const google_protobuf_FileOptions *msg) { return _upb_has_field(msg, 11); } UPB_INLINE upb_stringview google_protobuf_FileOptions_java_package(const google_protobuf_FileOptions *msg) { return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(28, 32)); } -UPB_INLINE bool google_protobuf_FileOptions_has_java_outer_classname(const google_protobuf_FileOptions *msg) { return _upb_has_field(msg, 11); } +UPB_INLINE bool google_protobuf_FileOptions_has_java_outer_classname(const google_protobuf_FileOptions *msg) { return _upb_has_field(msg, 12); } UPB_INLINE upb_stringview google_protobuf_FileOptions_java_outer_classname(const google_protobuf_FileOptions *msg) { return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(36, 48)); } -UPB_INLINE bool google_protobuf_FileOptions_has_optimize_for(const google_protobuf_FileOptions *msg) { return _upb_has_field(msg, 0); } +UPB_INLINE bool google_protobuf_FileOptions_has_optimize_for(const google_protobuf_FileOptions *msg) { return _upb_has_field(msg, 1); } UPB_INLINE google_protobuf_FileOptions_OptimizeMode google_protobuf_FileOptions_optimize_for(const google_protobuf_FileOptions *msg) { return UPB_FIELD_AT(msg, google_protobuf_FileOptions_OptimizeMode, UPB_SIZE(8, 8)); } -UPB_INLINE bool google_protobuf_FileOptions_has_java_multiple_files(const google_protobuf_FileOptions *msg) { return _upb_has_field(msg, 1); } +UPB_INLINE bool google_protobuf_FileOptions_has_java_multiple_files(const google_protobuf_FileOptions *msg) { return _upb_has_field(msg, 2); } UPB_INLINE bool google_protobuf_FileOptions_java_multiple_files(const google_protobuf_FileOptions *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(16, 16)); } -UPB_INLINE bool google_protobuf_FileOptions_has_go_package(const google_protobuf_FileOptions *msg) { return _upb_has_field(msg, 12); } +UPB_INLINE bool google_protobuf_FileOptions_has_go_package(const google_protobuf_FileOptions *msg) { return _upb_has_field(msg, 13); } UPB_INLINE upb_stringview google_protobuf_FileOptions_go_package(const google_protobuf_FileOptions *msg) { return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(44, 64)); } -UPB_INLINE bool google_protobuf_FileOptions_has_cc_generic_services(const google_protobuf_FileOptions *msg) { return _upb_has_field(msg, 2); } +UPB_INLINE bool google_protobuf_FileOptions_has_cc_generic_services(const google_protobuf_FileOptions *msg) { return _upb_has_field(msg, 3); } UPB_INLINE bool google_protobuf_FileOptions_cc_generic_services(const google_protobuf_FileOptions *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(17, 17)); } -UPB_INLINE bool google_protobuf_FileOptions_has_java_generic_services(const google_protobuf_FileOptions *msg) { return _upb_has_field(msg, 3); } +UPB_INLINE bool google_protobuf_FileOptions_has_java_generic_services(const google_protobuf_FileOptions *msg) { return _upb_has_field(msg, 4); } UPB_INLINE bool google_protobuf_FileOptions_java_generic_services(const google_protobuf_FileOptions *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(18, 18)); } -UPB_INLINE bool google_protobuf_FileOptions_has_py_generic_services(const google_protobuf_FileOptions *msg) { return _upb_has_field(msg, 4); } +UPB_INLINE bool google_protobuf_FileOptions_has_py_generic_services(const google_protobuf_FileOptions *msg) { return _upb_has_field(msg, 5); } UPB_INLINE bool google_protobuf_FileOptions_py_generic_services(const google_protobuf_FileOptions *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(19, 19)); } -UPB_INLINE bool google_protobuf_FileOptions_has_java_generate_equals_and_hash(const google_protobuf_FileOptions *msg) { return _upb_has_field(msg, 5); } +UPB_INLINE bool google_protobuf_FileOptions_has_java_generate_equals_and_hash(const google_protobuf_FileOptions *msg) { return _upb_has_field(msg, 6); } UPB_INLINE bool google_protobuf_FileOptions_java_generate_equals_and_hash(const google_protobuf_FileOptions *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(20, 20)); } -UPB_INLINE bool google_protobuf_FileOptions_has_deprecated(const google_protobuf_FileOptions *msg) { return _upb_has_field(msg, 6); } +UPB_INLINE bool google_protobuf_FileOptions_has_deprecated(const google_protobuf_FileOptions *msg) { return _upb_has_field(msg, 7); } UPB_INLINE bool google_protobuf_FileOptions_deprecated(const google_protobuf_FileOptions *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(21, 21)); } -UPB_INLINE bool google_protobuf_FileOptions_has_java_string_check_utf8(const google_protobuf_FileOptions *msg) { return _upb_has_field(msg, 7); } +UPB_INLINE bool google_protobuf_FileOptions_has_java_string_check_utf8(const google_protobuf_FileOptions *msg) { return _upb_has_field(msg, 8); } UPB_INLINE bool google_protobuf_FileOptions_java_string_check_utf8(const google_protobuf_FileOptions *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(22, 22)); } -UPB_INLINE bool google_protobuf_FileOptions_has_cc_enable_arenas(const google_protobuf_FileOptions *msg) { return _upb_has_field(msg, 8); } +UPB_INLINE bool google_protobuf_FileOptions_has_cc_enable_arenas(const google_protobuf_FileOptions *msg) { return _upb_has_field(msg, 9); } UPB_INLINE bool google_protobuf_FileOptions_cc_enable_arenas(const google_protobuf_FileOptions *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(23, 23)); } -UPB_INLINE bool google_protobuf_FileOptions_has_objc_class_prefix(const google_protobuf_FileOptions *msg) { return _upb_has_field(msg, 13); } +UPB_INLINE bool google_protobuf_FileOptions_has_objc_class_prefix(const google_protobuf_FileOptions *msg) { return _upb_has_field(msg, 14); } UPB_INLINE upb_stringview google_protobuf_FileOptions_objc_class_prefix(const google_protobuf_FileOptions *msg) { return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(52, 80)); } -UPB_INLINE bool google_protobuf_FileOptions_has_csharp_namespace(const google_protobuf_FileOptions *msg) { return _upb_has_field(msg, 14); } +UPB_INLINE bool google_protobuf_FileOptions_has_csharp_namespace(const google_protobuf_FileOptions *msg) { return _upb_has_field(msg, 15); } UPB_INLINE upb_stringview google_protobuf_FileOptions_csharp_namespace(const google_protobuf_FileOptions *msg) { return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(60, 96)); } -UPB_INLINE bool google_protobuf_FileOptions_has_swift_prefix(const google_protobuf_FileOptions *msg) { return _upb_has_field(msg, 15); } +UPB_INLINE bool google_protobuf_FileOptions_has_swift_prefix(const google_protobuf_FileOptions *msg) { return _upb_has_field(msg, 16); } UPB_INLINE upb_stringview google_protobuf_FileOptions_swift_prefix(const google_protobuf_FileOptions *msg) { return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(68, 112)); } -UPB_INLINE bool google_protobuf_FileOptions_has_php_class_prefix(const google_protobuf_FileOptions *msg) { return _upb_has_field(msg, 16); } +UPB_INLINE bool google_protobuf_FileOptions_has_php_class_prefix(const google_protobuf_FileOptions *msg) { return _upb_has_field(msg, 17); } UPB_INLINE upb_stringview google_protobuf_FileOptions_php_class_prefix(const google_protobuf_FileOptions *msg) { return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(76, 128)); } -UPB_INLINE bool google_protobuf_FileOptions_has_php_namespace(const google_protobuf_FileOptions *msg) { return _upb_has_field(msg, 17); } +UPB_INLINE bool google_protobuf_FileOptions_has_php_namespace(const google_protobuf_FileOptions *msg) { return _upb_has_field(msg, 18); } UPB_INLINE upb_stringview google_protobuf_FileOptions_php_namespace(const google_protobuf_FileOptions *msg) { return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(84, 144)); } -UPB_INLINE bool google_protobuf_FileOptions_has_php_generic_services(const google_protobuf_FileOptions *msg) { return _upb_has_field(msg, 9); } +UPB_INLINE bool google_protobuf_FileOptions_has_php_generic_services(const google_protobuf_FileOptions *msg) { return _upb_has_field(msg, 10); } UPB_INLINE bool google_protobuf_FileOptions_php_generic_services(const google_protobuf_FileOptions *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(24, 24)); } UPB_INLINE const google_protobuf_UninterpretedOption* const* google_protobuf_FileOptions_uninterpreted_option(const google_protobuf_FileOptions *msg, size_t *len) { return (const google_protobuf_UninterpretedOption* const*)_upb_array_accessor(msg, UPB_SIZE(92, 160), len); } @@ -615,13 +615,13 @@ UPB_INLINE char *google_protobuf_MessageOptions_serialize(const google_protobuf_ return upb_encode(msg, &google_protobuf_MessageOptions_msginit, arena, len); } -UPB_INLINE bool google_protobuf_MessageOptions_has_message_set_wire_format(const google_protobuf_MessageOptions *msg) { return _upb_has_field(msg, 0); } +UPB_INLINE bool google_protobuf_MessageOptions_has_message_set_wire_format(const google_protobuf_MessageOptions *msg) { return _upb_has_field(msg, 1); } UPB_INLINE bool google_protobuf_MessageOptions_message_set_wire_format(const google_protobuf_MessageOptions *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(1, 1)); } -UPB_INLINE bool google_protobuf_MessageOptions_has_no_standard_descriptor_accessor(const google_protobuf_MessageOptions *msg) { return _upb_has_field(msg, 1); } +UPB_INLINE bool google_protobuf_MessageOptions_has_no_standard_descriptor_accessor(const google_protobuf_MessageOptions *msg) { return _upb_has_field(msg, 2); } UPB_INLINE bool google_protobuf_MessageOptions_no_standard_descriptor_accessor(const google_protobuf_MessageOptions *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(2, 2)); } -UPB_INLINE bool google_protobuf_MessageOptions_has_deprecated(const google_protobuf_MessageOptions *msg) { return _upb_has_field(msg, 2); } +UPB_INLINE bool google_protobuf_MessageOptions_has_deprecated(const google_protobuf_MessageOptions *msg) { return _upb_has_field(msg, 3); } UPB_INLINE bool google_protobuf_MessageOptions_deprecated(const google_protobuf_MessageOptions *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(3, 3)); } -UPB_INLINE bool google_protobuf_MessageOptions_has_map_entry(const google_protobuf_MessageOptions *msg) { return _upb_has_field(msg, 3); } +UPB_INLINE bool google_protobuf_MessageOptions_has_map_entry(const google_protobuf_MessageOptions *msg) { return _upb_has_field(msg, 4); } UPB_INLINE bool google_protobuf_MessageOptions_map_entry(const google_protobuf_MessageOptions *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(4, 4)); } UPB_INLINE const google_protobuf_UninterpretedOption* const* google_protobuf_MessageOptions_uninterpreted_option(const google_protobuf_MessageOptions *msg, size_t *len) { return (const google_protobuf_UninterpretedOption* const*)_upb_array_accessor(msg, UPB_SIZE(8, 8), len); } @@ -647,17 +647,17 @@ UPB_INLINE char *google_protobuf_FieldOptions_serialize(const google_protobuf_Fi return upb_encode(msg, &google_protobuf_FieldOptions_msginit, arena, len); } -UPB_INLINE bool google_protobuf_FieldOptions_has_ctype(const google_protobuf_FieldOptions *msg) { return _upb_has_field(msg, 0); } +UPB_INLINE bool google_protobuf_FieldOptions_has_ctype(const google_protobuf_FieldOptions *msg) { return _upb_has_field(msg, 1); } UPB_INLINE google_protobuf_FieldOptions_CType google_protobuf_FieldOptions_ctype(const google_protobuf_FieldOptions *msg) { return UPB_FIELD_AT(msg, google_protobuf_FieldOptions_CType, UPB_SIZE(8, 8)); } -UPB_INLINE bool google_protobuf_FieldOptions_has_packed(const google_protobuf_FieldOptions *msg) { return _upb_has_field(msg, 2); } +UPB_INLINE bool google_protobuf_FieldOptions_has_packed(const google_protobuf_FieldOptions *msg) { return _upb_has_field(msg, 3); } UPB_INLINE bool google_protobuf_FieldOptions_packed(const google_protobuf_FieldOptions *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(24, 24)); } -UPB_INLINE bool google_protobuf_FieldOptions_has_deprecated(const google_protobuf_FieldOptions *msg) { return _upb_has_field(msg, 3); } +UPB_INLINE bool google_protobuf_FieldOptions_has_deprecated(const google_protobuf_FieldOptions *msg) { return _upb_has_field(msg, 4); } UPB_INLINE bool google_protobuf_FieldOptions_deprecated(const google_protobuf_FieldOptions *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(25, 25)); } -UPB_INLINE bool google_protobuf_FieldOptions_has_lazy(const google_protobuf_FieldOptions *msg) { return _upb_has_field(msg, 4); } +UPB_INLINE bool google_protobuf_FieldOptions_has_lazy(const google_protobuf_FieldOptions *msg) { return _upb_has_field(msg, 5); } UPB_INLINE bool google_protobuf_FieldOptions_lazy(const google_protobuf_FieldOptions *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(26, 26)); } -UPB_INLINE bool google_protobuf_FieldOptions_has_jstype(const google_protobuf_FieldOptions *msg) { return _upb_has_field(msg, 1); } +UPB_INLINE bool google_protobuf_FieldOptions_has_jstype(const google_protobuf_FieldOptions *msg) { return _upb_has_field(msg, 2); } UPB_INLINE google_protobuf_FieldOptions_JSType google_protobuf_FieldOptions_jstype(const google_protobuf_FieldOptions *msg) { return UPB_FIELD_AT(msg, google_protobuf_FieldOptions_JSType, UPB_SIZE(16, 16)); } -UPB_INLINE bool google_protobuf_FieldOptions_has_weak(const google_protobuf_FieldOptions *msg) { return _upb_has_field(msg, 5); } +UPB_INLINE bool google_protobuf_FieldOptions_has_weak(const google_protobuf_FieldOptions *msg) { return _upb_has_field(msg, 6); } UPB_INLINE bool google_protobuf_FieldOptions_weak(const google_protobuf_FieldOptions *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(27, 27)); } UPB_INLINE const google_protobuf_UninterpretedOption* const* google_protobuf_FieldOptions_uninterpreted_option(const google_protobuf_FieldOptions *msg, size_t *len) { return (const google_protobuf_UninterpretedOption* const*)_upb_array_accessor(msg, UPB_SIZE(28, 32), len); } @@ -705,9 +705,9 @@ UPB_INLINE char *google_protobuf_EnumOptions_serialize(const google_protobuf_Enu return upb_encode(msg, &google_protobuf_EnumOptions_msginit, arena, len); } -UPB_INLINE bool google_protobuf_EnumOptions_has_allow_alias(const google_protobuf_EnumOptions *msg) { return _upb_has_field(msg, 0); } +UPB_INLINE bool google_protobuf_EnumOptions_has_allow_alias(const google_protobuf_EnumOptions *msg) { return _upb_has_field(msg, 1); } UPB_INLINE bool google_protobuf_EnumOptions_allow_alias(const google_protobuf_EnumOptions *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(1, 1)); } -UPB_INLINE bool google_protobuf_EnumOptions_has_deprecated(const google_protobuf_EnumOptions *msg) { return _upb_has_field(msg, 1); } +UPB_INLINE bool google_protobuf_EnumOptions_has_deprecated(const google_protobuf_EnumOptions *msg) { return _upb_has_field(msg, 2); } UPB_INLINE bool google_protobuf_EnumOptions_deprecated(const google_protobuf_EnumOptions *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(2, 2)); } UPB_INLINE const google_protobuf_UninterpretedOption* const* google_protobuf_EnumOptions_uninterpreted_option(const google_protobuf_EnumOptions *msg, size_t *len) { return (const google_protobuf_UninterpretedOption* const*)_upb_array_accessor(msg, UPB_SIZE(4, 8), len); } @@ -731,7 +731,7 @@ UPB_INLINE char *google_protobuf_EnumValueOptions_serialize(const google_protobu return upb_encode(msg, &google_protobuf_EnumValueOptions_msginit, arena, len); } -UPB_INLINE bool google_protobuf_EnumValueOptions_has_deprecated(const google_protobuf_EnumValueOptions *msg) { return _upb_has_field(msg, 0); } +UPB_INLINE bool google_protobuf_EnumValueOptions_has_deprecated(const google_protobuf_EnumValueOptions *msg) { return _upb_has_field(msg, 1); } UPB_INLINE bool google_protobuf_EnumValueOptions_deprecated(const google_protobuf_EnumValueOptions *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(1, 1)); } UPB_INLINE const google_protobuf_UninterpretedOption* const* google_protobuf_EnumValueOptions_uninterpreted_option(const google_protobuf_EnumValueOptions *msg, size_t *len) { return (const google_protobuf_UninterpretedOption* const*)_upb_array_accessor(msg, UPB_SIZE(4, 8), len); } @@ -754,7 +754,7 @@ UPB_INLINE char *google_protobuf_ServiceOptions_serialize(const google_protobuf_ return upb_encode(msg, &google_protobuf_ServiceOptions_msginit, arena, len); } -UPB_INLINE bool google_protobuf_ServiceOptions_has_deprecated(const google_protobuf_ServiceOptions *msg) { return _upb_has_field(msg, 0); } +UPB_INLINE bool google_protobuf_ServiceOptions_has_deprecated(const google_protobuf_ServiceOptions *msg) { return _upb_has_field(msg, 1); } UPB_INLINE bool google_protobuf_ServiceOptions_deprecated(const google_protobuf_ServiceOptions *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(1, 1)); } UPB_INLINE const google_protobuf_UninterpretedOption* const* google_protobuf_ServiceOptions_uninterpreted_option(const google_protobuf_ServiceOptions *msg, size_t *len) { return (const google_protobuf_UninterpretedOption* const*)_upb_array_accessor(msg, UPB_SIZE(4, 8), len); } @@ -777,9 +777,9 @@ UPB_INLINE char *google_protobuf_MethodOptions_serialize(const google_protobuf_M return upb_encode(msg, &google_protobuf_MethodOptions_msginit, arena, len); } -UPB_INLINE bool google_protobuf_MethodOptions_has_deprecated(const google_protobuf_MethodOptions *msg) { return _upb_has_field(msg, 1); } +UPB_INLINE bool google_protobuf_MethodOptions_has_deprecated(const google_protobuf_MethodOptions *msg) { return _upb_has_field(msg, 2); } UPB_INLINE bool google_protobuf_MethodOptions_deprecated(const google_protobuf_MethodOptions *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(16, 16)); } -UPB_INLINE bool google_protobuf_MethodOptions_has_idempotency_level(const google_protobuf_MethodOptions *msg) { return _upb_has_field(msg, 0); } +UPB_INLINE bool google_protobuf_MethodOptions_has_idempotency_level(const google_protobuf_MethodOptions *msg) { return _upb_has_field(msg, 1); } UPB_INLINE google_protobuf_MethodOptions_IdempotencyLevel google_protobuf_MethodOptions_idempotency_level(const google_protobuf_MethodOptions *msg) { return UPB_FIELD_AT(msg, google_protobuf_MethodOptions_IdempotencyLevel, UPB_SIZE(8, 8)); } UPB_INLINE const google_protobuf_UninterpretedOption* const* google_protobuf_MethodOptions_uninterpreted_option(const google_protobuf_MethodOptions *msg, size_t *len) { return (const google_protobuf_UninterpretedOption* const*)_upb_array_accessor(msg, UPB_SIZE(20, 24), len); } @@ -804,17 +804,17 @@ UPB_INLINE char *google_protobuf_UninterpretedOption_serialize(const google_prot } UPB_INLINE const google_protobuf_UninterpretedOption_NamePart* const* google_protobuf_UninterpretedOption_name(const google_protobuf_UninterpretedOption *msg, size_t *len) { return (const google_protobuf_UninterpretedOption_NamePart* const*)_upb_array_accessor(msg, UPB_SIZE(56, 80), len); } -UPB_INLINE bool google_protobuf_UninterpretedOption_has_identifier_value(const google_protobuf_UninterpretedOption *msg) { return _upb_has_field(msg, 3); } +UPB_INLINE bool google_protobuf_UninterpretedOption_has_identifier_value(const google_protobuf_UninterpretedOption *msg) { return _upb_has_field(msg, 4); } UPB_INLINE upb_stringview google_protobuf_UninterpretedOption_identifier_value(const google_protobuf_UninterpretedOption *msg) { return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(32, 32)); } -UPB_INLINE bool google_protobuf_UninterpretedOption_has_positive_int_value(const google_protobuf_UninterpretedOption *msg) { return _upb_has_field(msg, 0); } +UPB_INLINE bool google_protobuf_UninterpretedOption_has_positive_int_value(const google_protobuf_UninterpretedOption *msg) { return _upb_has_field(msg, 1); } UPB_INLINE uint64_t google_protobuf_UninterpretedOption_positive_int_value(const google_protobuf_UninterpretedOption *msg) { return UPB_FIELD_AT(msg, uint64_t, UPB_SIZE(8, 8)); } -UPB_INLINE bool google_protobuf_UninterpretedOption_has_negative_int_value(const google_protobuf_UninterpretedOption *msg) { return _upb_has_field(msg, 1); } +UPB_INLINE bool google_protobuf_UninterpretedOption_has_negative_int_value(const google_protobuf_UninterpretedOption *msg) { return _upb_has_field(msg, 2); } UPB_INLINE int64_t google_protobuf_UninterpretedOption_negative_int_value(const google_protobuf_UninterpretedOption *msg) { return UPB_FIELD_AT(msg, int64_t, UPB_SIZE(16, 16)); } -UPB_INLINE bool google_protobuf_UninterpretedOption_has_double_value(const google_protobuf_UninterpretedOption *msg) { return _upb_has_field(msg, 2); } +UPB_INLINE bool google_protobuf_UninterpretedOption_has_double_value(const google_protobuf_UninterpretedOption *msg) { return _upb_has_field(msg, 3); } UPB_INLINE double google_protobuf_UninterpretedOption_double_value(const google_protobuf_UninterpretedOption *msg) { return UPB_FIELD_AT(msg, double, UPB_SIZE(24, 24)); } -UPB_INLINE bool google_protobuf_UninterpretedOption_has_string_value(const google_protobuf_UninterpretedOption *msg) { return _upb_has_field(msg, 4); } +UPB_INLINE bool google_protobuf_UninterpretedOption_has_string_value(const google_protobuf_UninterpretedOption *msg) { return _upb_has_field(msg, 5); } UPB_INLINE upb_stringview google_protobuf_UninterpretedOption_string_value(const google_protobuf_UninterpretedOption *msg) { return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(40, 48)); } -UPB_INLINE bool google_protobuf_UninterpretedOption_has_aggregate_value(const google_protobuf_UninterpretedOption *msg) { return _upb_has_field(msg, 5); } +UPB_INLINE bool google_protobuf_UninterpretedOption_has_aggregate_value(const google_protobuf_UninterpretedOption *msg) { return _upb_has_field(msg, 6); } UPB_INLINE upb_stringview google_protobuf_UninterpretedOption_aggregate_value(const google_protobuf_UninterpretedOption *msg) { return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(48, 64)); } UPB_INLINE google_protobuf_UninterpretedOption_NamePart** google_protobuf_UninterpretedOption_name_mutable(google_protobuf_UninterpretedOption *msg, size_t *len) { return (google_protobuf_UninterpretedOption_NamePart**)_upb_array_mutable_accessor(msg, UPB_SIZE(56, 80), len); } @@ -841,9 +841,9 @@ UPB_INLINE char *google_protobuf_UninterpretedOption_NamePart_serialize(const go return upb_encode(msg, &google_protobuf_UninterpretedOption_NamePart_msginit, arena, len); } -UPB_INLINE bool google_protobuf_UninterpretedOption_NamePart_has_name_part(const google_protobuf_UninterpretedOption_NamePart *msg) { return _upb_has_field(msg, 1); } +UPB_INLINE bool google_protobuf_UninterpretedOption_NamePart_has_name_part(const google_protobuf_UninterpretedOption_NamePart *msg) { return _upb_has_field(msg, 2); } UPB_INLINE upb_stringview google_protobuf_UninterpretedOption_NamePart_name_part(const google_protobuf_UninterpretedOption_NamePart *msg) { return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(4, 8)); } -UPB_INLINE bool google_protobuf_UninterpretedOption_NamePart_has_is_extension(const google_protobuf_UninterpretedOption_NamePart *msg) { return _upb_has_field(msg, 0); } +UPB_INLINE bool google_protobuf_UninterpretedOption_NamePart_has_is_extension(const google_protobuf_UninterpretedOption_NamePart *msg) { return _upb_has_field(msg, 1); } UPB_INLINE bool google_protobuf_UninterpretedOption_NamePart_is_extension(const google_protobuf_UninterpretedOption_NamePart *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(1, 1)); } UPB_INLINE void google_protobuf_UninterpretedOption_NamePart_set_name_part(google_protobuf_UninterpretedOption_NamePart *msg, upb_stringview value) { UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(4, 8)) = value; } @@ -886,9 +886,9 @@ UPB_INLINE char *google_protobuf_SourceCodeInfo_Location_serialize(const google_ UPB_INLINE int32_t const* google_protobuf_SourceCodeInfo_Location_path(const google_protobuf_SourceCodeInfo_Location *msg, size_t *len) { return (int32_t const*)_upb_array_accessor(msg, UPB_SIZE(20, 40), len); } UPB_INLINE int32_t const* google_protobuf_SourceCodeInfo_Location_span(const google_protobuf_SourceCodeInfo_Location *msg, size_t *len) { return (int32_t const*)_upb_array_accessor(msg, UPB_SIZE(24, 48), len); } -UPB_INLINE bool google_protobuf_SourceCodeInfo_Location_has_leading_comments(const google_protobuf_SourceCodeInfo_Location *msg) { return _upb_has_field(msg, 0); } +UPB_INLINE bool google_protobuf_SourceCodeInfo_Location_has_leading_comments(const google_protobuf_SourceCodeInfo_Location *msg) { return _upb_has_field(msg, 1); } UPB_INLINE upb_stringview google_protobuf_SourceCodeInfo_Location_leading_comments(const google_protobuf_SourceCodeInfo_Location *msg) { return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(4, 8)); } -UPB_INLINE bool google_protobuf_SourceCodeInfo_Location_has_trailing_comments(const google_protobuf_SourceCodeInfo_Location *msg) { return _upb_has_field(msg, 1); } +UPB_INLINE bool google_protobuf_SourceCodeInfo_Location_has_trailing_comments(const google_protobuf_SourceCodeInfo_Location *msg) { return _upb_has_field(msg, 2); } UPB_INLINE upb_stringview google_protobuf_SourceCodeInfo_Location_trailing_comments(const google_protobuf_SourceCodeInfo_Location *msg) { return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(12, 24)); } UPB_INLINE upb_stringview const* google_protobuf_SourceCodeInfo_Location_leading_detached_comments(const google_protobuf_SourceCodeInfo_Location *msg, size_t *len) { return (upb_stringview const*)_upb_array_accessor(msg, UPB_SIZE(28, 56), len); } @@ -937,11 +937,11 @@ UPB_INLINE char *google_protobuf_GeneratedCodeInfo_Annotation_serialize(const go } UPB_INLINE int32_t const* google_protobuf_GeneratedCodeInfo_Annotation_path(const google_protobuf_GeneratedCodeInfo_Annotation *msg, size_t *len) { return (int32_t const*)_upb_array_accessor(msg, UPB_SIZE(20, 32), len); } -UPB_INLINE bool google_protobuf_GeneratedCodeInfo_Annotation_has_source_file(const google_protobuf_GeneratedCodeInfo_Annotation *msg) { return _upb_has_field(msg, 2); } +UPB_INLINE bool google_protobuf_GeneratedCodeInfo_Annotation_has_source_file(const google_protobuf_GeneratedCodeInfo_Annotation *msg) { return _upb_has_field(msg, 3); } UPB_INLINE upb_stringview google_protobuf_GeneratedCodeInfo_Annotation_source_file(const google_protobuf_GeneratedCodeInfo_Annotation *msg) { return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(12, 16)); } -UPB_INLINE bool google_protobuf_GeneratedCodeInfo_Annotation_has_begin(const google_protobuf_GeneratedCodeInfo_Annotation *msg) { return _upb_has_field(msg, 0); } +UPB_INLINE bool google_protobuf_GeneratedCodeInfo_Annotation_has_begin(const google_protobuf_GeneratedCodeInfo_Annotation *msg) { return _upb_has_field(msg, 1); } UPB_INLINE int32_t google_protobuf_GeneratedCodeInfo_Annotation_begin(const google_protobuf_GeneratedCodeInfo_Annotation *msg) { return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(4, 4)); } -UPB_INLINE bool google_protobuf_GeneratedCodeInfo_Annotation_has_end(const google_protobuf_GeneratedCodeInfo_Annotation *msg) { return _upb_has_field(msg, 1); } +UPB_INLINE bool google_protobuf_GeneratedCodeInfo_Annotation_has_end(const google_protobuf_GeneratedCodeInfo_Annotation *msg) { return _upb_has_field(msg, 2); } UPB_INLINE int32_t google_protobuf_GeneratedCodeInfo_Annotation_end(const google_protobuf_GeneratedCodeInfo_Annotation *msg) { return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(8, 8)); } UPB_INLINE int32_t* google_protobuf_GeneratedCodeInfo_Annotation_path_mutable(google_protobuf_GeneratedCodeInfo_Annotation *msg, size_t *len) { return (int32_t*)_upb_array_mutable_accessor(msg, UPB_SIZE(20, 32), len); } diff --git a/tests/pb/test_encoder.cc b/tests/pb/test_encoder.cc index 6cc9a2a..a0f8453 100644 --- a/tests/pb/test_encoder.cc +++ b/tests/pb/test_encoder.cc @@ -27,14 +27,17 @@ void test_pb_roundtrip() { size_t n; const google_protobuf_FileDescriptorProto *const *files = google_protobuf_FileDescriptorSet_file(set, &n); - fprintf(stderr, "n: %d\n", (int)n); ASSERT(n == 1); upb::Status status; bool ok = symtab->AddFile(files[0], &status); - ASSERT(ok); + if (!ok) { + fprintf(stderr, "Error building def: %s\n", upb_status_errmsg(&status)); + ASSERT(false); + } const upb::MessageDef *md = symtab->LookupMessage("google.protobuf.FileDescriptorSet"); ASSERT(md); + printf("name: %s\n", md->full_name()); upb::reffed_ptr encoder_handlers( upb::pb::Encoder::NewHandlers(md)); upb::reffed_ptr method( diff --git a/upb/def.c b/upb/def.c index e9acd43..ba6de50 100644 --- a/upb/def.c +++ b/upb/def.c @@ -189,25 +189,6 @@ static const char *shortdefname(const char *fullname) { } } -static bool upb_isoneof(const void *def) { - UPB_UNUSED(def); - return true; -} - -static bool upb_isfield(const void *def) { - UPB_UNUSED(def); - return true; -} - -static const upb_oneofdef *upb_trygetoneof(const void *def) { - return upb_isoneof(def) ? (const upb_oneofdef*)def : NULL; -} - -static const upb_fielddef *upb_trygetfield(const void *def) { - return upb_isfield(def) ? (const upb_fielddef*)def : NULL; -} - - /* All submessage fields are lower than all other fields. * Secondly, fields are increasing in order. */ uint32_t field_rank(const upb_fielddef *f) { @@ -274,7 +255,7 @@ static bool assign_msg_indices(upb_msgdef *m, upb_status *s) { { /* Verify that all selectors for the message are distinct. */ #define TRY(type) \ - if (upb_handlers_getselector(f, type, &sel)) upb_inttable_insert(&t, sel, v); + if (upb_handlers_getselector(f, type, &sel)) { upb_inttable_insert(&t, sel, v); } upb_inttable t; upb_value v; @@ -363,62 +344,6 @@ static void assign_msg_wellknowntype(upb_msgdef *m) { } } -#if 0 -bool _upb_def_validate(upb_def *const*defs, size_t n, upb_status *s) { - size_t i; - - /* First perform validation, in two passes so we can check that we have a - * transitive closure without needing to search. */ - for (i = 0; i < n; i++) { - upb_def *def = defs[i]; - if (upb_def_isfrozen(def)) { - /* Could relax this requirement if it's annoying. */ - upb_status_seterrmsg(s, "def is already frozen"); - goto err; - } else if (def->type == UPB_DEF_FIELD) { - upb_status_seterrmsg(s, "standalone fielddefs can not be frozen"); - goto err; - } else { - /* Set now to detect transitive closure in the second pass. */ - def->came_from_user = true; - - if (def->type == UPB_DEF_ENUM && - !upb_validate_enumdef(upb_dyncast_enumdef(def), s)) { - goto err; - } - } - } - - /* Second pass of validation. Also assign selector bases and indexes, and - * compact tables. */ - for (i = 0; i < n; i++) { - upb_def *def = defs[i]; - upb_msgdef *m = upb_dyncast_msgdef_mutable(def); - upb_enumdef *e = upb_dyncast_enumdef_mutable(def); - if (m) { - upb_inttable_compact(&m->itof); - if (!assign_msg_indices(m, s)) { - goto err; - } - assign_msg_wellknowntype(m); - /* m->well_known_type = UPB_WELLKNOWN_UNSPECIFIED; */ - } else if (e) { - upb_inttable_compact(&e->iton); - } - } - - return true; - -err: - for (i = 0; i < n; i++) { - upb_def *def = defs[i]; - def->came_from_user = false; - } - UPB_ASSERT(!(s && upb_ok(s))); - return false; -} -#endif - /* upb_enumdef ****************************************************************/ @@ -545,6 +470,10 @@ const char *upb_fielddef_name(const upb_fielddef *f) { return f->full_name; } +uint32_t upb_fielddef_selectorbase(const upb_fielddef *f) { + return f->selector_base; +} + size_t upb_fielddef_getjsonname(const upb_fielddef *f, char *buf, size_t len) { const char *name = upb_fielddef_name(f); size_t src, dst = 0; @@ -703,6 +632,14 @@ upb_syntax_t upb_msgdef_syntax(const upb_msgdef *m) { return m->file->syntax; } +size_t upb_msgdef_selectorcount(const upb_msgdef *m) { + return m->selector_count; +} + +uint32_t upb_msgdef_submsgfieldcount(const upb_msgdef *m) { + return m->submsg_field_count; +} + const upb_fielddef *upb_msgdef_itof(const upb_msgdef *m, uint32_t i) { upb_value val; return upb_inttable_lookup32(&m->itof, i, &val) ? @@ -717,7 +654,7 @@ const upb_fielddef *upb_msgdef_ntof(const upb_msgdef *m, const char *name, return NULL; } - return upb_trygetfield(upb_value_getptr(val)); + return unpack_def(val, UPB_DEFTYPE_FIELD); } const upb_oneofdef *upb_msgdef_ntoo(const upb_msgdef *m, const char *name, @@ -728,7 +665,7 @@ const upb_oneofdef *upb_msgdef_ntoo(const upb_msgdef *m, const char *name, return NULL; } - return upb_trygetoneof(upb_value_getptr(val)); + return unpack_def(val, UPB_DEFTYPE_ONEOF); } bool upb_msgdef_lookupname(const upb_msgdef *m, const char *name, size_t len, @@ -739,8 +676,8 @@ bool upb_msgdef_lookupname(const upb_msgdef *m, const char *name, size_t len, return false; } - *o = upb_trygetoneof(upb_value_getptr(val)); - *f = upb_trygetfield(upb_value_getptr(val)); + *o = unpack_def(val, UPB_DEFTYPE_ONEOF); + *f = unpack_def(val, UPB_DEFTYPE_FIELD); UPB_ASSERT((*o != NULL) ^ (*f != NULL)); /* Exactly one of the two should be set. */ return true; } @@ -780,7 +717,7 @@ bool upb_msg_field_done(const upb_msg_field_iter *iter) { } upb_fielddef *upb_msg_iter_field(const upb_msg_field_iter *iter) { - return (upb_fielddef*)upb_value_getptr(upb_inttable_iter_value(iter)); + return (upb_fielddef *)upb_value_getconstptr(upb_inttable_iter_value(iter)); } void upb_msg_field_iter_setdone(upb_msg_field_iter *iter) { @@ -791,7 +728,7 @@ void upb_msg_oneof_begin(upb_msg_oneof_iter *iter, const upb_msgdef *m) { upb_strtable_begin(iter, &m->ntof); /* We need to skip past any initial fields. */ while (!upb_strtable_done(iter) && - !upb_isoneof(upb_value_getptr(upb_strtable_iter_value(iter)))) { + !unpack_def(upb_strtable_iter_value(iter), UPB_DEFTYPE_ONEOF)) { upb_strtable_next(iter); } } @@ -801,7 +738,7 @@ void upb_msg_oneof_next(upb_msg_oneof_iter *iter) { do { upb_strtable_next(iter); } while (!upb_strtable_done(iter) && - !upb_isoneof(upb_value_getptr(upb_strtable_iter_value(iter)))); + !unpack_def(upb_strtable_iter_value(iter), UPB_DEFTYPE_ONEOF)); } bool upb_msg_oneof_done(const upb_msg_oneof_iter *iter) { @@ -809,7 +746,7 @@ bool upb_msg_oneof_done(const upb_msg_oneof_iter *iter) { } upb_oneofdef *upb_msg_iter_oneof(const upb_msg_oneof_iter *iter) { - return (upb_oneofdef*)upb_value_getptr(upb_strtable_iter_value(iter)); + return (upb_oneofdef *)upb_value_getconstptr(upb_strtable_iter_value(iter)); } void upb_msg_oneof_iter_setdone(upb_msg_oneof_iter *iter) { @@ -965,7 +902,7 @@ const upb_enumdef *upb_symtab_lookupenum(const upb_symtab *s, const char *sym) { * 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(x) if (!(x)) { __builtin_trap(); return false; } #define CHK_OOM(x) if (!(x)) { upb_upberr_setoom(ctx->status); return false; } typedef struct { @@ -977,8 +914,36 @@ typedef struct { upb_status *status; /* Record errors here. */ } symtab_addctx; -static const char *makefullname(const char *prefix, upb_stringview name) { - return NULL; +static char* strviewdup(const symtab_addctx *ctx, upb_stringview view) { + if (view.size == 0) { + return NULL; + } + return upb_strdup2(view.data, view.size, ctx->alloc); +} + +static bool streql(const char *a, size_t n, const char *b) { + return n == strlen(b) && memcmp(a, b, n) == 0; +} + +static bool streql_view(upb_stringview view, const char *b) { + return streql(view.data, view.size, b); +} + +static const char *makefullname(const symtab_addctx *ctx, const char *prefix, + upb_stringview name) { + if (prefix) { + /* ret = prefix + '.' + name; */ + size_t n = strlen(prefix); + char *ret = upb_malloc(ctx->alloc, n + name.size + 2); + CHK_OOM(ret); + strcpy(ret, prefix); + ret[n] = '.'; + memcpy(&ret[n + 1], name.data, name.size); + ret[n + 1 + name.size] = '\0'; + return ret; + } else { + return strviewdup(ctx, name); + } } static bool symtab_add(const symtab_addctx *ctx, const char *name, @@ -1050,13 +1015,13 @@ static bool create_oneofdef( o = (upb_oneofdef*)&m->oneofs[m->oneof_count++]; o->parent = m; - o->full_name = makefullname(m->full_name, name); + o->full_name = makefullname(ctx, m->full_name, name); CHK_OOM(symtab_add(ctx, o->full_name, pack_def(o, UPB_DEFTYPE_ONEOF))); CHK_OOM(upb_strtable_insert3(&m->ntof, name.data, name.size, upb_value_ptr(o), ctx->alloc)); - CHK_OOM(upb_inttable_init2(&o->itof, UPB_CTYPE_PTR, ctx->alloc)); - CHK_OOM(upb_strtable_init2(&o->ntof, UPB_CTYPE_PTR, ctx->alloc)); + CHK_OOM(upb_inttable_init2(&o->itof, UPB_CTYPE_CONSTPTR, ctx->alloc)); + CHK_OOM(upb_strtable_init2(&o->ntof, UPB_CTYPE_CONSTPTR, ctx->alloc)); return true; } @@ -1071,7 +1036,13 @@ static bool parse_default(const symtab_addctx *ctx, const char *str, size_t len, f->defaultval.sint = val; break; } - case UPB_TYPE_ENUM: + case UPB_TYPE_ENUM: { + const upb_enumdef *e = f->sub.enumdef; + int32_t val; + CHK(upb_enumdef_ntoi(e, str, len, &val)); + f->defaultval.sint = val; + break; + } 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); @@ -1106,9 +1077,9 @@ static bool parse_default(const symtab_addctx *ctx, const char *str, size_t len, break; } case UPB_TYPE_BOOL: { - if (strcmp(str, "false") == 0) { + if (streql(str, len, "false")) { f->defaultval.boolean = false; - } else if (strcmp(str, "true") == 0) { + } else if (streql(str, len, "true")) { f->defaultval.boolean = true; } else { return false; @@ -1134,8 +1105,6 @@ static bool create_fielddef( upb_fielddef *f; const google_protobuf_FieldOptions *options; upb_stringview name; - upb_value packed_v = pack_def(f, UPB_DEFTYPE_FIELD); - upb_value v = upb_value_constptr(f); const char *full_name; const char *shortname; uint32_t field_number; @@ -1147,7 +1116,7 @@ static bool create_fielddef( name = google_protobuf_FieldDescriptorProto_name(field_proto); CHK(upb_isident(name, false, ctx->status)); - full_name = makefullname(prefix, name); + full_name = makefullname(ctx, prefix, name); shortname = shortdefname(full_name); field_number = google_protobuf_FieldDescriptorProto_number(field_proto); @@ -1163,13 +1132,17 @@ static bool create_fielddef( f->msgdef = m; f->is_extension_ = false; + upb_value packed_v = pack_def(f, UPB_DEFTYPE_FIELD); + upb_value v = upb_value_constptr(f); + if (!upb_strtable_insert3(&m->ntof, name.data, name.size, packed_v, alloc)) { upb_status_seterrf(ctx->status, "duplicate field name (%s)", shortname); return false; } if (!upb_inttable_insert2(&m->itof, field_number, v, alloc)) { - upb_status_seterrf(ctx->status, "duplicate field number (%u)", f->number_); + upb_status_seterrf(ctx->status, "duplicate field number (%u)", + field_number); return false; } } else { @@ -1220,13 +1193,6 @@ static bool create_fielddef( f->oneof = NULL; } - if (google_protobuf_FieldDescriptorProto_has_default_value(field_proto)) { - upb_stringview defaultval = - google_protobuf_FieldDescriptorProto_default_value(field_proto); - CHK(parse_default(ctx, defaultval.data, defaultval.size, f)); - } - - if (google_protobuf_FieldDescriptorProto_has_options(field_proto)) { options = google_protobuf_FieldDescriptorProto_options(field_proto); f->lazy_ = google_protobuf_FieldOptions_lazy(options); @@ -1251,7 +1217,7 @@ static bool create_enumdef( CHK(upb_isident(name, false, ctx->status)); e = (upb_enumdef*)&ctx->file->enums[ctx->file->enum_count++]; - e->full_name = makefullname(prefix, name); + e->full_name = makefullname(ctx, prefix, name); CHK_OOM(symtab_add(ctx, e->full_name, pack_def(e, UPB_DEFTYPE_ENUM))); CHK_OOM(upb_strtable_init2(&e->ntoi, UPB_CTYPE_INT32, ctx->alloc)); @@ -1264,7 +1230,7 @@ static bool create_enumdef( for (i = 0; i < n; i++) { const google_protobuf_EnumValueDescriptorProto *value = values[i]; upb_stringview name = google_protobuf_EnumValueDescriptorProto_name(value); - char *name2 = upb_strdup2(name.data, name.size, ctx->alloc); + char *name2 = strviewdup(ctx, name); int32_t num = google_protobuf_EnumValueDescriptorProto_number(value); upb_value v = upb_value_int32(num); @@ -1273,10 +1239,13 @@ static bool create_enumdef( return false; } - CHK_OOM(name2 && upb_strtable_insert(&e->ntoi, name2, v)); + CHK_OOM(name2) + CHK_OOM( + upb_strtable_insert3(&e->ntoi, name2, strlen(name2), v, ctx->alloc)); if (!upb_inttable_lookup(&e->iton, num, NULL)) { - CHK_OOM(upb_inttable_insert(&e->iton, num, upb_value_cstr(name2))); + upb_value v = upb_value_cstr(name2); + CHK_OOM(upb_inttable_insert2(&e->iton, num, v, ctx->alloc)); } } @@ -1298,11 +1267,11 @@ static bool create_msgdef(const symtab_addctx *ctx, const char *prefix, CHK(upb_isident(name, false, ctx->status)); m = (upb_msgdef*)&ctx->file->msgs[ctx->file->msg_count++]; - m->full_name = makefullname(prefix, name); + m->full_name = makefullname(ctx, prefix, name); CHK_OOM(symtab_add(ctx, m->full_name, pack_def(m, UPB_DEFTYPE_MSG))); - CHK_OOM(upb_inttable_init2(&m->itof, UPB_CTYPE_PTR, ctx->alloc)); - CHK_OOM(upb_strtable_init2(&m->ntof, UPB_CTYPE_PTR, ctx->alloc)); + CHK_OOM(upb_inttable_init2(&m->itof, UPB_CTYPE_CONSTPTR, ctx->alloc)); + CHK_OOM(upb_strtable_init2(&m->ntof, UPB_CTYPE_CONSTPTR, ctx->alloc)); m->file = ctx->file; m->map_entry = false; @@ -1321,6 +1290,8 @@ static bool create_msgdef(const symtab_addctx *ctx, const char *prefix, } fields = google_protobuf_DescriptorProto_field(msg_proto, &n); + m->field_count = 0; + m->fields = upb_malloc(ctx->alloc, sizeof(*m->fields) * n); for (i = 0; i < n; i++) { CHK(create_fielddef(ctx, m->full_name, m, fields[i])); } @@ -1343,13 +1314,6 @@ static bool create_msgdef(const symtab_addctx *ctx, const char *prefix, return true; } -static char* strviewdup(const symtab_addctx *ctx, upb_stringview view) { - if (view.size == 0) { - return NULL; - } - return upb_strdup2(view.data, view.size, ctx->alloc); -} - typedef struct { int msg_count; int enum_count; @@ -1361,6 +1325,8 @@ static void count_types_in_msg(const google_protobuf_DescriptorProto *msg_proto, const google_protobuf_DescriptorProto *const *msgs; size_t i, n; + counts->msg_count++; + msgs = google_protobuf_DescriptorProto_nested_type(msg_proto, &n); for (i = 0; i < n; i++) { count_types_in_msg(msgs[i], counts); @@ -1394,24 +1360,46 @@ static void count_types_in_file( static bool resolve_fielddef(const symtab_addctx *ctx, const char *prefix, upb_fielddef *f) { upb_stringview name; + const google_protobuf_FieldDescriptorProto *field_proto = f->sub.unresolved; + if (f->is_extension_) { - name = google_protobuf_FieldDescriptorProto_extendee(f->sub.unresolved); + if (!google_protobuf_FieldDescriptorProto_has_extendee(field_proto)) { + upb_status_seterrf(ctx->status, + "extension for field '%s' had no extendee", + f->full_name); + return false; + } + + name = google_protobuf_FieldDescriptorProto_extendee(field_proto); f->msgdef = symtab_resolve(ctx, f, prefix, name, UPB_DEFTYPE_MSG); CHK(f->msgdef); } - name = google_protobuf_FieldDescriptorProto_type_name(f->sub.unresolved); + if ((upb_fielddef_issubmsg(f) || f->type_ == UPB_DESCRIPTOR_TYPE_ENUM) && + !google_protobuf_FieldDescriptorProto_has_type_name(field_proto)) { + upb_status_seterrf(ctx->status, "field '%s' is missing type name", + f->full_name); + return false; + } + + name = google_protobuf_FieldDescriptorProto_type_name(field_proto); + if (upb_fielddef_issubmsg(f)) { f->sub.msgdef = symtab_resolve(ctx, f, prefix, name, UPB_DEFTYPE_MSG); CHK(f->sub.msgdef); } else if (f->type_ == UPB_DESCRIPTOR_TYPE_ENUM) { f->sub.enumdef = symtab_resolve(ctx, f, prefix, name, UPB_DEFTYPE_ENUM); CHK(f->sub.enumdef); + } - if (!upb_enumdef_iton(f->sub.enumdef, f->defaultval.sint)) { - upb_status_seterrf(ctx->status, - "enum field %s has default (%d) not in the enum", - f->full_name, f->defaultval.sint); + /* Have to delay resolving of the default value until now because of the enum + * case, since enum defaults are specified with a label. */ + if (google_protobuf_FieldDescriptorProto_has_default_value(field_proto)) { + upb_stringview defaultval = + google_protobuf_FieldDescriptorProto_default_value(field_proto); + if (!parse_default(ctx, defaultval.data, defaultval.size, f)) { + upb_status_seterrf(ctx->status, "bad default '" UPB_STRINGVIEW_FORMAT "'", + UPB_STRINGVIEW_ARGS(defaultval)); return false; } } @@ -1429,8 +1417,7 @@ static bool build_filedef( const google_protobuf_FieldDescriptorProto *const *exts; const upb_stringview* strs; size_t i, n; - decl_counts counts; - upb_stringview syntax, package; + decl_counts counts = {0}; count_types_in_file(file_proto, &counts); @@ -1438,29 +1425,48 @@ static bool build_filedef( file->enums = upb_malloc(alloc, sizeof(*file->enums) * counts.enum_count); file->exts = upb_malloc(alloc, sizeof(*file->exts) * counts.ext_count); + CHK_OOM(counts.msg_count == 0 || file->msgs); + CHK_OOM(counts.enum_count == 0 || file->enums); + CHK_OOM(counts.ext_count == 0 || file->exts); + /* We increment these as defs are added. */ file->msg_count = 0; file->enum_count = 0; file->ext_count = 0; - package = google_protobuf_FileDescriptorProto_package(file_proto); - CHK(upb_isident(package, true, ctx->status)); + if (!google_protobuf_FileDescriptorProto_has_name(file_proto)) { + upb_status_seterrmsg(ctx->status, "File has no name"); + return false; + } file->name = 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 (google_protobuf_FileDescriptorProto_has_package(file_proto)) { + upb_stringview package = + google_protobuf_FileDescriptorProto_package(file_proto); + CHK(upb_isident(package, true, ctx->status)); + file->package = strviewdup(ctx, package); + } else { + file->package = NULL; + } + + if (google_protobuf_FileDescriptorProto_has_syntax(file_proto)) { + upb_stringview 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; + if (streql_view(syntax, "proto2")) { + file->syntax = UPB_SYNTAX_PROTO2; + } else if (streql_view(syntax, "proto3")) { + file->syntax = UPB_SYNTAX_PROTO3; + } else { + upb_status_seterrf(ctx->status, "Invalid syntax '%s'", syntax); + return false; + } } else { - upb_status_seterrf(ctx->status, "Invalid syntax '%s'", syntax); - return false; + file->syntax = UPB_SYNTAX_PROTO2; } /* Read options. */ @@ -1475,7 +1481,7 @@ static bool build_filedef( /* Verify dependencies. */ strs = google_protobuf_FileDescriptorProto_dependency(file_proto, &n); file->deps = upb_malloc(alloc, sizeof(*file->deps) * n) ; - CHK_OOM(file->deps); + CHK_OOM(n == 0 || file->deps); for (i = 0; i < n; i++) { upb_stringview dep_name = strs[i]; @@ -1505,7 +1511,7 @@ static bool build_filedef( /* Create extensions. */ exts = google_protobuf_FileDescriptorProto_extension(file_proto, &n); file->exts = upb_malloc(alloc, sizeof(*file->exts) * n); - CHK_OOM(file->exts); + CHK_OOM(n == 0 || file->exts); for (i = 0; i < n; i++) { CHK(create_fielddef(ctx, file->package, NULL, exts[i])); } @@ -1518,7 +1524,7 @@ static bool build_filedef( for (i = 0; i < file->msg_count; i++) { const upb_msgdef *m = &file->msgs[i]; int j; - for (j = 0; i < m->field_count; i++) { + for (j = 0; j < m->field_count; j++) { CHK(resolve_fielddef(ctx, m->full_name, (upb_fielddef*)&m->fields[j])); } } @@ -1551,12 +1557,13 @@ bool upb_symtab_addfile(upb_symtab *s, 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; + symtab_addctx ctx; ctx.file = file; + ctx.symtab = s; ctx.alloc = alloc; ctx.tmp = upb_arena_alloc(&tmparena); ctx.addtab = &addtab; @@ -1565,7 +1572,7 @@ bool upb_symtab_addfile(upb_symtab *s, upb_arena_init(&tmparena); ok = file && - upb_strtable_init2(&addtab, UPB_CTYPE_PTR, ctx.tmp) && + upb_strtable_init2(&addtab, UPB_CTYPE_CONSTPTR, ctx.tmp) && build_filedef(&ctx, file, file_proto) && upb_symtab_addtotabs(s, &ctx, status); diff --git a/upb/generated_util.h b/upb/generated_util.h index 0a10099..88a983d 100644 --- a/upb/generated_util.h +++ b/upb/generated_util.h @@ -16,7 +16,7 @@ UPB_INLINE const void *_upb_array_accessor(const void *msg, size_t ofs, size_t *size) { const upb_array *arr = *PTR_AT(msg, ofs, const upb_array*); if (arr) { - if (size) *size = arr->size; + if (size) *size = arr->len; return arr->data; } else { if (size) *size = 0; @@ -28,7 +28,7 @@ UPB_INLINE void *_upb_array_mutable_accessor(void *msg, size_t ofs, size_t *size) { upb_array *arr = *PTR_AT(msg, ofs, upb_array*); if (arr) { - if (size) *size = arr->size; + if (size) *size = arr->len; return arr->data; } else { if (size) size = 0; @@ -66,7 +66,7 @@ UPB_INLINE void *_upb_array_resize_accessor(void *msg, size_t ofs, size_t size, } UPB_INLINE bool _upb_has_field(const void *msg, size_t idx) { - return (*PTR_AT(msg, idx / 8, const char) & (idx % 8)) != 0; + return (*PTR_AT(msg, idx / 8, const char) & (1 << (idx % 8))) != 0; } UPB_INLINE bool _upb_has_oneof_field(const void *msg, size_t case_ofs, int32_t num) { diff --git a/upb/msg.h b/upb/msg.h index 6002b41..6061470 100644 --- a/upb/msg.h +++ b/upb/msg.h @@ -98,6 +98,9 @@ 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_FORMAT "%.*s" +#define UPB_STRINGVIEW_ARGS(view) view.size, view.data + #define UPB_STRINGVIEW_INIT(ptr, len) {ptr, len} diff --git a/upb/upb.c b/upb/upb.c index 97f6c61..cbf5afb 100644 --- a/upb/upb.c +++ b/upb/upb.c @@ -31,6 +31,7 @@ static void nullz(upb_status *status) { upb_errorspace upb_upberr = {"upb error"}; void upb_upberr_setoom(upb_status *status) { + __builtin_trap(); status->error_space_ = &upb_upberr; upb_status_seterrmsg(status, "Out of memory"); } diff --git a/upb/upb.h b/upb/upb.h index 2fb7a88..020022b 100644 --- a/upb/upb.h +++ b/upb/upb.h @@ -463,6 +463,7 @@ struct upb_alloc { UPB_INLINE void *upb_malloc(upb_alloc *alloc, size_t size) { UPB_ASSERT(alloc); + UPB_ASSERT(size < 65535); return alloc->func(alloc, NULL, 0, size); } diff --git a/upbc/generator.cc b/upbc/generator.cc index bb29041..68996a9 100644 --- a/upbc/generator.cc +++ b/upbc/generator.cc @@ -521,7 +521,7 @@ void WriteSource(const protobuf::FileDescriptor* file, Output& output) { } if (MessageLayout::HasHasbit(field)) { - presence = absl::StrCat(layout.GetHasbitIndex(field) + 1); + presence = absl::StrCat(layout.GetHasbitIndex(field)); } else if (field->containing_oneof()) { MessageLayout::Size case_offset = layout.GetOneofCaseOffset(field->containing_oneof()); diff --git a/upbc/message_layout.cc b/upbc/message_layout.cc index 5956424..f0a6872 100644 --- a/upbc/message_layout.cc +++ b/upbc/message_layout.cc @@ -130,7 +130,9 @@ void MessageLayout::PlaceNonOneofFields( int hasbit_count = 0; for (auto field : field_order) { if (HasHasbit(field)) { - hasbit_indexes_[field] = hasbit_count++; + // We don't use hasbit 0, so that 0 can indicate "no presence" in the + // table. This wastes one hasbit, but we don't worry about it for now. + hasbit_indexes_[field] = ++hasbit_count; } } -- cgit v1.2.3 From 377871f10403c7b4e1cc6f769b9443b5197aecc8 Mon Sep 17 00:00:00 2001 From: Joshua Haberman Date: Sun, 16 Dec 2018 14:32:14 -0800 Subject: Got test_decoder working! --- BUILD | 15 + CMakeLists.txt | 1 + build_defs.bzl | 51 ++- tests/pb/test_decoder.cc | 91 +++--- tests/pb/test_decoder.proto | 42 +++ tools/dump_cinit.lua | 749 -------------------------------------------- tools/make_cmakelists.py | 3 + tools/upbc.lua | 91 ------ upb/def.c | 51 ++- upb/def.h | 10 +- upb/upb.h | 1 - upbc/generator.cc | 104 ++++++ 12 files changed, 317 insertions(+), 892 deletions(-) delete mode 100644 tools/dump_cinit.lua delete mode 100644 tools/upbc.lua (limited to 'upb/def.c') diff --git a/BUILD b/BUILD index 9b8513d..b3f397a 100644 --- a/BUILD +++ b/BUILD @@ -8,6 +8,7 @@ load( "make_shell_script", "upb_amalgamation", "upb_proto_library", + "upb_proto_reflection_library", ) # C/C++ rules ################################################################## @@ -167,10 +168,24 @@ cc_test( ], ) +proto_library( + name = "test_decoder_proto", + srcs = [ + "tests/pb/test_decoder.proto" + ] +) + +upb_proto_reflection_library( + name = "test_decoder_upbproto", + deps = ["test_decoder_proto"], + upbc = ":protoc-gen-upb", +) + cc_test( name = "test_decoder", srcs = ["tests/pb/test_decoder.cc"], deps = [ + ":test_decoder_upbproto", ":upb_pb", ":upb_test", ], diff --git a/CMakeLists.txt b/CMakeLists.txt index 6133c16..3439aac 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -131,6 +131,7 @@ add_executable(test_decoder tests/pb/test_decoder.cc) add_test(NAME test_decoder COMMAND test_decoder) target_link_libraries(test_decoder + test_decoder_upbproto upb_pb upb_test) add_executable(test_encoder diff --git a/build_defs.bzl b/build_defs.bzl index 8251014..3867976 100644 --- a/build_defs.bzl +++ b/build_defs.bzl @@ -217,7 +217,7 @@ def _remove_up(string): return _remove_suffix(string, ".proto") -def _upb_proto_library_srcs_impl(ctx): +def _upb_proto_srcs_impl(ctx, suffix): sources = [] outs = [] include_dirs = {} @@ -225,14 +225,19 @@ def _upb_proto_library_srcs_impl(ctx): if hasattr(dep, 'proto'): for src in dep.proto.transitive_sources: sources.append(src) - include_dirs[_remove_suffix(src.path, _remove_up(src.short_path) + "." + src.extension)] = True - outs.append(ctx.actions.declare_file(_remove_up(src.short_path) + ".upb.h")) - outs.append(ctx.actions.declare_file(_remove_up(src.short_path) + ".upb.c")) - outdir = _remove_suffix(outs[-1].path, _remove_up(src.short_path) + ".upb.c") + include_dir = _remove_suffix(src.path, _remove_up(src.short_path) + "." + src.extension) + if include_dir: + include_dirs[include_dir] = True + outs.append(ctx.actions.declare_file(_remove_up(src.short_path) + suffix + ".h")) + outs.append(ctx.actions.declare_file(_remove_up(src.short_path) + suffix + ".c")) + outdir = _remove_suffix(outs[-1].path, _remove_up(src.short_path) + suffix + ".c") source_paths = [d.path for d in sources] include_args = ["-I" + root for root in include_dirs.keys()] + print(source_paths) + print(include_args) + ctx.actions.run( inputs = [ctx.executable.upbc] + sources, outputs = outs, @@ -243,6 +248,12 @@ def _upb_proto_library_srcs_impl(ctx): return [DefaultInfo(files = depset(outs))] +def _upb_proto_library_srcs_impl(ctx): + return _upb_proto_srcs_impl(ctx, ".upb") + +def _upb_proto_reflection_library_srcs_impl(ctx): + return _upb_proto_srcs_impl(ctx, ".upbdefs") + _upb_proto_library_srcs = rule( implementation = _upb_proto_library_srcs_impl, attrs = { @@ -272,3 +283,33 @@ def upb_proto_library(name, deps, upbc): deps = [":upb"], copts = ["-Ibazel-out/k8-fastbuild/bin"], ) + +_upb_proto_reflection_library_srcs = rule( + implementation = _upb_proto_reflection_library_srcs_impl, + attrs = { + "upbc": attr.label( + executable = True, + cfg = "host", + ), + "protoc": attr.label( + executable = True, + cfg = "host", + default = "@com_google_protobuf//:protoc", + ), + "deps": attr.label_list(), + } +) + +def upb_proto_reflection_library(name, deps, upbc): + srcs_rule = name + "_defsrcs.cc" + _upb_proto_reflection_library_srcs( + name = srcs_rule, + upbc = upbc, + deps = deps, + ) + native.cc_library( + name = name, + srcs = [":" + srcs_rule], + deps = [":upb"], + copts = ["-Ibazel-out/k8-fastbuild/bin"], + ) diff --git a/tests/pb/test_decoder.cc b/tests/pb/test_decoder.cc index a931779..d0e3fa3 100644 --- a/tests/pb/test_decoder.cc +++ b/tests/pb/test_decoder.cc @@ -36,6 +36,7 @@ #include "tests/test_util.h" #include "tests/upb_test.h" +#include "tests/pb/test_decoder.upbdefs.h" #ifdef AMALGAMATED #include "upb.h" @@ -387,7 +388,6 @@ void reg_subm(upb_handlers *h, uint32_t num) { ASSERT( h->SetStartSubMessageHandler(f, UpbBind(startsubmsg, new uint32_t(num)))); ASSERT(h->SetEndSubMessageHandler(f, UpbBind(endsubmsg, new uint32_t(num)))); - ASSERT(upb_handlers_setsubhandlers(h, f, h)); } void reg_str(upb_handlers *h, uint32_t num) { @@ -399,52 +399,60 @@ void reg_str(upb_handlers *h, uint32_t num) { ASSERT(h->SetStringHandler(f, UpbBind(value_string, new uint32_t(num)))); } -upb::reffed_ptr NewHandlers(TestMode mode) { - - upb::reffed_ptr h(upb::Handlers::New(NewMessageDef().get())); +struct HandlerRegisterData { + TestMode mode; +}; - if (mode == ALL_HANDLERS) { +void callback(const void *closure, upb_handlers *h) { + const HandlerRegisterData* data = + static_cast(closure); + if (data->mode == ALL_HANDLERS) { h->SetStartMessageHandler(UpbMakeHandler(startmsg)); h->SetEndMessageHandler(UpbMakeHandler(endmsg)); // Register handlers for each type. - reg(h.get(), UPB_DESCRIPTOR_TYPE_DOUBLE); - reg (h.get(), UPB_DESCRIPTOR_TYPE_FLOAT); - reg (h.get(), UPB_DESCRIPTOR_TYPE_INT64); - reg(h.get(), UPB_DESCRIPTOR_TYPE_UINT64); - reg (h.get(), UPB_DESCRIPTOR_TYPE_INT32); - reg(h.get(), UPB_DESCRIPTOR_TYPE_FIXED64); - reg(h.get(), UPB_DESCRIPTOR_TYPE_FIXED32); - reg (h.get(), UPB_DESCRIPTOR_TYPE_BOOL); - reg(h.get(), UPB_DESCRIPTOR_TYPE_UINT32); - reg (h.get(), UPB_DESCRIPTOR_TYPE_ENUM); - reg (h.get(), UPB_DESCRIPTOR_TYPE_SFIXED32); - reg (h.get(), UPB_DESCRIPTOR_TYPE_SFIXED64); - reg (h.get(), UPB_DESCRIPTOR_TYPE_SINT32); - reg (h.get(), UPB_DESCRIPTOR_TYPE_SINT64); - - reg_str(h.get(), UPB_DESCRIPTOR_TYPE_STRING); - reg_str(h.get(), UPB_DESCRIPTOR_TYPE_BYTES); - reg_str(h.get(), rep_fn(UPB_DESCRIPTOR_TYPE_STRING)); - reg_str(h.get(), rep_fn(UPB_DESCRIPTOR_TYPE_BYTES)); + reg(h, UPB_DESCRIPTOR_TYPE_DOUBLE); + reg (h, UPB_DESCRIPTOR_TYPE_FLOAT); + reg (h, UPB_DESCRIPTOR_TYPE_INT64); + reg(h, UPB_DESCRIPTOR_TYPE_UINT64); + reg (h, UPB_DESCRIPTOR_TYPE_INT32); + reg(h, UPB_DESCRIPTOR_TYPE_FIXED64); + reg(h, UPB_DESCRIPTOR_TYPE_FIXED32); + reg (h, UPB_DESCRIPTOR_TYPE_BOOL); + reg(h, UPB_DESCRIPTOR_TYPE_UINT32); + reg (h, UPB_DESCRIPTOR_TYPE_ENUM); + reg (h, UPB_DESCRIPTOR_TYPE_SFIXED32); + reg (h, UPB_DESCRIPTOR_TYPE_SFIXED64); + reg (h, UPB_DESCRIPTOR_TYPE_SINT32); + reg (h, UPB_DESCRIPTOR_TYPE_SINT64); + + reg_str(h, UPB_DESCRIPTOR_TYPE_STRING); + reg_str(h, UPB_DESCRIPTOR_TYPE_BYTES); + reg_str(h, rep_fn(UPB_DESCRIPTOR_TYPE_STRING)); + reg_str(h, rep_fn(UPB_DESCRIPTOR_TYPE_BYTES)); // Register submessage/group handlers that are self-recursive // to this type, eg: message M { optional M m = 1; } - reg_subm(h.get(), UPB_DESCRIPTOR_TYPE_MESSAGE); - reg_subm(h.get(), rep_fn(UPB_DESCRIPTOR_TYPE_MESSAGE)); - reg_subm(h.get(), UPB_DESCRIPTOR_TYPE_GROUP); - reg_subm(h.get(), rep_fn(UPB_DESCRIPTOR_TYPE_GROUP)); + reg_subm(h, UPB_DESCRIPTOR_TYPE_MESSAGE); + reg_subm(h, rep_fn(UPB_DESCRIPTOR_TYPE_MESSAGE)); + + if (h->message_def()->full_name() == std::string("DecoderTest")) { + reg_subm(h, UPB_DESCRIPTOR_TYPE_GROUP); + reg_subm(h, rep_fn(UPB_DESCRIPTOR_TYPE_GROUP)); + } // For NOP_FIELD we register no handlers, so we can pad a proto freely without // changing the output. } - - bool ok = h->Freeze(NULL); - ASSERT(ok); - - return h; } +upb::reffed_ptr NewHandlers(upb::SymbolTable* symtab, + TestMode mode) { + HandlerRegisterData handlerdata; + handlerdata.mode = mode; + return upb::Handlers::NewFrozen(DecoderTest_getmsgdef(symtab), callback, + &handlerdata); +} /* Running of test cases ******************************************************/ @@ -1132,14 +1140,11 @@ upb::reffed_ptr NewMethod( return cache.GetDecoderMethod(upb::pb::DecoderMethodOptions(dest_handlers)); } -void test_emptyhandlers(bool allowjit) { +void test_emptyhandlers(upb::SymbolTable* symtab, bool allowjit) { // Create an empty handlers to make sure that the decoder can handle empty // messages. - upb::reffed_ptr md = upb::MessageDef::New(); - ASSERT(md->set_full_name("Empty", NULL)); - ASSERT(md->Freeze(NULL)); - - upb::reffed_ptr h(upb::Handlers::New(md.get())); + const upb::MessageDef* md = Empty_getmsgdef(symtab); + upb::reffed_ptr h(upb::Handlers::New(md)); bool ok = h->Freeze(NULL); ASSERT(ok); upb::reffed_ptr method = @@ -1178,9 +1183,9 @@ upb::reffed_ptr method = void run_tests(bool use_jit) { upb::reffed_ptr method; upb::reffed_ptr handlers; - upb::SymbolTable symtab; + upb::SymbolTable* symtab = upb::SymbolTable::New(); - handlers = NewHandlers(test_mode); + handlers = NewHandlers(symtab, test_mode); global_handlers = handlers.get(); method = NewMethod(handlers.get(), use_jit); @@ -1191,7 +1196,9 @@ void run_tests(bool use_jit) { test_invalid(); test_valid(); - test_emptyhandlers(use_jit); + test_emptyhandlers(symtab, use_jit); + + upb::SymbolTable::Free(symtab); } void run_test_suite() { diff --git a/tests/pb/test_decoder.proto b/tests/pb/test_decoder.proto index 8197dea..e9fa6ad 100644 --- a/tests/pb/test_decoder.proto +++ b/tests/pb/test_decoder.proto @@ -5,6 +5,8 @@ enum TestEnum { FOO = 1; } +message Empty {} + message DecoderTest { optional double f_double = 1; optional float f_float = 2; @@ -62,6 +64,26 @@ message DecoderTest { optional sfixed64 f_sfixed64 = 16; optional sint32 f_sint32 = 17; optional sint64 f_sint64 = 18; + + optional string nop_field = 40; + + repeated double r_double = 536869912; + repeated float r_float = 536869913; + repeated int64 r_int64 = 536869914; + repeated uint64 r_uint64 = 536869915; + repeated int32 r_int32 = 536869916; + repeated fixed64 r_fixed64 = 536869917; + repeated fixed32 r_fixed32 = 536869918; + repeated bool r_bool = 536869919; + repeated string r_string = 536869920; + repeated DecoderTest r_message = 536869922; + repeated bytes r_bytes = 536869923; + repeated uint32 r_uint32 = 536869924; + repeated TestEnum r_enum = 536869925; + repeated sfixed32 r_sfixed32 = 536869926; + repeated sfixed64 r_sfixed64 = 536869927; + repeated sint32 r_sint32 = 536869928; + repeated sint64 r_sint64 = 536869929; } optional group R_group = 536869921 { @@ -82,5 +104,25 @@ message DecoderTest { optional sfixed64 f_sfixed64 = 16; optional sint32 f_sint32 = 17; optional sint64 f_sint64 = 18; + + optional string nop_field = 40; + + repeated double r_double = 536869912; + repeated float r_float = 536869913; + repeated int64 r_int64 = 536869914; + repeated uint64 r_uint64 = 536869915; + repeated int32 r_int32 = 536869916; + repeated fixed64 r_fixed64 = 536869917; + repeated fixed32 r_fixed32 = 536869918; + repeated bool r_bool = 536869919; + repeated string r_string = 536869920; + repeated DecoderTest r_message = 536869922; + repeated bytes r_bytes = 536869923; + repeated uint32 r_uint32 = 536869924; + repeated TestEnum r_enum = 536869925; + repeated sfixed32 r_sfixed32 = 536869926; + repeated sfixed64 r_sfixed64 = 536869927; + repeated sint32 r_sint32 = 536869928; + repeated sint64 r_sint64 = 536869929; } } diff --git a/tools/dump_cinit.lua b/tools/dump_cinit.lua deleted file mode 100644 index 93ee12e..0000000 --- a/tools/dump_cinit.lua +++ /dev/null @@ -1,749 +0,0 @@ ---[[ - - Routines for dumping internal data structures into C initializers - that can be compiled into a .o file. - ---]] - -local upbtable = require "upb.table" -local upb = require "upb" -local export = {} - --- A tiny little abstraction that decouples the dump_* functions from --- what they're writing to (appending to a string, writing to file I/O, etc). --- This could possibly matter since naive string building is O(n^2) in the --- number of appends. -function export.str_appender() - local str = "" - local function append(fmt, ...) - str = str .. string.format(fmt, ...) - end - local function get() - return str - end - return append, get -end - -function export.file_appender(file) - local f = file - local function append(fmt, ...) - f:write(string.format(fmt, ...)) - end - return append -end - -function handler_types(base) - local ret = {} - for k, _ in pairs(base) do - if string.find(k, "^" .. "HANDLER_") then - ret[#ret + 1] = k - end - end - return ret -end - -function octchar(num) - assert(num < 8) - local idx = num + 1 -- 1-based index - return string.sub("01234567", idx, idx) -end - -function c_escape(num) - assert(num < 256) - return string.format("\\%s%s%s", - octchar(math.floor(num / 64)), - octchar(math.floor(num / 8) % 8), - octchar(num % 8)); -end - --- const(f, label) -> UPB_LABEL_REPEATED, where f:label() == upb.LABEL_REPEATED -function const(obj, name, base) - local val = obj[name] - base = base or upb - - -- Support both f:label() and f.label. - if type(val) == "function" then - val = val(obj) - end - - for k, v in pairs(base) do - if v == val and string.find(k, "^" .. string.upper(name)) then - return "UPB_" .. k - end - end - assert(false, "Couldn't find UPB_" .. string.upper(name) .. - " constant for value: " .. val) -end - -function sortedkeys(tab) - arr = {} - for key in pairs(tab) do - arr[#arr + 1] = key - end - table.sort(arr) - return arr -end - -function sorted_defs(defs) - local sorted = {} - - for def in defs do - if def.type == deftype then - sorted[#sorted + 1] = def - end - end - - table.sort(sorted, - function(a, b) return a:full_name() < b:full_name() end) - - return sorted -end - -function constlist(pattern) - local ret = {} - for k, v in pairs(upb) do - if string.find(k, "^" .. pattern) then - ret[k] = v - end - end - return ret -end - -function boolstr(val) - if val == true then - return "true" - elseif val == false then - return "false" - else - assert(false, "Bad bool value: " .. tostring(val)) - end -end - ---[[ - - LinkTable: an object that tracks all linkable objects and their offsets to - facilitate linking. - ---]] - -local LinkTable = {} -function LinkTable:new(types) - local linktab = { - types = types, - table = {}, -- ptr -> {type, 0-based offset} - obj_arrays = {} -- Establishes the ordering for each object type - } - for type, _ in pairs(types) do - linktab.obj_arrays[type] = {} - end - setmetatable(linktab, {__index = LinkTable}) -- Inheritance - return linktab -end - --- Adds a new object to the sequence of objects of this type. -function LinkTable:add(objtype, ptr, obj) - obj = obj or ptr - assert(self.table[obj] == nil) - assert(self.types[objtype]) - local arr = self.obj_arrays[objtype] - self.table[ptr] = {objtype, #arr} - arr[#arr + 1] = obj -end - --- Returns a C symbol name for the given objtype and offset. -function LinkTable:csym(objtype, offset) - local typestr = assert(self.types[objtype]) - return string.format("%s[%d]", typestr, offset) -end - --- Returns the address of the given C object. -function LinkTable:addr(obj) - if obj == upbtable.NULL then - return "NULL" - else - local tabent = assert(self.table[obj], "unknown object: " .. tostring(obj)) - return "&" .. self:csym(tabent[1], tabent[2]) - end -end - --- Returns an array declarator indicating how many objects have been added. -function LinkTable:cdecl(objtype) - return self:csym(objtype, #self.obj_arrays[objtype]) -end - -function LinkTable:objs(objtype) - -- Return iterator function, allowing use as: - -- for obj in linktable:objs(type) do - -- -- ... - -- done - local array = self.obj_arrays[objtype] - local i = 0 - return function() - i = i + 1 - if array[i] then return array[i] end - end -end - -function LinkTable:empty(objtype) - return #self.obj_arrays[objtype] == 0 -end - ---[[ - - Dumper: an object that can dump C initializers for several constructs. - Uses a LinkTable to resolve references when necessary. - ---]] - -local Dumper = {} -function Dumper:new(linktab) - local obj = {linktab = linktab} - setmetatable(obj, {__index = Dumper}) -- Inheritance - return obj -end - --- Dumps a upb_tabval, eg: --- UPB_TABVALUE_INIT(5) -function Dumper:_value(val, upbtype) - if type(val) == "nil" then - return "UPB_TABVALUE_EMPTY_INIT" - elseif type(val) == "number" then - -- Use upbtype to disambiguate what kind of number it is. - if upbtype == upbtable.CTYPE_INT32 then - return string.format("UPB_TABVALUE_INT_INIT(%d)", val) - else - -- TODO(haberman): add support for these so we can properly support - -- default values. - error("Unsupported number type " .. upbtype) - end - elseif type(val) == "string" then - return string.format('UPB_TABVALUE_PTR_INIT("%s")', val) - else - -- We take this as an object reference that has an entry in the link table. - return string.format("UPB_TABVALUE_PTR_INIT(%s)", self.linktab:addr(val)) - end -end - --- Dumps a table key. -function Dumper:tabkey(key) - if type(key) == "nil" then - return "UPB_TABKEY_NONE" - elseif type(key) == "string" then - local len = #key - local len1 = c_escape(len % 256) - local len2 = c_escape(math.floor(len / 256) % 256) - local len3 = c_escape(math.floor(len / (256 * 256)) % 256) - local len4 = c_escape(math.floor(len / (256 * 256 * 256)) % 256) - return string.format('UPB_TABKEY_STR("%s", "%s", "%s", "%s", "%s")', - len1, len2, len3, len4, key) - else - return string.format("UPB_TABKEY_NUM(%d)", key) - end -end - --- Dumps a table entry. -function Dumper:tabent(ent) - local key = self:tabkey(ent.key) - local val = self:_value(ent.value, ent.valtype) - local next = self.linktab:addr(ent.next) - return string.format(' {%s, %s, %s},\n', key, val, next) -end - --- Dumps an inttable array entry. This is almost the same as value() above, --- except that nil values have a special value to indicate "empty". -function Dumper:arrayval(val) - if val.val then - return string.format(" %s,\n", self:_value(val.val, val.valtype)) - else - return " UPB_TABVALUE_EMPTY_INIT,\n" - end -end - --- Dumps an initializer for the given strtable/inttable (respectively). Its --- entries must have previously been added to the linktable. -function Dumper:strtable(t) - -- UPB_STRTABLE_INIT(count, mask, type, size_lg2, entries) - return string.format( - "UPB_STRTABLE_INIT(%d, %d, %s, %d, %s)", - t.count, t.mask, const(t, "ctype", upbtable) , t.size_lg2, - self.linktab:addr(t.entries[1].ptr)) -end - -function Dumper:inttable(t) - local lt = assert(self.linktab) - -- UPB_INTTABLE_INIT(count, mask, type, size_lg2, ent, a, asize, acount) - local entries = "NULL" - if #t.entries > 0 then - entries = lt:addr(t.entries[1].ptr) - end - return string.format( - "UPB_INTTABLE_INIT(%d, %d, %s, %d, %s, %s, %d, %d)", - t.count, t.mask, const(t, "ctype", upbtable), t.size_lg2, entries, - lt:addr(t.array[1].ptr), t.array_size, t.array_count) -end - --- A visitor for visiting all tables of a def. Used first to count entries --- and later to dump them. -local function gettables(def) - if def:def_type() == upb.DEF_MSG then - return {int = upbtable.msgdef_itof(def), str = upbtable.msgdef_ntof(def)} - elseif def:def_type() == upb.DEF_ENUM then - return {int = upbtable.enumdef_iton(def), str = upbtable.enumdef_ntoi(def)} - end -end - -local function emit_file_warning(filedef, append) - append('/* This file was generated by upbc (the upb compiler) from the input\n') - append(' * file:\n') - append(' *\n') - append(' * %s\n', filedef:name()) - append(' *\n') - append(' * Do not edit -- your changes will be discarded when the file is\n') - append(' * regenerated. */\n\n') -end - -local function join(...) - return table.concat({...}, ".") -end - -local function split(str) - local ret = {} - for word in string.gmatch(str, "%w+") do - table.insert(ret, word) - end - return ret -end - -local function to_cident(...) - return string.gsub(join(...), "[%./]", "_") -end - -local function to_preproc(...) - return string.upper(to_cident(...)) -end - --- Strips away last path element, ie: --- foo.Bar.Baz -> foo.Bar -local function remove_name(name) - local package_end = 0 - for i=1,string.len(name) do - if string.byte(name, i) == string.byte(".", 1) then - package_end = i - 1 - end - end - return string.sub(name, 1, package_end) -end - -local function start_namespace(package, append) - local package_components = split(package) - for _, component in ipairs(package_components) do - append("namespace %s {\n", component) - end -end - -local function end_namespace(package, append) - local package_components = split(package) - for i=#package_components,1,-1 do - append("} /* namespace %s */\n", package_components[i]) - end -end - -local function well_known_type(m) - local type_map = {} - type_map["google.protobuf.Duration"] = "UPB_WELLKNOWN_DURATION" - type_map["google.protobuf.Timestamp"] = "UPB_WELLKNOWN_TIMESTAMP" - type_map["google.protobuf.Value"] = "UPB_WELLKNOWN_VALUE" - type_map["google.protobuf.ListValue"] = "UPB_WELLKNOWN_LISTVALUE" - type_map["google.protobuf.Struct"] = "UPB_WELLKNOWN_STRUCT" - type_map["google.protobuf.DoubleValue"] = "UPB_WELLKNOWN_DOUBLEVALUE" - type_map["google.protobuf.FloatValue"] = "UPB_WELLKNOWN_FLOATVALUE" - type_map["google.protobuf.Int64Value"] = "UPB_WELLKNOWN_INT64VALUE" - type_map["google.protobuf.UInt64Value"] = "UPB_WELLKNOWN_UINT64VALUE" - type_map["google.protobuf.Int32Value"] = "UPB_WELLKNOWN_INT32VALUE" - type_map["google.protobuf.UInt32Value"] = "UPB_WELLKNOWN_UINT32VALUE" - type_map["google.protobuf.BoolValue"] = "UPB_WELLKNOWN_BOOLVALUE" - type_map["google.protobuf.StringValue"] = "UPB_WELLKNOWN_STRINGVALUE" - type_map["google.protobuf.BytesValue"] = "UPB_WELLKNOWN_BYTESVALUE" - local t = type_map[m:full_name()] - if (t == nil) then - t = "UPB_WELLKNOWN_UNSPECIFIED" - end - return t -end - ---[[ - - Top-level, exported dumper functions - ---]] - -local function dump_defs_c(filedef, append) - local defs = {} - for def in filedef:defs(upb.DEF_ANY) do - defs[#defs + 1] = def - if (def:def_type() == upb.DEF_MSG) then - for field in def:fields() do - defs[#defs + 1] = field - end - end - end - - -- Sort all defs by (type, name). - -- This gives us a linear ordering that we can use to create offsets into - -- shared arrays like REFTABLES, hash table entries, and arrays. - table.sort(defs, function(a, b) - if a:def_type() ~= b:def_type() then - return a:def_type() < b:def_type() - else - return a:full_name() < b:full_name() end - end - ) - - -- Perform pre-pass to build the link table. - local linktab = LinkTable:new{ - [upb.DEF_MSG] = "msgs", - [upb.DEF_FIELD] = "fields", - [upb.DEF_ENUM] = "enums", - intentries = "intentries", - strentries = "strentries", - arrays = "arrays", - } - local reftable_count = 0 - - for _, def in ipairs(defs) do - assert(def:is_frozen(), "can only dump frozen defs.") - linktab:add(def:def_type(), def) - reftable_count = reftable_count + 2 - local tables = gettables(def) - if tables then - for _, e in ipairs(tables.str.entries) do - linktab:add("strentries", e.ptr, e) - end - for _, e in ipairs(tables.int.entries) do - linktab:add("intentries", e.ptr, e) - end - for _, e in ipairs(tables.int.array) do - linktab:add("arrays", e.ptr, e) - end - end - end - - -- Emit forward declarations. - emit_file_warning(filedef, append) - append('#include "upb/def.h"\n') - append('#include "upb/structdefs.int.h"\n\n') - append("static const upb_msgdef %s;\n", linktab:cdecl(upb.DEF_MSG)) - append("static const upb_fielddef %s;\n", linktab:cdecl(upb.DEF_FIELD)) - if not linktab:empty(upb.DEF_ENUM) then - append("static const upb_enumdef %s;\n", linktab:cdecl(upb.DEF_ENUM)) - end - append("static const upb_tabent %s;\n", linktab:cdecl("strentries")) - if not linktab:empty("intentries") then - append("static const upb_tabent %s;\n", linktab:cdecl("intentries")) - end - append("static const upb_tabval %s;\n", linktab:cdecl("arrays")) - append("\n") - append("#ifdef UPB_DEBUG_REFS\n") - append("static upb_inttable reftables[%d];\n", reftable_count) - append("#endif\n") - append("\n") - - -- Emit defs. - local dumper = Dumper:new(linktab) - - local reftable = 0 - - append("static const upb_msgdef %s = {\n", linktab:cdecl(upb.DEF_MSG)) - for m in linktab:objs(upb.DEF_MSG) do - local tables = gettables(m) - -- UPB_MSGDEF_INIT(name, selector_count, submsg_field_count, itof, ntof, - -- refs, ref2s) - append(' UPB_MSGDEF_INIT("%s", %d, %d, %s, %s, %s, %s, %s,' .. - ' &reftables[%d], &reftables[%d]),\n', - m:full_name(), - upbtable.msgdef_selector_count(m), - upbtable.msgdef_submsg_field_count(m), - dumper:inttable(tables.int), - dumper:strtable(tables.str), - boolstr(m:_map_entry()), - const(m, "syntax"), - well_known_type(m), - reftable, reftable + 1) - reftable = reftable + 2 - end - append("};\n\n") - - append("static const upb_fielddef %s = {\n", linktab:cdecl(upb.DEF_FIELD)) - for f in linktab:objs(upb.DEF_FIELD) do - local subdef = "NULL" - if f:has_subdef() then - subdef = string.format("(const upb_def*)(%s)", linktab:addr(f:subdef())) - end - local intfmt - if f:type() == upb.TYPE_UINT32 or - f:type() == upb.TYPE_INT32 or - f:type() == upb.TYPE_UINT64 or - f:type() == upb.TYPE_INT64 then - intfmt = const(f, "intfmt") - else - intfmt = "0" - end - -- UPB_FIELDDEF_INIT(label, type, intfmt, tagdelim, is_extension, lazy, - -- packed, name, num, msgdef, subdef, selector_base, - -- index, -- default_value) - append(' UPB_FIELDDEF_INIT(%s, %s, %s, %s, %s, %s, %s, "%s", %d, %s, ' .. - '%s, %d, %d, {0},' .. -- TODO: support default value - '&reftables[%d], &reftables[%d]),\n', - const(f, "label"), const(f, "type"), intfmt, - boolstr(f:istagdelim()), boolstr(f:is_extension()), - boolstr(f:lazy()), boolstr(f:packed()), f:name(), f:number(), - linktab:addr(f:containing_type()), subdef, - upbtable.fielddef_selector_base(f), f:index(), - reftable, reftable + 1 - ) - reftable = reftable + 2 - end - append("};\n\n") - - if not linktab:empty(upb.DEF_ENUM) then - append("static const upb_enumdef %s = {\n", linktab:cdecl(upb.DEF_ENUM)) - for e in linktab:objs(upb.DEF_ENUM) do - local tables = gettables(e) - -- UPB_ENUMDEF_INIT(name, ntoi, iton, defaultval) - append(' UPB_ENUMDEF_INIT("%s", %s, %s, %d, ' .. - '&reftables[%d], &reftables[%d]),\n', - e:full_name(), - dumper:strtable(tables.str), - dumper:inttable(tables.int), - --e:default()) - 0, - reftable, reftable + 1) - reftable = reftable + 2 - end - append("};\n\n") - end - - append("static const upb_tabent %s = {\n", linktab:cdecl("strentries")) - for ent in linktab:objs("strentries") do - append(dumper:tabent(ent)) - end - append("};\n\n"); - - if not linktab:empty("intentries") then - append("static const upb_tabent %s = {\n", linktab:cdecl("intentries")) - for ent in linktab:objs("intentries") do - append(dumper:tabent(ent)) - end - append("};\n\n"); - end - - append("static const upb_tabval %s = {\n", linktab:cdecl("arrays")) - for ent in linktab:objs("arrays") do - append(dumper:arrayval(ent)) - end - append("};\n\n"); - - append("#ifdef UPB_DEBUG_REFS\n") - append("static upb_inttable reftables[%d] = {\n", reftable_count) - for i = 1,reftable_count do - append(" UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),\n") - end - append("};\n") - append("#endif\n\n") - - append("static const upb_msgdef *refm(const upb_msgdef *m, const void *owner) {\n") - append(" upb_msgdef_ref(m, owner);\n") - append(" return m;\n") - append("}\n\n") - append("static const upb_enumdef *refe(const upb_enumdef *e, const void *owner) {\n") - append(" upb_enumdef_ref(e, owner);\n") - append(" return e;\n") - append("}\n\n") - - append("/* Public API. */\n") - - for m in linktab:objs(upb.DEF_MSG) do - append("const upb_msgdef *upbdefs_%s_get(const void *owner)" .. - " { return refm(%s, owner); }\n", - to_cident(m:full_name()), linktab:addr(m)) - end - - append("\n") - - for e in linktab:objs(upb.DEF_ENUM) do - append("const upb_enumdef *upbdefs_%s_get(const void *owner)" .. - " { return refe(%s, owner); }\n", - to_cident(e:full_name()), linktab:addr(e)) - end - - return linktab -end - -local function dump_defs_for_type(format, defs, append) - local sorted = sorted_defs(defs) - for _, def in ipairs(sorted) do - append(format, to_cident(def:full_name()), def:full_name()) - end - - append("\n") -end - -local function make_children_map(file) - -- Maps file:package() or msg:full_name() -> children. - local map = {} - for def in file:defs(upb.DEF_ANY) do - local container = remove_name(def:full_name()) - if not map[container] then - map[container] = {} - end - table.insert(map[container], def) - end - - -- Sort all the lists for a consistent ordering. - for name, children in pairs(map) do - table.sort(children, function(a, b) return a:name() < b:name() end) - end - - return map -end - -local print_classes - -local function print_message(def, map, indent, append) - append("\n") - append("%sclass %s : public ::upb::reffed_ptr {\n", - indent, def:name()) - append("%s public:\n", indent) - append("%s %s(const ::upb::MessageDef* m, const void *ref_donor = NULL)\n", - indent, def:name()) - append("%s : reffed_ptr(m, ref_donor) {\n", indent) - append("%s UPB_ASSERT(upbdefs_%s_is(m));\n", indent, to_cident(def:full_name())) - append("%s }\n", indent) - append("\n") - append("%s static %s get() {\n", indent, def:name()) - append("%s const ::upb::MessageDef* m = upbdefs_%s_get(&m);\n", indent, to_cident(def:full_name())) - append("%s return %s(m, &m);\n", indent, def:name()) - append("%s }\n", indent) - -- TODO(haberman): add fields - print_classes(def:full_name(), map, indent .. " ", append) - append("%s};\n", indent) -end - -local function print_enum(def, indent, append) - append("\n") - append("%sclass %s : public ::upb::reffed_ptr {\n", - indent, def:name()) - append("%s public:\n", indent) - append("%s %s(const ::upb::EnumDef* e, const void *ref_donor = NULL)\n", - indent, def:name()) - append("%s : reffed_ptr(e, ref_donor) {\n", indent) - append("%s UPB_ASSERT(upbdefs_%s_is(e));\n", indent, to_cident(def:full_name())) - append("%s }\n", indent) - append("%s static %s get() {\n", indent, def:name()) - append("%s const ::upb::EnumDef* e = upbdefs_%s_get(&e);\n", indent, to_cident(def:full_name())) - append("%s return %s(e, &e);\n", indent, def:name()) - append("%s }\n", indent) - append("%s};\n", indent) -end - -function print_classes(name, map, indent, append) - if not map[name] then - return - end - - for _, def in ipairs(map[name]) do - if def:def_type() == upb.DEF_MSG then - print_message(def, map, indent, append) - elseif def:def_type() == upb.DEF_ENUM then - print_enum(def, indent, append) - else - error("Unknown def type for " .. def:full_name()) - end - end -end - -local function dump_defs_h(file, append, linktab) - local basename_preproc = to_preproc(file:name()) - append("/* This file contains accessors for a set of compiled-in defs.\n") - append(" * Note that unlike Google's protobuf, it does *not* define\n") - append(" * generated classes or any other kind of data structure for\n") - append(" * actually storing protobufs. It only contains *defs* which\n") - append(" * let you reflect over a protobuf *schema*.\n") - append(" */\n") - emit_file_warning(file, append) - append('#ifndef %s_UPB_H_\n', basename_preproc) - append('#define %s_UPB_H_\n\n', basename_preproc) - append('#include "upb/def.h"\n\n') - append('UPB_BEGIN_EXTERN_C\n\n') - - -- Dump C enums for proto enums. - - append("/* MessageDefs: call these functions to get a ref to a msgdef. */\n") - dump_defs_for_type( - "const upb_msgdef *upbdefs_%s_get(const void *owner);\n", - file:defs(upb.DEF_MSG), append) - - append("/* EnumDefs: call these functions to get a ref to an enumdef. */\n") - dump_defs_for_type( - "const upb_enumdef *upbdefs_%s_get(const void *owner);\n", - file:defs(upb.DEF_ENUM), append) - - append("/* Functions to test whether this message is of a certain type. */\n") - dump_defs_for_type( - "UPB_INLINE bool upbdefs_%s_is(const upb_msgdef *m) {\n" .. - " return strcmp(upb_msgdef_fullname(m), \"%s\") == 0;\n}\n", - file:defs(upb.DEF_MSG), append) - - append("/* Functions to test whether this enum is of a certain type. */\n") - dump_defs_for_type( - "UPB_INLINE bool upbdefs_%s_is(const upb_enumdef *e) {\n" .. - " return strcmp(upb_enumdef_fullname(e), \"%s\") == 0;\n}\n", - file:defs(upb.DEF_ENUM), append) - - append("\n") - - -- fields - local fields = {} - - for f in linktab:objs(upb.DEF_FIELD) do - local symname = f:containing_type():full_name() .. "." .. f:name() - fields[#fields + 1] = {to_cident(symname), f} - end - - table.sort(fields, function(a, b) return a[1] < b[1] end) - - append("/* Functions to get a fielddef from a msgdef reference. */\n") - for _, field in ipairs(fields) do - local f = field[2] - local msg_cident = to_cident(f:containing_type():full_name()) - local field_cident = to_cident(f:name()) - append("UPB_INLINE const upb_fielddef *upbdefs_%s_f_%s(const upb_msgdef *m) {" .. - " UPB_ASSERT(upbdefs_%s_is(m));" .. - " return upb_msgdef_itof(m, %d); }\n", - msg_cident, field_cident, msg_cident, f:number()) - end - - append('\nUPB_END_EXTERN_C\n\n') - - -- C++ wrappers. - local children_map = make_children_map(file) - - append("#ifdef __cplusplus\n\n") - append("namespace upbdefs {\n") - start_namespace(file:package(), append) - print_classes(file:package(), children_map, "", append) - append("\n") - end_namespace(file:package(), append) - append("} /* namespace upbdefs */\n\n") - append("#endif /* __cplusplus */\n") - - append("\n") - append('#endif /* %s_UPB_H_ */\n', basename_preproc) -end - -function export.dump_defs(filedef, append_h, append_c) - local linktab = dump_defs_c(filedef, append_c) - dump_defs_h(filedef, append_h, linktab) -end - -return export diff --git a/tools/make_cmakelists.py b/tools/make_cmakelists.py index b8f46b9..2b426b5 100755 --- a/tools/make_cmakelists.py +++ b/tools/make_cmakelists.py @@ -120,6 +120,9 @@ class BuildFileFunctions(object): def upb_proto_library(self, **kwargs): pass + def upb_proto_reflection_library(self, **kwargs): + pass + def genrule(self, **kwargs): pass diff --git a/tools/upbc.lua b/tools/upbc.lua deleted file mode 100644 index 80d2886..0000000 --- a/tools/upbc.lua +++ /dev/null @@ -1,91 +0,0 @@ ---[[ - - The upb compiler. It can write two different kinds of output - files: - - - generated code for a C API (foo.upb.h, foo.upb.c) - - (obsolete): definitions of upb defs. (foo.upbdefs.h, foo.upbdefs.c) - ---]] - -local dump_cinit = require "dump_cinit" -local upb = require "upb" - -local generate_upbdefs = false -local outdir = "." - -i = 1 -while i <= #arg do - argument = arg[i] - if argument.sub(argument, 1, 2) == "--" then - if argument == "--generate-upbdefs" then - generate_upbdefs = true - elseif argument == "--outdir" then - i = i + 1 - outdir = arg[i] - else - print("Unknown flag: " .. argument) - return 1 - end - else - if src then - print("upbc can only handle one input file at a time.") - return 1 - end - src = argument - end - i = i + 1 -end - -if not src then - print("Usage: upbc [--generate-upbdefs] ") - return 1 -end - -function strip_proto(filename) - return string.gsub(filename, '%.proto$','') -end - -local function open(filename) - local full_name = outdir .. "/" .. filename - return assert(io.open(full_name, "w"), "couldn't open " .. full_name) -end - --- Open input/output files. -local f = assert(io.open(src, "r"), "couldn't open input file " .. src) -local descriptor = f:read("*all") -local files = upb.load_descriptor(descriptor) -local symtab = upb.SymbolTable() - -for _, file in ipairs(files) do - symtab:add_file(file) - local outbase = strip_proto(file:name()) - - -- Write upbdefs. - - local hfilename = outbase .. ".upbdefs.h" - local cfilename = outbase .. ".upbdefs.c" - - if os.getenv("UPBC_VERBOSE") then - print("upbc:") - print(string.format(" source file=%s", src)) - print(string.format(" output file base=%s", outbase)) - print(string.format(" hfilename=%s", hfilename)) - print(string.format(" cfilename=%s", cfilename)) - end - - os.execute(string.format("mkdir -p `dirname %s`", outbase)) - - assert(generate_upbdefs) - -- Legacy generated defs. - local hfile = open(hfilename) - local cfile = open(cfilename) - - local happend = dump_cinit.file_appender(hfile) - local cappend = dump_cinit.file_appender(cfile) - - dump_cinit.dump_defs(file, happend, cappend) - - hfile:close() - cfile:close() -end diff --git a/upb/def.c b/upb/def.c index ba6de50..047684e 100644 --- a/upb/def.c +++ b/upb/def.c @@ -643,7 +643,7 @@ uint32_t upb_msgdef_submsgfieldcount(const upb_msgdef *m) { const upb_fielddef *upb_msgdef_itof(const upb_msgdef *m, uint32_t i) { upb_value val; return upb_inttable_lookup32(&m->itof, i, &val) ? - upb_value_getptr(val) : NULL; + upb_value_getconstptr(val) : NULL; } const upb_fielddef *upb_msgdef_ntof(const upb_msgdef *m, const char *name, @@ -1128,12 +1128,14 @@ static bool create_fielddef( if (m) { /* direct message field. */ + upb_value v, packed_v; + f = (upb_fielddef*)&m->fields[m->field_count++]; f->msgdef = m; f->is_extension_ = false; - upb_value packed_v = pack_def(f, UPB_DEFTYPE_FIELD); - upb_value v = upb_value_constptr(f); + packed_v = pack_def(f, UPB_DEFTYPE_FIELD); + v = upb_value_constptr(f); if (!upb_strtable_insert3(&m->ntof, name.data, name.size, packed_v, alloc)) { upb_status_seterrf(ctx->status, "duplicate field name (%s)", shortname); @@ -1580,5 +1582,48 @@ bool upb_symtab_addfile(upb_symtab *s, return ok; } +/* Include here since we want most of this file to be stdio-free. */ +#include + +bool _upb_symtab_loaddefinit(upb_symtab *s, const upb_def_init *init) { + /* Since this function should never fail (it would indicate a bug in upb) we + * print errors to stderr instead of returning error status to the user. */ + upb_def_init **deps = init->deps; + google_protobuf_FileDescriptorProto *file; + upb_arena arena; + upb_status status = UPB_STATUS_INIT; + + if (upb_strtable_lookup(&s->files, init->filename, NULL)) { + return true; + } + + for (; *deps; deps++) { + if (!_upb_symtab_loaddefinit(s, *deps)) goto err; + } + + upb_arena_init(&arena); + file = google_protobuf_FileDescriptorProto_parsenew(init->descriptor, &arena); + + if (!file) { + upb_status_seterrf( + &status, + "Failed to parse compiled-in descriptor for file '%s'. This should " + "never happen.", + init->filename); + goto err; + } + + if (!upb_symtab_addfile(s, file, &status)) goto err; + + upb_arena_uninit(&arena); + return true; + +err: + fprintf(stderr, "Error loading compiled-in descriptor: %s\n", + upb_status_errmsg(&status)); + upb_arena_uninit(&arena); + return false; +} + #undef CHK #undef CHK_OOM diff --git a/upb/def.h b/upb/def.h index 4fe6d04..e6fdf21 100644 --- a/upb/def.h +++ b/upb/def.h @@ -659,7 +659,6 @@ 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 #ifdef __cplusplus @@ -707,6 +706,15 @@ bool upb_symtab_addfile(upb_symtab *s, const google_protobuf_FileDescriptorProto* file, upb_status *status); +/* For generated code only: loads a generated descriptor. */ +typedef struct upb_def_init { + struct upb_def_init **deps; + const char *filename; + upb_stringview descriptor; +} upb_def_init; + +bool _upb_symtab_loaddefinit(upb_symtab *s, const upb_def_init *init); + UPB_END_EXTERN_C #ifdef __cplusplus diff --git a/upb/upb.h b/upb/upb.h index 020022b..2fb7a88 100644 --- a/upb/upb.h +++ b/upb/upb.h @@ -463,7 +463,6 @@ struct upb_alloc { UPB_INLINE void *upb_malloc(upb_alloc *alloc, size_t size) { UPB_ASSERT(alloc); - UPB_ASSERT(size < 65535); return alloc->func(alloc, NULL, 0, size); } diff --git a/upbc/generator.cc b/upbc/generator.cc index 68996a9..3b4f6ac 100644 --- a/upbc/generator.cc +++ b/upbc/generator.cc @@ -8,6 +8,7 @@ #include "absl/strings/substitute.h" #include "google/protobuf/compiler/code_generator.h" #include "google/protobuf/descriptor.h" +#include "google/protobuf/descriptor.pb.h" #include "google/protobuf/io/zero_copy_stream.h" #include "upbc/generator.h" @@ -32,6 +33,14 @@ static std::string SourceFilename(std::string proto_filename) { return StripExtension(proto_filename) + ".upb.c"; } +static std::string DefHeaderFilename(std::string proto_filename) { + return StripExtension(proto_filename) + ".upbdefs.h"; +} + +static std::string DefSourceFilename(std::string proto_filename) { + return StripExtension(proto_filename) + ".upbdefs.c"; +} + class Output { public: Output(protobuf::io::ZeroCopyOutputStream* stream) : stream_(stream) {} @@ -165,6 +174,10 @@ std::string ToCIdent(absl::string_view str) { return absl::StrReplaceAll(str, {{".", "_"}, {"/", "_"}}); } +std::string DefInitSymbol(const protobuf::FileDescriptor *file) { + return ToCIdent(file->name()) + "_upbdefinit"; +} + std::string ToPreproc(absl::string_view str) { return absl::AsciiStrToUpper(ToCIdent(str)); } @@ -558,6 +571,91 @@ void WriteSource(const protobuf::FileDescriptor* file, Output& output) { output("\n"); } +void GenerateMessageDefAccessor(const protobuf::Descriptor* d, Output& output) { + output("UPB_INLINE const upb_msgdef *$0_getmsgdef(upb_symtab *s) {\n", + ToCIdent(d->full_name())); + output(" _upb_symtab_loaddefinit(s, &$0);\n", DefInitSymbol(d->file())); + output(" return upb_symtab_lookupmsg(s, \"$0\");\n", d->full_name()); + output("}\n"); + output("\n"); + + for (int i = 0; i < d->nested_type_count(); i++) { + GenerateMessageDefAccessor(d->nested_type(i), output); + } +} + +void WriteDefHeader(const protobuf::FileDescriptor* file, Output& output) { + EmitFileWarning(file, output); + + output("extern upb_def_init $0;\n", DefInitSymbol(file)); + + for (int i = 0; i < file->message_type_count(); i++) { + GenerateMessageDefAccessor(file->message_type(i), output); + } +} + +// Escape C++ trigraphs by escaping question marks to \? +std::string EscapeTrigraphs(absl::string_view to_escape) { + return absl::StrReplaceAll(to_escape, {{"?", "\\?"}}); +} + +void WriteDefSource(const protobuf::FileDescriptor* file, Output& output) { + EmitFileWarning(file, output); + + output("#include \"upb/def.h\"\n"); + output("\n"); + + for (int i = 0; i < file->dependency_count(); i++) { + output("extern upb_def_init $0;\n", DefInitSymbol(file->dependency(i))); + } + + protobuf::FileDescriptorProto file_proto; + file->CopyTo(&file_proto); + std::string file_data; + file_proto.SerializeToString(&file_data); + + output("static const char descriptor[$0] =\n", file_data.size()); + + { + if (file_data.size() > 65535) { + // Workaround for MSVC: "Error C1091: compiler limit: string exceeds + // 65535 bytes in length". Declare a static array of chars rather than + // use a string literal. Only write 25 bytes per line. + static const int kBytesPerLine = 25; + output("{ "); + for (int i = 0; i < file_data.size();) { + for (int j = 0; j < kBytesPerLine && i < file_data.size(); ++i, ++j) { + output("'$0', ", absl::CEscape(file_data.substr(i, 1))); + } + output("\n"); + } + output("'\\0' }"); // null-terminate + } else { + // Only write 40 bytes per line. + static const int kBytesPerLine = 40; + for (int i = 0; i < file_data.size(); i += kBytesPerLine) { + output( + "\"$0\"\n", + EscapeTrigraphs(absl::CEscape(file_data.substr(i, kBytesPerLine)))); + } + } + output(";\n"); + } + + output("static upb_def_init *deps[$0] = {\n", file->dependency_count() + 1); + for (int i = 0; i < file->dependency_count(); i++) { + output(" $0,\n", DefInitSymbol(file->dependency(i))); + } + output(" NULL\n"); + output("};\n"); + + output("upb_def_init $0 = {\n", DefInitSymbol(file)); + output(" deps,\n"); + output(" \"$0\",\n", file->name()); + output(" UPB_STRINGVIEW_INIT(descriptor, $0)\n", file_data.size()); + output("};\n"); +} + bool Generator::Generate(const protobuf::FileDescriptor* file, const std::string& parameter, protoc::GeneratorContext* context, @@ -568,6 +666,12 @@ bool Generator::Generate(const protobuf::FileDescriptor* file, Output c_output(context->Open(SourceFilename(file->name()))); WriteSource(file, c_output); + Output h_def_output(context->Open(DefHeaderFilename(file->name()))); + WriteDefHeader(file, h_def_output); + + Output c_def_output(context->Open(DefSourceFilename(file->name()))); + WriteDefSource(file, c_def_output); + return true; } -- cgit v1.2.3 From 5e958a8c055872ecd5b7f7d00f48212de5711ae5 Mon Sep 17 00:00:00 2001 From: Josh Haberman Date: Mon, 17 Dec 2018 09:16:46 -0800 Subject: test_json is working! --- BUILD | 21 +++- CMakeLists.txt | 1 + tests/json/test.upbdefs.c | 313 ---------------------------------------------- tests/json/test.upbdefs.h | 238 ----------------------------------- tests/json/test_json.cc | 13 +- tests/test_handlers.c | 11 +- upb/def.c | 2 +- upbc/generator.cc | 14 ++- 8 files changed, 44 insertions(+), 569 deletions(-) delete mode 100644 tests/json/test.upbdefs.c delete mode 100644 tests/json/test.upbdefs.h (limited to 'upb/def.c') diff --git a/BUILD b/BUILD index b3f397a..0f4231a 100644 --- a/BUILD +++ b/BUILD @@ -159,10 +159,17 @@ cc_test( ], ) +upb_proto_reflection_library( + name = "descriptor_upbproto", + deps = ["descriptor_proto"], + upbc = ":protoc-gen-upb", +) + cc_test( name = "test_handlers", srcs = ["tests/test_handlers.c"], deps = [ + ":descriptor_upbproto", ":upb_pb", ":upb_test", ], @@ -221,14 +228,24 @@ cc_test( ], ) +proto_library( + name = "test_json_proto", + srcs = ["tests/json/test.proto"], +) + +upb_proto_reflection_library( + name = "test_json_upbproto", + deps = ["test_json_proto"], + upbc = ":protoc-gen-upb", +) + cc_test( name = "test_json", srcs = [ - "tests/json/test.upbdefs.c", - "tests/json/test.upbdefs.h", "tests/json/test_json.cc", ], deps = [ + ":test_json_upbproto", ":upb_json", ":upb_test", ], diff --git a/CMakeLists.txt b/CMakeLists.txt index 3439aac..54dcf24 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -125,6 +125,7 @@ add_executable(test_handlers tests/test_handlers.c) add_test(NAME test_handlers COMMAND test_handlers) target_link_libraries(test_handlers + descriptor_upbproto upb_pb upb_test) add_executable(test_decoder diff --git a/tests/json/test.upbdefs.c b/tests/json/test.upbdefs.c deleted file mode 100644 index 933fe5f..0000000 --- a/tests/json/test.upbdefs.c +++ /dev/null @@ -1,313 +0,0 @@ -/* This file was generated by upbc (the upb compiler) from the input - * file: - * - * tests/json/test.proto - * - * Do not edit -- your changes will be discarded when the file is - * regenerated. */ - -#include "upb/def.h" -#include "upb/structdefs.int.h" - -static const upb_msgdef msgs[8]; -static const upb_fielddef fields[37]; -static const upb_enumdef enums[1]; -static const upb_tabent strentries[64]; -static const upb_tabval arrays[49]; - -#ifdef UPB_DEBUG_REFS -static upb_inttable reftables[92]; -#endif - -static const upb_msgdef msgs[8] = { - UPB_MSGDEF_INIT("upb.test.json.SubMessage", 4, 0, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[0], 2, 1), UPB_STRTABLE_INIT(1, 3, UPB_CTYPE_PTR, 2, &strentries[0]), false, UPB_SYNTAX_PROTO3, UPB_WELLKNOWN_UNSPECIFIED, &reftables[0], &reftables[1]), - UPB_MSGDEF_INIT("upb.test.json.TestMessage", 73, 8, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[2], 26, 24), UPB_STRTABLE_INIT(24, 31, UPB_CTYPE_PTR, 5, &strentries[4]), false, UPB_SYNTAX_PROTO3, UPB_WELLKNOWN_UNSPECIFIED, &reftables[2], &reftables[3]), - UPB_MSGDEF_INIT("upb.test.json.TestMessage.MapBoolStringEntry", 7, 0, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[28], 3, 2), UPB_STRTABLE_INIT(2, 3, UPB_CTYPE_PTR, 2, &strentries[36]), true, UPB_SYNTAX_PROTO3, UPB_WELLKNOWN_UNSPECIFIED, &reftables[4], &reftables[5]), - UPB_MSGDEF_INIT("upb.test.json.TestMessage.MapInt32StringEntry", 7, 0, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[31], 3, 2), UPB_STRTABLE_INIT(2, 3, UPB_CTYPE_PTR, 2, &strentries[40]), true, UPB_SYNTAX_PROTO3, UPB_WELLKNOWN_UNSPECIFIED, &reftables[6], &reftables[7]), - UPB_MSGDEF_INIT("upb.test.json.TestMessage.MapStringBoolEntry", 7, 0, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[34], 3, 2), UPB_STRTABLE_INIT(2, 3, UPB_CTYPE_PTR, 2, &strentries[44]), true, UPB_SYNTAX_PROTO3, UPB_WELLKNOWN_UNSPECIFIED, &reftables[8], &reftables[9]), - UPB_MSGDEF_INIT("upb.test.json.TestMessage.MapStringInt32Entry", 7, 0, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[37], 3, 2), UPB_STRTABLE_INIT(2, 3, UPB_CTYPE_PTR, 2, &strentries[48]), true, UPB_SYNTAX_PROTO3, UPB_WELLKNOWN_UNSPECIFIED, &reftables[10], &reftables[11]), - UPB_MSGDEF_INIT("upb.test.json.TestMessage.MapStringMsgEntry", 8, 1, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[40], 3, 2), UPB_STRTABLE_INIT(2, 3, UPB_CTYPE_PTR, 2, &strentries[52]), true, UPB_SYNTAX_PROTO3, UPB_WELLKNOWN_UNSPECIFIED, &reftables[12], &reftables[13]), - UPB_MSGDEF_INIT("upb.test.json.TestMessage.MapStringStringEntry", 9, 0, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[43], 3, 2), UPB_STRTABLE_INIT(2, 3, UPB_CTYPE_PTR, 2, &strentries[56]), true, UPB_SYNTAX_PROTO3, UPB_WELLKNOWN_UNSPECIFIED, &reftables[14], &reftables[15]), -}; - -static const upb_fielddef fields[37] = { - UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_INT32, UPB_INTFMT_VARIABLE, false, false, false, false, "foo", 1, &msgs[0], NULL, 3, 0, {0},&reftables[16], &reftables[17]), - UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "key", 1, &msgs[7], NULL, 3, 0, {0},&reftables[18], &reftables[19]), - UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_INT32, UPB_INTFMT_VARIABLE, false, false, false, false, "key", 1, &msgs[3], NULL, 3, 0, {0},&reftables[20], &reftables[21]), - UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "key", 1, &msgs[2], NULL, 3, 0, {0},&reftables[22], &reftables[23]), - UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "key", 1, &msgs[5], NULL, 3, 0, {0},&reftables[24], &reftables[25]), - UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "key", 1, &msgs[4], NULL, 3, 0, {0},&reftables[26], &reftables[27]), - UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "key", 1, &msgs[6], NULL, 5, 1, {0},&reftables[28], &reftables[29]), - UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "map_bool_string", 22, &msgs[1], (const upb_def*)(&msgs[2]), 23, 4, {0},&reftables[30], &reftables[31]), - UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "map_int32_string", 21, &msgs[1], (const upb_def*)(&msgs[3]), 20, 3, {0},&reftables[32], &reftables[33]), - UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "map_string_bool", 24, &msgs[1], (const upb_def*)(&msgs[4]), 29, 6, {0},&reftables[34], &reftables[35]), - UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "map_string_int32", 23, &msgs[1], (const upb_def*)(&msgs[5]), 26, 5, {0},&reftables[36], &reftables[37]), - UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "map_string_msg", 25, &msgs[1], (const upb_def*)(&msgs[6]), 32, 7, {0},&reftables[38], &reftables[39]), - UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "map_string_string", 20, &msgs[1], (const upb_def*)(&msgs[7]), 17, 2, {0},&reftables[40], &reftables[41]), - UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "optional_bool", 7, &msgs[1], NULL, 43, 14, {0},&reftables[42], &reftables[43]), - UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BYTES, 0, false, false, false, false, "optional_bytes", 6, &msgs[1], NULL, 40, 13, {0},&reftables[44], &reftables[45]), - UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_ENUM, 0, false, false, false, false, "optional_enum", 9, &msgs[1], (const upb_def*)(&enums[0]), 44, 15, {0},&reftables[46], &reftables[47]), - UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_INT32, UPB_INTFMT_VARIABLE, false, false, false, false, "optional_int32", 1, &msgs[1], NULL, 33, 8, {0},&reftables[48], &reftables[49]), - UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_INT64, UPB_INTFMT_VARIABLE, false, false, false, false, "optional_int64", 2, &msgs[1], NULL, 34, 9, {0},&reftables[50], &reftables[51]), - UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_MESSAGE, 0, false, false, false, false, "optional_msg", 8, &msgs[1], (const upb_def*)(&msgs[0]), 11, 0, {0},&reftables[52], &reftables[53]), - UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "optional_string", 5, &msgs[1], NULL, 37, 12, {0},&reftables[54], &reftables[55]), - UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_INT32, UPB_INTFMT_VARIABLE, false, false, false, false, "optional_uint32", 3, &msgs[1], NULL, 35, 10, {0},&reftables[56], &reftables[57]), - UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_INT64, UPB_INTFMT_VARIABLE, false, false, false, false, "optional_uint64", 4, &msgs[1], NULL, 36, 11, {0},&reftables[58], &reftables[59]), - UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_BOOL, 0, false, false, false, false, "repeated_bool", 17, &msgs[1], NULL, 69, 22, {0},&reftables[60], &reftables[61]), - UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_BYTES, 0, false, false, false, false, "repeated_bytes", 16, &msgs[1], NULL, 64, 21, {0},&reftables[62], &reftables[63]), - UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_ENUM, 0, false, false, false, false, "repeated_enum", 19, &msgs[1], (const upb_def*)(&enums[0]), 72, 23, {0},&reftables[64], &reftables[65]), - UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_INT32, UPB_INTFMT_VARIABLE, false, false, false, false, "repeated_int32", 11, &msgs[1], NULL, 47, 16, {0},&reftables[66], &reftables[67]), - UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_INT64, UPB_INTFMT_VARIABLE, false, false, false, false, "repeated_int64", 12, &msgs[1], NULL, 50, 17, {0},&reftables[68], &reftables[69]), - UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "repeated_msg", 18, &msgs[1], (const upb_def*)(&msgs[0]), 14, 1, {0},&reftables[70], &reftables[71]), - UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_STRING, 0, false, false, false, false, "repeated_string", 15, &msgs[1], NULL, 59, 20, {0},&reftables[72], &reftables[73]), - UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_UINT32, UPB_INTFMT_VARIABLE, false, false, false, false, "repeated_uint32", 13, &msgs[1], NULL, 53, 18, {0},&reftables[74], &reftables[75]), - UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_UINT64, UPB_INTFMT_VARIABLE, false, false, false, false, "repeated_uint64", 14, &msgs[1], NULL, 56, 19, {0},&reftables[76], &reftables[77]), - UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_MESSAGE, 0, false, false, false, false, "value", 2, &msgs[6], (const upb_def*)(&msgs[0]), 4, 0, {0},&reftables[78], &reftables[79]), - UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "value", 2, &msgs[7], NULL, 6, 1, {0},&reftables[80], &reftables[81]), - UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_INT32, UPB_INTFMT_VARIABLE, false, false, false, false, "value", 2, &msgs[5], NULL, 6, 1, {0},&reftables[82], &reftables[83]), - UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "value", 2, &msgs[2], NULL, 4, 1, {0},&reftables[84], &reftables[85]), - UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "value", 2, &msgs[4], NULL, 6, 1, {0},&reftables[86], &reftables[87]), - UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "value", 2, &msgs[3], NULL, 4, 1, {0},&reftables[88], &reftables[89]), -}; - -static const upb_enumdef enums[1] = { - UPB_ENUMDEF_INIT("upb.test.json.MyEnum", UPB_STRTABLE_INIT(3, 3, UPB_CTYPE_INT32, 2, &strentries[60]), UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_CSTR, 0, NULL, &arrays[46], 3, 3), 0, &reftables[90], &reftables[91]), -}; - -static const upb_tabent strentries[64] = { - {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, - {UPB_TABKEY_STR("\003", "\000", "\000", "\000", "foo"), UPB_TABVALUE_PTR_INIT(&fields[0]), NULL}, - {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, - {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, - {UPB_TABKEY_STR("\015", "\000", "\000", "\000", "repeated_enum"), UPB_TABVALUE_PTR_INIT(&fields[24]), NULL}, - {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, - {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, - {UPB_TABKEY_STR("\015", "\000", "\000", "\000", "optional_enum"), UPB_TABVALUE_PTR_INIT(&fields[15]), &strentries[31]}, - {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, - {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, - {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, - {UPB_TABKEY_STR("\016", "\000", "\000", "\000", "optional_int32"), UPB_TABVALUE_PTR_INIT(&fields[16]), NULL}, - {UPB_TABKEY_STR("\015", "\000", "\000", "\000", "repeated_bool"), UPB_TABVALUE_PTR_INIT(&fields[22]), NULL}, - {UPB_TABKEY_STR("\016", "\000", "\000", "\000", "repeated_bytes"), UPB_TABVALUE_PTR_INIT(&fields[23]), NULL}, - {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, - {UPB_TABKEY_STR("\016", "\000", "\000", "\000", "optional_int64"), UPB_TABVALUE_PTR_INIT(&fields[17]), NULL}, - {UPB_TABKEY_STR("\017", "\000", "\000", "\000", "optional_string"), UPB_TABVALUE_PTR_INIT(&fields[19]), NULL}, - {UPB_TABKEY_STR("\015", "\000", "\000", "\000", "optional_bool"), UPB_TABVALUE_PTR_INIT(&fields[13]), &strentries[30]}, - {UPB_TABKEY_STR("\020", "\000", "\000", "\000", "map_int32_string"), UPB_TABVALUE_PTR_INIT(&fields[8]), NULL}, - {UPB_TABKEY_STR("\016", "\000", "\000", "\000", "optional_bytes"), UPB_TABVALUE_PTR_INIT(&fields[14]), NULL}, - {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, - {UPB_TABKEY_STR("\014", "\000", "\000", "\000", "optional_msg"), UPB_TABVALUE_PTR_INIT(&fields[18]), NULL}, - {UPB_TABKEY_STR("\016", "\000", "\000", "\000", "repeated_int32"), UPB_TABVALUE_PTR_INIT(&fields[25]), &strentries[35]}, - {UPB_TABKEY_STR("\017", "\000", "\000", "\000", "repeated_uint32"), UPB_TABVALUE_PTR_INIT(&fields[29]), NULL}, - {UPB_TABKEY_STR("\017", "\000", "\000", "\000", "map_bool_string"), UPB_TABVALUE_PTR_INIT(&fields[7]), NULL}, - {UPB_TABKEY_STR("\017", "\000", "\000", "\000", "optional_uint64"), UPB_TABVALUE_PTR_INIT(&fields[21]), NULL}, - {UPB_TABKEY_STR("\017", "\000", "\000", "\000", "optional_uint32"), UPB_TABVALUE_PTR_INIT(&fields[20]), &strentries[32]}, - {UPB_TABKEY_STR("\017", "\000", "\000", "\000", "map_string_bool"), UPB_TABVALUE_PTR_INIT(&fields[9]), NULL}, - {UPB_TABKEY_STR("\016", "\000", "\000", "\000", "repeated_int64"), UPB_TABVALUE_PTR_INIT(&fields[26]), &strentries[34]}, - {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, - {UPB_TABKEY_STR("\016", "\000", "\000", "\000", "map_string_msg"), UPB_TABVALUE_PTR_INIT(&fields[11]), NULL}, - {UPB_TABKEY_STR("\020", "\000", "\000", "\000", "map_string_int32"), UPB_TABVALUE_PTR_INIT(&fields[10]), NULL}, - {UPB_TABKEY_STR("\021", "\000", "\000", "\000", "map_string_string"), UPB_TABVALUE_PTR_INIT(&fields[12]), NULL}, - {UPB_TABKEY_STR("\017", "\000", "\000", "\000", "repeated_uint64"), UPB_TABVALUE_PTR_INIT(&fields[30]), NULL}, - {UPB_TABKEY_STR("\014", "\000", "\000", "\000", "repeated_msg"), UPB_TABVALUE_PTR_INIT(&fields[27]), NULL}, - {UPB_TABKEY_STR("\017", "\000", "\000", "\000", "repeated_string"), UPB_TABVALUE_PTR_INIT(&fields[28]), NULL}, - {UPB_TABKEY_STR("\003", "\000", "\000", "\000", "key"), UPB_TABVALUE_PTR_INIT(&fields[3]), NULL}, - {UPB_TABKEY_STR("\005", "\000", "\000", "\000", "value"), UPB_TABVALUE_PTR_INIT(&fields[34]), NULL}, - {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, - {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, - {UPB_TABKEY_STR("\003", "\000", "\000", "\000", "key"), UPB_TABVALUE_PTR_INIT(&fields[2]), NULL}, - {UPB_TABKEY_STR("\005", "\000", "\000", "\000", "value"), UPB_TABVALUE_PTR_INIT(&fields[36]), NULL}, - {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, - {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, - {UPB_TABKEY_STR("\003", "\000", "\000", "\000", "key"), UPB_TABVALUE_PTR_INIT(&fields[5]), NULL}, - {UPB_TABKEY_STR("\005", "\000", "\000", "\000", "value"), UPB_TABVALUE_PTR_INIT(&fields[35]), NULL}, - {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, - {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, - {UPB_TABKEY_STR("\003", "\000", "\000", "\000", "key"), UPB_TABVALUE_PTR_INIT(&fields[4]), NULL}, - {UPB_TABKEY_STR("\005", "\000", "\000", "\000", "value"), UPB_TABVALUE_PTR_INIT(&fields[33]), NULL}, - {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, - {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, - {UPB_TABKEY_STR("\003", "\000", "\000", "\000", "key"), UPB_TABVALUE_PTR_INIT(&fields[6]), NULL}, - {UPB_TABKEY_STR("\005", "\000", "\000", "\000", "value"), UPB_TABVALUE_PTR_INIT(&fields[31]), NULL}, - {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, - {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, - {UPB_TABKEY_STR("\003", "\000", "\000", "\000", "key"), UPB_TABVALUE_PTR_INIT(&fields[1]), NULL}, - {UPB_TABKEY_STR("\005", "\000", "\000", "\000", "value"), UPB_TABVALUE_PTR_INIT(&fields[32]), NULL}, - {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, - {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, - {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, - {UPB_TABKEY_STR("\001", "\000", "\000", "\000", "A"), UPB_TABVALUE_INT_INIT(0), NULL}, - {UPB_TABKEY_STR("\001", "\000", "\000", "\000", "B"), UPB_TABVALUE_INT_INIT(1), &strentries[63]}, - {UPB_TABKEY_STR("\001", "\000", "\000", "\000", "C"), UPB_TABVALUE_INT_INIT(2), NULL}, -}; - -static const upb_tabval arrays[49] = { - UPB_TABVALUE_EMPTY_INIT, - UPB_TABVALUE_PTR_INIT(&fields[0]), - UPB_TABVALUE_EMPTY_INIT, - UPB_TABVALUE_PTR_INIT(&fields[16]), - UPB_TABVALUE_PTR_INIT(&fields[17]), - UPB_TABVALUE_PTR_INIT(&fields[20]), - UPB_TABVALUE_PTR_INIT(&fields[21]), - UPB_TABVALUE_PTR_INIT(&fields[19]), - UPB_TABVALUE_PTR_INIT(&fields[14]), - UPB_TABVALUE_PTR_INIT(&fields[13]), - UPB_TABVALUE_PTR_INIT(&fields[18]), - UPB_TABVALUE_PTR_INIT(&fields[15]), - UPB_TABVALUE_EMPTY_INIT, - UPB_TABVALUE_PTR_INIT(&fields[25]), - UPB_TABVALUE_PTR_INIT(&fields[26]), - UPB_TABVALUE_PTR_INIT(&fields[29]), - UPB_TABVALUE_PTR_INIT(&fields[30]), - UPB_TABVALUE_PTR_INIT(&fields[28]), - UPB_TABVALUE_PTR_INIT(&fields[23]), - UPB_TABVALUE_PTR_INIT(&fields[22]), - UPB_TABVALUE_PTR_INIT(&fields[27]), - UPB_TABVALUE_PTR_INIT(&fields[24]), - UPB_TABVALUE_PTR_INIT(&fields[12]), - UPB_TABVALUE_PTR_INIT(&fields[8]), - UPB_TABVALUE_PTR_INIT(&fields[7]), - UPB_TABVALUE_PTR_INIT(&fields[10]), - UPB_TABVALUE_PTR_INIT(&fields[9]), - UPB_TABVALUE_PTR_INIT(&fields[11]), - UPB_TABVALUE_EMPTY_INIT, - UPB_TABVALUE_PTR_INIT(&fields[3]), - UPB_TABVALUE_PTR_INIT(&fields[34]), - UPB_TABVALUE_EMPTY_INIT, - UPB_TABVALUE_PTR_INIT(&fields[2]), - UPB_TABVALUE_PTR_INIT(&fields[36]), - UPB_TABVALUE_EMPTY_INIT, - UPB_TABVALUE_PTR_INIT(&fields[5]), - UPB_TABVALUE_PTR_INIT(&fields[35]), - UPB_TABVALUE_EMPTY_INIT, - UPB_TABVALUE_PTR_INIT(&fields[4]), - UPB_TABVALUE_PTR_INIT(&fields[33]), - UPB_TABVALUE_EMPTY_INIT, - UPB_TABVALUE_PTR_INIT(&fields[6]), - UPB_TABVALUE_PTR_INIT(&fields[31]), - UPB_TABVALUE_EMPTY_INIT, - UPB_TABVALUE_PTR_INIT(&fields[1]), - UPB_TABVALUE_PTR_INIT(&fields[32]), - UPB_TABVALUE_PTR_INIT("A"), - UPB_TABVALUE_PTR_INIT("B"), - UPB_TABVALUE_PTR_INIT("C"), -}; - -#ifdef UPB_DEBUG_REFS -static upb_inttable reftables[92] = { - UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), - UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), - UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), - UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), - UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), - UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), - UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), - UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), - UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), - UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), - UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), - UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), - UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), - UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), - UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), - UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), - UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), - UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), - UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), - UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), - UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), - UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), - UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), - UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), - UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), - UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), - UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), - UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), - UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), - UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), - UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), - UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), - UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), - UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), - UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), - UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), - UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), - UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), - UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), - UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), - UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), - UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), - UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), - UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), - UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), - UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), - UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), - UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), - UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), - UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), - UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), - UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), - UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), - UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), - UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), - UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), - UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), - UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), - UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), - UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), - UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), - UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), - UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), - UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), - UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), - UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), - UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), - UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), - UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), - UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), - UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), - UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), - UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), - UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), - UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), - UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), - UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), - UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), - UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), - UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), - UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), - UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), - UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), - UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), - UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), - UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), - UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), - UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), - UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), - UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), - UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), - UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), -}; -#endif - -static const upb_msgdef *refm(const upb_msgdef *m, const void *owner) { - upb_msgdef_ref(m, owner); - return m; -} - -static const upb_enumdef *refe(const upb_enumdef *e, const void *owner) { - upb_enumdef_ref(e, owner); - return e; -} - -/* Public API. */ -const upb_msgdef *upbdefs_upb_test_json_SubMessage_get(const void *owner) { return refm(&msgs[0], owner); } -const upb_msgdef *upbdefs_upb_test_json_TestMessage_get(const void *owner) { return refm(&msgs[1], owner); } -const upb_msgdef *upbdefs_upb_test_json_TestMessage_MapBoolStringEntry_get(const void *owner) { return refm(&msgs[2], owner); } -const upb_msgdef *upbdefs_upb_test_json_TestMessage_MapInt32StringEntry_get(const void *owner) { return refm(&msgs[3], owner); } -const upb_msgdef *upbdefs_upb_test_json_TestMessage_MapStringBoolEntry_get(const void *owner) { return refm(&msgs[4], owner); } -const upb_msgdef *upbdefs_upb_test_json_TestMessage_MapStringInt32Entry_get(const void *owner) { return refm(&msgs[5], owner); } -const upb_msgdef *upbdefs_upb_test_json_TestMessage_MapStringMsgEntry_get(const void *owner) { return refm(&msgs[6], owner); } -const upb_msgdef *upbdefs_upb_test_json_TestMessage_MapStringStringEntry_get(const void *owner) { return refm(&msgs[7], owner); } - -const upb_enumdef *upbdefs_upb_test_json_MyEnum_get(const void *owner) { return refe(&enums[0], owner); } diff --git a/tests/json/test.upbdefs.h b/tests/json/test.upbdefs.h deleted file mode 100644 index 065c001..0000000 --- a/tests/json/test.upbdefs.h +++ /dev/null @@ -1,238 +0,0 @@ -/* This file contains accessors for a set of compiled-in defs. - * Note that unlike Google's protobuf, it does *not* define - * generated classes or any other kind of data structure for - * actually storing protobufs. It only contains *defs* which - * let you reflect over a protobuf *schema*. - */ -/* This file was generated by upbc (the upb compiler) from the input - * file: - * - * tests/json/test.proto - * - * Do not edit -- your changes will be discarded when the file is - * regenerated. */ - -#ifndef TESTS_JSON_TEST_PROTO_UPB_H_ -#define TESTS_JSON_TEST_PROTO_UPB_H_ - -#include "upb/def.h" - -UPB_BEGIN_EXTERN_C - -/* MessageDefs: call these functions to get a ref to a msgdef. */ -const upb_msgdef *upbdefs_upb_test_json_SubMessage_get(const void *owner); -const upb_msgdef *upbdefs_upb_test_json_TestMessage_get(const void *owner); -const upb_msgdef *upbdefs_upb_test_json_TestMessage_MapBoolStringEntry_get(const void *owner); -const upb_msgdef *upbdefs_upb_test_json_TestMessage_MapInt32StringEntry_get(const void *owner); -const upb_msgdef *upbdefs_upb_test_json_TestMessage_MapStringBoolEntry_get(const void *owner); -const upb_msgdef *upbdefs_upb_test_json_TestMessage_MapStringInt32Entry_get(const void *owner); -const upb_msgdef *upbdefs_upb_test_json_TestMessage_MapStringMsgEntry_get(const void *owner); -const upb_msgdef *upbdefs_upb_test_json_TestMessage_MapStringStringEntry_get(const void *owner); - -/* EnumDefs: call these functions to get a ref to an enumdef. */ -const upb_enumdef *upbdefs_upb_test_json_MyEnum_get(const void *owner); - -/* Functions to test whether this message is of a certain type. */ -UPB_INLINE bool upbdefs_upb_test_json_SubMessage_is(const upb_msgdef *m) { - return strcmp(upb_msgdef_fullname(m), "upb.test.json.SubMessage") == 0; -} -UPB_INLINE bool upbdefs_upb_test_json_TestMessage_is(const upb_msgdef *m) { - return strcmp(upb_msgdef_fullname(m), "upb.test.json.TestMessage") == 0; -} -UPB_INLINE bool upbdefs_upb_test_json_TestMessage_MapBoolStringEntry_is(const upb_msgdef *m) { - return strcmp(upb_msgdef_fullname(m), "upb.test.json.TestMessage.MapBoolStringEntry") == 0; -} -UPB_INLINE bool upbdefs_upb_test_json_TestMessage_MapInt32StringEntry_is(const upb_msgdef *m) { - return strcmp(upb_msgdef_fullname(m), "upb.test.json.TestMessage.MapInt32StringEntry") == 0; -} -UPB_INLINE bool upbdefs_upb_test_json_TestMessage_MapStringBoolEntry_is(const upb_msgdef *m) { - return strcmp(upb_msgdef_fullname(m), "upb.test.json.TestMessage.MapStringBoolEntry") == 0; -} -UPB_INLINE bool upbdefs_upb_test_json_TestMessage_MapStringInt32Entry_is(const upb_msgdef *m) { - return strcmp(upb_msgdef_fullname(m), "upb.test.json.TestMessage.MapStringInt32Entry") == 0; -} -UPB_INLINE bool upbdefs_upb_test_json_TestMessage_MapStringMsgEntry_is(const upb_msgdef *m) { - return strcmp(upb_msgdef_fullname(m), "upb.test.json.TestMessage.MapStringMsgEntry") == 0; -} -UPB_INLINE bool upbdefs_upb_test_json_TestMessage_MapStringStringEntry_is(const upb_msgdef *m) { - return strcmp(upb_msgdef_fullname(m), "upb.test.json.TestMessage.MapStringStringEntry") == 0; -} - -/* Functions to test whether this enum is of a certain type. */ -UPB_INLINE bool upbdefs_upb_test_json_MyEnum_is(const upb_enumdef *e) { - return strcmp(upb_enumdef_fullname(e), "upb.test.json.MyEnum") == 0; -} - - -/* Functions to get a fielddef from a msgdef reference. */ -UPB_INLINE const upb_fielddef *upbdefs_upb_test_json_SubMessage_f_foo(const upb_msgdef *m) { UPB_ASSERT(upbdefs_upb_test_json_SubMessage_is(m)); return upb_msgdef_itof(m, 1); } -UPB_INLINE const upb_fielddef *upbdefs_upb_test_json_TestMessage_MapBoolStringEntry_f_key(const upb_msgdef *m) { UPB_ASSERT(upbdefs_upb_test_json_TestMessage_MapBoolStringEntry_is(m)); return upb_msgdef_itof(m, 1); } -UPB_INLINE const upb_fielddef *upbdefs_upb_test_json_TestMessage_MapBoolStringEntry_f_value(const upb_msgdef *m) { UPB_ASSERT(upbdefs_upb_test_json_TestMessage_MapBoolStringEntry_is(m)); return upb_msgdef_itof(m, 2); } -UPB_INLINE const upb_fielddef *upbdefs_upb_test_json_TestMessage_MapInt32StringEntry_f_key(const upb_msgdef *m) { UPB_ASSERT(upbdefs_upb_test_json_TestMessage_MapInt32StringEntry_is(m)); return upb_msgdef_itof(m, 1); } -UPB_INLINE const upb_fielddef *upbdefs_upb_test_json_TestMessage_MapInt32StringEntry_f_value(const upb_msgdef *m) { UPB_ASSERT(upbdefs_upb_test_json_TestMessage_MapInt32StringEntry_is(m)); return upb_msgdef_itof(m, 2); } -UPB_INLINE const upb_fielddef *upbdefs_upb_test_json_TestMessage_MapStringBoolEntry_f_key(const upb_msgdef *m) { UPB_ASSERT(upbdefs_upb_test_json_TestMessage_MapStringBoolEntry_is(m)); return upb_msgdef_itof(m, 1); } -UPB_INLINE const upb_fielddef *upbdefs_upb_test_json_TestMessage_MapStringBoolEntry_f_value(const upb_msgdef *m) { UPB_ASSERT(upbdefs_upb_test_json_TestMessage_MapStringBoolEntry_is(m)); return upb_msgdef_itof(m, 2); } -UPB_INLINE const upb_fielddef *upbdefs_upb_test_json_TestMessage_MapStringInt32Entry_f_key(const upb_msgdef *m) { UPB_ASSERT(upbdefs_upb_test_json_TestMessage_MapStringInt32Entry_is(m)); return upb_msgdef_itof(m, 1); } -UPB_INLINE const upb_fielddef *upbdefs_upb_test_json_TestMessage_MapStringInt32Entry_f_value(const upb_msgdef *m) { UPB_ASSERT(upbdefs_upb_test_json_TestMessage_MapStringInt32Entry_is(m)); return upb_msgdef_itof(m, 2); } -UPB_INLINE const upb_fielddef *upbdefs_upb_test_json_TestMessage_MapStringMsgEntry_f_key(const upb_msgdef *m) { UPB_ASSERT(upbdefs_upb_test_json_TestMessage_MapStringMsgEntry_is(m)); return upb_msgdef_itof(m, 1); } -UPB_INLINE const upb_fielddef *upbdefs_upb_test_json_TestMessage_MapStringMsgEntry_f_value(const upb_msgdef *m) { UPB_ASSERT(upbdefs_upb_test_json_TestMessage_MapStringMsgEntry_is(m)); return upb_msgdef_itof(m, 2); } -UPB_INLINE const upb_fielddef *upbdefs_upb_test_json_TestMessage_MapStringStringEntry_f_key(const upb_msgdef *m) { UPB_ASSERT(upbdefs_upb_test_json_TestMessage_MapStringStringEntry_is(m)); return upb_msgdef_itof(m, 1); } -UPB_INLINE const upb_fielddef *upbdefs_upb_test_json_TestMessage_MapStringStringEntry_f_value(const upb_msgdef *m) { UPB_ASSERT(upbdefs_upb_test_json_TestMessage_MapStringStringEntry_is(m)); return upb_msgdef_itof(m, 2); } -UPB_INLINE const upb_fielddef *upbdefs_upb_test_json_TestMessage_f_map_bool_string(const upb_msgdef *m) { UPB_ASSERT(upbdefs_upb_test_json_TestMessage_is(m)); return upb_msgdef_itof(m, 22); } -UPB_INLINE const upb_fielddef *upbdefs_upb_test_json_TestMessage_f_map_int32_string(const upb_msgdef *m) { UPB_ASSERT(upbdefs_upb_test_json_TestMessage_is(m)); return upb_msgdef_itof(m, 21); } -UPB_INLINE const upb_fielddef *upbdefs_upb_test_json_TestMessage_f_map_string_bool(const upb_msgdef *m) { UPB_ASSERT(upbdefs_upb_test_json_TestMessage_is(m)); return upb_msgdef_itof(m, 24); } -UPB_INLINE const upb_fielddef *upbdefs_upb_test_json_TestMessage_f_map_string_int32(const upb_msgdef *m) { UPB_ASSERT(upbdefs_upb_test_json_TestMessage_is(m)); return upb_msgdef_itof(m, 23); } -UPB_INLINE const upb_fielddef *upbdefs_upb_test_json_TestMessage_f_map_string_msg(const upb_msgdef *m) { UPB_ASSERT(upbdefs_upb_test_json_TestMessage_is(m)); return upb_msgdef_itof(m, 25); } -UPB_INLINE const upb_fielddef *upbdefs_upb_test_json_TestMessage_f_map_string_string(const upb_msgdef *m) { UPB_ASSERT(upbdefs_upb_test_json_TestMessage_is(m)); return upb_msgdef_itof(m, 20); } -UPB_INLINE const upb_fielddef *upbdefs_upb_test_json_TestMessage_f_optional_bool(const upb_msgdef *m) { UPB_ASSERT(upbdefs_upb_test_json_TestMessage_is(m)); return upb_msgdef_itof(m, 7); } -UPB_INLINE const upb_fielddef *upbdefs_upb_test_json_TestMessage_f_optional_bytes(const upb_msgdef *m) { UPB_ASSERT(upbdefs_upb_test_json_TestMessage_is(m)); return upb_msgdef_itof(m, 6); } -UPB_INLINE const upb_fielddef *upbdefs_upb_test_json_TestMessage_f_optional_enum(const upb_msgdef *m) { UPB_ASSERT(upbdefs_upb_test_json_TestMessage_is(m)); return upb_msgdef_itof(m, 9); } -UPB_INLINE const upb_fielddef *upbdefs_upb_test_json_TestMessage_f_optional_int32(const upb_msgdef *m) { UPB_ASSERT(upbdefs_upb_test_json_TestMessage_is(m)); return upb_msgdef_itof(m, 1); } -UPB_INLINE const upb_fielddef *upbdefs_upb_test_json_TestMessage_f_optional_int64(const upb_msgdef *m) { UPB_ASSERT(upbdefs_upb_test_json_TestMessage_is(m)); return upb_msgdef_itof(m, 2); } -UPB_INLINE const upb_fielddef *upbdefs_upb_test_json_TestMessage_f_optional_msg(const upb_msgdef *m) { UPB_ASSERT(upbdefs_upb_test_json_TestMessage_is(m)); return upb_msgdef_itof(m, 8); } -UPB_INLINE const upb_fielddef *upbdefs_upb_test_json_TestMessage_f_optional_string(const upb_msgdef *m) { UPB_ASSERT(upbdefs_upb_test_json_TestMessage_is(m)); return upb_msgdef_itof(m, 5); } -UPB_INLINE const upb_fielddef *upbdefs_upb_test_json_TestMessage_f_optional_uint32(const upb_msgdef *m) { UPB_ASSERT(upbdefs_upb_test_json_TestMessage_is(m)); return upb_msgdef_itof(m, 3); } -UPB_INLINE const upb_fielddef *upbdefs_upb_test_json_TestMessage_f_optional_uint64(const upb_msgdef *m) { UPB_ASSERT(upbdefs_upb_test_json_TestMessage_is(m)); return upb_msgdef_itof(m, 4); } -UPB_INLINE const upb_fielddef *upbdefs_upb_test_json_TestMessage_f_repeated_bool(const upb_msgdef *m) { UPB_ASSERT(upbdefs_upb_test_json_TestMessage_is(m)); return upb_msgdef_itof(m, 17); } -UPB_INLINE const upb_fielddef *upbdefs_upb_test_json_TestMessage_f_repeated_bytes(const upb_msgdef *m) { UPB_ASSERT(upbdefs_upb_test_json_TestMessage_is(m)); return upb_msgdef_itof(m, 16); } -UPB_INLINE const upb_fielddef *upbdefs_upb_test_json_TestMessage_f_repeated_enum(const upb_msgdef *m) { UPB_ASSERT(upbdefs_upb_test_json_TestMessage_is(m)); return upb_msgdef_itof(m, 19); } -UPB_INLINE const upb_fielddef *upbdefs_upb_test_json_TestMessage_f_repeated_int32(const upb_msgdef *m) { UPB_ASSERT(upbdefs_upb_test_json_TestMessage_is(m)); return upb_msgdef_itof(m, 11); } -UPB_INLINE const upb_fielddef *upbdefs_upb_test_json_TestMessage_f_repeated_int64(const upb_msgdef *m) { UPB_ASSERT(upbdefs_upb_test_json_TestMessage_is(m)); return upb_msgdef_itof(m, 12); } -UPB_INLINE const upb_fielddef *upbdefs_upb_test_json_TestMessage_f_repeated_msg(const upb_msgdef *m) { UPB_ASSERT(upbdefs_upb_test_json_TestMessage_is(m)); return upb_msgdef_itof(m, 18); } -UPB_INLINE const upb_fielddef *upbdefs_upb_test_json_TestMessage_f_repeated_string(const upb_msgdef *m) { UPB_ASSERT(upbdefs_upb_test_json_TestMessage_is(m)); return upb_msgdef_itof(m, 15); } -UPB_INLINE const upb_fielddef *upbdefs_upb_test_json_TestMessage_f_repeated_uint32(const upb_msgdef *m) { UPB_ASSERT(upbdefs_upb_test_json_TestMessage_is(m)); return upb_msgdef_itof(m, 13); } -UPB_INLINE const upb_fielddef *upbdefs_upb_test_json_TestMessage_f_repeated_uint64(const upb_msgdef *m) { UPB_ASSERT(upbdefs_upb_test_json_TestMessage_is(m)); return upb_msgdef_itof(m, 14); } - -UPB_END_EXTERN_C - -#ifdef __cplusplus - -namespace upbdefs { -namespace upb { -namespace test { -namespace json { - -class MyEnum : public ::upb::reffed_ptr { - public: - MyEnum(const ::upb::EnumDef* e, const void *ref_donor = NULL) - : reffed_ptr(e, ref_donor) { - UPB_ASSERT(upbdefs_upb_test_json_MyEnum_is(e)); - } - static MyEnum get() { - const ::upb::EnumDef* e = upbdefs_upb_test_json_MyEnum_get(&e); - return MyEnum(e, &e); - } -}; - -class SubMessage : public ::upb::reffed_ptr { - public: - SubMessage(const ::upb::MessageDef* m, const void *ref_donor = NULL) - : reffed_ptr(m, ref_donor) { - UPB_ASSERT(upbdefs_upb_test_json_SubMessage_is(m)); - } - - static SubMessage get() { - const ::upb::MessageDef* m = upbdefs_upb_test_json_SubMessage_get(&m); - return SubMessage(m, &m); - } -}; - -class TestMessage : public ::upb::reffed_ptr { - public: - TestMessage(const ::upb::MessageDef* m, const void *ref_donor = NULL) - : reffed_ptr(m, ref_donor) { - UPB_ASSERT(upbdefs_upb_test_json_TestMessage_is(m)); - } - - static TestMessage get() { - const ::upb::MessageDef* m = upbdefs_upb_test_json_TestMessage_get(&m); - return TestMessage(m, &m); - } - - class MapBoolStringEntry : public ::upb::reffed_ptr { - public: - MapBoolStringEntry(const ::upb::MessageDef* m, const void *ref_donor = NULL) - : reffed_ptr(m, ref_donor) { - UPB_ASSERT(upbdefs_upb_test_json_TestMessage_MapBoolStringEntry_is(m)); - } - - static MapBoolStringEntry get() { - const ::upb::MessageDef* m = upbdefs_upb_test_json_TestMessage_MapBoolStringEntry_get(&m); - return MapBoolStringEntry(m, &m); - } - }; - - class MapInt32StringEntry : public ::upb::reffed_ptr { - public: - MapInt32StringEntry(const ::upb::MessageDef* m, const void *ref_donor = NULL) - : reffed_ptr(m, ref_donor) { - UPB_ASSERT(upbdefs_upb_test_json_TestMessage_MapInt32StringEntry_is(m)); - } - - static MapInt32StringEntry get() { - const ::upb::MessageDef* m = upbdefs_upb_test_json_TestMessage_MapInt32StringEntry_get(&m); - return MapInt32StringEntry(m, &m); - } - }; - - class MapStringBoolEntry : public ::upb::reffed_ptr { - public: - MapStringBoolEntry(const ::upb::MessageDef* m, const void *ref_donor = NULL) - : reffed_ptr(m, ref_donor) { - UPB_ASSERT(upbdefs_upb_test_json_TestMessage_MapStringBoolEntry_is(m)); - } - - static MapStringBoolEntry get() { - const ::upb::MessageDef* m = upbdefs_upb_test_json_TestMessage_MapStringBoolEntry_get(&m); - return MapStringBoolEntry(m, &m); - } - }; - - class MapStringInt32Entry : public ::upb::reffed_ptr { - public: - MapStringInt32Entry(const ::upb::MessageDef* m, const void *ref_donor = NULL) - : reffed_ptr(m, ref_donor) { - UPB_ASSERT(upbdefs_upb_test_json_TestMessage_MapStringInt32Entry_is(m)); - } - - static MapStringInt32Entry get() { - const ::upb::MessageDef* m = upbdefs_upb_test_json_TestMessage_MapStringInt32Entry_get(&m); - return MapStringInt32Entry(m, &m); - } - }; - - class MapStringMsgEntry : public ::upb::reffed_ptr { - public: - MapStringMsgEntry(const ::upb::MessageDef* m, const void *ref_donor = NULL) - : reffed_ptr(m, ref_donor) { - UPB_ASSERT(upbdefs_upb_test_json_TestMessage_MapStringMsgEntry_is(m)); - } - - static MapStringMsgEntry get() { - const ::upb::MessageDef* m = upbdefs_upb_test_json_TestMessage_MapStringMsgEntry_get(&m); - return MapStringMsgEntry(m, &m); - } - }; - - class MapStringStringEntry : public ::upb::reffed_ptr { - public: - MapStringStringEntry(const ::upb::MessageDef* m, const void *ref_donor = NULL) - : reffed_ptr(m, ref_donor) { - UPB_ASSERT(upbdefs_upb_test_json_TestMessage_MapStringStringEntry_is(m)); - } - - static MapStringStringEntry get() { - const ::upb::MessageDef* m = upbdefs_upb_test_json_TestMessage_MapStringStringEntry_get(&m); - return MapStringStringEntry(m, &m); - } - }; -}; - -} /* namespace json */ -} /* namespace test */ -} /* namespace upb */ -} /* namespace upbdefs */ - -#endif /* __cplusplus */ - -#endif /* TESTS_JSON_TEST_PROTO_UPB_H_ */ diff --git a/tests/json/test_json.cc b/tests/json/test_json.cc index 815d292..98bf59e 100644 --- a/tests/json/test_json.cc +++ b/tests/json/test_json.cc @@ -203,12 +203,13 @@ void test_json_roundtrip_message(const char* json_src, // Starts with a message in JSON format, parses and directly serializes again, // and compares the result. void test_json_roundtrip() { - upb::reffed_ptr md( - upbdefs::upb::test::json::TestMessage::get()); + upb::SymbolTable* symtab = upb::SymbolTable::New(); + const upb::MessageDef* md = upb_test_json_TestMessage_getmsgdef(symtab); + ASSERT(md); upb::reffed_ptr serialize_handlers( - upb::json::Printer::NewHandlers(md.get(), false)); + upb::json::Printer::NewHandlers(md, false)); upb::reffed_ptr parser_method( - upb::json::ParserMethod::New(md.get())); + upb::json::ParserMethod::New(md)); for (const TestCase* test_case = kTestRoundtripMessages; test_case->input != NULL; test_case++) { @@ -224,7 +225,7 @@ void test_json_roundtrip() { } } - serialize_handlers = upb::json::Printer::NewHandlers(md.get(), true); + serialize_handlers = upb::json::Printer::NewHandlers(md, true); for (const TestCase* test_case = kTestRoundtripMessagesPreserve; test_case->input != NULL; test_case++) { @@ -239,6 +240,8 @@ void test_json_roundtrip() { i); } } + + upb::SymbolTable::Free(symtab); } extern "C" { diff --git a/tests/test_handlers.c b/tests/test_handlers.c index fe6fb82..2b19cab 100644 --- a/tests/test_handlers.c +++ b/tests/test_handlers.c @@ -1,9 +1,9 @@ -#include "upb/handlers.h" -#include "upb/descriptor/descriptor.upbdefs.h" -#include "upb_test.h" #include #include +#include "google/protobuf/descriptor.upbdefs.h" +#include "upb/handlers.h" +#include "upb_test.h" static bool startmsg(void *c, const void *hd) { UPB_UNUSED(c); @@ -13,9 +13,9 @@ static bool startmsg(void *c, const void *hd) { static void test_error() { /* Test creating handlers of a static msgdef. */ - const upb_msgdef *m = upbdefs_google_protobuf_DescriptorProto_get(&m); + upb_symtab *s = upb_symtab_new(); + const upb_msgdef *m = google_protobuf_DescriptorProto_getmsgdef(s); upb_handlers *h = upb_handlers_new(m, &h); - upb_msgdef_unref(m, &m); /* Attempt to set the same handler twice causes error. */ ASSERT(upb_ok(upb_handlers_status(h))); @@ -31,6 +31,7 @@ static void test_error() { ASSERT(upb_handlers_isfrozen(h)); upb_handlers_unref(h, &h); + upb_symtab_free(s); } int run_tests(int argc, char *argv[]) { diff --git a/upb/def.c b/upb/def.c index 047684e..c10394e 100644 --- a/upb/def.c +++ b/upb/def.c @@ -467,7 +467,7 @@ bool upb_fielddef_packed(const upb_fielddef *f) { } const char *upb_fielddef_name(const upb_fielddef *f) { - return f->full_name; + return shortdefname(f->full_name); } uint32_t upb_fielddef_selectorbase(const upb_fielddef *f) { diff --git a/upbc/generator.cc b/upbc/generator.cc index 3b4f6ac..d8ec831 100644 --- a/upbc/generator.cc +++ b/upbc/generator.cc @@ -587,7 +587,11 @@ void GenerateMessageDefAccessor(const protobuf::Descriptor* d, Output& output) { void WriteDefHeader(const protobuf::FileDescriptor* file, Output& output) { EmitFileWarning(file, output); + output("#include \"upb/def.h\"\n"); + output("\n"); + output("extern upb_def_init $0;\n", DefInitSymbol(file)); + output("\n"); for (int i = 0; i < file->message_type_count(); i++) { GenerateMessageDefAccessor(file->message_type(i), output); @@ -621,10 +625,10 @@ void WriteDefSource(const protobuf::FileDescriptor* file, Output& output) { // Workaround for MSVC: "Error C1091: compiler limit: string exceeds // 65535 bytes in length". Declare a static array of chars rather than // use a string literal. Only write 25 bytes per line. - static const int kBytesPerLine = 25; + static const size_t kBytesPerLine = 25; output("{ "); - for (int i = 0; i < file_data.size();) { - for (int j = 0; j < kBytesPerLine && i < file_data.size(); ++i, ++j) { + for (size_t i = 0; i < file_data.size();) { + for (size_t j = 0; j < kBytesPerLine && i < file_data.size(); ++i, ++j) { output("'$0', ", absl::CEscape(file_data.substr(i, 1))); } output("\n"); @@ -632,8 +636,8 @@ void WriteDefSource(const protobuf::FileDescriptor* file, Output& output) { output("'\\0' }"); // null-terminate } else { // Only write 40 bytes per line. - static const int kBytesPerLine = 40; - for (int i = 0; i < file_data.size(); i += kBytesPerLine) { + static const size_t kBytesPerLine = 40; + for (size_t i = 0; i < file_data.size(); i += kBytesPerLine) { output( "\"$0\"\n", EscapeTrigraphs(absl::CEscape(file_data.substr(i, kBytesPerLine)))); -- cgit v1.2.3 From 9dd2446531827a9848983a2dbe3bfb612ed7047e Mon Sep 17 00:00:00 2001 From: Josh Haberman Date: Mon, 17 Dec 2018 10:07:00 -0800 Subject: test_cpp is working! --- BUILD | 44 ++---- build_defs.bzl | 3 - tests/test_cpp.cc | 414 +++++------------------------------------------------- upb/def.c | 8 +- 4 files changed, 57 insertions(+), 412 deletions(-) (limited to 'upb/def.c') diff --git a/BUILD b/BUILD index 0f4231a..bf988f9 100644 --- a/BUILD +++ b/BUILD @@ -209,10 +209,24 @@ cc_test( ], ) +proto_library( + name = "test_cpp_proto", + srcs = [ + "tests/test_cpp.proto" + ] +) + +upb_proto_reflection_library( + name = "test_cpp_upbproto", + deps = ["test_cpp_proto"], + upbc = ":protoc-gen-upb", +) + cc_test( name = "test_cpp", srcs = ["tests/test_cpp.cc"], deps = [ + ":test_cpp_upbproto", ":upb", ":upb_pb", ":upb_test", @@ -331,17 +345,6 @@ lua_library( strip_prefix = "upb/bindings/lua", ) -lua_library( - name = "lua/upbc_lib", - srcs = [ - "tools/dump_cinit.lua", - ], - luadeps = [ - "lua/upb", - ], - strip_prefix = "tools", -) - # Lua tests. ################################################################### lua_test( @@ -358,14 +361,6 @@ lua_test( # upb compiler ################################################################# -lua_binary( - name = "lua_upbc", - luadeps = [ - "lua/upbc_lib", - ], - luamain = "tools/upbc.lua", -) - cc_library( name = "upbc_generator", hdrs = ["upbc/generator.h"], @@ -491,17 +486,6 @@ genrule( cmd = "cp $< $@", ) -#genrule( -# name = "generated_json_test_proto_upbdefs", -# srcs = ["generated/tests/json/test.proto.pb"], -# outs = [ -# "generated/tests/json/test.upbdefs.h", -# "generated/tests/json/test.upbdefs.c", -# ], -# cmd = "UPBC=$$PWD/$(location :lua_upbc); INFILE=$$PWD/$<; cd $(GENDIR)/generated && $$UPBC --generate-upbdefs $$INFILE", -# tools = [":lua_upbc"], -#) - genrule( name = "generate_json_ragel", srcs = ["upb/json/parser.rl"], diff --git a/build_defs.bzl b/build_defs.bzl index 3867976..717a0e7 100644 --- a/build_defs.bzl +++ b/build_defs.bzl @@ -235,9 +235,6 @@ def _upb_proto_srcs_impl(ctx, suffix): source_paths = [d.path for d in sources] include_args = ["-I" + root for root in include_dirs.keys()] - print(source_paths) - print(include_args) - ctx.actions.run( inputs = [ctx.executable.upbc] + sources, outputs = outs, diff --git a/tests/test_cpp.cc b/tests/test_cpp.cc index 2cd9802..b6d8212 100644 --- a/tests/test_cpp.cc +++ b/tests/test_cpp.cc @@ -11,13 +11,12 @@ #include #include +#include "tests/test_cpp.upbdefs.h" #include "upb/def.h" -#include "upb/descriptor/reader.h" #include "upb/handlers.h" #include "upb/pb/decoder.h" -#include "upb/pb/glue.h" -#include "upb_test.h" #include "upb/upb.h" +#include "upb_test.h" template void AssertInsert(T* const container, const typename T::value_type& val) { @@ -25,182 +24,6 @@ void AssertInsert(T* const container, const typename T::value_type& val) { ASSERT(inserted); } -static void TestCastsUpDown() { - upb::reffed_ptr reffed_md(upb::MessageDef::New()); - const upb::MessageDef* md = reffed_md.get(); - - // Upcast to reffed_ptr implicitly. - upb::reffed_ptr reffed_def = reffed_md; - ASSERT(reffed_def.get() == upb::upcast(reffed_md.get())); - - // Upcast to raw pointer must be explicit. - const upb::Def* def = upb::upcast(md); - ASSERT(def == reffed_def.get()); - const upb::Def* def2 = upb::upcast(reffed_md.get()); - ASSERT(def2 == reffed_def.get()); - - // Downcast/dyncast of raw pointer uses upb::down_cast/upb::dyn_cast. - const upb::MessageDef* md2 = upb::down_cast(def); - const upb::MessageDef* md3 = upb::dyn_cast(def); - ASSERT(md == md2); - ASSERT(md == md3); - - // Downcast/dyncast of reffed_ptr uses down_cast/dyn_cast members. - upb::reffed_ptr md4( - reffed_def.down_cast()); - upb::reffed_ptr md5( - reffed_def.dyn_cast()); - ASSERT(md == md4.get()); - ASSERT(md == md5.get()); - - // Failed dyncast returns NULL. - ASSERT(upb::dyn_cast(def) == NULL); - ASSERT(reffed_def.dyn_cast().get() == NULL); -} - -static void TestCastsConst0() { - // Should clean up properly even if it is not assigned to anything. - upb::MessageDef::New(); -} - -static void TestCastsConst1() { - // Test reffed mutable -> reffed mutable construction/assignment. - upb::reffed_ptr md(upb::MessageDef::New()); - upb::MessageDef *md2 = md.get(); - md = upb::MessageDef::New(); - ASSERT(md.get()); - ASSERT(md.get() != md2); -} - -static void TestCastsConst2() { - // Test reffed mutable -> reffed mutable upcast construction/assignment. - upb::reffed_ptr md(upb::MessageDef::New()); - upb::reffed_ptr def = md; - ASSERT(upb::upcast(md.get()) == def.get()); - def = md; - ASSERT(upb::upcast(md.get()) == def.get()); -} - -static void TestCastsConst3() { - // Test reffed mutable -> reffed mutable downcast. - upb::reffed_ptr def(upb::MessageDef::New()); - upb::reffed_ptr md = def.down_cast(); - ASSERT(upb::upcast(md.get()) == def.get()); -} - -static void TestCastsConst4() { - // Test reffed mutable -> reffed mutable dyncast. - upb::reffed_ptr def(upb::MessageDef::New()); - upb::reffed_ptr md = def.dyn_cast(); - ASSERT(upb::upcast(md.get()) == def.get()); -} - -static void TestCastsConst5() { - // Test reffed mutable -> reffed const construction/assignment. - upb::reffed_ptr md(upb::MessageDef::New()); - const upb::MessageDef *md2 = md.get(); - md = upb::MessageDef::New(); - ASSERT(md.get()); - ASSERT(md.get() != md2); -} - -static void TestCastsConst6() { - // Test reffed mutable -> reffed const upcast construction/assignment. - upb::reffed_ptr md(upb::MessageDef::New()); - upb::reffed_ptr def = md; - ASSERT(upb::upcast(md.get()) == def.get()); - def = md; - ASSERT(upb::upcast(md.get()) == def.get()); -} - -static void TestCastsConst7() { - // Test reffed mutable -> reffed const downcast. - upb::reffed_ptr def(upb::MessageDef::New()); - upb::reffed_ptr md = - def.down_cast(); - ASSERT(upb::upcast(md.get()) == def.get()); -} - -static void TestCastsConst8() { - // Test reffed mutable -> reffed const dyncast. - upb::reffed_ptr def(upb::MessageDef::New()); - upb::reffed_ptr md = - def.dyn_cast(); - ASSERT(upb::upcast(md.get()) == def.get()); -} - -static void TestCastsConst9() { - // Test plain mutable -> plain mutable upcast - upb::reffed_ptr md(upb::MessageDef::New()); - upb::Def* def = upb::upcast(md.get()); - ASSERT(upb::down_cast(def) == md.get()); -} - -static void TestCastsConst10() { - // Test plain const -> plain const upcast - upb::reffed_ptr md(upb::MessageDef::New()); - const upb::Def* def = upb::upcast(md.get()); - ASSERT(upb::down_cast(def) == md.get()); -} - -static void TestSymbolTable(const char *descriptor_file) { - upb::Status status; - std::ifstream file_in(descriptor_file, std::ios::binary); - std::string descriptor((std::istreambuf_iterator(file_in)), - (std::istreambuf_iterator())); - std::vector > files; - if (!upb::LoadDescriptor(descriptor, &status, &files)) { - std::cerr << "Couldn't load descriptor: " << status.error_message(); - exit(1); - } - - upb::SymbolTable* s = upb::SymbolTable::New(); - - for (size_t i = 0; i < files.size(); i++) { - ASSERT(s->AddFile(files[i].get(), &status)); - } - - upb::reffed_ptr md(s->LookupMessage("C")); - ASSERT(md.get()); - - // We want a def that satisfies this to test iteration. - ASSERT(md->field_count() > 1); - -#ifdef UPB_CXX11 - // Test range-based for. - std::set fielddefs; - for (const upb::FieldDef* f : md.get()->fields()) { - AssertInsert(&fielddefs, f); - ASSERT(f->containing_type() == md.get()); - } - ASSERT(fielddefs.size() == md->field_count()); -#endif - - ASSERT(md.get()); - upb::SymbolTable::Free(s); -} - -static void TestCasts1() { - upb::reffed_ptr md(upb::MessageDef::New()); - const upb::Def* def = upb::upcast(md.get()); - const upb::MessageDef* md2 = upb::down_cast(def); - const upb::MessageDef* md3 = upb::dyn_cast(def); - - ASSERT(md.get() == md2); - ASSERT(md.get() == md3); - - const upb::EnumDef* ed = upb::dyn_cast(def); - ASSERT(!ed); -} - -static void TestCasts2() { - // Test mutable -> const cast. - upb::reffed_ptr md(upb::MessageDef::New()); - upb::Def* def = upb::upcast(md.get()); - const upb::MessageDef* const_md = upb::down_cast(def); - ASSERT(const_md == md.get()); -} - // // Tests for registering and calling handlers in all their variants. // This test code is very repetitive because we have to declare each @@ -225,7 +48,7 @@ static const int kExpectedHandlerData = 1232323; class StringBufTesterBase { public: - static const upb::FieldDef::Type kFieldType = UPB_TYPE_STRING; + static const int kFieldNumber = 3; StringBufTesterBase() : seen_(false), handler_data_val_(0) {} @@ -461,7 +284,7 @@ class StartMsgTesterBase { public: // We don't need the FieldDef it will create, but the test harness still // requires that we provide one. - static const upb::FieldDef::Type kFieldType = UPB_TYPE_STRING; + static const int kFieldNumber = 3; StartMsgTesterBase() : seen_(false), handler_data_val_(0) {} @@ -612,7 +435,7 @@ class StartMsgTesterBoolMethodWithHandlerData : public StartMsgTesterBase { class Int32ValueTesterBase { public: - static const upb::FieldDef::Type kFieldType = UPB_TYPE_INT32; + static const int kFieldNumber = 1; Int32ValueTesterBase() : seen_(false), val_(0), handler_data_val_(0) {} @@ -770,21 +593,20 @@ class ValueTesterInt32BoolMethodWithHandlerData : public Int32ValueTesterBase { template void TestHandler() { - upb::reffed_ptr md(upb::MessageDef::New()); - upb::reffed_ptr f(upb::FieldDef::New()); - f->set_type(T::kFieldType); - ASSERT(f->set_name("test", NULL)); - ASSERT(f->set_number(1, NULL)); - ASSERT(md->AddField(f, NULL)); - ASSERT(md->Freeze(NULL)); - - upb::reffed_ptr h(upb::Handlers::New(md.get())); + upb::SymbolTable* symtab = upb::SymbolTable::New(); + const upb::MessageDef* md = upb_test_TestMessage_getmsgdef(symtab); + ASSERT(md); + const upb::FieldDef* f = md->FindFieldByNumber(T::kFieldNumber); + ASSERT(f); + + upb::reffed_ptr h(upb::Handlers::New(md)); T tester; - tester.Register(h.get(), f.get()); + tester.Register(h.get(), f); ASSERT(h->Freeze(NULL)); upb::Sink sink(h.get(), &tester); - tester.CallAndVerify(&sink, f.get()); + tester.CallAndVerify(&sink, f); + upb::SymbolTable::Free(symtab); } class T1 {}; @@ -850,59 +672,24 @@ void DoNothingEndMessageHandler(C* closure, upb::Status *status) { void TestMismatchedTypes() { // First create a schema for our test. - upb::reffed_ptr md(upb::MessageDef::New()); - - upb::reffed_ptr f(upb::FieldDef::New()); - f->set_type(UPB_TYPE_INT32); - ASSERT(f->set_name("i32", NULL)); - ASSERT(f->set_number(1, NULL)); - ASSERT(md->AddField(f, NULL)); - const upb::FieldDef* i32 = f.get(); - - f = upb::FieldDef::New(); - f->set_type(UPB_TYPE_INT32); - ASSERT(f->set_name("r_i32", NULL)); - ASSERT(f->set_number(2, NULL)); - f->set_label(UPB_LABEL_REPEATED); - ASSERT(md->AddField(f, NULL)); - const upb::FieldDef* r_i32 = f.get(); - - f = upb::FieldDef::New(); - f->set_type(UPB_TYPE_STRING); - ASSERT(f->set_name("str", NULL)); - ASSERT(f->set_number(3, NULL)); - ASSERT(md->AddField(f, NULL)); - const upb::FieldDef* str = f.get(); - - f = upb::FieldDef::New(); - f->set_type(UPB_TYPE_STRING); - ASSERT(f->set_name("r_str", NULL)); - ASSERT(f->set_number(4, NULL)); - f->set_label(UPB_LABEL_REPEATED); - ASSERT(md->AddField(f, NULL)); - const upb::FieldDef* r_str = f.get(); - - f = upb::FieldDef::New(); - f->set_type(UPB_TYPE_MESSAGE); - ASSERT(f->set_name("msg", NULL)); - ASSERT(f->set_number(5, NULL)); - ASSERT(f->set_message_subdef(md.get(), NULL)); - ASSERT(md->AddField(f, NULL)); - const upb::FieldDef* msg = f.get(); - - f = upb::FieldDef::New(); - f->set_type(UPB_TYPE_MESSAGE); - ASSERT(f->set_name("r_msg", NULL)); - ASSERT(f->set_number(6, NULL)); - ASSERT(f->set_message_subdef(md.get(), NULL)); - f->set_label(UPB_LABEL_REPEATED); - ASSERT(md->AddField(f, NULL)); - const upb::FieldDef* r_msg = f.get(); - - ASSERT(md->Freeze(NULL)); + upb::SymbolTable* symtab = upb::SymbolTable::New(); + const upb::MessageDef* md = upb_test_TestMessage_getmsgdef(symtab); + ASSERT(md); + const upb::FieldDef* i32 = md->FindFieldByName("i32"); + const upb::FieldDef* r_i32 = md->FindFieldByName("r_i32"); + const upb::FieldDef* str = md->FindFieldByName("str"); + const upb::FieldDef* r_str = md->FindFieldByName("r_str"); + const upb::FieldDef* msg = md->FindFieldByName("msg"); + const upb::FieldDef* r_msg = md->FindFieldByName("r_msg"); + ASSERT(i32); + ASSERT(r_i32); + ASSERT(str); + ASSERT(r_str); + ASSERT(msg); + ASSERT(r_msg); // Now test the type-checking in handler registration. - upb::reffed_ptr h(upb::Handlers::New(md.get())); + upb::reffed_ptr h(upb::Handlers::New(md)); // Establish T1 as the top-level closure type. ASSERT(h->SetInt32Handler(i32, UpbMakeHandler(DoNothingInt32Handler))); @@ -1007,7 +794,7 @@ void TestMismatchedTypes() { // For our second test we do the same in reverse. We directly set the type of // the frame and then observe failures at registering a Start* handler that // returns a different type. - h = upb::Handlers::New(md.get()); + h = upb::Handlers::New(md); // First establish the type of a sequence frame directly. ASSERT(h->SetInt32Handler(r_i32, UpbMakeHandler(DoNothingInt32Handler))); @@ -1040,7 +827,7 @@ void TestMismatchedTypes() { // should exist to return the closure type of the inner frame but no // StartSequence/StartString handler is registered. - h = upb::Handlers::New(md.get()); + h = upb::Handlers::New(md); // Establish T1 as top-level closure type. ASSERT(h->SetInt32Handler(i32, UpbMakeHandler(DoNothingInt32Handler))); @@ -1061,7 +848,7 @@ void TestMismatchedTypes() { ASSERT(h->Freeze(NULL)); // Test for a broken chain that is two deep. - h = upb::Handlers::New(md.get()); + h = upb::Handlers::New(md); // Establish T1 as top-level closure type. ASSERT(h->SetInt32Handler(i32, UpbMakeHandler(DoNothingInt32Handler))); @@ -1104,145 +891,24 @@ class IntIncrementer { void TestHandlerDataDestruction() { - upb::reffed_ptr md(upb::MessageDef::New()); - upb::reffed_ptr f(upb::FieldDef::New()); - f->set_type(UPB_TYPE_INT32); - ASSERT(f->set_name("test", NULL)); - ASSERT(f->set_number(1, NULL)); - ASSERT(md->AddField(f, NULL)); - ASSERT(md->Freeze(NULL)); + upb::SymbolTable* symtab = upb::SymbolTable::New(); + const upb::MessageDef* md = upb_test_TestMessage_getmsgdef(symtab); + const upb::FieldDef* f = md->FindFieldByName("i32"); int x = 0; { - upb::reffed_ptr h(upb::Handlers::New(md.get())); + upb::reffed_ptr h(upb::Handlers::New(md)); h->SetInt32Handler( - f.get(), UpbBind(&IntIncrementer::Handler, new IntIncrementer(&x))); + f, UpbBind(&IntIncrementer::Handler, new IntIncrementer(&x))); ASSERT(x == 1); } ASSERT(x == 0); } -void TestOneofs() { - upb::Status status; - upb::reffed_ptr md(upb::MessageDef::New()); - upb::reffed_ptr o(upb::OneofDef::New()); - - o->set_name("test_oneof", &status); - ASSERT(status.ok()); - - for (int i = 0; i < 5; i++) { - std::ostringstream fieldname; - fieldname << "field_" << i; - upb::reffed_ptr f(upb::FieldDef::New()); - f->set_name(fieldname.str(), &status); - ASSERT(status.ok()); - f->set_type(UPB_TYPE_INT32); - f->set_number(i + 1, &status); - ASSERT(status.ok()); - f->set_label(UPB_LABEL_OPTIONAL); - - o->AddField(f.get(), &status); - ASSERT(status.ok()); - } - - md->AddOneof(o.get(), &status); - ASSERT(status.ok()); - - int field_count = 0; - for (upb::OneofDef::iterator it = o->begin(); it != o->end(); ++it) { - upb::FieldDef* f = *it; - ASSERT(f->type() == UPB_TYPE_INT32); - field_count++; - } - ASSERT(field_count == 5); - - upb::MessageDef::oneof_iterator msg_it = md->oneof_begin(); - ASSERT(msg_it != md->oneof_end()); - ASSERT((*msg_it) == o.get()); - -#ifdef UPB_CXX11 - // Test range-based for on both fields and oneofs (with the iterator adaptor). - field_count = 0; - for (auto* field : md->fields()) { - UPB_UNUSED(field); - field_count++; - } - ASSERT(field_count == 5); - - int oneof_count = 0; - for (auto* oneof : md->oneofs()) { - UPB_UNUSED(oneof); - oneof_count++; - } - ASSERT(oneof_count == 1); -#endif // UPB_CXX11 - - // Test that we can add a new field to the oneof and that it becomes a member - // of the msgdef as well. - upb::reffed_ptr newf(upb::FieldDef::New()); - newf->set_name("new_field_10", &status); - ASSERT(status.ok()); - newf->set_number(10, &status); - ASSERT(status.ok()); - newf->set_label(UPB_LABEL_OPTIONAL); - newf->set_type(UPB_TYPE_INT32); - o->AddField(newf.get(), &status); - ASSERT(status.ok()); - ASSERT(newf->containing_type() == md.get()); - - // Test that we can add a new field to the msgdef first and then to the oneof. - upb::reffed_ptr newf2(upb::FieldDef::New()); - newf2->set_name("new_field_11", &status); - ASSERT(status.ok()); - newf2->set_number(11, &status); - ASSERT(status.ok()); - newf2->set_label(UPB_LABEL_OPTIONAL); - newf2->set_type(UPB_TYPE_INT32); - md->AddField(newf2.get(), &status); - ASSERT(status.ok()); - o->AddField(newf2.get(), &status); - ASSERT(status.ok()); - ASSERT(newf2->containing_oneof() == o.get()); - - // Test that we cannot add REQUIRED or REPEATED fields to the oneof. - upb::reffed_ptr newf3(upb::FieldDef::New()); - newf3->set_name("new_field_12", &status); - ASSERT(status.ok()); - newf3->set_number(12, &status); - ASSERT(status.ok()); - newf3->set_label(UPB_LABEL_REQUIRED); - newf3->set_type(UPB_TYPE_INT32); - o->AddField(newf3.get(), &status); - ASSERT(!status.ok()); - newf->set_label(UPB_LABEL_REPEATED); - o->AddField(newf3.get(), &status); - ASSERT(!status.ok()); -} - extern "C" { int run_tests(int argc, char *argv[]) { - if (argc < 2) { - fprintf(stderr, "Usage: test_cpp \n"); - return 1; - } - TestSymbolTable(argv[1]); - TestCastsUpDown(); - TestCasts1(); - TestCasts2(); - TestCastsConst0(); - TestCastsConst1(); - TestCastsConst2(); - TestCastsConst3(); - TestCastsConst4(); - TestCastsConst5(); - TestCastsConst6(); - TestCastsConst7(); - TestCastsConst8(); - TestCastsConst9(); - TestCastsConst10(); - TestHandler(); TestHandler(); TestHandler(); @@ -1276,8 +942,6 @@ int run_tests(int argc, char *argv[]) { TestHandlerDataDestruction(); - TestOneofs(); - return 0; } diff --git a/upb/def.c b/upb/def.c index c10394e..ccbf407 100644 --- a/upb/def.c +++ b/upb/def.c @@ -921,12 +921,12 @@ static char* strviewdup(const symtab_addctx *ctx, upb_stringview view) { return upb_strdup2(view.data, view.size, ctx->alloc); } -static bool streql(const char *a, size_t n, const char *b) { +static bool streql2(const char *a, size_t n, const char *b) { return n == strlen(b) && memcmp(a, b, n) == 0; } static bool streql_view(upb_stringview view, const char *b) { - return streql(view.data, view.size, b); + return streql2(view.data, view.size, b); } static const char *makefullname(const symtab_addctx *ctx, const char *prefix, @@ -1077,9 +1077,9 @@ static bool parse_default(const symtab_addctx *ctx, const char *str, size_t len, break; } case UPB_TYPE_BOOL: { - if (streql(str, len, "false")) { + if (streql2(str, len, "false")) { f->defaultval.boolean = false; - } else if (streql(str, len, "true")) { + } else if (streql2(str, len, "true")) { f->defaultval.boolean = true; } else { return false; -- cgit v1.2.3 From 8afe0b03a349cc259fb731ff2d2e0a13e47c166a Mon Sep 17 00:00:00 2001 From: Joshua Haberman Date: Thu, 20 Dec 2018 09:53:13 -0800 Subject: Some fixes for Ruby. --- upb/def.c | 55 ++++++++++++++++++++++++++++++++++++++++++++++++++++--- upb/def.h | 3 +++ upb/msgfactory.c | 9 --------- 3 files changed, 55 insertions(+), 12 deletions(-) (limited to 'upb/def.c') diff --git a/upb/def.c b/upb/def.c index ccbf407..83e5a99 100644 --- a/upb/def.c +++ b/upb/def.c @@ -355,6 +355,10 @@ const char *upb_enumdef_name(const upb_enumdef *e) { return shortdefname(e->full_name); } +const upb_filedef *upb_enumdef_file(const upb_enumdef *e) { + return e->file; +} + int32_t upb_enumdef_default(const upb_enumdef *e) { UPB_ASSERT(upb_enumdef_iton(e, e->defaultval)); return e->defaultval; @@ -606,6 +610,12 @@ bool upb_fielddef_hassubdef(const upb_fielddef *f) { return upb_fielddef_issubmsg(f) || upb_fielddef_type(f) == UPB_TYPE_ENUM; } +bool upb_fielddef_haspresence(const upb_fielddef *f) { + if (upb_fielddef_isseq(f)) return false; + if (upb_fielddef_issubmsg(f)) return true; + return f->file->syntax == UPB_SYNTAX_PROTO2; +} + static bool between(int32_t x, int32_t low, int32_t high) { return x >= low && x <= high; } @@ -624,6 +634,10 @@ const char *upb_msgdef_fullname(const upb_msgdef *m) { return m->full_name; } +const upb_filedef *upb_msgdef_file(const upb_msgdef *m) { + return m->file; +} + const char *upb_msgdef_name(const upb_msgdef *m) { return shortdefname(m->full_name); } @@ -1166,6 +1180,12 @@ static bool create_fielddef( * to the field_proto until later when we can properly resolve it. */ f->sub.unresolved = field_proto; + if (f->label_ == UPB_LABEL_REQUIRED && f->file->syntax == UPB_SYNTAX_PROTO3) { + upb_status_seterrf(ctx->status, "proto3 fields cannot be required (%s)", + f->full_name); + return false; + } + if (google_protobuf_FieldDescriptorProto_has_oneof_index(field_proto)) { int oneof_index = google_protobuf_FieldDescriptorProto_oneof_index(field_proto); @@ -1229,6 +1249,13 @@ static bool create_enumdef( values = google_protobuf_EnumDescriptorProto_value(enum_proto, &n); + if (n == 0) { + upb_status_seterrf(ctx->status, + "enums must contain at least one value (%s)", + e->full_name); + return false; + } + for (i = 0; i < n; i++) { const google_protobuf_EnumValueDescriptorProto *value = values[i]; upb_stringview name = google_protobuf_EnumValueDescriptorProto_name(value); @@ -1236,6 +1263,13 @@ static bool create_enumdef( int32_t num = google_protobuf_EnumValueDescriptorProto_number(value); upb_value v = upb_value_int32(num); + if (n == 0 && e->file->syntax == UPB_SYNTAX_PROTO3 && num != 0) { + upb_status_seterrf(ctx->status, + "for proto3, the first enum value must be zero (%s)", + e->full_name); + return false; + } + if (upb_strtable_lookup(&e->ntoi, name2, NULL)) { upb_status_seterrf(ctx->status, "duplicate enum label '%s'", name2); return false; @@ -1399,9 +1433,24 @@ static bool resolve_fielddef(const symtab_addctx *ctx, const char *prefix, if (google_protobuf_FieldDescriptorProto_has_default_value(field_proto)) { upb_stringview defaultval = google_protobuf_FieldDescriptorProto_default_value(field_proto); + + if (f->file->syntax == UPB_SYNTAX_PROTO3) { + upb_status_seterrf(ctx->status, + "proto3 fields cannot have explicit defaults (%s)", + f->full_name); + return false; + } + + if (upb_fielddef_issubmsg(f)) { + upb_status_seterrf(ctx->status, + "message fields cannot have explicit defaults (%s)", + f->full_name); + return false; + } + if (!parse_default(ctx, defaultval.data, defaultval.size, f)) { - upb_status_seterrf(ctx->status, "bad default '" UPB_STRINGVIEW_FORMAT "'", - UPB_STRINGVIEW_ARGS(defaultval)); + upb_status_seterrf(ctx->status, "couldn't parse default for field (%s)", + f->full_name); return false; } } @@ -1532,7 +1581,7 @@ static bool build_filedef( } return true; -} + } static bool upb_symtab_addtotabs(upb_symtab *s, symtab_addctx *ctx, upb_status *status) { diff --git a/upb/def.h b/upb/def.h index e6fdf21..8664fb5 100644 --- a/upb/def.h +++ b/upb/def.h @@ -202,6 +202,7 @@ float upb_fielddef_defaultfloat(const upb_fielddef *f); double upb_fielddef_defaultdouble(const upb_fielddef *f); const char *upb_fielddef_defaultstr(const upb_fielddef *f, size_t *len); bool upb_fielddef_hassubdef(const upb_fielddef *f); +bool upb_fielddef_haspresence(const upb_fielddef *f); const upb_msgdef *upb_fielddef_msgsubdef(const upb_fielddef *f); const upb_enumdef *upb_fielddef_enumsubdef(const upb_fielddef *f); @@ -349,6 +350,7 @@ class upb::MessageDef { UPB_BEGIN_EXTERN_C const char *upb_msgdef_fullname(const upb_msgdef *m); +const upb_filedef *upb_msgdef_file(const upb_msgdef *m); const char *upb_msgdef_name(const upb_msgdef *m); int upb_msgdef_numoneofs(const upb_msgdef *m); upb_syntax_t upb_msgdef_syntax(const upb_msgdef *m); @@ -485,6 +487,7 @@ UPB_BEGIN_EXTERN_C const char *upb_enumdef_fullname(const upb_enumdef *e); const char *upb_enumdef_name(const upb_enumdef *e); +const upb_filedef *upb_enumdef_file(const upb_enumdef *e); int32_t upb_enumdef_default(const upb_enumdef *e); int upb_enumdef_numvals(const upb_enumdef *e); diff --git a/upb/msgfactory.c b/upb/msgfactory.c index 73347b8..63df49e 100644 --- a/upb/msgfactory.c +++ b/upb/msgfactory.c @@ -46,15 +46,6 @@ static uint8_t upb_msg_fielddefsize(const upb_fielddef *f) { } } -static bool upb_fielddef_haspresence(const upb_fielddef *f) { - if (upb_fielddef_isseq(f)) return false; - if (upb_fielddef_issubmsg(f)) return true; - - /* Primitive field: return true unless there is a message that specifies - * presence should not exist. */ - return upb_msgdef_syntax(upb_fielddef_containingtype(f)) == UPB_SYNTAX_PROTO2; -} - /** upb_msglayout *************************************************************/ -- cgit v1.2.3 From d0c8bb84f449e7fc94a85ac1594cb8090f3c9bb8 Mon Sep 17 00:00:00 2001 From: Joshua Haberman Date: Mon, 31 Dec 2018 20:00:22 -0800 Subject: WIP. --- upb/def.c | 9 ++++++--- upb/msg.h | 2 +- 2 files changed, 7 insertions(+), 4 deletions(-) (limited to 'upb/def.c') diff --git a/upb/def.c b/upb/def.c index 83e5a99..aff8401 100644 --- a/upb/def.c +++ b/upb/def.c @@ -916,7 +916,7 @@ const upb_enumdef *upb_symtab_lookupenum(const upb_symtab *s, const char *sym) { * 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)) { __builtin_trap(); return false; } +#define CHK(x) if (!(x)) { return false; } #define CHK_OOM(x) if (!(x)) { upb_upberr_setoom(ctx->status); return false; } typedef struct { @@ -1105,6 +1105,7 @@ static bool parse_default(const symtab_addctx *ctx, const char *str, size_t len, case UPB_TYPE_BYTES: /* XXX: need to interpret the C-escaped value. */ f->defaultval.str = newstr(ctx->alloc, str, len); + break; case UPB_TYPE_MESSAGE: /* Should not have a default value. */ return false; @@ -1449,8 +1450,10 @@ static bool resolve_fielddef(const symtab_addctx *ctx, const char *prefix, } if (!parse_default(ctx, defaultval.data, defaultval.size, f)) { - upb_status_seterrf(ctx->status, "couldn't parse default for field (%s)", - f->full_name); + upb_status_seterrf(ctx->status, + "couldn't parse default '" UPB_STRINGVIEW_FORMAT + "' for field (%s)", + UPB_STRINGVIEW_ARGS(defaultval), f->full_name); return false; } } diff --git a/upb/msg.h b/upb/msg.h index 6061470..4529478 100644 --- a/upb/msg.h +++ b/upb/msg.h @@ -99,7 +99,7 @@ UPB_INLINE bool upb_stringview_eql(upb_stringview a, upb_stringview b) { } #define UPB_STRINGVIEW_FORMAT "%.*s" -#define UPB_STRINGVIEW_ARGS(view) view.size, view.data +#define UPB_STRINGVIEW_ARGS(view) (int)(view).size, (view).data #define UPB_STRINGVIEW_INIT(ptr, len) {ptr, len} -- cgit v1.2.3 From 31e0997c1abaa531505d28e36473f1c972ca0849 Mon Sep 17 00:00:00 2001 From: Joshua Haberman Date: Wed, 2 Jan 2019 13:00:53 -0800 Subject: Some bugfixes. --- upb/def.c | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++++--------- upb/def.h | 2 +- 2 files changed, 53 insertions(+), 10 deletions(-) (limited to 'upb/def.c') diff --git a/upb/def.c b/upb/def.c index aff8401..27de875 100644 --- a/upb/def.c +++ b/upb/def.c @@ -295,7 +295,7 @@ static bool assign_msg_indices(upb_msgdef *m, upb_status *s) { for(upb_msg_oneof_begin(&k, m), i = 0; !upb_msg_oneof_done(&k); upb_msg_oneof_next(&k), i++) { - upb_oneofdef *o = upb_msg_iter_oneof(&k); + upb_oneofdef *o = (upb_oneofdef*)upb_msg_iter_oneof(&k); o->index = i; } @@ -570,8 +570,13 @@ const char *upb_fielddef_defaultstr(const upb_fielddef *f, size_t *len) { UPB_ASSERT(upb_fielddef_type(f) == UPB_TYPE_STRING || upb_fielddef_type(f) == UPB_TYPE_BYTES || upb_fielddef_type(f) == UPB_TYPE_ENUM); - if (len) *len = str->len; - return str->str; + if (str) { + if (len) *len = str->len; + return str->str; + } else { + if (len) *len = 0; + return NULL; + } } const upb_msgdef *upb_fielddef_msgsubdef(const upb_fielddef *f) { @@ -759,8 +764,8 @@ bool upb_msg_oneof_done(const upb_msg_oneof_iter *iter) { return upb_strtable_done(iter); } -upb_oneofdef *upb_msg_iter_oneof(const upb_msg_oneof_iter *iter) { - return (upb_oneofdef *)upb_value_getconstptr(upb_strtable_iter_value(iter)); +const upb_oneofdef *upb_msg_iter_oneof(const upb_msg_oneof_iter *iter) { + return unpack_def(upb_strtable_iter_value(iter), UPB_DEFTYPE_ONEOF); } void upb_msg_oneof_iter_setdone(upb_msg_oneof_iter *iter) { @@ -1026,13 +1031,15 @@ static bool create_oneofdef( const google_protobuf_OneofDescriptorProto *oneof_proto) { upb_oneofdef *o; upb_stringview name = google_protobuf_OneofDescriptorProto_name(oneof_proto); + upb_value v; o = (upb_oneofdef*)&m->oneofs[m->oneof_count++]; o->parent = m; o->full_name = makefullname(ctx, m->full_name, name); - CHK_OOM(symtab_add(ctx, o->full_name, pack_def(o, UPB_DEFTYPE_ONEOF))); - CHK_OOM(upb_strtable_insert3(&m->ntof, name.data, name.size, upb_value_ptr(o), - ctx->alloc)); + + v = pack_def(o, UPB_DEFTYPE_ONEOF); + CHK_OOM(symtab_add(ctx, o->full_name, v)); + CHK_OOM(upb_strtable_insert3(&m->ntof, name.data, name.size, v, ctx->alloc)); CHK_OOM(upb_inttable_init2(&o->itof, UPB_CTYPE_CONSTPTR, ctx->alloc)); CHK_OOM(upb_strtable_init2(&o->ntof, UPB_CTYPE_CONSTPTR, ctx->alloc)); @@ -1113,6 +1120,33 @@ static bool parse_default(const symtab_addctx *ctx, const char *str, size_t len, return true; } +static void set_default_default(const symtab_addctx *ctx, upb_fielddef *f) { + switch (upb_fielddef_type(f)) { + case UPB_TYPE_INT32: + case UPB_TYPE_INT64: + case UPB_TYPE_ENUM: + f->defaultval.sint = 0; + break; + case UPB_TYPE_UINT64: + case UPB_TYPE_UINT32: + f->defaultval.uint = 0; + break; + case UPB_TYPE_DOUBLE: + case UPB_TYPE_FLOAT: + f->defaultval.dbl = 0; + break; + case UPB_TYPE_STRING: + case UPB_TYPE_BYTES: + f->defaultval.str = newstr(ctx->alloc, NULL, 0); + break; + case UPB_TYPE_BOOL: + f->defaultval.boolean = false; + break; + case UPB_TYPE_MESSAGE: + break; + } +} + static bool create_fielddef( const symtab_addctx *ctx, const char *prefix, upb_msgdef *m, const google_protobuf_FieldDescriptorProto *field_proto) { @@ -1190,6 +1224,8 @@ static bool create_fielddef( if (google_protobuf_FieldDescriptorProto_has_oneof_index(field_proto)) { int oneof_index = google_protobuf_FieldDescriptorProto_oneof_index(field_proto); + upb_oneofdef *oneof; + upb_value v = upb_value_constptr(f); if (upb_fielddef_label(f) != UPB_LABEL_OPTIONAL) { upb_status_seterrf(ctx->status, @@ -1211,7 +1247,11 @@ static bool create_fielddef( return false; } - f->oneof = &m->oneofs[oneof_index]; + oneof = (upb_oneofdef*)&m->oneofs[oneof_index]; + f->oneof = oneof; + + CHK(upb_inttable_insert2(&oneof->itof, f->number_, v, alloc)); + CHK(upb_strtable_insert3(&oneof->ntof, name.data, name.size, v, alloc)); } else { f->oneof = NULL; } @@ -1246,6 +1286,7 @@ static bool create_enumdef( CHK_OOM(upb_strtable_init2(&e->ntoi, UPB_CTYPE_INT32, ctx->alloc)); CHK_OOM(upb_inttable_init2(&e->iton, UPB_CTYPE_CSTR, ctx->alloc)); + e->file = ctx->file; e->defaultval = 0; values = google_protobuf_EnumDescriptorProto_value(enum_proto, &n); @@ -1456,6 +1497,8 @@ static bool resolve_fielddef(const symtab_addctx *ctx, const char *prefix, UPB_STRINGVIEW_ARGS(defaultval), f->full_name); return false; } + } else { + set_default_default(ctx, f); } return true; diff --git a/upb/def.h b/upb/def.h index bd36d92..81b5659 100644 --- a/upb/def.h +++ b/upb/def.h @@ -429,7 +429,7 @@ void upb_msg_field_iter_setdone(upb_msg_field_iter *iter); void upb_msg_oneof_begin(upb_msg_oneof_iter *iter, const upb_msgdef *m); void upb_msg_oneof_next(upb_msg_oneof_iter *iter); bool upb_msg_oneof_done(const upb_msg_oneof_iter *iter); -upb_oneofdef *upb_msg_iter_oneof(const upb_msg_oneof_iter *iter); +const upb_oneofdef *upb_msg_iter_oneof(const upb_msg_oneof_iter *iter); void upb_msg_oneof_iter_setdone(upb_msg_oneof_iter *iter); UPB_END_EXTERN_C -- cgit v1.2.3 From cb26d883d1290ed258e5594454c2ffe0526b13f9 Mon Sep 17 00:00:00 2001 From: Joshua Haberman Date: Mon, 14 Jan 2019 10:56:58 -0800 Subject: WIP. --- google/protobuf/descriptor.upb.h | 8 +- tests/conformance_upb.c | 16 +-- tests/json/test_json.cc | 4 +- tests/pb/test_decoder.cc | 14 +-- tests/pb/test_encoder.cc | 9 +- tests/test_cpp.cc | 2 +- tests/test_util.h | 21 ++-- upb/bindings/lua/def.c | 9 +- upb/bindings/lua/msg.c | 13 +- upb/bindings/lua/upb/pb.c | 8 +- upb/decode.h | 8 +- upb/def.c | 41 ++++--- upb/def.h | 37 +++--- upb/encode.h | 8 +- upb/generated_util.h | 3 +- upb/handlers.c | 8 +- upb/handlers.h | 39 +++--- upb/json/parser.c | 259 ++++++++++++++++----------------------- upb/json/parser.h | 37 +++--- upb/json/parser.rl | 153 +++++++++-------------- upb/json/printer.c | 8 +- upb/json/printer.h | 14 ++- upb/msg.h | 28 ++--- upb/msgfactory.h | 12 +- upb/pb/compile_decoder.c | 2 +- upb/pb/decoder.c | 22 ++-- upb/pb/decoder.h | 28 +++-- upb/pb/decoder.int.h | 4 +- upb/pb/encoder.c | 22 ++-- upb/pb/encoder.h | 14 ++- upb/pb/textprinter.c | 26 ++-- upb/pb/textprinter.h | 75 +++++------- upb/sink.c | 70 ----------- upb/sink.h | 33 ++--- upb/table.int.h | 15 --- upb/upb.c | 75 +++++------- upb/upb.h | 161 +++++++++--------------- upbc/generator.cc | 8 +- 38 files changed, 555 insertions(+), 759 deletions(-) (limited to 'upb/def.c') diff --git a/google/protobuf/descriptor.upb.h b/google/protobuf/descriptor.upb.h index 32bccc7..7e62be5 100644 --- a/google/protobuf/descriptor.upb.h +++ b/google/protobuf/descriptor.upb.h @@ -16,7 +16,9 @@ #include "upb/decode.h" #include "upb/encode.h" #include "upb/port_def.inc" -UPB_BEGIN_EXTERN_C +#ifdef __cplusplus +extern "C" { +#endif struct google_protobuf_FileDescriptorSet; struct google_protobuf_FileDescriptorProto; @@ -1668,7 +1670,9 @@ UPB_INLINE void google_protobuf_GeneratedCodeInfo_Annotation_set_end(google_prot } -UPB_END_EXTERN_C +#ifdef __cplusplus +} /* extern "C" */ +#endif #include "upb/port_undef.inc" diff --git a/tests/conformance_upb.c b/tests/conformance_upb.c index e0a7d8c..cefac4c 100644 --- a/tests/conformance_upb.c +++ b/tests/conformance_upb.c @@ -130,7 +130,7 @@ void DoTest( } bool DoTestIo() { - upb_arena arena; + upb_arena *arena; upb_alloc *alloc; upb_status status; char *serialized_input; @@ -145,8 +145,8 @@ bool DoTestIo() { return false; } - upb_arena_init(&arena); - alloc = upb_arena_alloc(&arena); + arena = upb_arena_new(); + alloc = upb_arena_alloc(arena); serialized_input = upb_malloc(alloc, input_size); if (!CheckedRead(STDIN_FILENO, serialized_input, input_size)) { @@ -155,24 +155,26 @@ bool DoTestIo() { } request = conformance_ConformanceRequest_parsenew( - upb_stringview_make(serialized_input, input_size), &arena); - response = conformance_ConformanceResponse_new(&arena); + upb_stringview_make(serialized_input, input_size), arena); + response = conformance_ConformanceResponse_new(arena); if (request) { - DoTest(request, response, &arena); + DoTest(request, response, arena); } else { fprintf(stderr, "conformance_upb: parse of ConformanceRequest failed: %s\n", upb_status_errmsg(&status)); } serialized_output = conformance_ConformanceResponse_serialize( - response, &arena, &output_size); + response, arena, &output_size); CheckedWrite(STDOUT_FILENO, &output_size, sizeof(uint32_t)); CheckedWrite(STDOUT_FILENO, serialized_output, output_size); test_count++; + upb_arena_free(arena); + return true; } diff --git a/tests/json/test_json.cc b/tests/json/test_json.cc index b0fd3e3..1f7d364 100644 --- a/tests/json/test_json.cc +++ b/tests/json/test_json.cc @@ -174,9 +174,9 @@ void test_json_roundtrip_message(const char* json_src, VerboseParserEnvironment env(verbose); StringSink data_sink; upb::json::PrinterPtr printer = upb::json::PrinterPtr::Create( - env.env(), serialize_handlers, data_sink.Sink()); + env.arena(), serialize_handlers, data_sink.Sink()); upb::json::ParserPtr parser = upb::json::ParserPtr::Create( - env.env(), parser_method, NULL, printer.input(), false); + env.arena(), parser_method, NULL, printer.input(), false); env.ResetBytesSink(parser.input()); env.Reset(json_src, strlen(json_src), false, false); diff --git a/tests/pb/test_decoder.cc b/tests/pb/test_decoder.cc index ec7a788..b2dd812 100644 --- a/tests/pb/test_decoder.cc +++ b/tests/pb/test_decoder.cc @@ -452,10 +452,10 @@ void callback(const void *closure, upb::Handlers* h_ptr) { const upb::Handlers *global_handlers; upb::pb::DecoderMethodPtr global_method; -upb::pb::DecoderPtr CreateDecoder(upb::Environment* env, +upb::pb::DecoderPtr CreateDecoder(upb::Arena* arena, upb::pb::DecoderMethodPtr method, upb::Sink sink) { - upb::pb::DecoderPtr ret = upb::pb::DecoderPtr::Create(env, method, sink); + upb::pb::DecoderPtr ret = upb::pb::DecoderPtr::Create(arena, method, sink); ret.set_max_nesting(MAX_NESTING); return ret; } @@ -556,7 +556,7 @@ void do_run_decoder(VerboseParserEnvironment* env, upb::pb::DecoderPtr decoder, void run_decoder(const string& proto, const string* expected_output) { VerboseParserEnvironment env(filter_hash != 0); upb::Sink sink(global_handlers, &closures[0]); - upb::pb::DecoderPtr decoder = CreateDecoder(env.env(), global_method, sink); + upb::pb::DecoderPtr decoder = CreateDecoder(env.arena(), global_method, sink); env.ResetBytesSink(decoder.input()); for (size_t i = 0; i < proto.size(); i++) { for (size_t j = i; j < UPB_MIN(proto.size(), i + 5); j++) { @@ -872,10 +872,9 @@ void test_valid() { if (!filter_hash || filter_hash == testhash) { testhash = emptyhash; upb::Status status; - upb::Environment env; - env.ReportErrorsTo(&status); + upb::Arena arena; upb::Sink sink(global_handlers, &closures[0]); - upb::pb::DecoderPtr decoder = CreateDecoder(&env, global_method, sink); + upb::pb::DecoderPtr decoder = CreateDecoder(&arena, global_method, sink); output.clear(); bool ok = upb::PutBuffer(std::string(), decoder.input()); ASSERT(ok); @@ -1161,7 +1160,8 @@ void test_emptyhandlers(upb::SymbolTable* symtab, bool allowjit) { for (int i = 0; testdata[i].data; i++) { VerboseParserEnvironment env(filter_hash != 0); upb::Sink sink(global_method.dest_handlers(), &closures[0]); - upb::pb::DecoderPtr decoder = CreateDecoder(env.env(), global_method, sink); + upb::pb::DecoderPtr decoder = + CreateDecoder(env.arena(), global_method, sink); env.ResetBytesSink(decoder.input()); env.Reset(testdata[i].data, testdata[i].length, true, false); ASSERT(env.Start()); diff --git a/tests/pb/test_encoder.cc b/tests/pb/test_encoder.cc index 35c0e1e..7145097 100644 --- a/tests/pb/test_encoder.cc +++ b/tests/pb/test_encoder.cc @@ -24,7 +24,7 @@ void test_pb_roundtrip() { upb::Arena arena; google_protobuf_FileDescriptorSet *set = google_protobuf_FileDescriptorSet_parsenew( - upb_stringview_make(input.c_str(), input.size()), &arena); + upb_stringview_make(input.c_str(), input.size()), arena.ptr()); ASSERT(set); size_t n; const google_protobuf_FileDescriptorProto *const *files = @@ -33,7 +33,7 @@ void test_pb_roundtrip() { upb::Status status; bool ok = symtab.AddFile(files[0], &status); if (!ok) { - fprintf(stderr, "Error building def: %s\n", upb_status_errmsg(&status)); + fprintf(stderr, "Error building def: %s\n", status.error_message()); ASSERT(false); } upb::MessageDefPtr md = @@ -43,13 +43,12 @@ void test_pb_roundtrip() { ASSERT(encoder_handlers); const upb::pb::DecoderMethodPtr method = decoder_cache.Get(md); - upb::InlinedEnvironment<512> env; std::string output; upb::StringSink string_sink(&output); upb::pb::EncoderPtr encoder = - upb::pb::EncoderPtr::Create(&env, encoder_handlers, string_sink.input()); + upb::pb::EncoderPtr::Create(&arena, encoder_handlers, string_sink.input()); upb::pb::DecoderPtr decoder = - upb::pb::DecoderPtr::Create(&env, method, encoder.input()); + upb::pb::DecoderPtr::Create(&arena, method, encoder.input()); ok = upb::PutBuffer(input, decoder.input()); ASSERT(ok); ASSERT(input == output); diff --git a/tests/test_cpp.cc b/tests/test_cpp.cc index a5bfbc7..5e9a8dd 100644 --- a/tests/test_cpp.cc +++ b/tests/test_cpp.cc @@ -672,7 +672,7 @@ void DoNothingStringBufHandler(C* closure, const char *buf, size_t len) { } template -void DoNothingEndMessageHandler(C* closure, upb::Status *status) { +void DoNothingEndMessageHandler(C* closure, upb_status *status) { UPB_UNUSED(closure); UPB_UNUSED(status); } diff --git a/tests/test_util.h b/tests/test_util.h index 0b5ddd4..04ca3fb 100644 --- a/tests/test_util.h +++ b/tests/test_util.h @@ -30,15 +30,11 @@ upb_bufhandle global_handle; class VerboseParserEnvironment { public: /* Pass verbose=true to print detailed diagnostics to stderr. */ - VerboseParserEnvironment(bool verbose) : verbose_(verbose) { - env_.SetErrorFunction(&VerboseParserEnvironment::OnError, this); - } + VerboseParserEnvironment(bool verbose) : verbose_(verbose) {} static bool OnError(void *ud, const upb::Status* status) { VerboseParserEnvironment* env = static_cast(ud); - env->saw_error_ = true; - if (env->expect_error_ && env->verbose_) { fprintf(stderr, "Encountered error, as expected: "); } else if (!env->expect_error_) { @@ -56,7 +52,6 @@ class VerboseParserEnvironment { len_ = len; ofs_ = 0; expect_error_ = expect_error; - saw_error_ = false; end_ok_set_ = false; skip_until_ = may_skip ? 0 : -1; skipped_with_null_ = false; @@ -94,12 +89,12 @@ class VerboseParserEnvironment { bool CheckConsistency() { /* If we called end (which we should only do when previous bytes are fully * accepted), then end() should return true iff there were no errors. */ - if (end_ok_set_ && end_ok_ != !saw_error_) { + if (end_ok_set_ && end_ok_ != status_.ok()) { fprintf(stderr, "End() status and saw_error didn't match.\n"); return false; } - if (expect_error_ && !saw_error_) { + if (expect_error_ && status_.ok()) { fprintf(stderr, "Expected error but saw none.\n"); return false; } @@ -158,8 +153,9 @@ class VerboseParserEnvironment { } } - if (saw_error_) + if (!status_.ok()) { return false; + } if (parsed > bytes && skip_until_ >= 0) { skip_until_ = ofs_ + parsed; @@ -175,12 +171,14 @@ class VerboseParserEnvironment { } size_t ofs() { return ofs_; } - upb::Environment* env() { return &env_; } bool SkippedWithNull() { return skipped_with_null_; } + upb::Arena* arena() { return &arena_; } + private: - upb::Environment env_; + upb::Arena arena_; + upb::Status status_; upb::BytesSink sink_; const char* buf_; size_t len_; @@ -188,7 +186,6 @@ class VerboseParserEnvironment { size_t ofs_; void *subc_; bool expect_error_; - bool saw_error_; bool end_ok_; bool end_ok_set_; diff --git a/upb/bindings/lua/def.c b/upb/bindings/lua/def.c index 76510be..c38b6d1 100644 --- a/upb/bindings/lua/def.c +++ b/upb/bindings/lua/def.c @@ -15,13 +15,14 @@ #define LUPB_SYMTAB "lupb.symtab" #define LUPB_OBJCACHE "lupb.objcache" -#define CHK(pred) do { \ - upb_status status = UPB_STATUS_INIT; \ - pred; \ +#define CHK(pred) \ + do { \ + upb_status status; \ + upb_status_clear(&status); \ + pred; \ lupb_checkstatus(L, &status); \ } while (0) - /* lupb_wrapper ***************************************************************/ /* Wrappers around upb objects. */ diff --git a/upb/bindings/lua/msg.c b/upb/bindings/lua/msg.c index e983f46..df5a143 100644 --- a/upb/bindings/lua/msg.c +++ b/upb/bindings/lua/msg.c @@ -100,16 +100,21 @@ static void *lupb_newuserdata(lua_State *L, size_t size, const char *type) { * it is an internal memory management detail. Other objects refer to this * object from their userdata to keep the arena-owned data alive. */ +typedef struct { + upb_arena *arena; +} lupb_arena; + upb_arena *lupb_arena_check(lua_State *L, int narg) { - return luaL_checkudata(L, narg, LUPB_ARENA); + lupb_arena *a = luaL_checkudata(L, narg, LUPB_ARENA); + return a ? a->arena : NULL; } int lupb_arena_new(lua_State *L) { - upb_arena *a = lupb_newuserdata(L, sizeof(upb_arena), LUPB_ARENA); + lupb_arena *a = lupb_newuserdata(L, sizeof(lupb_arena), LUPB_ARENA); /* TODO(haberman): use Lua alloc func as block allocator? Would need to * verify that all cases of upb_malloc in msg/table are longjmp-safe. */ - upb_arena_init(a); + a->arena = upb_arena_new(); return 1; } @@ -140,7 +145,7 @@ static void lupb_arena_initsingleton(lua_State *L) { static int lupb_arena_gc(lua_State *L) { upb_arena *a = lupb_arena_check(L, 1); - upb_arena_uninit(a); + upb_arena_free(a); return 0; } diff --git a/upb/bindings/lua/upb/pb.c b/upb/bindings/lua/upb/pb.c index bca2ee8..2edefe0 100644 --- a/upb/bindings/lua/upb/pb.c +++ b/upb/bindings/lua/upb/pb.c @@ -27,17 +27,15 @@ static int lupb_pb_decode(lua_State *L) { static int lupb_pb_encode(lua_State *L) { const upb_msglayout *layout; const upb_msg *msg = lupb_msg_checkmsg2(L, 1, &layout); - upb_arena arena; + upb_arena *arena = upb_arena_new(); size_t size; char *result; - upb_arena_init(&arena); - - result = upb_encode(msg, (const void*)layout, &arena, &size); + result = upb_encode(msg, (const void*)layout, arena, &size); /* Free resources before we potentially bail on error. */ lua_pushlstring(L, result, size); - upb_arena_uninit(&arena); + upb_arena_free(arena); /* TODO(haberman): check for error. */ return 1; diff --git a/upb/decode.h b/upb/decode.h index 79774ed..790d7ef 100644 --- a/upb/decode.h +++ b/upb/decode.h @@ -7,10 +7,14 @@ #include "upb/msg.h" -UPB_BEGIN_EXTERN_C +#ifdef __cplusplus +extern "C" { +#endif bool upb_decode(upb_stringview buf, upb_msg *msg, const upb_msglayout *l); -UPB_END_EXTERN_C +#ifdef __cplusplus +} /* extern "C" */ +#endif #endif /* UPB_DECODE_H_ */ diff --git a/upb/def.c b/upb/def.c index 27de875..c744138 100644 --- a/upb/def.c +++ b/upb/def.c @@ -125,7 +125,7 @@ static upb_value pack_def(const void *ptr, upb_deftype_t type) { } struct upb_symtab { - upb_arena arena; + upb_arena *arena; upb_strtable syms; /* full_name -> packed def ptr */ upb_strtable files; /* file_name -> upb_filedef* */ }; @@ -224,7 +224,7 @@ static bool assign_msg_indices(upb_msgdef *m, upb_status *s) { fields = upb_gmalloc(n * sizeof(*fields)); if (!fields) { - upb_upberr_setoom(s); + upb_status_setoom(s); return false; } @@ -870,7 +870,7 @@ const upb_enumdef *upb_filedef_enum(const upb_filedef *f, int i) { } void upb_symtab_free(upb_symtab *s) { - upb_arena_uninit(&s->arena); + upb_arena_free(s->arena); upb_gfree(s); } @@ -882,12 +882,12 @@ upb_symtab *upb_symtab_new() { return NULL; } - upb_arena_init(&s->arena); - alloc = upb_arena_alloc(&s->arena); + s->arena = upb_arena_new(); + alloc = upb_arena_alloc(s->arena); 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_arena_free(s->arena); upb_gfree(s); s = NULL; } @@ -922,7 +922,7 @@ const upb_enumdef *upb_symtab_lookupenum(const upb_symtab *s, const char *sym) { * 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; } +#define CHK_OOM(x) if (!(x)) { upb_status_setoom(ctx->status); return false; } typedef struct { const upb_symtab *symtab; @@ -1632,7 +1632,7 @@ static bool build_filedef( 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_alloc *alloc = upb_arena_alloc(s->arena); upb_strtable_iter iter; CHK_OOM(upb_strtable_insert3(&s->files, file->name, strlen(file->name), @@ -1652,9 +1652,9 @@ static bool upb_symtab_addtotabs(upb_symtab *s, symtab_addctx *ctx, bool upb_symtab_addfile(upb_symtab *s, const google_protobuf_FileDescriptorProto *file_proto, upb_status *status) { - upb_arena tmparena; + upb_arena *tmparena = upb_arena_new(); upb_strtable addtab; - upb_alloc *alloc = upb_arena_alloc(&s->arena); + upb_alloc *alloc = upb_arena_alloc(s->arena); upb_filedef *file = upb_malloc(alloc, sizeof(*file)); bool ok; symtab_addctx ctx; @@ -1662,18 +1662,16 @@ bool upb_symtab_addfile(upb_symtab *s, ctx.file = file; ctx.symtab = s; ctx.alloc = alloc; - ctx.tmp = upb_arena_alloc(&tmparena); + ctx.tmp = upb_arena_alloc(tmparena); ctx.addtab = &addtab; ctx.status = status; - upb_arena_init(&tmparena); - ok = file && upb_strtable_init2(&addtab, UPB_CTYPE_CONSTPTR, ctx.tmp) && build_filedef(&ctx, file, file_proto) && upb_symtab_addtotabs(s, &ctx, status); - upb_arena_uninit(&tmparena); + upb_arena_free(tmparena); return ok; } @@ -1685,19 +1683,22 @@ bool _upb_symtab_loaddefinit(upb_symtab *s, const upb_def_init *init) { * print errors to stderr instead of returning error status to the user. */ upb_def_init **deps = init->deps; google_protobuf_FileDescriptorProto *file; - upb_arena arena; - upb_status status = UPB_STATUS_INIT; + upb_arena *arena; + upb_status status; + + upb_status_clear(&status); if (upb_strtable_lookup(&s->files, init->filename, NULL)) { return true; } + arena = upb_arena_new(); + for (; *deps; deps++) { if (!_upb_symtab_loaddefinit(s, *deps)) goto err; } - upb_arena_init(&arena); - file = google_protobuf_FileDescriptorProto_parsenew(init->descriptor, &arena); + file = google_protobuf_FileDescriptorProto_parsenew(init->descriptor, arena); if (!file) { upb_status_seterrf( @@ -1710,13 +1711,13 @@ bool _upb_symtab_loaddefinit(upb_symtab *s, const upb_def_init *init) { if (!upb_symtab_addfile(s, file, &status)) goto err; - upb_arena_uninit(&arena); + upb_arena_free(arena); return true; err: fprintf(stderr, "Error loading compiled-in descriptor: %s\n", upb_status_errmsg(&status)); - upb_arena_uninit(&arena); + upb_arena_free(arena); return false; } diff --git a/upb/def.h b/upb/def.h index fb8a71d..b1cf275 100644 --- a/upb/def.h +++ b/upb/def.h @@ -56,7 +56,9 @@ typedef struct upb_symtab upb_symtab; * protobuf wire format. */ #define UPB_MAX_FIELDNUMBER ((1 << 29) - 1) -UPB_BEGIN_EXTERN_C +#ifdef __cplusplus +extern "C" { +#endif const char *upb_fielddef_fullname(const upb_fielddef *f); upb_fieldtype_t upb_fielddef_type(const upb_fielddef *f); @@ -93,9 +95,8 @@ const upb_enumdef *upb_fielddef_enumsubdef(const upb_fielddef *f); /* Internal only. */ uint32_t upb_fielddef_selectorbase(const upb_fielddef *f); -UPB_END_EXTERN_C - #ifdef __cplusplus +} /* extern "C" */ /* A upb_fielddef describes a single field in a message. It is most often * found as a part of a upb_msgdef, but can also stand alone to represent @@ -228,7 +229,9 @@ class upb::FieldDefPtr { /* upb_oneofdef ***************************************************************/ -UPB_BEGIN_EXTERN_C +#ifdef __cplusplus +extern "C" { +#endif typedef upb_inttable_iter upb_oneof_iter; @@ -262,9 +265,8 @@ void upb_oneof_iter_setdone(upb_oneof_iter *iter); bool upb_oneof_iter_isequal(const upb_oneof_iter *iter1, const upb_oneof_iter *iter2); -UPB_END_EXTERN_C - #ifdef __cplusplus +} /* extern "C" */ /* Class that represents a oneof. */ class upb::OneofDefPtr { @@ -365,7 +367,9 @@ typedef upb_strtable_iter upb_msg_oneof_iter; #define UPB_TIMESTAMP_SECONDS 1 #define UPB_TIMESTAMP_NANOS 2 -UPB_BEGIN_EXTERN_C +#ifdef __cplusplus +extern "C" { +#endif const char *upb_msgdef_fullname(const upb_msgdef *m); const upb_filedef *upb_msgdef_file(const upb_msgdef *m); @@ -441,9 +445,8 @@ void upb_msg_oneof_iter_setdone(upb_msg_oneof_iter * iter); bool upb_msg_oneof_iter_isequal(const upb_msg_oneof_iter *iter1, const upb_msg_oneof_iter *iter2); -UPB_END_EXTERN_C - #ifdef __cplusplus +} /* extern "C" */ /* Structure that describes a single .proto message type. */ class upb::MessageDefPtr { @@ -711,7 +714,9 @@ class upb::EnumDefPtr { /* upb_filedef ****************************************************************/ -UPB_BEGIN_EXTERN_C +#ifdef __cplusplus +extern "C" { +#endif const char *upb_filedef_name(const upb_filedef *f); const char *upb_filedef_package(const upb_filedef *f); @@ -725,9 +730,8 @@ 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 - #ifdef __cplusplus +} /* extern "C" */ /* Class that represents a .proto file with some things defined in it. * @@ -773,7 +777,9 @@ class upb::FileDefPtr { /* upb_symtab *****************************************************************/ -UPB_BEGIN_EXTERN_C +#ifdef __cplusplus +extern "C" { +#endif upb_symtab *upb_symtab_new(); void upb_symtab_free(upb_symtab* s); @@ -795,9 +801,8 @@ typedef struct upb_def_init { bool _upb_symtab_loaddefinit(upb_symtab *s, const upb_def_init *init); -UPB_END_EXTERN_C - #ifdef __cplusplus +} /* extern "C" */ /* Non-const methods in upb::SymbolTable are NOT thread-safe. */ class upb::SymbolTable { @@ -823,7 +828,7 @@ class upb::SymbolTable { /* Adds the given serialized FileDescriptorProto to the pool. */ bool AddFile(const google_protobuf_FileDescriptorProto *file_proto, Status *status) { - return upb_symtab_addfile(ptr_.get(), file_proto, status); + return upb_symtab_addfile(ptr_.get(), file_proto, status->ptr()); } private: diff --git a/upb/encode.h b/upb/encode.h index 1a451b0..6842777 100644 --- a/upb/encode.h +++ b/upb/encode.h @@ -7,11 +7,15 @@ #include "upb/msg.h" -UPB_BEGIN_EXTERN_C +#ifdef __cplusplus +extern "C" { +#endif char *upb_encode(const void *msg, const upb_msglayout *l, upb_arena *arena, size_t *size); -UPB_END_EXTERN_C +#ifdef __cplusplus +} /* extern "C" */ +#endif #endif /* UPB_ENCODE_H_ */ diff --git a/upb/generated_util.h b/upb/generated_util.h index 3989f1e..657280f 100644 --- a/upb/generated_util.h +++ b/upb/generated_util.h @@ -54,10 +54,9 @@ UPB_INLINE void *_upb_array_resize_accessor(void *msg, size_t ofs, size_t size, size_t new_size = UPB_MAX(arr->size, 4); size_t old_bytes = arr->size * elem_size; size_t new_bytes; - upb_alloc *alloc = upb_arena_alloc(arr->arena); while (new_size < size) new_size *= 2; new_bytes = new_size * elem_size; - arr->data = upb_realloc(alloc, arr->data, old_bytes, new_bytes); + arr->data = upb_arena_realloc(arena, arr->data, old_bytes, new_bytes); if (!arr->data) { return NULL; } diff --git a/upb/handlers.c b/upb/handlers.c index ca978bf..aa23b46 100644 --- a/upb/handlers.c +++ b/upb/handlers.c @@ -390,7 +390,7 @@ uint32_t upb_handlers_selectorcount(const upb_fielddef *f) { /* upb_handlercache ***********************************************************/ struct upb_handlercache { - upb_arena arena; + upb_arena *arena; upb_inttable tab; /* maps upb_msgdef* -> upb_handlers*. */ upb_inttable cleanup_; upb_handlers_callback *callback; @@ -407,7 +407,7 @@ const upb_handlers *upb_handlercache_get(upb_handlercache *c, return upb_value_getptr(v); } - h = upb_handlers_new(md, c, &c->arena); + h = upb_handlers_new(md, c, c->arena); v = upb_value_ptr(h); if (!h) return NULL; @@ -442,7 +442,7 @@ upb_handlercache *upb_handlercache_new(upb_handlers_callback *callback, if (!cache) return NULL; - upb_arena_init(&cache->arena); + cache->arena = upb_arena_new(); cache->callback = callback; cache->closure = closure; @@ -470,7 +470,7 @@ void upb_handlercache_free(upb_handlercache *cache) { upb_inttable_uninit(&cache->tab); upb_inttable_uninit(&cache->cleanup_); - upb_arena_uninit(&cache->arena); + upb_arena_free(cache->arena); upb_gfree(cache); } diff --git a/upb/handlers.h b/upb/handlers.h index 44cad18..764e83e 100644 --- a/upb/handlers.h +++ b/upb/handlers.h @@ -157,7 +157,9 @@ typedef size_t upb_string_handlerfunc(void *c, const void *hd, const char *buf, struct upb_handlers; typedef struct upb_handlers upb_handlers; -UPB_BEGIN_EXTERN_C +#ifdef __cplusplus +extern "C" { +#endif /* Mutating accessors. */ const upb_status *upb_handlers_status(upb_handlers *h); @@ -235,9 +237,8 @@ UPB_INLINE upb_selector_t upb_handlers_getendselector(upb_selector_t start) { uint32_t upb_handlers_selectorbaseoffset(const upb_fielddef *f); uint32_t upb_handlers_selectorcount(const upb_fielddef *f); -UPB_END_EXTERN_C - #ifdef __cplusplus +} /* extern "C" */ namespace upb { typedef upb_handlers Handlers; @@ -303,7 +304,9 @@ template class upb::Handler { const upb_handlerattr& attr() const { return attr_; } private: - UPB_DISALLOW_COPY_AND_ASSIGN(Handler) + Handler(const Handler&) = delete; + Handler& operator=(const Handler&) = delete; + FuncPtr handler_; mutable upb_handlerattr attr_; mutable bool registered_; @@ -334,7 +337,8 @@ class upb::HandlersPtr { typedef Handler StartFieldHandler; typedef Handler EndFieldHandler; typedef Handler StartMessageHandler; - typedef Handler EndMessageHandler; + typedef Handler + EndMessageHandler; typedef Handler StartStringHandler; typedef Handler @@ -590,7 +594,9 @@ class upb::HandlersPtr { /* upb_handlercache ***********************************************************/ -UPB_BEGIN_EXTERN_C +#ifdef __cplusplus +extern "C" { +#endif struct upb_handlercache; typedef struct upb_handlercache upb_handlercache; @@ -605,9 +611,8 @@ const upb_handlers *upb_handlercache_get(upb_handlercache *cache, bool upb_handlercache_addcleanup(upb_handlercache *h, void *p, upb_handlerfree *hfree); -UPB_END_EXTERN_C - #ifdef __cplusplus +} /* extern "C" */ class upb::HandlerCache { public: @@ -631,8 +636,6 @@ class upb::HandlerCache { /* upb_byteshandler ***********************************************************/ -UPB_BEGIN_EXTERN_C - typedef struct { upb_func *func; @@ -665,6 +668,10 @@ UPB_INLINE void upb_byteshandler_init(upb_byteshandler *handler) { *handler = init; } +#ifdef __cplusplus +extern "C" { +#endif + /* Caller must ensure that "d" outlives the handlers. */ bool upb_byteshandler_setstartstr(upb_byteshandler *h, upb_startstr_handlerfunc *func, void *d); @@ -674,16 +681,18 @@ bool upb_byteshandler_setendstr(upb_byteshandler *h, upb_endfield_handlerfunc *func, void *d); #ifdef __cplusplus +} /* extern "C" */ + namespace upb { typedef upb_byteshandler BytesHandler; } #endif -UPB_END_EXTERN_C - /** Message handlers ******************************************************************/ -UPB_BEGIN_EXTERN_C +#ifdef __cplusplus +extern "C" { +#endif /* These are the handlers used internally by upb_msgfactory_getmergehandlers(). * They write scalar data to a known offset from the message pointer. @@ -710,7 +719,9 @@ bool upb_msg_getscalarhandlerdata(const upb_handlers *h, -UPB_END_EXTERN_C +#ifdef __cplusplus +} /* extern "C" */ +#endif #include "upb/handlers-inl.h" diff --git a/upb/json/parser.c b/upb/json/parser.c index 1dac800..a594bfd 100644 --- a/upb/json/parser.c +++ b/upb/json/parser.c @@ -212,7 +212,7 @@ typedef struct { } upb_jsonparser_frame; struct upb_json_parser { - upb_env *env; + upb_arena *arena; const upb_json_parsermethod *method; upb_bytessink input_; @@ -221,7 +221,7 @@ struct upb_json_parser { upb_jsonparser_frame *top; upb_jsonparser_frame *limit; - upb_status status; + upb_status *status; /* Ragel's internal parsing stack for the parsing state machine. */ int current_state; @@ -259,7 +259,7 @@ struct upb_json_parser { }; struct upb_json_codecache { - upb_arena arena; + upb_arena *arena; upb_inttable methods; /* upb_msgdef* -> upb_json_parsermethod* */ }; @@ -277,7 +277,7 @@ static upb_jsonparser_any_frame *json_parser_any_frame_new( upb_json_parser *p) { upb_jsonparser_any_frame *frame; - frame = upb_env_malloc(p->env, sizeof(upb_jsonparser_any_frame)); + frame = upb_arena_malloc(p->arena, sizeof(upb_jsonparser_any_frame)); frame->encoder_handlercache = upb_pb_encoder_newcache(); frame->parser_codecache = upb_json_codecache_new(); @@ -301,12 +301,12 @@ static void json_parser_any_frame_set_payload_type( /* Initialize encoder. */ h = upb_handlercache_get(frame->encoder_handlercache, payload_type); - encoder = upb_pb_encoder_create(p->env, h, frame->stringsink.sink); + encoder = upb_pb_encoder_create(p->arena, h, frame->stringsink.sink); /* Initialize parser. */ parser_method = upb_json_codecache_get(frame->parser_codecache, payload_type); upb_sink_reset(&frame->sink, h, encoder); - frame->parser = upb_json_parser_create(p->env, parser_method, p->symtab, + frame->parser = upb_json_parser_create(p->arena, parser_method, p->symtab, frame->sink, p->ignore_json_unknown); } @@ -372,8 +372,7 @@ static upb_selector_t parser_getsel(upb_json_parser *p) { static bool check_stack(upb_json_parser *p) { if ((p->top + 1) == p->limit) { - upb_status_seterrmsg(&p->status, "Nesting too deep"); - upb_env_reporterror(p->env, &p->status); + upb_status_seterrmsg(p->status, "Nesting too deep"); return false; } @@ -468,10 +467,9 @@ static bool base64_push(upb_json_parser *p, upb_selector_t sel, const char *ptr, char output[3]; if (limit - ptr < 4) { - upb_status_seterrf(&p->status, + upb_status_seterrf(p->status, "Base64 input for bytes field not a multiple of 4: %s", upb_fielddef_name(p->top->f)); - upb_env_reporterror(p->env, &p->status); return false; } @@ -495,10 +493,9 @@ static bool base64_push(upb_json_parser *p, upb_selector_t sel, const char *ptr, otherchar: if (nonbase64(ptr[0]) || nonbase64(ptr[1]) || nonbase64(ptr[2]) || nonbase64(ptr[3]) ) { - upb_status_seterrf(&p->status, + upb_status_seterrf(p->status, "Non-base64 characters in bytes field: %s", upb_fielddef_name(p->top->f)); - upb_env_reporterror(p->env, &p->status); return false; } if (ptr[2] == '=') { uint32_t val; @@ -536,11 +533,10 @@ otherchar: } badpadding: - upb_status_seterrf(&p->status, + upb_status_seterrf(p->status, "Incorrect base64 padding for field: %s (%.*s)", upb_fielddef_name(p->top->f), 4, ptr); - upb_env_reporterror(p->env, &p->status); return false; } @@ -584,10 +580,9 @@ static bool accumulate_realloc(upb_json_parser *p, size_t need) { new_size = saturating_multiply(new_size, 2); } - mem = upb_env_realloc(p->env, p->accumulate_buf, old_size, new_size); + mem = upb_arena_realloc(p->arena, p->accumulate_buf, old_size, new_size); if (!mem) { - upb_status_seterrmsg(&p->status, "Out of memory allocating buffer."); - upb_env_reporterror(p->env, &p->status); + upb_status_seterrmsg(p->status, "Out of memory allocating buffer."); return false; } @@ -610,8 +605,7 @@ static bool accumulate_append(upb_json_parser *p, const char *buf, size_t len, } if (!checked_add(p->accumulated_len, len, &need)) { - upb_status_seterrmsg(&p->status, "Integer overflow."); - upb_env_reporterror(p->env, &p->status); + upb_status_seterrmsg(p->status, "Integer overflow."); return false; } @@ -689,8 +683,7 @@ static bool multipart_text(upb_json_parser *p, const char *buf, size_t len, switch (p->multipart_state) { case MULTIPART_INACTIVE: upb_status_seterrmsg( - &p->status, "Internal error: unexpected state MULTIPART_INACTIVE"); - upb_env_reporterror(p->env, &p->status); + p->status, "Internal error: unexpected state MULTIPART_INACTIVE"); return false; case MULTIPART_ACCUMULATE: @@ -1055,8 +1048,7 @@ static bool parse_number(upb_json_parser *p, bool is_quoted) { multipart_end(p); return true; } else { - upb_status_seterrf(&p->status, "error parsing number: %s", buf); - upb_env_reporterror(p->env, &p->status); + upb_status_seterrf(p->status, "error parsing number: %s", buf); multipart_end(p); return false; } @@ -1070,10 +1062,9 @@ static bool parser_putbool(upb_json_parser *p, bool val) { } if (upb_fielddef_type(p->top->f) != UPB_TYPE_BOOL) { - upb_status_seterrf(&p->status, + upb_status_seterrf(p->status, "Boolean value specified for non-bool field: %s", upb_fielddef_name(p->top->f)); - upb_env_reporterror(p->env, &p->status); return false; } @@ -1248,10 +1239,9 @@ static bool start_stringval(upb_json_parser *p) { multipart_startaccum(p); return true; } else { - upb_status_seterrf(&p->status, + upb_status_seterrf(p->status, "String specified for bool or submessage field: %s", upb_fielddef_name(p->top->f)); - upb_env_reporterror(p->env, &p->status); return false; } } @@ -1284,8 +1274,7 @@ static bool end_any_stringval(upb_json_parser *p) { payload_type = upb_symtab_lookupmsg2(p->symtab, buf, len); if (payload_type == NULL) { upb_status_seterrf( - &p->status, "Cannot find packed type: %.*s\n", (int)len, buf); - upb_env_reporterror(p->env, &p->status); + p->status, "Cannot find packed type: %.*s\n", (int)len, buf); return false; } @@ -1294,8 +1283,7 @@ static bool end_any_stringval(upb_json_parser *p) { return true; } else { upb_status_seterrf( - &p->status, "Invalid type url: %.*s\n", (int)len, buf); - upb_env_reporterror(p->env, &p->status); + p->status, "Invalid type url: %.*s\n", (int)len, buf); return false; } } @@ -1347,8 +1335,7 @@ static bool end_stringval_nontop(upb_json_parser *p) { upb_selector_t sel = parser_getsel(p); upb_sink_putint32(&p->top->sink, sel, int_val); } else { - upb_status_seterrf(&p->status, "Enum value unknown: '%.*s'", len, buf); - upb_env_reporterror(p->env, &p->status); + upb_status_seterrf(p->status, "Enum value unknown: '%.*s'", len, buf); } break; @@ -1365,8 +1352,7 @@ static bool end_stringval_nontop(upb_json_parser *p) { default: UPB_ASSERT(false); - upb_status_seterrmsg(&p->status, "Internal error in JSON decoder"); - upb_env_reporterror(p->env, &p->status); + upb_status_seterrmsg(p->status, "Internal error in JSON decoder"); ok = false; break; } @@ -1445,25 +1431,22 @@ static bool end_duration_base(upb_json_parser *p, const char *ptr) { memcpy(seconds_buf, buf, fraction_start); seconds = strtol(seconds_buf, &end, 10); if (errno == ERANGE || end != seconds_buf + fraction_start) { - upb_status_seterrf(&p->status, "error parsing duration: %s", + upb_status_seterrf(p->status, "error parsing duration: %s", seconds_buf); - upb_env_reporterror(p->env, &p->status); return false; } if (seconds > 315576000000) { - upb_status_seterrf(&p->status, "error parsing duration: " + upb_status_seterrf(p->status, "error parsing duration: " "maximum acceptable value is " "315576000000"); - upb_env_reporterror(p->env, &p->status); return false; } if (seconds < -315576000000) { - upb_status_seterrf(&p->status, "error parsing duration: " + upb_status_seterrf(p->status, "error parsing duration: " "minimum acceptable value is " "-315576000000"); - upb_env_reporterror(p->env, &p->status); return false; } @@ -1472,9 +1455,8 @@ static bool end_duration_base(upb_json_parser *p, const char *ptr) { memcpy(nanos_buf + 1, buf + fraction_start, len - fraction_start); val = strtod(nanos_buf, &end); if (errno == ERANGE || end != nanos_buf + len - fraction_start + 1) { - upb_status_seterrf(&p->status, "error parsing duration: %s", + upb_status_seterrf(p->status, "error parsing duration: %s", nanos_buf); - upb_env_reporterror(p->env, &p->status); return false; } @@ -1500,7 +1482,7 @@ static bool end_duration_base(upb_json_parser *p, const char *ptr) { upb_sink_putint32(&p->top->sink, parser_getsel(p), nanos); end_member(p); - /* Continue previous environment */ + /* Continue previous arena */ multipart_startaccum(p); return true; @@ -1530,8 +1512,7 @@ static bool end_timestamp_base(upb_json_parser *p, const char *ptr) { /* Parse seconds */ if (strptime(timestamp_buf, "%FT%H:%M:%S%Z", &p->tm) == NULL) { - upb_status_seterrf(&p->status, "error parsing timestamp: %s", buf); - upb_env_reporterror(p->env, &p->status); + upb_status_seterrf(p->status, "error parsing timestamp: %s", buf); return false; } @@ -1564,9 +1545,8 @@ static bool end_timestamp_fraction(upb_json_parser *p, const char *ptr) { buf = accumulate_getptr(p, &len); if (len > 10) { - upb_status_seterrf(&p->status, + upb_status_seterrf(p->status, "error parsing timestamp: at most 9-digit fraction."); - upb_env_reporterror(p->env, &p->status); return false; } @@ -1576,9 +1556,8 @@ static bool end_timestamp_fraction(upb_json_parser *p, const char *ptr) { val = strtod(nanos_buf, &end); if (errno == ERANGE || end != nanos_buf + len + 1) { - upb_status_seterrf(&p->status, "error parsing timestamp nanos: %s", + upb_status_seterrf(p->status, "error parsing timestamp nanos: %s", nanos_buf); - upb_env_reporterror(p->env, &p->status); return false; } @@ -1620,8 +1599,7 @@ static bool end_timestamp_zone(upb_json_parser *p, const char *ptr) { if (buf[0] != 'Z') { if (sscanf(buf + 1, "%2d:00", &hours) != 1) { - upb_status_seterrf(&p->status, "error parsing timestamp offset"); - upb_env_reporterror(p->env, &p->status); + upb_status_seterrf(p->status, "error parsing timestamp offset"); return false; } @@ -1637,10 +1615,9 @@ static bool end_timestamp_zone(upb_json_parser *p, const char *ptr) { /* Check timestamp boundary */ if (seconds < -62135596800) { - upb_status_seterrf(&p->status, "error parsing timestamp: " + upb_status_seterrf(p->status, "error parsing timestamp: " "minimum acceptable value is " "0001-01-01T00:00:00Z"); - upb_env_reporterror(p->env, &p->status); return false; } @@ -1681,8 +1658,7 @@ static bool parse_mapentry_key(upb_json_parser *p) { p->top->f = upb_msgdef_itof(p->top->m, UPB_MAPENTRY_KEY); if (p->top->f == NULL) { - upb_status_seterrmsg(&p->status, "mapentry message has no key"); - upb_env_reporterror(p->env, &p->status); + upb_status_seterrmsg(p->status, "mapentry message has no key"); return false; } switch (upb_fielddef_type(p->top->f)) { @@ -1705,9 +1681,8 @@ static bool parse_mapentry_key(upb_json_parser *p) { return false; } } else { - upb_status_seterrmsg(&p->status, + upb_status_seterrmsg(p->status, "Map bool key not 'true' or 'false'"); - upb_env_reporterror(p->env, &p->status); return false; } multipart_end(p); @@ -1725,8 +1700,7 @@ static bool parse_mapentry_key(upb_json_parser *p) { break; } default: - upb_status_seterrmsg(&p->status, "Invalid field type for map key"); - upb_env_reporterror(p->env, &p->status); + upb_status_seterrmsg(p->status, "Invalid field type for map key"); return false; } @@ -1785,8 +1759,7 @@ static bool handle_mapentry(upb_json_parser *p) { p->top->is_mapentry = true; /* set up to pop frame after value is parsed. */ p->top->mapfield = mapfield; if (p->top->f == NULL) { - upb_status_seterrmsg(&p->status, "mapentry message has no value"); - upb_env_reporterror(p->env, &p->status); + upb_status_seterrmsg(p->status, "mapentry message has no value"); return false; } @@ -1821,8 +1794,7 @@ static bool end_membername(upb_json_parser *p) { multipart_end(p); return true; } else { - upb_status_seterrf(&p->status, "No such field: %.*s\n", (int)len, buf); - upb_env_reporterror(p->env, &p->status); + upb_status_seterrf(p->status, "No such field: %.*s\n", (int)len, buf); return false; } } @@ -1848,14 +1820,13 @@ static bool end_any_membername(upb_json_parser *p) { static void end_member(upb_json_parser *p) { /* If we just parsed a map-entry value, end that frame too. */ if (p->top->is_mapentry) { - upb_status s = UPB_STATUS_INIT; upb_selector_t sel; bool ok; const upb_fielddef *mapfield; UPB_ASSERT(p->top > p->stack); /* send ENDMSG on submsg. */ - upb_sink_endmsg(&p->top->sink, &s); + upb_sink_endmsg(&p->top->sink, p->status); mapfield = p->top->mapfield; /* send ENDSUBMSG in repeated-field-of-mapentries frame. */ @@ -1949,10 +1920,9 @@ static bool start_subobject(upb_json_parser *p) { return true; } else { - upb_status_seterrf(&p->status, + upb_status_seterrf(p->status, "Object specified for non-message/group field: %s", upb_fielddef_name(p->top->f)); - upb_env_reporterror(p->env, &p->status); return false; } } @@ -2060,10 +2030,9 @@ static bool start_array(upb_json_parser *p) { } if (!upb_fielddef_isseq(p->top->f)) { - upb_status_seterrf(&p->status, + upb_status_seterrf(p->status, "Array specified for non-repeated field: %s", upb_fielddef_name(p->top->f)); - upb_env_reporterror(p->env, &p->status); return false; } @@ -2122,12 +2091,7 @@ static void start_object(upb_json_parser *p) { static void end_object(upb_json_parser *p) { if (!p->top->is_map && p->top->m != NULL) { - upb_status status; - upb_status_clear(&status); - upb_sink_endmsg(&p->top->sink, &status); - if (!upb_ok(&status)) { - upb_env_reporterror(p->env, &status); - } + upb_sink_endmsg(&p->top->sink, p->status); } } @@ -2146,8 +2110,7 @@ static bool end_any_object(upb_json_parser *p, const char *ptr) { if (json_parser_any_frame_has_value(p->top->any_frame) && !json_parser_any_frame_has_type_url(p->top->any_frame)) { - upb_status_seterrmsg(&p->status, "No valid type url"); - upb_env_reporterror(p->env, &p->status); + upb_status_seterrmsg(p->status, "No valid type url"); return false; } @@ -2162,8 +2125,7 @@ static bool end_any_object(upb_json_parser *p, const char *ptr) { p->top->any_frame->before_type_url_end - p->top->any_frame->before_type_url_start); if (p->top->any_frame->before_type_url_start == NULL) { - upb_status_seterrmsg(&p->status, "invalid data for well known type."); - upb_env_reporterror(p->env, &p->status); + upb_status_seterrmsg(p->status, "invalid data for well known type."); return false; } p->top->any_frame->before_type_url_start++; @@ -2175,8 +2137,7 @@ static bool end_any_object(upb_json_parser *p, const char *ptr) { (ptr + 1) - p->top->any_frame->after_type_url_start); if (p->top->any_frame->after_type_url_start == NULL) { - upb_status_seterrmsg(&p->status, "Invalid data for well known type."); - upb_env_reporterror(p->env, &p->status); + upb_status_seterrmsg(p->status, "Invalid data for well known type."); return false; } p->top->any_frame->after_type_url_start++; @@ -2249,7 +2210,6 @@ static bool end_any_object(upb_json_parser *p, const char *ptr) { /* Deallocate any parse frame. */ json_parser_any_frame_free(p->top->any_frame); - upb_env_free(p->env, p->top->any_frame); return true; } @@ -2419,11 +2379,11 @@ static bool is_string_wrapper_object(upb_json_parser *p) { * final state once, when the closing '"' is seen. */ -#line 2581 "upb/json/parser.rl" +#line 2541 "upb/json/parser.rl" -#line 2427 "upb/json/parser.c" +#line 2387 "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, @@ -2670,7 +2630,7 @@ static const int json_en_value_machine = 75; static const int json_en_main = 1; -#line 2584 "upb/json/parser.rl" +#line 2544 "upb/json/parser.rl" size_t parse(void *closure, const void *hd, const char *buf, size_t size, const upb_bufhandle *handle) { @@ -2693,7 +2653,7 @@ size_t parse(void *closure, const void *hd, const char *buf, size_t size, capture_resume(parser, buf); -#line 2697 "upb/json/parser.c" +#line 2657 "upb/json/parser.c" { int _klen; unsigned int _trans; @@ -2768,83 +2728,83 @@ _match: switch ( *_acts++ ) { case 1: -#line 2432 "upb/json/parser.rl" +#line 2392 "upb/json/parser.rl" { p--; {cs = stack[--top]; goto _again;} } break; case 2: -#line 2434 "upb/json/parser.rl" +#line 2394 "upb/json/parser.rl" { p--; {stack[top++] = cs; cs = 23;goto _again;} } break; case 3: -#line 2438 "upb/json/parser.rl" +#line 2398 "upb/json/parser.rl" { start_text(parser, p); } break; case 4: -#line 2439 "upb/json/parser.rl" +#line 2399 "upb/json/parser.rl" { CHECK_RETURN_TOP(end_text(parser, p)); } break; case 5: -#line 2445 "upb/json/parser.rl" +#line 2405 "upb/json/parser.rl" { start_hex(parser); } break; case 6: -#line 2446 "upb/json/parser.rl" +#line 2406 "upb/json/parser.rl" { hexdigit(parser, p); } break; case 7: -#line 2447 "upb/json/parser.rl" +#line 2407 "upb/json/parser.rl" { CHECK_RETURN_TOP(end_hex(parser)); } break; case 8: -#line 2453 "upb/json/parser.rl" +#line 2413 "upb/json/parser.rl" { CHECK_RETURN_TOP(escape(parser, p)); } break; case 9: -#line 2459 "upb/json/parser.rl" +#line 2419 "upb/json/parser.rl" { p--; {cs = stack[--top]; goto _again;} } break; case 10: -#line 2471 "upb/json/parser.rl" +#line 2431 "upb/json/parser.rl" { start_duration_base(parser, p); } break; case 11: -#line 2472 "upb/json/parser.rl" +#line 2432 "upb/json/parser.rl" { CHECK_RETURN_TOP(end_duration_base(parser, p)); } break; case 12: -#line 2474 "upb/json/parser.rl" +#line 2434 "upb/json/parser.rl" { p--; {cs = stack[--top]; goto _again;} } break; case 13: -#line 2479 "upb/json/parser.rl" +#line 2439 "upb/json/parser.rl" { start_timestamp_base(parser, p); } break; case 14: -#line 2480 "upb/json/parser.rl" +#line 2440 "upb/json/parser.rl" { CHECK_RETURN_TOP(end_timestamp_base(parser, p)); } break; case 15: -#line 2482 "upb/json/parser.rl" +#line 2442 "upb/json/parser.rl" { start_timestamp_fraction(parser, p); } break; case 16: -#line 2483 "upb/json/parser.rl" +#line 2443 "upb/json/parser.rl" { CHECK_RETURN_TOP(end_timestamp_fraction(parser, p)); } break; case 17: -#line 2485 "upb/json/parser.rl" +#line 2445 "upb/json/parser.rl" { start_timestamp_zone(parser, p); } break; case 18: -#line 2486 "upb/json/parser.rl" +#line 2446 "upb/json/parser.rl" { CHECK_RETURN_TOP(end_timestamp_zone(parser, p)); } break; case 19: -#line 2488 "upb/json/parser.rl" +#line 2448 "upb/json/parser.rl" { p--; {cs = stack[--top]; goto _again;} } break; case 20: -#line 2493 "upb/json/parser.rl" +#line 2453 "upb/json/parser.rl" { if (is_wellknown_msg(parser, UPB_WELLKNOWN_TIMESTAMP)) { {stack[top++] = cs; cs = 47;goto _again;} @@ -2856,11 +2816,11 @@ _match: } break; case 21: -#line 2504 "upb/json/parser.rl" +#line 2464 "upb/json/parser.rl" { p--; {stack[top++] = cs; cs = 75;goto _again;} } break; case 22: -#line 2509 "upb/json/parser.rl" +#line 2469 "upb/json/parser.rl" { if (is_wellknown_msg(parser, UPB_WELLKNOWN_ANY)) { start_any_member(parser, p); @@ -2870,11 +2830,11 @@ _match: } break; case 23: -#line 2516 "upb/json/parser.rl" +#line 2476 "upb/json/parser.rl" { CHECK_RETURN_TOP(end_membername(parser)); } break; case 24: -#line 2519 "upb/json/parser.rl" +#line 2479 "upb/json/parser.rl" { if (is_wellknown_msg(parser, UPB_WELLKNOWN_ANY)) { end_any_member(parser, p); @@ -2884,7 +2844,7 @@ _match: } break; case 25: -#line 2530 "upb/json/parser.rl" +#line 2490 "upb/json/parser.rl" { if (is_wellknown_msg(parser, UPB_WELLKNOWN_ANY)) { start_any_object(parser, p); @@ -2894,7 +2854,7 @@ _match: } break; case 26: -#line 2539 "upb/json/parser.rl" +#line 2499 "upb/json/parser.rl" { if (is_wellknown_msg(parser, UPB_WELLKNOWN_ANY)) { CHECK_RETURN_TOP(end_any_object(parser, p)); @@ -2904,54 +2864,54 @@ _match: } break; case 27: -#line 2551 "upb/json/parser.rl" +#line 2511 "upb/json/parser.rl" { CHECK_RETURN_TOP(start_array(parser)); } break; case 28: -#line 2555 "upb/json/parser.rl" +#line 2515 "upb/json/parser.rl" { end_array(parser); } break; case 29: -#line 2560 "upb/json/parser.rl" +#line 2520 "upb/json/parser.rl" { CHECK_RETURN_TOP(start_number(parser, p)); } break; case 30: -#line 2561 "upb/json/parser.rl" +#line 2521 "upb/json/parser.rl" { CHECK_RETURN_TOP(end_number(parser, p)); } break; case 31: -#line 2563 "upb/json/parser.rl" +#line 2523 "upb/json/parser.rl" { CHECK_RETURN_TOP(start_stringval(parser)); } break; case 32: -#line 2564 "upb/json/parser.rl" +#line 2524 "upb/json/parser.rl" { CHECK_RETURN_TOP(end_stringval(parser)); } break; case 33: -#line 2566 "upb/json/parser.rl" +#line 2526 "upb/json/parser.rl" { CHECK_RETURN_TOP(end_bool(parser, true)); } break; case 34: -#line 2568 "upb/json/parser.rl" +#line 2528 "upb/json/parser.rl" { CHECK_RETURN_TOP(end_bool(parser, false)); } break; case 35: -#line 2570 "upb/json/parser.rl" +#line 2530 "upb/json/parser.rl" { CHECK_RETURN_TOP(end_null(parser)); } break; case 36: -#line 2572 "upb/json/parser.rl" +#line 2532 "upb/json/parser.rl" { CHECK_RETURN_TOP(start_subobject_full(parser)); } break; case 37: -#line 2573 "upb/json/parser.rl" +#line 2533 "upb/json/parser.rl" { end_subobject_full(parser); } break; case 38: -#line 2578 "upb/json/parser.rl" +#line 2538 "upb/json/parser.rl" { p--; {cs = stack[--top]; goto _again;} } break; -#line 2955 "upb/json/parser.c" +#line 2915 "upb/json/parser.c" } } @@ -2968,32 +2928,32 @@ _again: while ( __nacts-- > 0 ) { switch ( *__acts++ ) { case 0: -#line 2430 "upb/json/parser.rl" +#line 2390 "upb/json/parser.rl" { p--; {cs = stack[--top]; if ( p == pe ) goto _test_eof; goto _again;} } break; case 30: -#line 2561 "upb/json/parser.rl" +#line 2521 "upb/json/parser.rl" { CHECK_RETURN_TOP(end_number(parser, p)); } break; case 33: -#line 2566 "upb/json/parser.rl" +#line 2526 "upb/json/parser.rl" { CHECK_RETURN_TOP(end_bool(parser, true)); } break; case 34: -#line 2568 "upb/json/parser.rl" +#line 2528 "upb/json/parser.rl" { CHECK_RETURN_TOP(end_bool(parser, false)); } break; case 35: -#line 2570 "upb/json/parser.rl" +#line 2530 "upb/json/parser.rl" { CHECK_RETURN_TOP(end_null(parser)); } break; case 37: -#line 2573 "upb/json/parser.rl" +#line 2533 "upb/json/parser.rl" { end_subobject_full(parser); } break; -#line 2997 "upb/json/parser.c" +#line 2957 "upb/json/parser.c" } } } @@ -3001,11 +2961,10 @@ goto _again;} } _out: {} } -#line 2606 "upb/json/parser.rl" +#line 2566 "upb/json/parser.rl" if (p != pe) { - upb_status_seterrf(&parser->status, "Parse error at '%.*s'\n", pe - p, p); - upb_env_reporterror(parser->env, &parser->status); + upb_status_seterrf(parser->status, "Parse error at '%.*s'\n", pe - p, p); } else { capture_suspend(parser, &p); } @@ -3049,26 +3008,25 @@ static void json_parser_reset(upb_json_parser *p) { /* Emit Ragel initialization of the parser. */ -#line 3053 "upb/json/parser.c" +#line 3012 "upb/json/parser.c" { cs = json_start; top = 0; } -#line 2653 "upb/json/parser.rl" +#line 2612 "upb/json/parser.rl" p->current_state = cs; p->parser_top = top; accumulate_clear(p); p->multipart_state = MULTIPART_INACTIVE; p->capture = NULL; p->accumulated = NULL; - upb_status_clear(&p->status); } static upb_json_parsermethod *parsermethod_new(upb_json_codecache *c, const upb_msgdef *md) { upb_msg_field_iter i; - upb_alloc *alloc = upb_arena_alloc(&c->arena); + upb_alloc *alloc = upb_arena_alloc(c->arena); upb_json_parsermethod *m = upb_malloc(alloc, sizeof(*m)); @@ -3109,19 +3067,20 @@ static upb_json_parsermethod *parsermethod_new(upb_json_codecache *c, /* Public API *****************************************************************/ -upb_json_parser *upb_json_parser_create(upb_env *env, +upb_json_parser *upb_json_parser_create(upb_arena *arena, const upb_json_parsermethod *method, const upb_symtab* symtab, upb_sink output, bool ignore_json_unknown) { #ifndef NDEBUG - const size_t size_before = upb_env_bytesallocated(env); + const size_t size_before = upb_arena_bytesallocated(arena); #endif - upb_json_parser *p = upb_env_malloc(env, sizeof(upb_json_parser)); + upb_json_parser *p = upb_arena_malloc(arena, sizeof(upb_json_parser)); if (!p) return false; - p->env = env; + p->arena = arena; p->method = method; + p->status = NULL; p->limit = p->stack + UPB_JSON_MAX_DEPTH; p->accumulate_buf = NULL; p->accumulate_buf_size = 0; @@ -3143,8 +3102,8 @@ upb_json_parser *upb_json_parser_create(upb_env *env, p->ignore_json_unknown = ignore_json_unknown; /* If this fails, uncomment and increase the value in parser.h. */ - /* fprintf(stderr, "%zd\n", upb_env_bytesallocated(env) - size_before); */ - UPB_ASSERT_DEBUGVAR(upb_env_bytesallocated(env) - size_before <= + /* fprintf(stderr, "%zd\n", upb_arena_bytesallocated(arena) - size_before); */ + UPB_ASSERT_DEBUGVAR(upb_arena_bytesallocated(arena) - size_before <= UPB_JSON_PARSER_SIZE); return p; } @@ -3164,8 +3123,8 @@ upb_json_codecache *upb_json_codecache_new() { c = upb_gmalloc(sizeof(*c)); - upb_arena_init(&c->arena); - alloc = upb_arena_alloc(&c->arena); + c->arena = upb_arena_new(); + alloc = upb_arena_alloc(c->arena); upb_inttable_init2(&c->methods, UPB_CTYPE_CONSTPTR, alloc); @@ -3173,7 +3132,7 @@ upb_json_codecache *upb_json_codecache_new() { } void upb_json_codecache_free(upb_json_codecache *c) { - upb_arena_uninit(&c->arena); + upb_arena_free(c->arena); upb_gfree(c); } @@ -3182,7 +3141,7 @@ const upb_json_parsermethod *upb_json_codecache_get(upb_json_codecache *c, upb_json_parsermethod *m; upb_value v; upb_msg_field_iter i; - upb_alloc *alloc = upb_arena_alloc(&c->arena); + upb_alloc *alloc = upb_arena_alloc(c->arena); if (upb_inttable_lookupptr(&c->methods, md, &v)) { return upb_value_getconstptr(v); diff --git a/upb/json/parser.h b/upb/json/parser.h index d1a1471..2a06fcf 100644 --- a/upb/json/parser.h +++ b/upb/json/parser.h @@ -25,14 +25,15 @@ class ParserMethodPtr; struct upb_json_parsermethod; typedef struct upb_json_parsermethod upb_json_parsermethod; -UPB_BEGIN_EXTERN_C +#ifdef __cplusplus +extern "C" { +#endif const upb_byteshandler* upb_json_parsermethod_inputhandler( const upb_json_parsermethod* m); -UPB_END_EXTERN_C - #ifdef __cplusplus +} /* extern "C" */ class upb::json::ParserMethodPtr { public: @@ -62,17 +63,19 @@ class upb::json::ParserMethodPtr { struct upb_json_parser; typedef struct upb_json_parser upb_json_parser; -UPB_BEGIN_EXTERN_C +#ifdef __cplusplus +extern "C" { +#endif -upb_json_parser* -upb_json_parser_create(upb_env* e, const upb_json_parsermethod* m, - const upb_symtab* symtab, upb_sink output, - bool ignore_json_unknown); +upb_json_parser* upb_json_parser_create(upb_arena* a, + const upb_json_parsermethod* m, + const upb_symtab* symtab, + upb_sink output, + bool ignore_json_unknown); upb_bytessink upb_json_parser_input(upb_json_parser* p); -UPB_END_EXTERN_C - #ifdef __cplusplus +} /* extern "C" */ /* Parses an incoming BytesStream, pushing the results to the destination * sink. */ @@ -80,12 +83,13 @@ class upb::json::ParserPtr { public: ParserPtr(upb_json_parser* ptr) : ptr_(ptr) {} - static ParserPtr Create(Environment* env, ParserMethodPtr method, + static ParserPtr Create(Arena* arena, ParserMethodPtr method, SymbolTable* symtab, Sink output, bool ignore_json_unknown) { upb_symtab* symtab_ptr = symtab ? symtab->ptr() : nullptr; - return ParserPtr(upb_json_parser_create( - env, method.ptr(), symtab_ptr, output.sink(), ignore_json_unknown)); + return ParserPtr(upb_json_parser_create(arena->ptr(), method.ptr(), + symtab_ptr, output.sink(), + ignore_json_unknown)); } BytesSink input() { return upb_json_parser_input(ptr_); } @@ -101,16 +105,17 @@ class upb::json::ParserPtr { struct upb_json_codecache; typedef struct upb_json_codecache upb_json_codecache; -UPB_BEGIN_EXTERN_C +#ifdef __cplusplus +extern "C" { +#endif upb_json_codecache *upb_json_codecache_new(); void upb_json_codecache_free(upb_json_codecache *cache); const upb_json_parsermethod* upb_json_codecache_get(upb_json_codecache* cache, const upb_msgdef* md); -UPB_END_EXTERN_C - #ifdef __cplusplus +} /* extern "C" */ class upb::json::CodeCache { public: diff --git a/upb/json/parser.rl b/upb/json/parser.rl index 05a9505..a117d0c 100644 --- a/upb/json/parser.rl +++ b/upb/json/parser.rl @@ -210,7 +210,7 @@ typedef struct { } upb_jsonparser_frame; struct upb_json_parser { - upb_env *env; + upb_arena *arena; const upb_json_parsermethod *method; upb_bytessink input_; @@ -219,7 +219,7 @@ struct upb_json_parser { upb_jsonparser_frame *top; upb_jsonparser_frame *limit; - upb_status status; + upb_status *status; /* Ragel's internal parsing stack for the parsing state machine. */ int current_state; @@ -257,7 +257,7 @@ struct upb_json_parser { }; struct upb_json_codecache { - upb_arena arena; + upb_arena *arena; upb_inttable methods; /* upb_msgdef* -> upb_json_parsermethod* */ }; @@ -275,7 +275,7 @@ static upb_jsonparser_any_frame *json_parser_any_frame_new( upb_json_parser *p) { upb_jsonparser_any_frame *frame; - frame = upb_env_malloc(p->env, sizeof(upb_jsonparser_any_frame)); + frame = upb_arena_malloc(p->arena, sizeof(upb_jsonparser_any_frame)); frame->encoder_handlercache = upb_pb_encoder_newcache(); frame->parser_codecache = upb_json_codecache_new(); @@ -299,12 +299,12 @@ static void json_parser_any_frame_set_payload_type( /* Initialize encoder. */ h = upb_handlercache_get(frame->encoder_handlercache, payload_type); - encoder = upb_pb_encoder_create(p->env, h, frame->stringsink.sink); + encoder = upb_pb_encoder_create(p->arena, h, frame->stringsink.sink); /* Initialize parser. */ parser_method = upb_json_codecache_get(frame->parser_codecache, payload_type); upb_sink_reset(&frame->sink, h, encoder); - frame->parser = upb_json_parser_create(p->env, parser_method, p->symtab, + frame->parser = upb_json_parser_create(p->arena, parser_method, p->symtab, frame->sink, p->ignore_json_unknown); } @@ -370,8 +370,7 @@ static upb_selector_t parser_getsel(upb_json_parser *p) { static bool check_stack(upb_json_parser *p) { if ((p->top + 1) == p->limit) { - upb_status_seterrmsg(&p->status, "Nesting too deep"); - upb_env_reporterror(p->env, &p->status); + upb_status_seterrmsg(p->status, "Nesting too deep"); return false; } @@ -466,10 +465,9 @@ static bool base64_push(upb_json_parser *p, upb_selector_t sel, const char *ptr, char output[3]; if (limit - ptr < 4) { - upb_status_seterrf(&p->status, + upb_status_seterrf(p->status, "Base64 input for bytes field not a multiple of 4: %s", upb_fielddef_name(p->top->f)); - upb_env_reporterror(p->env, &p->status); return false; } @@ -493,10 +491,9 @@ static bool base64_push(upb_json_parser *p, upb_selector_t sel, const char *ptr, otherchar: if (nonbase64(ptr[0]) || nonbase64(ptr[1]) || nonbase64(ptr[2]) || nonbase64(ptr[3]) ) { - upb_status_seterrf(&p->status, + upb_status_seterrf(p->status, "Non-base64 characters in bytes field: %s", upb_fielddef_name(p->top->f)); - upb_env_reporterror(p->env, &p->status); return false; } if (ptr[2] == '=') { uint32_t val; @@ -534,11 +531,10 @@ otherchar: } badpadding: - upb_status_seterrf(&p->status, + upb_status_seterrf(p->status, "Incorrect base64 padding for field: %s (%.*s)", upb_fielddef_name(p->top->f), 4, ptr); - upb_env_reporterror(p->env, &p->status); return false; } @@ -582,10 +578,9 @@ static bool accumulate_realloc(upb_json_parser *p, size_t need) { new_size = saturating_multiply(new_size, 2); } - mem = upb_env_realloc(p->env, p->accumulate_buf, old_size, new_size); + mem = upb_arena_realloc(p->arena, p->accumulate_buf, old_size, new_size); if (!mem) { - upb_status_seterrmsg(&p->status, "Out of memory allocating buffer."); - upb_env_reporterror(p->env, &p->status); + upb_status_seterrmsg(p->status, "Out of memory allocating buffer."); return false; } @@ -608,8 +603,7 @@ static bool accumulate_append(upb_json_parser *p, const char *buf, size_t len, } if (!checked_add(p->accumulated_len, len, &need)) { - upb_status_seterrmsg(&p->status, "Integer overflow."); - upb_env_reporterror(p->env, &p->status); + upb_status_seterrmsg(p->status, "Integer overflow."); return false; } @@ -687,8 +681,7 @@ static bool multipart_text(upb_json_parser *p, const char *buf, size_t len, switch (p->multipart_state) { case MULTIPART_INACTIVE: upb_status_seterrmsg( - &p->status, "Internal error: unexpected state MULTIPART_INACTIVE"); - upb_env_reporterror(p->env, &p->status); + p->status, "Internal error: unexpected state MULTIPART_INACTIVE"); return false; case MULTIPART_ACCUMULATE: @@ -1053,8 +1046,7 @@ static bool parse_number(upb_json_parser *p, bool is_quoted) { multipart_end(p); return true; } else { - upb_status_seterrf(&p->status, "error parsing number: %s", buf); - upb_env_reporterror(p->env, &p->status); + upb_status_seterrf(p->status, "error parsing number: %s", buf); multipart_end(p); return false; } @@ -1068,10 +1060,9 @@ static bool parser_putbool(upb_json_parser *p, bool val) { } if (upb_fielddef_type(p->top->f) != UPB_TYPE_BOOL) { - upb_status_seterrf(&p->status, + upb_status_seterrf(p->status, "Boolean value specified for non-bool field: %s", upb_fielddef_name(p->top->f)); - upb_env_reporterror(p->env, &p->status); return false; } @@ -1246,10 +1237,9 @@ static bool start_stringval(upb_json_parser *p) { multipart_startaccum(p); return true; } else { - upb_status_seterrf(&p->status, + upb_status_seterrf(p->status, "String specified for bool or submessage field: %s", upb_fielddef_name(p->top->f)); - upb_env_reporterror(p->env, &p->status); return false; } } @@ -1282,8 +1272,7 @@ static bool end_any_stringval(upb_json_parser *p) { payload_type = upb_symtab_lookupmsg2(p->symtab, buf, len); if (payload_type == NULL) { upb_status_seterrf( - &p->status, "Cannot find packed type: %.*s\n", (int)len, buf); - upb_env_reporterror(p->env, &p->status); + p->status, "Cannot find packed type: %.*s\n", (int)len, buf); return false; } @@ -1292,8 +1281,7 @@ static bool end_any_stringval(upb_json_parser *p) { return true; } else { upb_status_seterrf( - &p->status, "Invalid type url: %.*s\n", (int)len, buf); - upb_env_reporterror(p->env, &p->status); + p->status, "Invalid type url: %.*s\n", (int)len, buf); return false; } } @@ -1345,8 +1333,7 @@ static bool end_stringval_nontop(upb_json_parser *p) { upb_selector_t sel = parser_getsel(p); upb_sink_putint32(&p->top->sink, sel, int_val); } else { - upb_status_seterrf(&p->status, "Enum value unknown: '%.*s'", len, buf); - upb_env_reporterror(p->env, &p->status); + upb_status_seterrf(p->status, "Enum value unknown: '%.*s'", len, buf); } break; @@ -1363,8 +1350,7 @@ static bool end_stringval_nontop(upb_json_parser *p) { default: UPB_ASSERT(false); - upb_status_seterrmsg(&p->status, "Internal error in JSON decoder"); - upb_env_reporterror(p->env, &p->status); + upb_status_seterrmsg(p->status, "Internal error in JSON decoder"); ok = false; break; } @@ -1443,25 +1429,22 @@ static bool end_duration_base(upb_json_parser *p, const char *ptr) { memcpy(seconds_buf, buf, fraction_start); seconds = strtol(seconds_buf, &end, 10); if (errno == ERANGE || end != seconds_buf + fraction_start) { - upb_status_seterrf(&p->status, "error parsing duration: %s", + upb_status_seterrf(p->status, "error parsing duration: %s", seconds_buf); - upb_env_reporterror(p->env, &p->status); return false; } if (seconds > 315576000000) { - upb_status_seterrf(&p->status, "error parsing duration: " + upb_status_seterrf(p->status, "error parsing duration: " "maximum acceptable value is " "315576000000"); - upb_env_reporterror(p->env, &p->status); return false; } if (seconds < -315576000000) { - upb_status_seterrf(&p->status, "error parsing duration: " + upb_status_seterrf(p->status, "error parsing duration: " "minimum acceptable value is " "-315576000000"); - upb_env_reporterror(p->env, &p->status); return false; } @@ -1470,9 +1453,8 @@ static bool end_duration_base(upb_json_parser *p, const char *ptr) { memcpy(nanos_buf + 1, buf + fraction_start, len - fraction_start); val = strtod(nanos_buf, &end); if (errno == ERANGE || end != nanos_buf + len - fraction_start + 1) { - upb_status_seterrf(&p->status, "error parsing duration: %s", + upb_status_seterrf(p->status, "error parsing duration: %s", nanos_buf); - upb_env_reporterror(p->env, &p->status); return false; } @@ -1498,7 +1480,7 @@ static bool end_duration_base(upb_json_parser *p, const char *ptr) { upb_sink_putint32(&p->top->sink, parser_getsel(p), nanos); end_member(p); - /* Continue previous environment */ + /* Continue previous arena */ multipart_startaccum(p); return true; @@ -1528,8 +1510,7 @@ static bool end_timestamp_base(upb_json_parser *p, const char *ptr) { /* Parse seconds */ if (strptime(timestamp_buf, "%FT%H:%M:%S%Z", &p->tm) == NULL) { - upb_status_seterrf(&p->status, "error parsing timestamp: %s", buf); - upb_env_reporterror(p->env, &p->status); + upb_status_seterrf(p->status, "error parsing timestamp: %s", buf); return false; } @@ -1562,9 +1543,8 @@ static bool end_timestamp_fraction(upb_json_parser *p, const char *ptr) { buf = accumulate_getptr(p, &len); if (len > 10) { - upb_status_seterrf(&p->status, + upb_status_seterrf(p->status, "error parsing timestamp: at most 9-digit fraction."); - upb_env_reporterror(p->env, &p->status); return false; } @@ -1574,9 +1554,8 @@ static bool end_timestamp_fraction(upb_json_parser *p, const char *ptr) { val = strtod(nanos_buf, &end); if (errno == ERANGE || end != nanos_buf + len + 1) { - upb_status_seterrf(&p->status, "error parsing timestamp nanos: %s", + upb_status_seterrf(p->status, "error parsing timestamp nanos: %s", nanos_buf); - upb_env_reporterror(p->env, &p->status); return false; } @@ -1618,8 +1597,7 @@ static bool end_timestamp_zone(upb_json_parser *p, const char *ptr) { if (buf[0] != 'Z') { if (sscanf(buf + 1, "%2d:00", &hours) != 1) { - upb_status_seterrf(&p->status, "error parsing timestamp offset"); - upb_env_reporterror(p->env, &p->status); + upb_status_seterrf(p->status, "error parsing timestamp offset"); return false; } @@ -1635,10 +1613,9 @@ static bool end_timestamp_zone(upb_json_parser *p, const char *ptr) { /* Check timestamp boundary */ if (seconds < -62135596800) { - upb_status_seterrf(&p->status, "error parsing timestamp: " + upb_status_seterrf(p->status, "error parsing timestamp: " "minimum acceptable value is " "0001-01-01T00:00:00Z"); - upb_env_reporterror(p->env, &p->status); return false; } @@ -1679,8 +1656,7 @@ static bool parse_mapentry_key(upb_json_parser *p) { p->top->f = upb_msgdef_itof(p->top->m, UPB_MAPENTRY_KEY); if (p->top->f == NULL) { - upb_status_seterrmsg(&p->status, "mapentry message has no key"); - upb_env_reporterror(p->env, &p->status); + upb_status_seterrmsg(p->status, "mapentry message has no key"); return false; } switch (upb_fielddef_type(p->top->f)) { @@ -1703,9 +1679,8 @@ static bool parse_mapentry_key(upb_json_parser *p) { return false; } } else { - upb_status_seterrmsg(&p->status, + upb_status_seterrmsg(p->status, "Map bool key not 'true' or 'false'"); - upb_env_reporterror(p->env, &p->status); return false; } multipart_end(p); @@ -1723,8 +1698,7 @@ static bool parse_mapentry_key(upb_json_parser *p) { break; } default: - upb_status_seterrmsg(&p->status, "Invalid field type for map key"); - upb_env_reporterror(p->env, &p->status); + upb_status_seterrmsg(p->status, "Invalid field type for map key"); return false; } @@ -1783,8 +1757,7 @@ static bool handle_mapentry(upb_json_parser *p) { p->top->is_mapentry = true; /* set up to pop frame after value is parsed. */ p->top->mapfield = mapfield; if (p->top->f == NULL) { - upb_status_seterrmsg(&p->status, "mapentry message has no value"); - upb_env_reporterror(p->env, &p->status); + upb_status_seterrmsg(p->status, "mapentry message has no value"); return false; } @@ -1819,8 +1792,7 @@ static bool end_membername(upb_json_parser *p) { multipart_end(p); return true; } else { - upb_status_seterrf(&p->status, "No such field: %.*s\n", (int)len, buf); - upb_env_reporterror(p->env, &p->status); + upb_status_seterrf(p->status, "No such field: %.*s\n", (int)len, buf); return false; } } @@ -1846,14 +1818,13 @@ static bool end_any_membername(upb_json_parser *p) { static void end_member(upb_json_parser *p) { /* If we just parsed a map-entry value, end that frame too. */ if (p->top->is_mapentry) { - upb_status s = UPB_STATUS_INIT; upb_selector_t sel; bool ok; const upb_fielddef *mapfield; UPB_ASSERT(p->top > p->stack); /* send ENDMSG on submsg. */ - upb_sink_endmsg(&p->top->sink, &s); + upb_sink_endmsg(&p->top->sink, p->status); mapfield = p->top->mapfield; /* send ENDSUBMSG in repeated-field-of-mapentries frame. */ @@ -1947,10 +1918,9 @@ static bool start_subobject(upb_json_parser *p) { return true; } else { - upb_status_seterrf(&p->status, + upb_status_seterrf(p->status, "Object specified for non-message/group field: %s", upb_fielddef_name(p->top->f)); - upb_env_reporterror(p->env, &p->status); return false; } } @@ -2058,10 +2028,9 @@ static bool start_array(upb_json_parser *p) { } if (!upb_fielddef_isseq(p->top->f)) { - upb_status_seterrf(&p->status, + upb_status_seterrf(p->status, "Array specified for non-repeated field: %s", upb_fielddef_name(p->top->f)); - upb_env_reporterror(p->env, &p->status); return false; } @@ -2120,12 +2089,7 @@ static void start_object(upb_json_parser *p) { static void end_object(upb_json_parser *p) { if (!p->top->is_map && p->top->m != NULL) { - upb_status status; - upb_status_clear(&status); - upb_sink_endmsg(&p->top->sink, &status); - if (!upb_ok(&status)) { - upb_env_reporterror(p->env, &status); - } + upb_sink_endmsg(&p->top->sink, p->status); } } @@ -2144,8 +2108,7 @@ static bool end_any_object(upb_json_parser *p, const char *ptr) { if (json_parser_any_frame_has_value(p->top->any_frame) && !json_parser_any_frame_has_type_url(p->top->any_frame)) { - upb_status_seterrmsg(&p->status, "No valid type url"); - upb_env_reporterror(p->env, &p->status); + upb_status_seterrmsg(p->status, "No valid type url"); return false; } @@ -2160,8 +2123,7 @@ static bool end_any_object(upb_json_parser *p, const char *ptr) { p->top->any_frame->before_type_url_end - p->top->any_frame->before_type_url_start); if (p->top->any_frame->before_type_url_start == NULL) { - upb_status_seterrmsg(&p->status, "invalid data for well known type."); - upb_env_reporterror(p->env, &p->status); + upb_status_seterrmsg(p->status, "invalid data for well known type."); return false; } p->top->any_frame->before_type_url_start++; @@ -2173,8 +2135,7 @@ static bool end_any_object(upb_json_parser *p, const char *ptr) { (ptr + 1) - p->top->any_frame->after_type_url_start); if (p->top->any_frame->after_type_url_start == NULL) { - upb_status_seterrmsg(&p->status, "Invalid data for well known type."); - upb_env_reporterror(p->env, &p->status); + upb_status_seterrmsg(p->status, "Invalid data for well known type."); return false; } p->top->any_frame->after_type_url_start++; @@ -2247,7 +2208,6 @@ static bool end_any_object(upb_json_parser *p, const char *ptr) { /* Deallocate any parse frame. */ json_parser_any_frame_free(p->top->any_frame); - upb_env_free(p->env, p->top->any_frame); return true; } @@ -2605,8 +2565,7 @@ size_t parse(void *closure, const void *hd, const char *buf, size_t size, %% write exec; if (p != pe) { - upb_status_seterrf(&parser->status, "Parse error at '%.*s'\n", pe - p, p); - upb_env_reporterror(parser->env, &parser->status); + upb_status_seterrf(parser->status, "Parse error at '%.*s'\n", pe - p, p); } else { capture_suspend(parser, &p); } @@ -2656,13 +2615,12 @@ static void json_parser_reset(upb_json_parser *p) { p->multipart_state = MULTIPART_INACTIVE; p->capture = NULL; p->accumulated = NULL; - upb_status_clear(&p->status); } static upb_json_parsermethod *parsermethod_new(upb_json_codecache *c, const upb_msgdef *md) { upb_msg_field_iter i; - upb_alloc *alloc = upb_arena_alloc(&c->arena); + upb_alloc *alloc = upb_arena_alloc(c->arena); upb_json_parsermethod *m = upb_malloc(alloc, sizeof(*m)); @@ -2703,19 +2661,20 @@ static upb_json_parsermethod *parsermethod_new(upb_json_codecache *c, /* Public API *****************************************************************/ -upb_json_parser *upb_json_parser_create(upb_env *env, +upb_json_parser *upb_json_parser_create(upb_arena *arena, const upb_json_parsermethod *method, const upb_symtab* symtab, upb_sink output, bool ignore_json_unknown) { #ifndef NDEBUG - const size_t size_before = upb_env_bytesallocated(env); + const size_t size_before = upb_arena_bytesallocated(arena); #endif - upb_json_parser *p = upb_env_malloc(env, sizeof(upb_json_parser)); + upb_json_parser *p = upb_arena_malloc(arena, sizeof(upb_json_parser)); if (!p) return false; - p->env = env; + p->arena = arena; p->method = method; + p->status = NULL; p->limit = p->stack + UPB_JSON_MAX_DEPTH; p->accumulate_buf = NULL; p->accumulate_buf_size = 0; @@ -2737,8 +2696,8 @@ upb_json_parser *upb_json_parser_create(upb_env *env, p->ignore_json_unknown = ignore_json_unknown; /* If this fails, uncomment and increase the value in parser.h. */ - /* fprintf(stderr, "%zd\n", upb_env_bytesallocated(env) - size_before); */ - UPB_ASSERT_DEBUGVAR(upb_env_bytesallocated(env) - size_before <= + /* fprintf(stderr, "%zd\n", upb_arena_bytesallocated(arena) - size_before); */ + UPB_ASSERT_DEBUGVAR(upb_arena_bytesallocated(arena) - size_before <= UPB_JSON_PARSER_SIZE); return p; } @@ -2758,8 +2717,8 @@ upb_json_codecache *upb_json_codecache_new() { c = upb_gmalloc(sizeof(*c)); - upb_arena_init(&c->arena); - alloc = upb_arena_alloc(&c->arena); + c->arena = upb_arena_new(); + alloc = upb_arena_alloc(c->arena); upb_inttable_init2(&c->methods, UPB_CTYPE_CONSTPTR, alloc); @@ -2767,7 +2726,7 @@ upb_json_codecache *upb_json_codecache_new() { } void upb_json_codecache_free(upb_json_codecache *c) { - upb_arena_uninit(&c->arena); + upb_arena_free(c->arena); upb_gfree(c); } @@ -2776,7 +2735,7 @@ const upb_json_parsermethod *upb_json_codecache_get(upb_json_codecache *c, upb_json_parsermethod *m; upb_value v; upb_msg_field_iter i; - upb_alloc *alloc = upb_arena_alloc(&c->arena); + upb_alloc *alloc = upb_arena_alloc(c->arena); if (upb_inttable_lookupptr(&c->methods, md, &v)) { return upb_value_getconstptr(v); diff --git a/upb/json/printer.c b/upb/json/printer.c index 83f1a58..bc18055 100644 --- a/upb/json/printer.c +++ b/upb/json/printer.c @@ -1252,13 +1252,13 @@ static void json_printer_reset(upb_json_printer *p) { /* Public API *****************************************************************/ -upb_json_printer *upb_json_printer_create(upb_env *e, const upb_handlers *h, +upb_json_printer *upb_json_printer_create(upb_arena *a, const upb_handlers *h, upb_bytessink output) { #ifndef NDEBUG - size_t size_before = upb_env_bytesallocated(e); + size_t size_before = upb_arena_bytesallocated(a); #endif - upb_json_printer *p = upb_env_malloc(e, sizeof(upb_json_printer)); + upb_json_printer *p = upb_arena_malloc(a, sizeof(upb_json_printer)); if (!p) return NULL; p->output_ = output; @@ -1268,7 +1268,7 @@ upb_json_printer *upb_json_printer_create(upb_env *e, const upb_handlers *h, p->nanos = 0; /* If this fails, increase the value in printer.h. */ - UPB_ASSERT_DEBUGVAR(upb_env_bytesallocated(e) - size_before <= + UPB_ASSERT_DEBUGVAR(upb_arena_bytesallocated(a) - size_before <= UPB_JSON_PRINTER_SIZE); return p; } diff --git a/upb/json/printer.h b/upb/json/printer.h index a7a37bb..857ae47 100644 --- a/upb/json/printer.h +++ b/upb/json/printer.h @@ -24,10 +24,12 @@ class PrinterPtr; struct upb_json_printer; typedef struct upb_json_printer upb_json_printer; -UPB_BEGIN_EXTERN_C +#ifdef __cplusplus +extern "C" { +#endif /* Native C API. */ -upb_json_printer *upb_json_printer_create(upb_env *e, const upb_handlers *h, +upb_json_printer *upb_json_printer_create(upb_arena *a, const upb_handlers *h, upb_bytessink output); upb_sink upb_json_printer_input(upb_json_printer *p); const upb_handlers *upb_json_printer_newhandlers(const upb_msgdef *md, @@ -36,18 +38,18 @@ const upb_handlers *upb_json_printer_newhandlers(const upb_msgdef *md, upb_handlercache *upb_json_printer_newcache(bool preserve_proto_fieldnames); -UPB_END_EXTERN_C - #ifdef __cplusplus +} /* extern "C" */ /* Prints an incoming stream of data to a BytesSink in JSON format. */ class upb::json::PrinterPtr { public: PrinterPtr(upb_json_printer* ptr) : ptr_(ptr) {} - static PrinterPtr Create(Environment *env, const upb::Handlers *handlers, + static PrinterPtr Create(Arena *arena, const upb::Handlers *handlers, BytesSink output) { - return PrinterPtr(upb_json_printer_create(env, handlers, output.sink())); + return PrinterPtr( + upb_json_printer_create(arena->ptr(), handlers, output.sink())); } /* The input to the printer. */ diff --git a/upb/msg.h b/upb/msg.h index 4529478..149b7ab 100644 --- a/upb/msg.h +++ b/upb/msg.h @@ -37,18 +37,22 @@ class MessageLayout; #endif -UPB_DECLARE_TYPE(upb::Map, upb_map) -UPB_DECLARE_TYPE(upb::MapIterator, upb_mapiter) - -struct upb_array; -typedef struct upb_array upb_array; - /* TODO(haberman): C++ accessors */ -UPB_BEGIN_EXTERN_C +#ifdef __cplusplus +extern "C" { +#endif typedef void upb_msg; +struct upb_array; +typedef struct upb_array upb_array; + +struct upb_map; +typedef struct upb_map upb_map; + +struct upb_mapiter; +typedef struct upb_mapiter upb_mapiter; /** upb_msglayout *************************************************************/ @@ -75,7 +79,6 @@ typedef struct upb_msglayout { bool extendable; } upb_msglayout; - /** upb_stringview ************************************************************/ typedef struct { @@ -103,7 +106,6 @@ UPB_INLINE bool upb_stringview_eql(upb_stringview a, upb_stringview b) { #define UPB_STRINGVIEW_INIT(ptr, len) {ptr, len} - /** upb_msgval ****************************************************************/ /* A union representing all possible protobuf values. Used for generic get/set @@ -156,7 +158,6 @@ UPB_INLINE upb_msgval upb_msgval_makestr(const char *data, size_t size) { return upb_msgval_str(upb_stringview_make(data, size)); } - /** upb_msg *******************************************************************/ /* A upb_msg represents a protobuf message. It always corresponds to a specific @@ -216,7 +217,6 @@ bool upb_msg_clearfield(upb_msg *msg, /* TODO(haberman): copyfrom()/mergefrom()? */ - /** upb_array *****************************************************************/ /* A upb_array stores data for a repeated field. The memory management @@ -236,7 +236,6 @@ upb_msgval upb_array_get(const upb_array *arr, size_t i); bool upb_array_set(upb_array *arr, size_t i, upb_msgval val); - /** upb_map *******************************************************************/ /* A upb_map stores data for a map field. The memory management semantics are @@ -268,7 +267,6 @@ bool upb_map_set(upb_map *map, /* Deletes an entry in the map. Returns true if the key was present. */ bool upb_map_del(upb_map *map, upb_msgval key); - /** upb_mapiter ***************************************************************/ /* For iterating over a map. Map iterators are invalidated by mutations to the @@ -290,6 +288,8 @@ upb_msgval upb_mapiter_value(const upb_mapiter *i); void upb_mapiter_setdone(upb_mapiter *i); bool upb_mapiter_isequal(const upb_mapiter *i1, const upb_mapiter *i2); -UPB_END_EXTERN_C +#ifdef __cplusplus +} /* extern "C" */ +#endif #endif /* UPB_MSG_H_ */ diff --git a/upb/msgfactory.h b/upb/msgfactory.h index 73a26ba..9b3b599 100644 --- a/upb/msgfactory.h +++ b/upb/msgfactory.h @@ -5,10 +5,15 @@ #ifndef UPB_MSGFACTORY_H_ #define UPB_MSGFACTORY_H_ -UPB_DECLARE_TYPE(upb::MessageFactory, upb_msgfactory) - /** upb_msgfactory ************************************************************/ +struct upb_msgfactory; +typedef struct upb_msgfactory upb_msgfactory; + +#ifdef __cplusplus +extern "C" { +#endif + /* A upb_msgfactory contains a cache of upb_msglayout, upb_handlers, and * upb_visitorplan objects. These are the objects necessary to represent, * populate, and and visit upb_msg objects. @@ -36,5 +41,8 @@ const upb_symtab *upb_msgfactory_symtab(const upb_msgfactory *f); const upb_msglayout *upb_msgfactory_getlayout(upb_msgfactory *f, const upb_msgdef *m); +#ifdef __cplusplus +} /* extern "C" */ +#endif #endif /* UPB_MSGFACTORY_H_ */ diff --git a/upb/pb/compile_decoder.c b/upb/pb/compile_decoder.c index e17ca03..ca497ed 100644 --- a/upb/pb/compile_decoder.c +++ b/upb/pb/compile_decoder.c @@ -907,7 +907,7 @@ upb_pbcodecache *upb_pbcodecache_new(upb_handlercache *dest) { c->allow_jit = true; c->lazy = false; - upb_arena_init(&c->arena); + c->arena = upb_arena_new(); if (!upb_inttable_init(&c->groups, UPB_CTYPE_CONSTPTR)) return NULL; return c; diff --git a/upb/pb/decoder.c b/upb/pb/decoder.c index cd64f72..5068225 100644 --- a/upb/pb/decoder.c +++ b/upb/pb/decoder.c @@ -99,9 +99,7 @@ static bool in_residual_buf(const upb_pbdecoder *d, const char *p); * benchmarks. */ static void seterr(upb_pbdecoder *d, const char *msg) { - upb_status status = UPB_STATUS_INIT; - upb_status_seterrmsg(&status, msg); - upb_env_reporterror(d->env, &status); + upb_status_seterrmsg(d->status, msg); } void upb_pbdecoder_seterr(upb_pbdecoder *d, const char *msg) { @@ -992,24 +990,24 @@ void upb_pbdecoder_reset(upb_pbdecoder *d) { d->residual_end = d->residual; } -upb_pbdecoder *upb_pbdecoder_create(upb_env *e, const upb_pbdecodermethod *m, +upb_pbdecoder *upb_pbdecoder_create(upb_arena *a, const upb_pbdecodermethod *m, upb_sink sink) { const size_t default_max_nesting = 64; #ifndef NDEBUG - size_t size_before = upb_env_bytesallocated(e); + size_t size_before = upb_arena_bytesallocated(a); #endif - upb_pbdecoder *d = upb_env_malloc(e, sizeof(upb_pbdecoder)); + upb_pbdecoder *d = upb_arena_malloc(a, sizeof(upb_pbdecoder)); if (!d) return NULL; d->method_ = m; - d->callstack = upb_env_malloc(e, callstacksize(d, default_max_nesting)); - d->stack = upb_env_malloc(e, stacksize(d, default_max_nesting)); + d->callstack = upb_arena_malloc(a, callstacksize(d, default_max_nesting)); + d->stack = upb_arena_malloc(a, stacksize(d, default_max_nesting)); if (!d->stack || !d->callstack) { return NULL; } - d->env = e; + d->arena = a; d->limit = d->stack + default_max_nesting - 1; d->stack_size = default_max_nesting; d->status = NULL; @@ -1024,7 +1022,7 @@ upb_pbdecoder *upb_pbdecoder_create(upb_env *e, const upb_pbdecodermethod *m, d->top->sink = sink; /* If this fails, increase the value in decoder.h. */ - UPB_ASSERT_DEBUGVAR(upb_env_bytesallocated(e) - size_before <= + UPB_ASSERT_DEBUGVAR(upb_arena_bytesallocated(a) - size_before <= UPB_PB_DECODER_SIZE); return d; } @@ -1057,7 +1055,7 @@ bool upb_pbdecoder_setmaxnesting(upb_pbdecoder *d, size_t max) { /* Need to reallocate stack and callstack to accommodate. */ size_t old_size = stacksize(d, d->stack_size); size_t new_size = stacksize(d, max); - void *p = upb_env_realloc(d->env, d->stack, old_size, new_size); + void *p = upb_arena_realloc(d->arena, d->stack, old_size, new_size); if (!p) { return false; } @@ -1065,7 +1063,7 @@ bool upb_pbdecoder_setmaxnesting(upb_pbdecoder *d, size_t max) { old_size = callstacksize(d, d->stack_size); new_size = callstacksize(d, max); - p = upb_env_realloc(d->env, d->callstack, old_size, new_size); + p = upb_arena_realloc(d->arena, d->callstack, old_size, new_size); if (!p) { return false; } diff --git a/upb/pb/decoder.h b/upb/pb/decoder.h index ba381f3..6fcef03 100644 --- a/upb/pb/decoder.h +++ b/upb/pb/decoder.h @@ -40,7 +40,9 @@ class DecoderMethodOptions; struct upb_pbdecodermethod; typedef struct upb_pbdecodermethod upb_pbdecodermethod; -UPB_BEGIN_EXTERN_C +#ifdef __cplusplus +extern "C" { +#endif const upb_handlers *upb_pbdecodermethod_desthandlers( const upb_pbdecodermethod *m); @@ -48,9 +50,8 @@ const upb_byteshandler *upb_pbdecodermethod_inputhandler( const upb_pbdecodermethod *m); bool upb_pbdecodermethod_isnative(const upb_pbdecodermethod *m); -UPB_END_EXTERN_C - #ifdef __cplusplus +} /* extern "C" */ /* Represents the code to parse a protobuf according to a destination * Handlers. */ @@ -95,9 +96,11 @@ class upb::pb::DecoderMethodPtr { struct upb_pbdecoder; typedef struct upb_pbdecoder upb_pbdecoder; -UPB_BEGIN_EXTERN_C +#ifdef __cplusplus +extern "C" { +#endif -upb_pbdecoder *upb_pbdecoder_create(upb_env *e, +upb_pbdecoder *upb_pbdecoder_create(upb_arena *arena, const upb_pbdecodermethod *method, upb_sink output); const upb_pbdecodermethod *upb_pbdecoder_method(const upb_pbdecoder *d); @@ -107,9 +110,8 @@ size_t upb_pbdecoder_maxnesting(const upb_pbdecoder *d); bool upb_pbdecoder_setmaxnesting(upb_pbdecoder *d, size_t max); void upb_pbdecoder_reset(upb_pbdecoder *d); -UPB_END_EXTERN_C - #ifdef __cplusplus +} /* extern "C" */ /* A Decoder receives binary protobuf data on its input sink and pushes the * decoded data to its output sink. */ @@ -124,9 +126,10 @@ class upb::pb::DecoderPtr { * must also outlive this decoder. * * The sink must match the given method. */ - static DecoderPtr Create(Environment *env, DecoderMethodPtr method, + static DecoderPtr Create(Arena *arena, DecoderMethodPtr method, upb::Sink output) { - return DecoderPtr(upb_pbdecoder_create(env, method.ptr(), output.sink())); + return DecoderPtr( + upb_pbdecoder_create(arena->ptr(), method.ptr(), output.sink())); } /* Returns the DecoderMethod this decoder is parsing from. */ @@ -171,7 +174,9 @@ class upb::pb::DecoderPtr { struct upb_pbcodecache; typedef struct upb_pbcodecache upb_pbcodecache; -UPB_BEGIN_EXTERN_C +#ifdef __cplusplus +extern "C" { +#endif upb_pbcodecache *upb_pbcodecache_new(upb_handlercache *dest); void upb_pbcodecache_free(upb_pbcodecache *c); @@ -181,9 +186,8 @@ void upb_pbcodecache_setlazy(upb_pbcodecache *c, bool lazy); const upb_pbdecodermethod *upb_pbcodecache_get(upb_pbcodecache *c, const upb_msgdef *md); -UPB_END_EXTERN_C - #ifdef __cplusplus +} /* extern "C" */ /* A class for caching protobuf processing code, whether bytecode for the * interpreted decoder or machine code for the JIT. diff --git a/upb/pb/decoder.int.h b/upb/pb/decoder.int.h index 8d464fa..47eb3ed 100644 --- a/upb/pb/decoder.int.h +++ b/upb/pb/decoder.int.h @@ -73,7 +73,7 @@ typedef enum { UPB_INLINE opcode getop(uint32_t instr) { return instr & 0xff; } struct upb_pbcodecache { - upb_arena arena; + upb_arena *arena; upb_handlercache *dest; bool allow_jit; bool lazy; @@ -169,7 +169,7 @@ struct upb_pbdecodermethod { }; struct upb_pbdecoder { - upb_env *env; + upb_arena *arena; /* Our input sink. */ upb_bytessink input_; diff --git a/upb/pb/encoder.c b/upb/pb/encoder.c index 1496eba..722cc5b 100644 --- a/upb/pb/encoder.c +++ b/upb/pb/encoder.c @@ -91,7 +91,7 @@ typedef struct { } upb_pb_encoder_segment; struct upb_pb_encoder { - upb_env *env; + upb_arena *arena; /* Our input and output. */ upb_sink input_; @@ -150,7 +150,7 @@ static bool reserve(upb_pb_encoder *e, size_t bytes) { new_size *= 2; } - new_buf = upb_env_realloc(e->env, e->buf, old_size, new_size); + new_buf = upb_arena_realloc(e->arena, e->buf, old_size, new_size); if (new_buf == NULL) { return false; @@ -230,7 +230,7 @@ static bool start_delim(upb_pb_encoder *e) { (e->seglimit - e->segbuf) * sizeof(upb_pb_encoder_segment); size_t new_size = old_size * 2; upb_pb_encoder_segment *new_buf = - upb_env_realloc(e->env, e->segbuf, old_size, new_size); + upb_arena_realloc(e->arena, e->segbuf, old_size, new_size); if (new_buf == NULL) { return false; @@ -526,22 +526,22 @@ upb_handlercache *upb_pb_encoder_newcache() { return upb_handlercache_new(newhandlers_callback, NULL); } -upb_pb_encoder *upb_pb_encoder_create(upb_env *env, const upb_handlers *h, +upb_pb_encoder *upb_pb_encoder_create(upb_arena *arena, const upb_handlers *h, upb_bytessink output) { const size_t initial_bufsize = 256; const size_t initial_segbufsize = 16; /* TODO(haberman): make this configurable. */ const size_t stack_size = 64; #ifndef NDEBUG - const size_t size_before = upb_env_bytesallocated(env); + const size_t size_before = upb_arena_bytesallocated(arena); #endif - upb_pb_encoder *e = upb_env_malloc(env, sizeof(upb_pb_encoder)); + upb_pb_encoder *e = upb_arena_malloc(arena, sizeof(upb_pb_encoder)); if (!e) return NULL; - e->buf = upb_env_malloc(env, initial_bufsize); - e->segbuf = upb_env_malloc(env, initial_segbufsize * sizeof(*e->segbuf)); - e->stack = upb_env_malloc(env, stack_size * sizeof(*e->stack)); + e->buf = upb_arena_malloc(arena, initial_bufsize); + e->segbuf = upb_arena_malloc(arena, initial_segbufsize * sizeof(*e->segbuf)); + e->stack = upb_arena_malloc(arena, stack_size * sizeof(*e->stack)); if (!e->buf || !e->segbuf || !e->stack) { return NULL; @@ -554,13 +554,13 @@ upb_pb_encoder *upb_pb_encoder_create(upb_env *env, const upb_handlers *h, upb_pb_encoder_reset(e); upb_sink_reset(&e->input_, h, e); - e->env = env; + e->arena = arena; e->output_ = output; e->subc = output.closure; e->ptr = e->buf; /* If this fails, increase the value in encoder.h. */ - UPB_ASSERT_DEBUGVAR(upb_env_bytesallocated(env) - size_before <= + UPB_ASSERT_DEBUGVAR(upb_arena_bytesallocated(arena) - size_before <= UPB_PB_ENCODER_SIZE); return e; } diff --git a/upb/pb/encoder.h b/upb/pb/encoder.h index 7aa2870..780f60f 100644 --- a/upb/pb/encoder.h +++ b/upb/pb/encoder.h @@ -35,17 +35,18 @@ class EncoderPtr; struct upb_pb_encoder; typedef struct upb_pb_encoder upb_pb_encoder; -UPB_BEGIN_EXTERN_C +#ifdef __cplusplus +extern "C" { +#endif upb_sink upb_pb_encoder_input(upb_pb_encoder *p); -upb_pb_encoder* upb_pb_encoder_create(upb_env* e, const upb_handlers* h, +upb_pb_encoder* upb_pb_encoder_create(upb_arena* a, const upb_handlers* h, upb_bytessink output); upb_handlercache *upb_pb_encoder_newcache(); -UPB_END_EXTERN_C - #ifdef __cplusplus +} /* extern "C" { */ class upb::pb::EncoderPtr { public: @@ -55,9 +56,10 @@ class upb::pb::EncoderPtr { /* Creates a new encoder in the given environment. The Handlers must have * come from NewHandlers() below. */ - static EncoderPtr Create(Environment* env, const Handlers* handlers, + static EncoderPtr Create(Arena* arena, const Handlers* handlers, BytesSink output) { - return EncoderPtr(upb_pb_encoder_create(env, handlers, output.sink())); + return EncoderPtr( + upb_pb_encoder_create(arena->ptr(), handlers, output.sink())); } /* The input to the encoder. */ diff --git a/upb/pb/textprinter.c b/upb/pb/textprinter.c index d1d539d..91d0d55 100644 --- a/upb/pb/textprinter.c +++ b/upb/pb/textprinter.c @@ -18,7 +18,7 @@ struct upb_textprinter { upb_sink input_; - upb_bytessink *output_; + upb_bytessink output_; int indent_depth_; bool single_line_; void *subc; @@ -35,13 +35,13 @@ static int indent(upb_textprinter *p) { int i; if (!p->single_line_) for (i = 0; i < p->indent_depth_; i++) - upb_bytessink_putbuf(p->output_, p->subc, " ", 2, NULL); + upb_bytessink_putbuf(&p->output_, p->subc, " ", 2, NULL); return 0; } static int endfield(upb_textprinter *p) { const char ch = (p->single_line_ ? ' ' : '\n'); - upb_bytessink_putbuf(p->output_, p->subc, &ch, 1, NULL); + upb_bytessink_putbuf(&p->output_, p->subc, &ch, 1, NULL); return 0; } @@ -60,7 +60,7 @@ static int putescaped(upb_textprinter *p, const char *buf, size_t len, bool is_hex_escape; if (dstend - dst < 4) { - upb_bytessink_putbuf(p->output_, p->subc, dstbuf, dst - dstbuf, NULL); + upb_bytessink_putbuf(&p->output_, p->subc, dstbuf, dst - dstbuf, NULL); dst = dstbuf; } @@ -88,7 +88,7 @@ static int putescaped(upb_textprinter *p, const char *buf, size_t len, last_hex_escape = is_hex_escape; } /* Flush remaining data. */ - upb_bytessink_putbuf(p->output_, p->subc, dstbuf, dst - dstbuf, NULL); + upb_bytessink_putbuf(&p->output_, p->subc, dstbuf, dst - dstbuf, NULL); return 0; } @@ -114,7 +114,7 @@ bool putf(upb_textprinter *p, const char *fmt, ...) { va_end(args); UPB_ASSERT(written == len); - ok = upb_bytessink_putbuf(p->output_, p->subc, str, len, NULL); + ok = upb_bytessink_putbuf(&p->output_, p->subc, str, len, NULL); upb_gfree(str); return ok; } @@ -126,7 +126,7 @@ static bool textprinter_startmsg(void *c, const void *hd) { upb_textprinter *p = c; UPB_UNUSED(hd); if (p->indent_depth_ == 0) { - upb_bytessink_start(p->output_, 0, &p->subc); + upb_bytessink_start(&p->output_, 0, &p->subc); } return true; } @@ -136,7 +136,7 @@ static bool textprinter_endmsg(void *c, const void *hd, upb_status *s) { UPB_UNUSED(hd); UPB_UNUSED(s); if (p->indent_depth_ == 0) { - upb_bytessink_end(p->output_); + upb_bytessink_end(&p->output_); } return true; } @@ -241,7 +241,7 @@ static bool textprinter_endsubmsg(void *closure, const void *handler_data) { UPB_UNUSED(handler_data); p->indent_depth_--; CHECK(indent(p)); - upb_bytessink_putbuf(p->output_, p->subc, "}", 1, NULL); + upb_bytessink_putbuf(&p->output_, p->subc, "}", 1, NULL); CHECK(endfield(p)); return true; err: @@ -315,9 +315,9 @@ static void textprinter_reset(upb_textprinter *p, bool single_line) { /* Public API *****************************************************************/ -upb_textprinter *upb_textprinter_create(upb_env *env, const upb_handlers *h, - upb_bytessink *output) { - upb_textprinter *p = upb_env_malloc(env, sizeof(upb_textprinter)); +upb_textprinter *upb_textprinter_create(upb_arena *arena, const upb_handlers *h, + upb_bytessink output) { + upb_textprinter *p = upb_arena_malloc(arena, sizeof(upb_textprinter)); if (!p) return NULL; p->output_ = output; @@ -331,7 +331,7 @@ upb_handlercache *upb_textprinter_newcache() { return upb_handlercache_new(&onmreg, NULL); } -upb_sink *upb_textprinter_input(upb_textprinter *p) { return &p->input_; } +upb_sink upb_textprinter_input(upb_textprinter *p) { return p->input_; } void upb_textprinter_setsingleline(upb_textprinter *p, bool single_line) { p->single_line_ = single_line; diff --git a/upb/pb/textprinter.h b/upb/pb/textprinter.h index 06ff7d5..e59e11d 100644 --- a/upb/pb/textprinter.h +++ b/upb/pb/textprinter.h @@ -17,60 +17,51 @@ class TextPrinter; } /* namespace upb */ #endif -UPB_DECLARE_TYPE(upb::pb::TextPrinter, upb_textprinter) +/* upb_textprinter ************************************************************/ + +struct upb_textprinter; +typedef struct upb_textprinter upb_textprinter; #ifdef __cplusplus +extern "C" { +#endif -class upb::pb::TextPrinter { +/* C API. */ +upb_textprinter *upb_textprinter_create(upb_arena *arena, const upb_handlers *h, + upb_bytessink output); +void upb_textprinter_setsingleline(upb_textprinter *p, bool single_line); +upb_sink upb_textprinter_input(upb_textprinter *p); +upb_handlercache *upb_textprinter_newcache(); + +#ifdef __cplusplus +} /* extern "C" */ + +class upb::pb::TextPrinterPtr { public: + TextPrinterPtr(upb_textprinter* ptr) : ptr_(ptr) {} + /* The given handlers must have come from NewHandlers(). It must outlive the * TextPrinter. */ - static TextPrinter *Create(Environment *env, const upb::Handlers *handlers, - BytesSink *output); + static TextPrinterPtr *Create(Arena *arena, const upb::Handlers *handlers, + BytesSink output) { + return TextPrinterPtr(upb_textprinter_create(arena, handlers, output)); + } - void SetSingleLineMode(bool single_line); + void SetSingleLineMode(bool single_line) { + upb_textprinter_setsingleline(ptr_, single_line); + } - Sink* input(); + Sink input() { return upb_textprinter_input(ptr_); } /* If handler caching becomes a requirement we can add a code cache as in * decoder.h */ - static HandlerCache* NewCache(); -}; - -#endif - -UPB_BEGIN_EXTERN_C + static HandlerCache NewCache() { + return HandlerCache(upb_textprinter_newcache()); + } -/* C API. */ -upb_textprinter *upb_textprinter_create(upb_env *env, const upb_handlers *h, - upb_bytessink *output); -void upb_textprinter_setsingleline(upb_textprinter *p, bool single_line); -upb_sink *upb_textprinter_input(upb_textprinter *p); - -upb_handlercache *upb_textprinter_newcache(); - -UPB_END_EXTERN_C - -#ifdef __cplusplus - -namespace upb { -namespace pb { -inline TextPrinter *TextPrinter::Create(Environment *env, - const upb::Handlers *handlers, - BytesSink *output) { - return upb_textprinter_create(env, handlers, output); -} -inline void TextPrinter::SetSingleLineMode(bool single_line) { - upb_textprinter_setsingleline(this, single_line); -} -inline Sink* TextPrinter::input() { - return upb_textprinter_input(this); -} -inline HandlerCache* TextPrinter::NewCache() { - return upb_textprinter_newcache(); -} -} /* namespace pb */ -} /* namespace upb */ + private: + upb_textprinter* ptr_; +}; #endif diff --git a/upb/sink.c b/upb/sink.c index 6ef5718..7a7eeb4 100644 --- a/upb/sink.c +++ b/upb/sink.c @@ -15,73 +15,3 @@ bool upb_bufsrc_putbuf(const char *buf, size_t len, upb_bytessink sink) { } return ret; } - -struct upb_bufsink { - upb_byteshandler handler; - upb_bytessink sink; - upb_env *env; - char *ptr; - size_t len, size; -}; - -static void *upb_bufsink_start(void *_sink, const void *hd, size_t size_hint) { - upb_bufsink *sink = _sink; - UPB_UNUSED(hd); - UPB_UNUSED(size_hint); - sink->len = 0; - return sink; -} - -static size_t upb_bufsink_string(void *_sink, const void *hd, const char *ptr, - size_t len, const upb_bufhandle *handle) { - upb_bufsink *sink = _sink; - size_t new_size = sink->size; - - UPB_ASSERT(new_size > 0); - UPB_UNUSED(hd); - UPB_UNUSED(handle); - - while (sink->len + len > new_size) { - new_size *= 2; - } - - if (new_size != sink->size) { - sink->ptr = upb_env_realloc(sink->env, sink->ptr, sink->size, new_size); - sink->size = new_size; - } - - memcpy(sink->ptr + sink->len, ptr, len); - sink->len += len; - - return len; -} - -upb_bufsink *upb_bufsink_new(upb_env *env) { - upb_bufsink *sink = upb_env_malloc(env, sizeof(upb_bufsink)); - upb_byteshandler_init(&sink->handler); - upb_byteshandler_setstartstr(&sink->handler, upb_bufsink_start, NULL); - upb_byteshandler_setstring(&sink->handler, upb_bufsink_string, NULL); - - upb_bytessink_reset(&sink->sink, &sink->handler, sink); - - sink->env = env; - sink->size = 32; - sink->ptr = upb_env_malloc(env, sink->size); - sink->len = 0; - - return sink; -} - -void upb_bufsink_free(upb_bufsink *sink) { - upb_env_free(sink->env, sink->ptr); - upb_env_free(sink->env, sink); -} - -upb_bytessink *upb_bufsink_sink(upb_bufsink *sink) { - return &sink->sink; -} - -const char *upb_bufsink_getdata(const upb_bufsink *sink, size_t *len) { - *len = sink->len; - return sink->ptr; -} diff --git a/upb/sink.h b/upb/sink.h index 1855542..d93d966 100644 --- a/upb/sink.h +++ b/upb/sink.h @@ -29,7 +29,9 @@ class Sink; /* upb_sink *******************************************************************/ -UPB_BEGIN_EXTERN_C +#ifdef __cplusplus +extern "C" { +#endif typedef struct { const upb_handlers *handlers; @@ -192,9 +194,8 @@ UPB_INLINE bool upb_sink_endsubmsg(upb_sink *s, upb_selector_t sel) { return endsubmsg(s->closure, hd); } -UPB_END_EXTERN_C - #ifdef __cplusplus +} /* extern "C" */ /* A upb::Sink is an object that binds a upb::Handlers object to some runtime * state. It represents an endpoint to which data can be sent. @@ -288,7 +289,9 @@ class upb::Sink { * sink->EndMessage(&status); * sink->EndSubMessage(endsubmsg_selector); */ bool StartMessage() { return upb_sink_startmsg(&sink_); } - bool EndMessage(Status* status) { return upb_sink_endmsg(&sink_, status); } + bool EndMessage(upb_status *status) { + return upb_sink_endmsg(&sink_, status); + } /* Putting of individual values. These work for both repeated and * non-repeated fields, but for repeated fields you must wrap them in @@ -489,13 +492,14 @@ class upb::BytesSink { /* upb_bufsrc *****************************************************************/ -UPB_BEGIN_EXTERN_C +#ifdef __cplusplus +extern "C" { +#endif bool upb_bufsrc_putbuf(const char *buf, size_t len, upb_bytessink sink); -UPB_END_EXTERN_C - #ifdef __cplusplus +} /* extern "C" */ namespace upb { template bool PutBuffer(const T& str, BytesSink sink) { @@ -505,19 +509,4 @@ template bool PutBuffer(const T& str, BytesSink sink) { #endif /* __cplusplus */ -/* upb_bufsink ****************************************************************/ - -/* A class for accumulating output string data in a flat buffer. */ -struct upb_bufsink; -typedef struct upb_bufsink upb_bufsink; - -UPB_BEGIN_EXTERN_C - -upb_bufsink *upb_bufsink_init(upb_env *env); -void upb_bufsink_free(upb_bufsink *sink); -upb_bytessink *upb_bufsink_sink(upb_bufsink *sink); -const char *upb_bufsink_getdata(const upb_bufsink *sink, size_t *len); - -UPB_END_EXTERN_C - #endif diff --git a/upb/table.int.h b/upb/table.int.h index 63dce59..2b86390 100644 --- a/upb/table.int.h +++ b/upb/table.int.h @@ -156,21 +156,6 @@ UPB_INLINE upb_value upb_value_double(double cval) { * initializing a non-first union member. */ typedef uintptr_t upb_tabkey; -#define UPB_TABKEY_NUM(n) n -#define UPB_TABKEY_NONE 0 -/* The preprocessor isn't quite powerful enough to turn the compile-time string - * length into a byte-wise string representation, so code generation needs to - * help it along. - * - * "len1" is the low byte and len4 is the high byte. */ -#ifdef UPB_BIG_ENDIAN -#define UPB_TABKEY_STR(len1, len2, len3, len4, strval) \ - (uintptr_t)(len4 len3 len2 len1 strval) -#else -#define UPB_TABKEY_STR(len1, len2, len3, len4, strval) \ - (uintptr_t)(len1 len2 len3 len4 strval) -#endif - UPB_INLINE char *upb_tabstr(upb_tabkey key, uint32_t *len) { char* mem = (char*)key; if (len) memcpy(len, mem, sizeof(*len)); diff --git a/upb/upb.c b/upb/upb.c index 68e26b0..f56f6c4 100644 --- a/upb/upb.c +++ b/upb/upb.c @@ -8,12 +8,6 @@ #include #include "upb/upb.h" -bool upb_dumptostderr(void *closure, const upb_status* status) { - UPB_UNUSED(closure); - fprintf(stderr, "%s\n", upb_status_errmsg(status)); - return false; -} - /* Guarantee null-termination and provide ellipsis truncation. * It may be tempting to "optimize" this by initializing these final * four bytes up-front and then being careful never to overwrite them, @@ -29,24 +23,17 @@ static void nullz(upb_status *status) { void upb_status_clear(upb_status *status) { if (!status) return; - status->ok_ = true; - status->code_ = 0; + status->ok = true; status->msg[0] = '\0'; } -bool upb_ok(const upb_status *status) { return status->ok_; } - -upb_errorspace *upb_status_errspace(const upb_status *status) { - return status->error_space_; -} - -int upb_status_errcode(const upb_status *status) { return status->code_; } +bool upb_ok(const upb_status *status) { return status->ok; } const char *upb_status_errmsg(const upb_status *status) { return status->msg; } void upb_status_seterrmsg(upb_status *status, const char *msg) { if (!status) return; - status->ok_ = false; + status->ok = false; strncpy(status->msg, msg, sizeof(status->msg)); nullz(status); } @@ -60,17 +47,11 @@ void upb_status_seterrf(upb_status *status, const char *fmt, ...) { void upb_status_vseterrf(upb_status *status, const char *fmt, va_list args) { if (!status) return; - status->ok_ = false; + status->ok = false; _upb_vsnprintf(status->msg, sizeof(status->msg), fmt, args); nullz(status); } -void upb_status_copy(upb_status *to, const upb_status *from) { - if (!to) return; - *to = *from; -} - - /* upb_alloc ******************************************************************/ static void *upb_global_allocfunc(upb_alloc *alloc, void *ptr, size_t oldsize, @@ -87,7 +68,6 @@ static void *upb_global_allocfunc(upb_alloc *alloc, void *ptr, size_t oldsize, upb_alloc upb_alloc_global = {&upb_global_allocfunc}; - /* upb_arena ******************************************************************/ /* Be conservative and choose 16 in case anyone is using SSE. */ @@ -115,11 +95,7 @@ struct upb_arena { /* Cleanup entries. Pointer to a cleanup_ent, defined in env.c */ void *cleanup_head; - - /* For future expansion, since the size of this struct is exposed to users. */ - void *future1; - void *future2; -} upb_arena; +}; typedef struct mem_block { struct mem_block *next; @@ -149,7 +125,6 @@ static void upb_arena_addblock(upb_arena *a, void *ptr, size_t size, /* TODO(haberman): ASAN poison. */ } - static mem_block *upb_arena_allocblock(upb_arena *a, size_t size) { size_t block_size = UPB_MAX(size, a->next_block_size) + sizeof(mem_block); mem_block *block = upb_malloc(a->block_alloc, block_size); @@ -202,7 +177,25 @@ static void *upb_arena_doalloc(upb_alloc *alloc, void *ptr, size_t oldsize, /* Public Arena API ***********************************************************/ -void upb_arena_init(upb_arena *a) { +upb_arena *upb_arena_init(void *mem, size_t n, upb_alloc *alloc) { + const size_t first_block_overhead = sizeof(upb_arena) + sizeof(mem_block); + upb_arena *a; + bool owned = false; + + if (n < first_block_overhead) { + /* We need to malloc the initial block. */ + n = first_block_overhead + 256; + owned = true; + if (!alloc || !(mem = upb_malloc(alloc, n))) { + return NULL; + } + } + + a = mem; + mem = (char*)mem + sizeof(*a); + n -= sizeof(*a); + upb_arena_addblock(a, mem, n, owned); + a->alloc.func = &upb_arena_doalloc; a->block_alloc = &upb_alloc_global; a->bytes_allocated = 0; @@ -210,21 +203,12 @@ void upb_arena_init(upb_arena *a) { a->max_block_size = 16384; a->cleanup_head = NULL; a->block_head = NULL; -} - -void upb_arena_init2(upb_arena *a, void *mem, size_t size, upb_alloc *alloc) { - upb_arena_init(a); + a->block_alloc = alloc; - if (size > sizeof(mem_block)) { - upb_arena_addblock(a, mem, size, false); - } - - if (alloc) { - a->block_alloc = alloc; - } + return a; } -void upb_arena_uninit(upb_arena *a) { +void upb_arena_free(upb_arena *a) { cleanup_ent *ent = a->cleanup_head; mem_block *block = a->block_head; @@ -236,6 +220,7 @@ void upb_arena_uninit(upb_arena *a) { /* Must do this after running cleanup functions, because this will delete * the memory we store our cleanup entries in! */ while (block) { + /* Load first since we are deleting block. */ mem_block *next = block->next; if (block->owned) { @@ -244,10 +229,6 @@ void upb_arena_uninit(upb_arena *a) { block = next; } - - /* Protect against multiple-uninit. */ - a->cleanup_head = NULL; - a->block_head = NULL; } bool upb_arena_addcleanup(upb_arena *a, upb_cleanup_func *func, void *ud) { diff --git a/upb/upb.h b/upb/upb.h index 4384812..07b0455 100644 --- a/upb/upb.h +++ b/upb/upb.h @@ -15,14 +15,11 @@ #include #ifdef __cplusplus +#include namespace upb { -class Allocator; class Arena; -class Environment; -class ErrorSpace; class Status; template class InlinedArena; -template class InlinedEnvironment; } #endif @@ -74,46 +71,14 @@ template class InlinedEnvironment; #error Need implementations of [v]snprintf and va_copy #endif -#if (defined(__cplusplus) && __cplusplus >= 201103L) || \ - defined(__GXX_EXPERIMENTAL_CXX0X__) || \ +#ifdef __cplusplus +#if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__) || \ (defined(_MSC_VER) && _MSC_VER >= 1900) // C++11 is present #else #error upb requires C++11 for C++ support #endif - -/* UPB_DISALLOW_COPY_AND_ASSIGN() - * UPB_DISALLOW_POD_OPS() - * - * Declare these in the "private" section of a C++ class to forbid copy/assign - * or all POD ops (construct, destruct, copy, assign) on that class. */ -#include -#define UPB_DISALLOW_COPY_AND_ASSIGN(class_name) \ - class_name(const class_name&) = delete; \ - void operator=(const class_name&) = delete; -#define UPB_DISALLOW_POD_OPS(class_name, full_class_name) \ - class_name() = delete; \ - ~class_name() = delete; \ - UPB_DISALLOW_COPY_AND_ASSIGN(class_name) -#define UPB_ASSERT_STDLAYOUT(type) \ - static_assert(std::is_standard_layout::value, \ - #type " must be standard layout"); - -#ifdef __cplusplus - -#define UPB_BEGIN_EXTERN_C extern "C" { -#define UPB_END_EXTERN_C } -#define UPB_DECLARE_TYPE(cppname, cname) typedef cppname cname; - -#else /* !defined(__cplusplus) */ - -#define UPB_BEGIN_EXTERN_C -#define UPB_END_EXTERN_C -#define UPB_DECLARE_TYPE(cppname, cname) \ - struct cname; \ - typedef struct cname cname; - -#endif /* defined(__cplusplus) */ +#endif #define UPB_MAX(x, y) ((x) > (y) ? (x) : (y)) #define UPB_MIN(x, y) ((x) < (y) ? (x) : (y)) @@ -138,21 +103,26 @@ template class InlinedEnvironment; #define UPB_UNREACHABLE() do { assert(0); } while(0) #endif -/* upb::Status ****************************************************************/ +/* upb_status *****************************************************************/ -/* upb::Status represents a success or failure status and error message. +/* upb_status represents a success or failure status and error message. * It owns no resources and allocates no memory, so it should work * even in OOM situations. */ -UPB_DECLARE_TYPE(upb::Status, upb_status) /* The maximum length of an error message before it will get truncated. */ -#define UPB_STATUS_MAX_MESSAGE 128 +#define UPB_STATUS_MAX_MESSAGE 127 -UPB_BEGIN_EXTERN_C +typedef struct { + bool ok; + char msg[UPB_STATUS_MAX_MESSAGE]; /* Error message; NULL-terminated. */ +} upb_status; + +#ifdef __cplusplus +extern "C" { +#endif const char *upb_status_errmsg(const upb_status *status); bool upb_ok(const upb_status *status); -int upb_status_errcode(const upb_status *status); /* Any of the functions that write to a status object allow status to be NULL, * to support use cases where the function's caller does not care about the @@ -161,60 +131,44 @@ void upb_status_clear(upb_status *status); void upb_status_seterrmsg(upb_status *status, const char *msg); void upb_status_seterrf(upb_status *status, const char *fmt, ...); void upb_status_vseterrf(upb_status *status, const char *fmt, va_list args); -void upb_status_copy(upb_status *to, const upb_status *from); -UPB_END_EXTERN_C +UPB_INLINE void upb_status_setoom(upb_status *status) { + upb_status_seterrmsg(status, "out of memory"); +} #ifdef __cplusplus +} /* extern "C" */ class upb::Status { public: - Status() { upb_status_clear(this); } + Status() { upb_status_clear(&status_); } - /* Returns true if there is no error. */ - bool ok() const { return upb_ok(this); } + upb_status* ptr() { return &status_; } - /* Optional error space and code, useful if the caller wants to - * programmatically check the specific kind of error. */ - ErrorSpace* error_space() { return upb_status_errspace(this); } - int error_code() const { return upb_status_errcode(this); } + /* Returns true if there is no error. */ + bool ok() const { return upb_ok(&status_); } - /* The returned string is invalidated by any other call into the status. */ - const char *error_message() const { return upb_status_errmsg(this); } + /* Guaranteed to be NULL-terminated. */ + const char *error_message() const { return upb_status_errmsg(&status_); } /* The error message will be truncated if it is longer than * UPB_STATUS_MAX_MESSAGE-4. */ - void SetErrorMessage(const char* msg) { upb_status_seterrmsg(this, msg); } - void SetFormattedErrorMessage(const char* fmt, ...) { + void SetErrorMessage(const char *msg) { upb_status_seterrmsg(&status_, msg); } + void SetFormattedErrorMessage(const char *fmt, ...) { va_list args; va_start(args, fmt); - upb_status_vseterrf(this, fmt, args); + upb_status_vseterrf(&status_, fmt, args); va_end(args); } /* Resets the status to a successful state with no message. */ - void Clear() { upb_status_clear(this); } - - void CopyFrom(const Status& other) { upb_status_copy(this, &other); } + void Clear() { upb_status_clear(&status_); } private: - UPB_DISALLOW_COPY_AND_ASSIGN(Status) -#else -struct upb_status { -#endif - bool ok_; - - /* Specific status code defined by some error space (optional). */ - int code_; - upb_errorspace *error_space_; - - /* TODO(haberman): add file/line of error? */ - - /* Error message; NULL-terminated. */ - char msg[UPB_STATUS_MAX_MESSAGE]; + upb_status status_; }; -#define UPB_STATUS_INIT {true, 0, NULL, {0}} +#endif /* __cplusplus */ /** upb_alloc *****************************************************************/ @@ -291,17 +245,23 @@ UPB_INLINE void upb_gfree(void *ptr) { typedef void upb_cleanup_func(void *ud); struct upb_arena; -typedef upb_arena upb_arena; +typedef struct upb_arena upb_arena; -UPB_BEGIN_EXTERN_C +#ifdef __cplusplus +extern "C" { +#endif -upb_arena *upb_arena_new2(void *mem, size_t n, upb_alloc *alloc); +/* Creates an arena from the given initial block (if any -- n may be 0). + * Additional blocks will be allocated from |alloc|. If |alloc| is NULL, this + * is a fixed-size arena and cannot grow. */ +upb_arena *upb_arena_init(void *mem, size_t n, upb_alloc *alloc); void upb_arena_free(upb_arena *a); bool upb_arena_addcleanup(upb_arena *a, upb_cleanup_func *func, void *ud); size_t upb_arena_bytesallocated(const upb_arena *a); UPB_INLINE upb_alloc *upb_arena_alloc(upb_arena *a) { return (upb_alloc*)a; } +/* Convenience wrappers around upb_alloc functions. */ UPB_INLINE void *upb_arena_malloc(upb_arena *a, size_t size) { return upb_malloc(upb_arena_alloc(a), size); } @@ -312,52 +272,38 @@ UPB_INLINE void *upb_arena_realloc(upb_arena *a, void *ptr, size_t oldsize, } UPB_INLINE upb_arena *upb_arena_new() { - return upb_arena_new2(NULL, 0, &upb_alloc_global); + return upb_arena_init(NULL, 0, &upb_alloc_global); } -UPB_END_EXTERN_C - #ifdef __cplusplus +} /* extern "C" */ class upb::Arena { public: /* A simple arena with no initial memory block and the default allocator. */ - Arena() { upb_arena_init(&arena_); } + Arena() : ptr_(upb_arena_new(), upb_arena_free) {} - upb_arena* ptr() { return &arena_; } - - /* Constructs an arena with the given initial block which allocates blocks - * with the given allocator. The given allocator must outlive the Arena. - * - * If you pass NULL for the allocator it will default to the global allocator - * upb_alloc_global, and NULL/0 for the initial block will cause there to be - * no initial block. */ - Arena(void *mem, size_t len, upb_alloc *a) { - upb_arena_init2(&arena_, mem, len, a); - } - - ~Arena() { upb_arena_uninit(&arena_); } + upb_arena* ptr() { return ptr_.get(); } /* Allows this arena to be used as a generic allocator. * * The arena does not need free() calls so when using Arena as an allocator * it is safe to skip them. However they are no-ops so there is no harm in * calling free() either. */ - upb_alloc *allocator() { return upb_arena_alloc(&arena_); } + upb_alloc *allocator() { return upb_arena_alloc(ptr_.get()); } /* Add a cleanup function to run when the arena is destroyed. * Returns false on out-of-memory. */ bool AddCleanup(upb_cleanup_func *func, void *ud) { - return upb_arena_addcleanup(&arena_, func, ud); + return upb_arena_addcleanup(ptr_.get(), func, ud); } /* Total number of bytes that have been allocated. It is undefined what * Realloc() does to &arena_ counter. */ - size_t BytesAllocated() const { return upb_arena_bytesallocated(&arena_); } + size_t BytesAllocated() const { return upb_arena_bytesallocated(ptr_.get()); } private: - UPB_DISALLOW_COPY_AND_ASSIGN(Arena) - upb_arena arena_; + std::unique_ptr ptr_; }; #endif @@ -373,13 +319,16 @@ class upb::Arena { template class upb::InlinedArena : public upb::Arena { public: - InlinedArena() : Arena(initial_block_, N, NULL) {} - explicit InlinedArena(Allocator* a) : Arena(initial_block_, N, a) {} + InlinedArena() : ptr_(upb_arena_new(&initial_block_, N, &upb_alloc_global)) {} + + upb_arena* ptr() { return ptr_.get(); } private: - UPB_DISALLOW_COPY_AND_ASSIGN(InlinedArena) + InlinedArena(const InlinedArena*) = delete; + InlinedArena& operator=(const InlinedArena*) = delete; - char initial_block_[N + UPB_ARENA_BLOCK_OVERHEAD]; + std::unique_ptr ptr_; + char initial_block_[N]; }; #endif /* __cplusplus */ diff --git a/upbc/generator.cc b/upbc/generator.cc index ddfaa7b..de40eee 100644 --- a/upbc/generator.cc +++ b/upbc/generator.cc @@ -502,7 +502,9 @@ void WriteHeader(const protobuf::FileDescriptor* file, Output& output) { "#include \"upb/decode.h\"\n" "#include \"upb/encode.h\"\n" "#include \"upb/port_def.inc\"\n" - "UPB_BEGIN_EXTERN_C\n\n", + "#ifdef __cplusplus\n" + "extern \"C\" {\n" + "#endif\n\n", ToPreproc(file->name())); // Forward-declare types defined in this file. @@ -548,7 +550,9 @@ void WriteHeader(const protobuf::FileDescriptor* file, Output& output) { } output( - "UPB_END_EXTERN_C\n" + "#ifdef __cplusplus\n" + "} /* extern \"C\" */\n" + "#endif\n" "\n" "#include \"upb/port_undef.inc\"\n" "\n" -- cgit v1.2.3 From 9349b703a33c76b0d50a15c6d372e8948e045749 Mon Sep 17 00:00:00 2001 From: Joshua Haberman Date: Tue, 15 Jan 2019 13:35:39 -0800 Subject: Fixed a few bugs surfaced by Ruby. --- upb/def.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'upb/def.c') diff --git a/upb/def.c b/upb/def.c index ae2306f..aedd88d 100644 --- a/upb/def.c +++ b/upb/def.c @@ -552,7 +552,7 @@ uint32_t upb_fielddef_defaultuint32(const upb_fielddef *f) { bool upb_fielddef_defaultbool(const upb_fielddef *f) { chkdefaulttype(f, UPB_TYPE_BOOL); - return f->defaultval.uint; + return f->defaultval.boolean; } float upb_fielddef_defaultfloat(const upb_fielddef *f) { @@ -1094,7 +1094,7 @@ static bool parse_default(const symtab_addctx *ctx, const char *str, size_t len, /* 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; + f->defaultval.flt = val; break; } case UPB_TYPE_BOOL: { @@ -1305,7 +1305,7 @@ static bool create_enumdef( int32_t num = google_protobuf_EnumValueDescriptorProto_number(value); upb_value v = upb_value_int32(num); - if (n == 0 && e->file->syntax == UPB_SYNTAX_PROTO3 && num != 0) { + if (i == 0 && e->file->syntax == UPB_SYNTAX_PROTO3 && num != 0) { upb_status_seterrf(ctx->status, "for proto3, the first enum value must be zero (%s)", e->full_name); -- cgit v1.2.3 From 01557462cc211cec9c7bddede77995b938067ea5 Mon Sep 17 00:00:00 2001 From: Joshua Haberman Date: Wed, 16 Jan 2019 18:50:46 -0800 Subject: upb_symtab_add() returns upb_filedef* instead of bool. --- tests/pb/test_encoder.cc | 6 +++--- upb/def.c | 8 ++++---- upb/def.h | 13 +++++++------ 3 files changed, 14 insertions(+), 13 deletions(-) (limited to 'upb/def.c') diff --git a/tests/pb/test_encoder.cc b/tests/pb/test_encoder.cc index 8b78ea8..f0b31c6 100644 --- a/tests/pb/test_encoder.cc +++ b/tests/pb/test_encoder.cc @@ -31,8 +31,8 @@ void test_pb_roundtrip() { google_protobuf_FileDescriptorSet_file(set, &n); ASSERT(n == 1); upb::Status status; - bool ok = symtab.AddFile(files[0], &status); - if (!ok) { + upb::FileDefPtr file_def = symtab.AddFile(files[0], &status); + if (!file_def) { fprintf(stderr, "Error building def: %s\n", status.error_message()); ASSERT(false); } @@ -49,7 +49,7 @@ void test_pb_roundtrip() { upb::pb::EncoderPtr::Create(&arena, encoder_handlers, string_sink.input()); upb::pb::DecoderPtr decoder = upb::pb::DecoderPtr::Create(&arena, method, encoder.input(), &status); - ok = upb::PutBuffer(input, decoder.input()); + bool ok = upb::PutBuffer(input, decoder.input()); ASSERT(ok); ASSERT(input == output); } diff --git a/upb/def.c b/upb/def.c index aedd88d..4a893d1 100644 --- a/upb/def.c +++ b/upb/def.c @@ -1649,9 +1649,9 @@ static bool upb_symtab_addtotabs(upb_symtab *s, symtab_addctx *ctx, return true; } -bool upb_symtab_addfile(upb_symtab *s, - const google_protobuf_FileDescriptorProto *file_proto, - upb_status *status) { +const upb_filedef *upb_symtab_addfile( + upb_symtab *s, const google_protobuf_FileDescriptorProto *file_proto, + upb_status *status) { upb_arena *tmparena = upb_arena_new(); upb_strtable addtab; upb_alloc *alloc = upb_arena_alloc(s->arena); @@ -1672,7 +1672,7 @@ bool upb_symtab_addfile(upb_symtab *s, upb_symtab_addtotabs(s, &ctx, status); upb_arena_free(tmparena); - return ok; + return ok ? file : NULL; } /* Include here since we want most of this file to be stdio-free. */ diff --git a/upb/def.h b/upb/def.h index 4fd8509..7675138 100644 --- a/upb/def.h +++ b/upb/def.h @@ -788,9 +788,9 @@ 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); int upb_symtab_filecount(const upb_symtab *s); -bool upb_symtab_addfile(upb_symtab *s, - const google_protobuf_FileDescriptorProto* file, - upb_status *status); +const upb_filedef *upb_symtab_addfile( + upb_symtab *s, const google_protobuf_FileDescriptorProto *file, + upb_status *status); /* For generated code only: loads a generated descriptor. */ typedef struct upb_def_init { @@ -826,9 +826,10 @@ class upb::SymbolTable { /* TODO: iteration? */ /* Adds the given serialized FileDescriptorProto to the pool. */ - bool AddFile(const google_protobuf_FileDescriptorProto *file_proto, - Status *status) { - return upb_symtab_addfile(ptr_.get(), file_proto, status->ptr()); + FileDefPtr AddFile(const google_protobuf_FileDescriptorProto *file_proto, + Status *status) { + return FileDefPtr( + upb_symtab_addfile(ptr_.get(), file_proto, status->ptr())); } private: -- cgit v1.2.3 From 04923fc26e1ca9f935fe10fb0de0fa932f7aa8b4 Mon Sep 17 00:00:00 2001 From: Joshua Haberman Date: Sat, 19 Jan 2019 19:38:03 -0800 Subject: Some fixes for PHP. --- upb/def.c | 21 +++++++++++++-------- upb/pb/encoder.c | 1 + 2 files changed, 14 insertions(+), 8 deletions(-) (limited to 'upb/def.c') diff --git a/upb/def.c b/upb/def.c index 5b239dd..f816c4f 100644 --- a/upb/def.c +++ b/upb/def.c @@ -818,7 +818,7 @@ bool upb_oneof_done(upb_oneof_iter *iter) { } upb_fielddef *upb_oneof_iter_field(const upb_oneof_iter *iter) { - return (upb_fielddef*)upb_value_getptr(upb_inttable_iter_value(iter)); + return (upb_fielddef *)upb_value_getconstptr(upb_inttable_iter_value(iter)); } void upb_oneof_iter_setdone(upb_oneof_iter *iter) { @@ -936,9 +936,6 @@ typedef struct { } symtab_addctx; static char* strviewdup(const symtab_addctx *ctx, upb_strview view) { - if (view.size == 0) { - return NULL; - } return upb_strdup2(view.data, view.size, ctx->alloc); } @@ -1329,6 +1326,8 @@ static bool create_enumdef( } } + upb_inttable_compact2(&e->iton, ctx->alloc); + return true; } @@ -1378,6 +1377,7 @@ static bool create_msgdef(const symtab_addctx *ctx, const char *prefix, CHK(assign_msg_indices(m, ctx->status)); assign_msg_wellknowntype(m); + upb_inttable_compact2(&m->itof, ctx->alloc); /* This message is built. Now build nested messages and enums. */ @@ -1571,10 +1571,15 @@ static bool build_filedef( /* Read options. */ file_options_proto = google_protobuf_FileDescriptorProto_options(file_proto); if (file_options_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)); + if (google_protobuf_FileOptions_has_php_class_prefix(file_options_proto)) { + file->phpprefix = strviewdup( + ctx, + google_protobuf_FileOptions_php_class_prefix(file_options_proto)); + } + if (google_protobuf_FileOptions_has_php_namespace(file_options_proto)) { + file->phpnamespace = strviewdup( + ctx, google_protobuf_FileOptions_php_namespace(file_options_proto)); + } } /* Verify dependencies. */ diff --git a/upb/pb/encoder.c b/upb/pb/encoder.c index 2da34db..5f74010 100644 --- a/upb/pb/encoder.c +++ b/upb/pb/encoder.c @@ -433,6 +433,7 @@ T(sint64, int64_t, upb_zzenc_64, encode_varint) /* code to build the handlers *************************************************/ +#include static void newhandlers_callback(const void *closure, upb_handlers *h) { const upb_msgdef *m; upb_msg_field_iter i; -- cgit v1.2.3 From 315c167bedbe33386e0bffd537d1f28eb259c986 Mon Sep 17 00:00:00 2001 From: Joshua Haberman Date: Wed, 23 Jan 2019 12:58:20 -0800 Subject: Some more fixes for PHP. --- upb/def.c | 204 ++++++++++++++++++++++++----------------------- upb/def.h | 7 +- upb/pb/compile_decoder.c | 1 + upb/upb.c | 6 +- 4 files changed, 115 insertions(+), 103 deletions(-) (limited to 'upb/def.c') diff --git a/upb/def.c b/upb/def.c index f816c4f..38ef9fa 100644 --- a/upb/def.c +++ b/upb/def.c @@ -106,6 +106,12 @@ struct upb_filedef { int ext_count; }; +struct upb_symtab { + upb_arena *arena; + upb_strtable syms; /* full_name -> packed def ptr */ + upb_strtable files; /* file_name -> upb_filedef* */ +}; + /* Inside a symtab we store tagged pointers to specific def types. */ typedef enum { UPB_DEFTYPE_MSG = 0, @@ -124,12 +130,6 @@ static upb_value pack_def(const void *ptr, upb_deftype_t 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 are locale-dependent, which we don't want. */ static bool upb_isbetween(char c, char low, char high) { return c >= low && c <= high; @@ -825,97 +825,6 @@ void upb_oneof_iter_setdone(upb_oneof_iter *iter) { upb_inttable_iter_setdone(iter); } -/* upb_filedef ****************************************************************/ - -const char *upb_filedef_name(const upb_filedef *f) { - return f->name; -} - -const char *upb_filedef_package(const upb_filedef *f) { - return f->package; -} - -const char *upb_filedef_phpprefix(const upb_filedef *f) { - return f->phpprefix; -} - -const char *upb_filedef_phpnamespace(const upb_filedef *f) { - return f->phpnamespace; -} - -upb_syntax_t upb_filedef_syntax(const upb_filedef *f) { - return f->syntax; -} - -int upb_filedef_msgcount(const upb_filedef *f) { - return f->msg_count; -} - -int upb_filedef_depcount(const upb_filedef *f) { - return f->dep_count; -} - -int upb_filedef_enumcount(const upb_filedef *f) { - return f->enum_count; -} - -const upb_filedef *upb_filedef_dep(const upb_filedef *f, int i) { - return i < 0 || i >= f->dep_count ? NULL : f->deps[i]; -} - -const upb_msgdef *upb_filedef_msg(const upb_filedef *f, int i) { - return i < 0 || i >= f->msg_count ? NULL : &f->msgs[i]; -} - -const upb_enumdef *upb_filedef_enum(const upb_filedef *f, int i) { - return i < 0 || i >= f->enum_count ? NULL : &f->enums[i]; -} - -void upb_symtab_free(upb_symtab *s) { - upb_arena_free(s->arena); - upb_gfree(s); -} - -upb_symtab *upb_symtab_new() { - upb_symtab *s = upb_gmalloc(sizeof(*s)); - upb_alloc *alloc; - - if (!s) { - return NULL; - } - - s->arena = upb_arena_new(); - alloc = upb_arena_alloc(s->arena); - - if (!upb_strtable_init2(&s->syms, UPB_CTYPE_CONSTPTR, alloc) || - !upb_strtable_init2(&s->files, UPB_CTYPE_CONSTPTR, alloc)) { - upb_arena_free(s->arena); - upb_gfree(s); - s = NULL; - } - return s; -} - -const upb_msgdef *upb_symtab_lookupmsg(const upb_symtab *s, const char *sym) { - upb_value v; - 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; - 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; - return upb_strtable_lookup(&s->syms, sym, &v) ? - unpack_def(v, UPB_DEFTYPE_ENUM) : NULL; -} - - /* Code to build defs from descriptor protos. *********************************/ /* There is a question of how much validation to do here. It will be difficult @@ -1593,8 +1502,9 @@ static bool build_filedef( 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); + "Depends on file '" UPB_STRVIEW_FORMAT + "', but it has not been loaded", + UPB_STRVIEW_ARGS(dep_name)); return false; } file->deps[i] = upb_value_getconstptr(v); @@ -1656,6 +1566,102 @@ static bool upb_symtab_addtotabs(upb_symtab *s, symtab_addctx *ctx, return true; } +/* upb_filedef ****************************************************************/ + +const char *upb_filedef_name(const upb_filedef *f) { + return f->name; +} + +const char *upb_filedef_package(const upb_filedef *f) { + return f->package; +} + +const char *upb_filedef_phpprefix(const upb_filedef *f) { + return f->phpprefix; +} + +const char *upb_filedef_phpnamespace(const upb_filedef *f) { + return f->phpnamespace; +} + +upb_syntax_t upb_filedef_syntax(const upb_filedef *f) { + return f->syntax; +} + +int upb_filedef_msgcount(const upb_filedef *f) { + return f->msg_count; +} + +int upb_filedef_depcount(const upb_filedef *f) { + return f->dep_count; +} + +int upb_filedef_enumcount(const upb_filedef *f) { + return f->enum_count; +} + +const upb_filedef *upb_filedef_dep(const upb_filedef *f, int i) { + return i < 0 || i >= f->dep_count ? NULL : f->deps[i]; +} + +const upb_msgdef *upb_filedef_msg(const upb_filedef *f, int i) { + return i < 0 || i >= f->msg_count ? NULL : &f->msgs[i]; +} + +const upb_enumdef *upb_filedef_enum(const upb_filedef *f, int i) { + return i < 0 || i >= f->enum_count ? NULL : &f->enums[i]; +} + +void upb_symtab_free(upb_symtab *s) { + upb_arena_free(s->arena); + upb_gfree(s); +} + +upb_symtab *upb_symtab_new() { + upb_symtab *s = upb_gmalloc(sizeof(*s)); + upb_alloc *alloc; + + if (!s) { + return NULL; + } + + s->arena = upb_arena_new(); + alloc = upb_arena_alloc(s->arena); + + if (!upb_strtable_init2(&s->syms, UPB_CTYPE_CONSTPTR, alloc) || + !upb_strtable_init2(&s->files, UPB_CTYPE_CONSTPTR, alloc)) { + upb_arena_free(s->arena); + upb_gfree(s); + s = NULL; + } + return s; +} + +const upb_msgdef *upb_symtab_lookupmsg(const upb_symtab *s, const char *sym) { + upb_value v; + 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; + 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; + return upb_strtable_lookup(&s->syms, sym, &v) ? + unpack_def(v, UPB_DEFTYPE_ENUM) : NULL; +} + +const upb_filedef *upb_symtab_lookupfile(const upb_symtab *s, const char *name) { + upb_value v; + return upb_strtable_lookup(&s->files, name, &v) ? upb_value_getconstptr(v) + : NULL; +} + const upb_filedef *upb_symtab_addfile( upb_symtab *s, const google_protobuf_FileDescriptorProto *file_proto, upb_status *status) { diff --git a/upb/def.h b/upb/def.h index 2c336c5..9a722f3 100644 --- a/upb/def.h +++ b/upb/def.h @@ -818,6 +818,7 @@ 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); +const upb_filedef *upb_symtab_lookupfile(const upb_symtab *s, const char *name); int upb_symtab_filecount(const upb_symtab *s); const upb_filedef *upb_symtab_addfile( upb_symtab *s, const google_protobuf_FileDescriptorProto *file, @@ -850,10 +851,14 @@ class upb::SymbolTable { return MessageDefPtr(upb_symtab_lookupmsg(ptr_.get(), sym)); } - const EnumDefPtr LookupEnum(const char *sym) const { + EnumDefPtr LookupEnum(const char *sym) const { return EnumDefPtr(upb_symtab_lookupenum(ptr_.get(), sym)); } + FileDefPtr LookupFile(const char *name) const { + return FileDefPtr(upb_symtab_lookupfile(ptr_.get(), name)); + } + /* TODO: iteration? */ /* Adds the given serialized FileDescriptorProto to the pool. */ diff --git a/upb/pb/compile_decoder.c b/upb/pb/compile_decoder.c index 75cff48..89f000a 100644 --- a/upb/pb/compile_decoder.c +++ b/upb/pb/compile_decoder.c @@ -890,6 +890,7 @@ void upb_pbcodecache_free(upb_pbcodecache *c) { } upb_inttable_uninit(&c->groups); + upb_arena_free(c->arena); upb_gfree(c); } diff --git a/upb/upb.c b/upb/upb.c index d8d2723..9f80639 100644 --- a/upb/upb.c +++ b/upb/upb.c @@ -191,10 +191,8 @@ upb_arena *upb_arena_init(void *mem, size_t n, upb_alloc *alloc) { } } - a = mem; - mem = (char*)mem + sizeof(*a); + a = (void*)((char*)mem + n - sizeof(*a)); n -= sizeof(*a); - upb_arena_addblock(a, mem, n, owned); a->alloc.func = &upb_arena_doalloc; a->block_alloc = &upb_alloc_global; @@ -205,6 +203,8 @@ upb_arena *upb_arena_init(void *mem, size_t n, upb_alloc *alloc) { a->block_head = NULL; a->block_alloc = alloc; + upb_arena_addblock(a, mem, n, owned); + return a; } -- cgit v1.2.3 From 2719bcff0d1972994e98433b830a921e2ded5fc4 Mon Sep 17 00:00:00 2001 From: Josh Haberman Date: Thu, 24 Jan 2019 15:53:36 -0800 Subject: Fixes for Google-internal tests. --- upb/def.c | 22 ++++++++++++++++++++++ upb/def.h | 6 +++++- 2 files changed, 27 insertions(+), 1 deletion(-) (limited to 'upb/def.c') diff --git a/upb/def.c b/upb/def.c index 38ef9fa..4d4fea9 100644 --- a/upb/def.c +++ b/upb/def.c @@ -958,6 +958,28 @@ static bool create_oneofdef( static bool parse_default(const symtab_addctx *ctx, const char *str, size_t len, upb_fielddef *f) { char *end; + char nullz[64]; + errno = 0; + + switch (upb_fielddef_type(f)) { + case UPB_TYPE_INT32: + case UPB_TYPE_INT64: + case UPB_TYPE_UINT32: + case UPB_TYPE_UINT64: + case UPB_TYPE_DOUBLE: + case UPB_TYPE_FLOAT: + /* Standard C number parsing functions expect null-terminated strings. */ + if (len >= sizeof(nullz) - 1) { + return false; + } + memcpy(nullz, str, len); + nullz[len] = '\0'; + str = nullz; + break; + default: + break; + } + switch (upb_fielddef_type(f)) { case UPB_TYPE_INT32: { long val = strtol(str, &end, 0); diff --git a/upb/def.h b/upb/def.h index 9a722f3..f2b7032 100644 --- a/upb/def.h +++ b/upb/def.h @@ -134,6 +134,7 @@ uint32_t upb_fielddef_selectorbase(const upb_fielddef *f); * an extension. */ class upb::FieldDefPtr { public: + FieldDefPtr() : ptr_(nullptr) {} explicit FieldDefPtr(const upb_fielddef *ptr) : ptr_(ptr) {} const upb_fielddef* ptr() const { return ptr_; } @@ -302,6 +303,7 @@ bool upb_oneof_iter_isequal(const upb_oneof_iter *iter1, /* Class that represents a oneof. */ class upb::OneofDefPtr { public: + OneofDefPtr() : ptr_(nullptr) {} explicit OneofDefPtr(const upb_oneofdef *ptr) : ptr_(ptr) {} const upb_oneofdef* ptr() const { return ptr_; } @@ -482,7 +484,8 @@ bool upb_msg_oneof_iter_isequal(const upb_msg_oneof_iter *iter1, /* Structure that describes a single .proto message type. */ class upb::MessageDefPtr { public: - MessageDefPtr(const upb_msgdef *ptr) : ptr_(ptr) {} + MessageDefPtr() : ptr_(nullptr) {} + explicit MessageDefPtr(const upb_msgdef *ptr) : ptr_(ptr) {} const upb_msgdef *ptr() const { return ptr_; } explicit operator bool() const { return ptr_ != nullptr; } @@ -689,6 +692,7 @@ int32_t upb_enum_iter_number(upb_enum_iter *iter); class upb::EnumDefPtr { public: + EnumDefPtr() : ptr_(nullptr) {} explicit EnumDefPtr(const upb_enumdef* ptr) : ptr_(ptr) {} const upb_enumdef* ptr() const { return ptr_; } -- cgit v1.2.3 From 0dbbfd1f8041f863f8f4c6ada33c4102520d406f Mon Sep 17 00:00:00 2001 From: Josh Haberman Date: Sat, 26 Jan 2019 19:14:16 -0800 Subject: Added missing functions. --- tests/test_cpp.cc | 20 ++++++++++++++++++++ upb/def.c | 10 ++++++++++ 2 files changed, 30 insertions(+) (limited to 'upb/def.c') diff --git a/tests/test_cpp.cc b/tests/test_cpp.cc index 86d7bc5..f1badc4 100644 --- a/tests/test_cpp.cc +++ b/tests/test_cpp.cc @@ -893,6 +893,26 @@ void TestHandlerDataDestruction() { ASSERT(x == 0); } +void TestIteration() { + upb::SymbolTable symtab; + upb::MessageDefPtr md(upb_test_TestMessage_getmsgdef(symtab.ptr())); + + // Test range-based for on both fields and oneofs (with the iterator adaptor). + int field_count = 0; + for (auto field : md.fields()) { + UPB_UNUSED(field); + field_count++; + } + ASSERT(field_count == md.field_count()); + + int oneof_count = 0; + for (auto oneof : md.oneofs()) { + UPB_UNUSED(oneof); + oneof_count++; + } + ASSERT(oneof_count == md.oneof_count()); +} + extern "C" { int run_tests(int argc, char *argv[]) { diff --git a/upb/def.c b/upb/def.c index 4d4fea9..6d653ca 100644 --- a/upb/def.c +++ b/upb/def.c @@ -745,6 +745,11 @@ void upb_msg_field_iter_setdone(upb_msg_field_iter *iter) { upb_inttable_iter_setdone(iter); } +bool upb_msg_field_iter_isequal(const upb_msg_field_iter * iter1, + const upb_msg_field_iter * iter2) { + return upb_inttable_iter_isequal(iter1, iter2); +} + void upb_msg_oneof_begin(upb_msg_oneof_iter *iter, const upb_msgdef *m) { upb_strtable_begin(iter, &m->ntof); /* We need to skip past any initial fields. */ @@ -774,6 +779,11 @@ void upb_msg_oneof_iter_setdone(upb_msg_oneof_iter *iter) { upb_strtable_iter_setdone(iter); } +bool upb_msg_oneof_iter_isequal(const upb_msg_oneof_iter *iter1, + const upb_msg_oneof_iter *iter2) { + return upb_strtable_iter_isequal(iter1, iter2); +} + /* upb_oneofdef ***************************************************************/ const char *upb_oneofdef_name(const upb_oneofdef *o) { -- cgit v1.2.3