Example #1
0
File: reader.c Project: YauzZ/upb
// 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;
}
Example #2
0
File: reader.c Project: YauzZ/upb
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;
}
Example #3
0
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;
}
Example #4
0
File: reader.c Project: YauzZ/upb
// 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;
}
Example #5
0
// 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;
}
Example #6
0
// 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;
}