// Handlers for google.protobuf.DescriptorProto (representing a message). static bool msg_startmsg(void *closure, const void *hd) { UPB_UNUSED(hd); upb_descreader *r = closure; upb_deflist_push(&r->defs, UPB_UPCAST(upb_msgdef_new(&r->defs))); upb_descreader_startcontainer(r); return true; }
static bool pushextension(void *closure, const void *hd) { UPB_UNUSED(hd); upb_descreader *r = closure; assert(upb_fielddef_containingtypename(r->f)); upb_fielddef_setisextension(r->f, true); upb_deflist_push(&r->defs, UPB_UPCAST(r->f)); r->f = NULL; return true; }
bool upb_symtab_add(upb_symtab *s, upb_def **defs, int n, upb_status *status) { upb_rwlock_wrlock(&s->lock); // Add all defs to a table for resolution. upb_strtable addtab; upb_strtable_init(&addtab, n, sizeof(upb_symtab_ent)); for (int i = 0; i < n; i++) { upb_def *def = defs[i]; if (upb_strtable_lookup(&addtab, def->fqname)) { upb_status_seterrf(status, "Conflicting defs named '%s'", def->fqname); upb_strtable_free(&addtab); return false; } upb_strtable_insert(&addtab, def->fqname, &def); } // All existing defs that can reach defs that are being replaced must // themselves be replaced with versions that will point to the new defs. // Do a DFS -- any path that finds a new def must replace all ancestors. upb_strtable *symtab = &s->symtab; upb_strtable_iter i; upb_strtable_begin(&i, symtab); for(; !upb_strtable_done(&i); upb_strtable_next(&i)) { upb_def *open_defs[UPB_MAX_TYPE_DEPTH]; const upb_symtab_ent *e = upb_strtable_iter_value(&i); upb_symtab_dfs(e->def, open_defs, 0, &addtab); } // Resolve all refs. upb_strtable_begin(&i, &addtab); for(; !upb_strtable_done(&i); upb_strtable_next(&i)) { const upb_symtab_ent *e = upb_strtable_iter_value(&i); upb_msgdef *m = upb_dyncast_msgdef(e->def); if(!m) continue; // Type names are resolved relative to the message in which they appear. const char *base = m->base.fqname; upb_msg_iter j; for(j = upb_msg_begin(m); !upb_msg_done(j); j = upb_msg_next(m, j)) { upb_fielddef *f = upb_msg_iter_field(j); if (f->type == 0) { upb_status_seterrf(status, "Field type was not set."); return false; } if (!upb_hassubdef(f)) continue; // No resolving necessary. upb_downcast_unresolveddef(f->def); // Type check. const char *name = f->def->fqname; // Resolve from either the addtab (pending adds) or symtab (existing // defs). If both exist, prefer the pending add, because it will be // overwriting the existing def. upb_symtab_ent *found; if(!(found = upb_resolve(&addtab, base, name)) && !(found = upb_resolve(symtab, base, name))) { upb_status_seterrf(status, "could not resolve symbol '%s' " "in context '%s'", name, base); return false; } // Check the type of the found def. upb_fieldtype_t expected = upb_issubmsg(f) ? UPB_DEF_MSG : UPB_DEF_ENUM; if(found->def->type != expected) { upb_status_seterrliteral(status, "Unexpected type"); return false; } if (!upb_fielddef_resolve(f, found->def, status)) return false; } } // The defs in the transaction have been vetted, and can be moved to the // symtab without causing errors. upb_strtable_begin(&i, &addtab); for(; !upb_strtable_done(&i); upb_strtable_next(&i)) { const upb_symtab_ent *tmptab_e = upb_strtable_iter_value(&i); upb_def_movetosymtab(tmptab_e->def, s); upb_symtab_ent *symtab_e = upb_strtable_lookup(&s->symtab, tmptab_e->def->fqname); if(symtab_e) { upb_deflist_push(&s->olddefs, symtab_e->def); symtab_e->def = tmptab_e->def; } else { upb_strtable_insert(&s->symtab, tmptab_e->def->fqname, tmptab_e); } } upb_strtable_free(&addtab); upb_rwlock_unlock(&s->lock); upb_symtab_gc(s); return true; }
// Handlers for google.protobuf.EnumDescriptorProto. static bool enum_startmsg(void *closure, const void *hd) { UPB_UNUSED(hd); upb_descreader *r = closure; upb_deflist_push(&r->defs, UPB_UPCAST(upb_enumdef_new(&r->defs))); return true; }
// Handlers for google.protobuf.DescriptorProto (representing a message). static bool msg_startmsg(void *_r) { upb_descreader *r = _r; upb_deflist_push(&r->defs, upb_upcast(upb_msgdef_new(&r->defs))); upb_descreader_startcontainer(r); return true; }
// Handlers for google.protobuf.EnumDescriptorProto. static bool enum_startmsg(void *_r) { upb_descreader *r = _r; upb_deflist_push(&r->defs, upb_upcast(upb_enumdef_new(&r->defs))); return true; }