bool upb_msgdef_addfields(upb_msgdef *m, upb_fielddef *const *fields, int n, const void *ref_donor, upb_status *s) { // Check constraints for all fields before performing any action. for (int i = 0; i < n; i++) { upb_fielddef *f = fields[i]; // TODO(haberman): handle the case where two fields of the input duplicate // name or number. if (f->msgdef != NULL) { upb_status_seterrliteral(s, "fielddef already belongs to a message"); return false; } else if (upb_fielddef_name(f) == NULL || upb_fielddef_number(f) == 0) { upb_status_seterrliteral(s, "field name or number were not set"); return false; } else if(upb_msgdef_itof(m, upb_fielddef_number(f)) || upb_msgdef_ntof(m, upb_fielddef_name(f))) { upb_status_seterrliteral(s, "duplicate field name or number"); return false; } } // Constraint checks ok, perform the action. for (int i = 0; i < n; i++) { upb_fielddef *f = fields[i]; f->msgdef = m; 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); } return true; }
bool upb_msgdef_addfields(upb_msgdef *m, upb_fielddef *const *fields, int n, const void *ref_donor) { // Check constraints for all fields before performing any action. for (int i = 0; i < n; i++) { upb_fielddef *f = fields[i]; // TODO(haberman): handle the case where two fields of the input duplicate // name or number. if (f->msgdef != NULL || upb_fielddef_name(f) == NULL || upb_fielddef_number(f) == 0 || upb_msgdef_itof(m, upb_fielddef_number(f)) || upb_msgdef_ntof(m, upb_fielddef_name(f))) return false; } // Constraint checks ok, perform the action. for (int i = 0; i < n; i++) { upb_fielddef *f = fields[i]; f->msgdef = m; 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); } return true; }
bool upb_msgdef_addfields(upb_msgdef *m, upb_fielddef *const *fields, int n, 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. // Check constraints for all fields before performing any action. for (int i = 0; i < n; i++) { upb_fielddef *f = fields[i]; // TODO(haberman): handle the case where two fields of the input duplicate // name or number. 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_msgdef_ntof(m, upb_fielddef_name(f))) { upb_status_seterrmsg(s, "duplicate field name or number"); return false; } } // Constraint checks ok, perform the action. for (int i = 0; i < n; i++) { upb_fielddef *f = fields[i]; 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); } return true; }
bool upb_fielddef_setsubdef(upb_fielddef *f, const upb_def *subdef) { assert(!upb_fielddef_isfrozen(f)); assert(upb_fielddef_hassubdef(f)); if (subdef && !upb_subdef_typecheck(f, subdef)) 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_handlers_setsubhandlers(upb_handlers *h, const upb_fielddef *f, const upb_handlers *sub) { assert(sub); assert(!upb_handlers_isfrozen(h)); assert(upb_fielddef_issubmsg(f)); if (SUBH_F(h, f)) return false; // Can't reset. if (UPB_UPCAST(upb_handlers_msgdef(sub)) != upb_fielddef_subdef(f)) { return false; } SUBH_F(h, f) = sub; upb_ref2(sub, h); return true; }
static upb_pbdecodermethod *newmethod(const upb_handlers *dest_handlers, mgroup *group) { static const struct upb_refcounted_vtbl vtbl = {visitmethod, freemethod}; upb_pbdecodermethod *ret = malloc(sizeof(*ret)); upb_refcounted_init(UPB_UPCAST(ret), &vtbl, &ret); upb_byteshandler_init(&ret->input_handler_); // The method references the group and vice-versa, in a circular reference. upb_ref2(ret, group); upb_ref2(group, ret); upb_inttable_insertptr(&group->methods, dest_handlers, upb_value_ptr(ret)); upb_refcounted_unref(UPB_UPCAST(ret), &ret); ret->group = UPB_UPCAST(group); ret->dest_handlers_ = dest_handlers; ret->is_native_ = false; // If we JIT, it will update this later. upb_inttable_init(&ret->dispatch, UPB_CTYPE_UINT64); if (ret->dest_handlers_) { upb_handlers_ref(ret->dest_handlers_, ret); } return ret; }