bool upb_def_freeze(upb_def *const* defs, int n, upb_status *s) { // First perform validation, in two passes so we can check that we have a // transitive closure without needing to search. for (int 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_seterrliteral(s, "def is already frozen"); goto err; } else if (def->type == UPB_DEF_FIELD) { upb_status_seterrliteral(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; } } for (int i = 0; i < n; i++) { upb_msgdef *m = upb_dyncast_msgdef_mutable(defs[i]); upb_enumdef *e = upb_dyncast_enumdef_mutable(defs[i]); if (m) { upb_inttable_compact(&m->itof); upb_msg_iter j; uint32_t selector = UPB_STATIC_SELECTOR_COUNT; for(upb_msg_begin(&j, m); !upb_msg_done(&j); upb_msg_next(&j)) { upb_fielddef *f = upb_msg_iter_field(&j); assert(f->msgdef == m); if (!upb_validate_field(f, s)) goto err; f->selector_base = selector + upb_handlers_selectorbaseoffset(f); selector += upb_handlers_selectorcount(f); } m->selector_count = selector; } else if (e) { upb_inttable_compact(&e->iton); } } // Validation all passed; freeze the defs. return upb_refcounted_freeze((upb_refcounted*const*)defs, n, s); err: for (int i = 0; i < n; i++) { defs[i]->came_from_user = false; } assert(!upb_ok(s)); return false; }
bool upb_def_freeze(upb_def *const* defs, int n, upb_status *s) { // First perform validation, in two passes so we can check that we have a // transitive closure without needing to search. for (int 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; } } // Second pass of validation. Also assign selector bases and indexes, and // compact tables. for (int i = 0; i < n; i++) { upb_msgdef *m = upb_dyncast_msgdef_mutable(defs[i]); upb_enumdef *e = upb_dyncast_enumdef_mutable(defs[i]); if (m) { upb_inttable_compact(&m->itof); assign_msg_indices(m, s); } else if (e) { upb_inttable_compact(&e->iton); } } // Def graph contains FieldDefs between each MessageDef, so double the limit. int maxdepth = UPB_MAX_MESSAGE_DEPTH * 2; // Validation all passed; freeze the defs. return upb_refcounted_freeze((upb_refcounted * const *)defs, n, s, maxdepth); err: for (int i = 0; i < n; i++) { defs[i]->came_from_user = false; } assert(!upb_ok(s)); return false; }