upb_def *upb_def_dup(const upb_def *def, const void *o) { switch (def->type) { case UPB_DEF_MSG: return upb_upcast(upb_msgdef_dup(upb_downcast_msgdef(def), o)); case UPB_DEF_FIELD: return upb_upcast(upb_fielddef_dup(upb_downcast_fielddef(def), o)); case UPB_DEF_ENUM: return upb_upcast(upb_enumdef_dup(upb_downcast_enumdef(def), o)); default: assert(false); return NULL; } }
upb_msgdef *upb_msgdef_dup(const upb_msgdef *m, const void *owner) { upb_msgdef *newm = upb_msgdef_new(owner); if (!newm) return NULL; upb_def_setfullname(upb_upcast(newm), upb_def_fullname(upb_upcast(m))); upb_msg_iter i; for(upb_msg_begin(&i, m); !upb_msg_done(&i); upb_msg_next(&i)) { upb_fielddef *f = upb_fielddef_dup(upb_msg_iter_field(&i), &f); if (!f || !upb_msgdef_addfield(newm, f, &f)) { upb_msgdef_unref(newm, owner); return NULL; } } return newm; }
upb_fielddef *upb_fielddef_new(const void *owner) { static const struct upb_refcounted_vtbl vtbl = {visitfield, freefield}; upb_fielddef *f = malloc(sizeof(*f)); if (!f) return NULL; if (!upb_def_init(upb_upcast(f), UPB_DEF_FIELD, &vtbl, owner)) { free(f); return NULL; } f->msgdef = NULL; f->sub.def = 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; // 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; }
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_upcast(m)); free(m); }
static void freefield(upb_refcounted *r) { upb_fielddef *f = (upb_fielddef*)r; upb_fielddef_uninit_default(f); if (f->subdef_is_symbolic) free(f->sub.name); upb_def_uninit(upb_upcast(f)); free(f); }
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_upcast(def), vtbl, owner)) return false; def->type = type; def->fullname = NULL; def->came_from_user = false; return true; }
static void msg_endmsg(void *_r, upb_status *status) { upb_descreader *r = _r; upb_msgdef *m = upb_descreader_top(r); if(!upb_def_fullname(upb_upcast(m))) { upb_status_seterrliteral(status, "Encountered message with no name."); return; } upb_descreader_endcontainer(r); }
static size_t msg_onname(void *_r, void *fval, const char *buf, size_t n) { UPB_UNUSED(fval); upb_descreader *r = _r; upb_msgdef *m = upb_descreader_top(r); // XXX: see comment at the top of the file. char *name = upb_strndup(buf, n); upb_def_setfullname(upb_upcast(m), name); upb_descreader_setscopename(r, name); // Passes ownership of name. return n; }
static void visitfield(const upb_refcounted *r, upb_refcounted_visit *visit, void *closure) { const upb_fielddef *f = (const upb_fielddef*)r; if (f->msgdef) { visit(r, upb_upcast2(f->msgdef), closure); } if (!f->subdef_is_symbolic && f->sub.def) { visit(r, upb_upcast(f->sub.def), closure); } }
static void upb_enumdef_free(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_strdup() from upb_enumdef_addval(). free(upb_value_getcstr(upb_inttable_iter_value(&i))); } upb_strtable_uninit(&e->ntoi); upb_inttable_uninit(&e->iton); upb_def_uninit(upb_upcast(e)); free(e); }
upb_enumdef *upb_enumdef_new(const void *owner) { static const struct upb_refcounted_vtbl vtbl = {NULL, &upb_enumdef_free}; upb_enumdef *e = malloc(sizeof(*e)); if (!e) return NULL; if (!upb_def_init(upb_upcast(e), UPB_DEF_ENUM, &vtbl, owner)) goto err2; 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: free(e); return NULL; }
upb_msgdef *upb_msgdef_new(const void *owner) { static const struct upb_refcounted_vtbl vtbl = {visitmsg, freemsg}; upb_msgdef *m = malloc(sizeof(*m)); if (!m) return NULL; if (!upb_def_init(upb_upcast(m), UPB_DEF_MSG, &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; return m; err1: upb_inttable_uninit(&m->itof); err2: free(m); return NULL; }
upb_fielddef *upb_fielddef_new(const void *owner) { static const struct upb_refcounted_vtbl vtbl = {visitfield, freefield}; upb_fielddef *f = malloc(sizeof(*f)); if (!f) return NULL; if (!upb_def_init(upb_upcast(f), UPB_DEF_FIELD, &vtbl, owner)) { free(f); return NULL; } f->msgdef = NULL; f->sub.def = NULL; f->subdef_is_symbolic = false; f->subdef_is_owned = false; f->label_ = UPB_LABEL(OPTIONAL); // These are initialized to be invalid; the user must set them explicitly. // Could relax this later if it's convenient and non-confusing to have a // defaults for them. f->type_ = UPB_TYPE_NONE; f->number_ = 0; upb_fielddef_init_default(f); return f; }
void upb_msgdef_checkref(const upb_msgdef *m, const void *owner) { upb_def_checkref(upb_upcast(m), owner); }
const char *upb_msgdef_fullname(const upb_msgdef *m) { return upb_def_fullname(upb_upcast(m)); }
bool upb_msgdef_isfrozen(const upb_msgdef *m) { return upb_def_isfrozen(upb_upcast(m)); }
void upb_msgdef_donateref( const upb_msgdef *m, const void *from, const void *to) { upb_def_donateref(upb_upcast(m), from, to); }
bool upb_enumdef_isfrozen(const upb_enumdef *e) { return upb_def_isfrozen(upb_upcast(e)); }
static const char *msgdef_name(const upb_msgdef *m) { const char *name = upb_def_fullname(upb_upcast(m)); return name ? name : "(anonymous)"; }
bool upb_fielddef_setname(upb_fielddef *f, const char *name, upb_status *s) { return upb_def_setfullname(upb_upcast(f), name, s); }
const char *upb_enumdef_fullname(const upb_enumdef *e) { return upb_def_fullname(upb_upcast(e)); }
void upb_fielddef_checkref(const upb_fielddef *f, const void *owner) { upb_def_checkref(upb_upcast(f), owner); }
const char *upb_fielddef_name(const upb_fielddef *f) { return upb_def_fullname(upb_upcast(f)); }
void upb_fielddef_donateref( const upb_fielddef *f, const void *from, const void *to) { upb_def_donateref(upb_upcast(f), from, to); }
bool upb_fielddef_isfrozen(const upb_fielddef *f) { return upb_def_isfrozen(upb_upcast(f)); }
void upb_enumdef_checkref(const upb_enumdef *e, const void *owner) { upb_def_checkref(upb_upcast(e), owner); }
bool upb_msgdef_setfullname(upb_msgdef *m, const char *fullname, upb_status *s) { return upb_def_setfullname(upb_upcast(m), fullname, s); }
void upb_enumdef_donateref( const upb_enumdef *e, const void *from, const void *to) { upb_def_donateref(upb_upcast(e), from, to); }
bool upb_def_isfrozen(const upb_def *def) { return upb_refcounted_isfrozen(upb_upcast(def)); }
bool upb_enumdef_setfullname(upb_enumdef *e, const char *fullname, upb_status *s) { return upb_def_setfullname(upb_upcast(e), fullname, s); }