Exemple #1
0
static bool upb_fielddef_resolve(upb_fielddef *f, upb_def *def, upb_status *s) {
  assert(upb_dyncast_unresolveddef(f->def));
  upb_def_unref(f->def);
  f->def = def;
  if (f->type == UPB_TYPE(ENUM) && f->default_is_symbolic) {
    // Resolve the enum's default from a string to an integer.
    upb_strref *str = (upb_strref*)upb_value_getstrref(f->defaultval);
    assert(str);  // Should point to either a real default or the empty string.
    upb_enumdef *e = upb_downcast_enumdef(f->def);
    int32_t val = 0;
    // Could do a sanity check that the default value does not have embedded
    // NULLs.
    if (str->ptr[0] == '\0') {
      upb_value_setint32(&f->defaultval, e->defaultval);
    } else {
      bool success = upb_enumdef_ntoi(e, str->ptr, &val);
      if (!success) {
        upb_status_seterrf(
            s, "Default enum value (%s) is not a member of the enum", str);
        return false;
      }
      upb_value_setint32(&f->defaultval, val);
    }
    upb_strref_free(str);
  }
  return true;
}
Exemple #2
0
static bool upb_fielddef_resolve(upb_fielddef *f, upb_def *def, upb_status *s) {
  assert(upb_dyncast_unresolveddef(f->def));
  upb_def_unref(f->def);
  f->def = def;
  if (f->type == UPB_TYPE(ENUM) && f->default_is_symbolic) {
    // Resolve the enum's default from a string to an integer.
    upb_byteregion *bytes = upb_value_getbyteregion(f->defaultval);
    assert(bytes);  // Points to either a real default or the empty string.
    upb_enumdef *e = upb_downcast_enumdef(f->def);
    int32_t val = 0;
    // Could do a sanity check that the default value does not have embedded
    // NULLs.
    if (upb_byteregion_len(bytes) == 0) {
      upb_value_setint32(&f->defaultval, e->defaultval);
    } else {
      size_t len;
      // ptr is guaranteed to be NULL-terminated because the byteregion was
      // created with upb_byteregion_newl().
      const char *ptr = upb_byteregion_getptr(bytes, 0, &len);
      assert(len == upb_byteregion_len(bytes));  // Should all be in one chunk.
      bool success = upb_enumdef_ntoi(e, ptr, &val);
      if (!success) {
        upb_status_seterrf(
            s, "Default enum value (%s) is not a member of the enum", ptr);
        return false;
      }
      upb_value_setint32(&f->defaultval, val);
    }
    upb_byteregion_free(bytes);
  }
  return true;
}
Exemple #3
0
static void cleanup()
{
  free(input_str);
  upb_def_unref(UPB_UPCAST(def), &def);
  upb_decoder_uninit(&decoder);
  upb_decoderplan_unref(plan);
  upb_stringsrc_uninit(&stringsrc);
}
static void cleanup()
{
  for (int i = 0; i < NUM_MESSAGES; i++)
    upb_stdmsg_free(msg[i], def);
  upb_def_unref(UPB_UPCAST(def));
  upb_stringsrc_uninit(&strsrc);
  upb_decoder_uninit(&d);
}
Exemple #5
0
static void upb_symtab_free(upb_refcounted *r) {
  upb_symtab *s = (upb_symtab*)r;
  upb_strtable_iter i;
  upb_strtable_begin(&i, &s->symtab);
  for (; !upb_strtable_done(&i); upb_strtable_next(&i)) {
    const upb_def *def = upb_value_getptr(upb_strtable_iter_value(&i));
    upb_def_unref(def, s);
  }
  upb_strtable_uninit(&s->symtab);
  free(s);
}
Exemple #6
0
static void upb_fielddef_free(upb_fielddef *f) {
  upb_fielddef_uninit_default(f);
  if (f->def) {
    // We own a ref on the subdef iff we are not part of a msgdef.
    if (f->msgdef == NULL) {
      if (f->def) upb_downcast_unresolveddef(f->def);  // assert() check.
      upb_def_unref(f->def);
    }
  }
  free(f->name);
  free(f);
}
static void cleanup()
{
  if (!BYREF) {
    // Undo our fabrication from before.
    input_str->refcount.v = 1;
  }
  upb_string_unref(input_str);
  upb_msg_unref(msg, def);
  upb_def_unref(UPB_UPCAST(def));
  upb_stringsrc_uninit(&strsrc);
  upb_decoder_uninit(&d);
}
Exemple #8
0
int main() {
  upb_symtab *s = upb_symtab_new();

  // Will be empty atm since we haven't added anything to the symtab.
  int count;
  const upb_def **defs = upb_symtab_getdefs(s, &count, UPB_DEF_ANY);
  for (int i = 0; i < count; i++) {
    upb_def_unref(defs[i]);
  }
  free(defs);

  upb_symtab_unref(s);
  return 0;
}
Exemple #9
0
static void test_cycles() {
  bool ok;
  upb_symtab *s = load_test_proto(&s);
  const upb_msgdef *m;
  const upb_fielddef *f;
  const upb_def *def;
  const upb_def *def2;

  /* Test cycle detection by making a cyclic def's main refcount go to zero
   * and then be incremented to one again. */
  def = upb_symtab_lookup(s, "A");
  upb_def_ref(def, &def);
  ASSERT(def);
  ASSERT(upb_def_isfrozen(def));
  upb_symtab_unref(s, &s);

  /* Message A has only one subfield: "optional B b = 1". */
  m = upb_downcast_msgdef(def);
  f = upb_msgdef_itof(m, 1);
  ASSERT(f);
  ASSERT(upb_fielddef_hassubdef(f));
  ASSERT(upb_msgdef_ntofz(m, "b") == f);
  ASSERT(upb_msgdef_ntof(m, "b", 1) == f);
  def2 = upb_fielddef_subdef(f);
  ASSERT(upb_downcast_msgdef(def2));
  ok = strcmp(upb_def_fullname(def2), "B") == 0;
  ASSERT(ok);

  upb_def_ref(def2, &def2);
  upb_def_unref(def, &def);

  /* We know "def" is still alive because it's reachable from def2. */
  ok = strcmp(upb_def_fullname(def), "A") == 0;
  ASSERT(ok);
  upb_def_unref(def2, &def2);
}
Exemple #10
0
int main() {
  upb_symtab *symtab = upb_symtab_new();
  upb_symtab_add_descriptorproto(symtab);
  upb_def *fds = upb_symtab_lookup(
      symtab, UPB_STRLIT("google.protobuf.FileDescriptorSet"));

  upb_stdio *in = upb_stdio_new();
  upb_stdio_reset(in, stdin);
  upb_stdio *out = upb_stdio_new();
  upb_stdio_reset(out, stdout);
  upb_decoder d;
  upb_decoder_init(&d, upb_downcast_msgdef(fds));
  upb_decoder_reset(&d, upb_stdio_bytesrc(in));
  upb_textprinter *p = upb_textprinter_new();
  upb_handlers handlers;
  upb_handlers_init(&handlers);
  upb_textprinter_reset(p, &handlers, upb_stdio_bytesink(out), false);
  upb_src *src = upb_decoder_src(&d);
  upb_src_sethandlers(src, &handlers);

  upb_status status = UPB_STATUS_INIT;
  upb_src_run(src, &status);

  assert(upb_ok(&status));

  upb_status_uninit(&status);
  upb_stdio_free(in);
  upb_stdio_free(out);
  upb_decoder_uninit(&d);
  upb_textprinter_free(p);
  upb_def_unref(fds);
  upb_symtab_unref(symtab);

  // Prevent C library from holding buffers open, so Valgrind doesn't see
  // memory leaks.
  fclose(stdin);
  fclose(stdout);
}
Exemple #11
0
int main(int argc, char *argv[]) {
  if (argc < 3) {
    fprintf(stderr, "Usage: stream_transcode <descfile> <msgname>\n");
    return 1;
  }

  upb_symtab *symtab = upb_symtab_new();
  size_t desc_len;
  const char *desc = upb_readfile(argv[1], &desc_len);
  if (!desc) {
    fprintf(stderr, "Couldn't open descriptor file: %s\n", argv[1]);
    return 1;
  }

  upb_status status = UPB_STATUS_INIT;
  upb_load_descriptor_into_symtab(symtab, desc, desc_len, &status);
  if (!upb_ok(&status)) {
    fprintf(stderr, "Error parsing descriptor: %s", upb_status_getstr(&status));
    return 1;
  }
  free((void*)desc);

  const upb_def *md = upb_symtab_lookup(symtab, argv[2]);
  if (!md) {
    fprintf(stderr, "Descriptor did not contain message: %s\n", argv[2]);
    return 1;
  }

  const upb_msgdef *m = upb_dyncast_msgdef_const(md);
  if (!m) {
    fprintf(stderr, "Def was not a msgdef.\n");
    return 1;
  }

  upb_stdio in, out;
  upb_stdio_init(&in);
  upb_stdio_init(&out);
  upb_stdio_reset(&in, stdin);
  upb_stdio_reset(&out, stdout);

  upb_handlers *handlers = upb_handlers_new();
  upb_textprinter *p = upb_textprinter_new();
  upb_textprinter_reset(p, upb_stdio_bytesink(&out), false);
  upb_textprinter_reghandlers(handlers, m);

  upb_decoder d;
  upb_decoder_init(&d, handlers);
  upb_decoder_reset(&d, upb_stdio_bytesrc(&in), 0, UPB_NONDELIMITED, p);

  upb_status_clear(&status);
  upb_decoder_decode(&d, &status);

  if (!upb_ok(&status)) {
    fprintf(stderr, "Error parsing input: %s", upb_status_getstr(&status));
  }

  upb_status_uninit(&status);
  upb_stdio_uninit(&in);
  upb_stdio_uninit(&out);
  upb_decoder_uninit(&d);
  upb_textprinter_free(p);
  upb_def_unref(UPB_UPCAST(m));
  upb_symtab_unref(symtab);

  // Prevent C library from holding buffers open, so Valgrind doesn't see
  // memory leaks.
  fclose(stdin);
  fclose(stdout);
}
Exemple #12
0
void upb_msgdef_unref(const upb_msgdef *m, const void *owner) {
  upb_def_unref(upb_upcast(m), owner);
}
Exemple #13
0
void upb_fielddef_unref(const upb_fielddef *f, const void *owner) {
  upb_def_unref(upb_upcast(f), owner);
}
Exemple #14
0
void upb_enumdef_unref(const upb_enumdef *e, const void *owner) {
  upb_def_unref(upb_upcast(e), owner);
}
Exemple #15
0
bool upb_fielddef_settypename(upb_fielddef *f, const char *name) {
  upb_def_unref(f->def);
  f->def = UPB_UPCAST(upb_unresolveddef_new(name));
  return true;
}
Exemple #16
0
Fichier : def.c Projet : YauzZ/upb
void upb_msgdef_unref(const upb_msgdef *m, const void *owner) {
  upb_def_unref(UPB_UPCAST(m), owner);
}
Exemple #17
0
void upb_deflist_uninit(upb_deflist *l) {
  for(uint32_t i = 0; i < l->len; i++) upb_def_unref(l->defs[i]);
  free(l->defs);
}
Exemple #18
0
void upb_deflist_uninit(upb_deflist *l) {
  if (l->owned)
    for(size_t i = 0; i < l->len; i++)
      upb_def_unref(l->defs[i], l);
  free(l->defs);
}
Exemple #19
0
Fichier : def.c Projet : YauzZ/upb
void upb_enumdef_unref(const upb_enumdef *e, const void *owner) {
  upb_def_unref(UPB_UPCAST(e), owner);
}
Exemple #20
0
Fichier : def.c Projet : YauzZ/upb
void upb_fielddef_unref(const upb_fielddef *f, const void *owner) {
  upb_def_unref(UPB_UPCAST(f), owner);
}
Exemple #21
0
static void PyUpb_Def_dealloc(PyObject *obj) {
  PyUpb_ObjWrapper *wrapper = (void*)obj;
  upb_def_unref((upb_def*)wrapper->obj);
  obj->ob_type->tp_free(obj);
}
Exemple #22
0
/* TODO(haberman): we need a lot more testing of error conditions.
 * The came_from_user stuff in particular is not tested. */
bool upb_symtab_add(upb_symtab *s, upb_def *const*defs, int n, void *ref_donor,
                    upb_status *status) {
  int i;
  upb_strtable_iter iter;
  upb_def **add_defs = NULL;
  upb_strtable addtab;
  upb_inttable seen;

  assert(!upb_symtab_isfrozen(s));
  if (!upb_strtable_init(&addtab, UPB_CTYPE_PTR)) {
    upb_status_seterrmsg(status, "out of memory");
    return false;
  }

  /* Add new defs to our "add" set. */
  for (i = 0; i < n; i++) {
    upb_def *def = defs[i];
    const char *fullname;
    upb_fielddef *f;

    if (upb_def_isfrozen(def)) {
      upb_status_seterrmsg(status, "added defs must be mutable");
      goto err;
    }
    assert(!upb_def_isfrozen(def));
    fullname = upb_def_fullname(def);
    if (!fullname) {
      upb_status_seterrmsg(
          status, "Anonymous defs cannot be added to a symtab");
      goto err;
    }

    f = upb_dyncast_fielddef_mutable(def);

    if (f) {
      if (!upb_fielddef_containingtypename(f)) {
        upb_status_seterrmsg(status,
                             "Standalone fielddefs must have a containing type "
                             "(extendee) name set");
        goto err;
      }
    } else {
      if (upb_strtable_lookup(&addtab, fullname, NULL)) {
        upb_status_seterrf(status, "Conflicting defs named '%s'", fullname);
        goto err;
      }
      /* We need this to back out properly, because if there is a failure we
       * need to donate the ref back to the caller. */
      def->came_from_user = true;
      upb_def_donateref(def, ref_donor, s);
      if (!upb_strtable_insert(&addtab, fullname, upb_value_ptr(def)))
        goto oom_err;
    }
  }

  /* Add standalone fielddefs (ie. extensions) to the appropriate messages.
   * If the appropriate message only exists in the existing symtab, duplicate
   * it so we have a mutable copy we can add the fields to. */
  for (i = 0; i < n; i++) {
    upb_def *def = defs[i];
    upb_fielddef *f = upb_dyncast_fielddef_mutable(def);
    const char *msgname;
    upb_value v;
    upb_msgdef *m;

    if (!f) continue;
    msgname = upb_fielddef_containingtypename(f);
    /* We validated this earlier in this function. */
    assert(msgname);

    /* If the extendee name is absolutely qualified, move past the initial ".".
     * TODO(haberman): it is not obvious what it would mean if this was not
     * absolutely qualified. */
    if (msgname[0] == '.') {
      msgname++;
    }

    if (upb_strtable_lookup(&addtab, msgname, &v)) {
      /* Extendee is in the set of defs the user asked us to add. */
      m = upb_value_getptr(v);
    } else {
      /* Need to find and dup the extendee from the existing symtab. */
      const upb_msgdef *frozen_m = upb_symtab_lookupmsg(s, msgname);
      if (!frozen_m) {
        upb_status_seterrf(status,
                           "Tried to extend message %s that does not exist "
                           "in this SymbolTable.",
                           msgname);
        goto err;
      }
      m = upb_msgdef_dup(frozen_m, s);
      if (!m) goto oom_err;
      if (!upb_strtable_insert(&addtab, msgname, upb_value_ptr(m))) {
        upb_msgdef_unref(m, s);
        goto oom_err;
      }
    }

    if (!upb_msgdef_addfield(m, f, ref_donor, status)) {
      goto err;
    }
  }

  /* Add dups of any existing def that can reach a def with the same name as
   * anything in our "add" set. */
  if (!upb_inttable_init(&seen, UPB_CTYPE_BOOL)) goto oom_err;
  upb_strtable_begin(&iter, &s->symtab);
  for (; !upb_strtable_done(&iter); upb_strtable_next(&iter)) {
    upb_def *def = upb_value_getptr(upb_strtable_iter_value(&iter));
    upb_resolve_dfs(def, &addtab, s, &seen, status);
    if (!upb_ok(status)) goto err;
  }
  upb_inttable_uninit(&seen);

  /* Now using the table, resolve symbolic references for subdefs. */
  upb_strtable_begin(&iter, &addtab);
  for (; !upb_strtable_done(&iter); upb_strtable_next(&iter)) {
    const char *base;
    upb_def *def = upb_value_getptr(upb_strtable_iter_value(&iter));
    upb_msgdef *m = upb_dyncast_msgdef_mutable(def);
    upb_msg_field_iter j;

    if (!m) continue;
    /* Type names are resolved relative to the message in which they appear. */
    base = upb_msgdef_fullname(m);

    for(upb_msg_field_begin(&j, m);
        !upb_msg_field_done(&j);
        upb_msg_field_next(&j)) {
      upb_fielddef *f = upb_msg_iter_field(&j);
      const char *name = upb_fielddef_subdefname(f);
      if (name && !upb_fielddef_subdef(f)) {
        /* Try the lookup in the current set of to-be-added defs first. If not
         * there, try existing defs. */
        upb_def *subdef = upb_resolvename(&addtab, base, name);
        if (subdef == NULL) {
          subdef = upb_resolvename(&s->symtab, base, name);
        }
        if (subdef == NULL) {
          upb_status_seterrf(
              status, "couldn't resolve name '%s' in message '%s'", name, base);
          goto err;
        } else if (!upb_fielddef_setsubdef(f, subdef, status)) {
          goto err;
        }
      }
    }
  }

  /* We need an array of the defs in addtab, for passing to upb_def_freeze. */
  add_defs = malloc(sizeof(void*) * upb_strtable_count(&addtab));
  if (add_defs == NULL) goto oom_err;
  upb_strtable_begin(&iter, &addtab);
  for (n = 0; !upb_strtable_done(&iter); upb_strtable_next(&iter)) {
    add_defs[n++] = upb_value_getptr(upb_strtable_iter_value(&iter));
  }

  if (!upb_def_freeze(add_defs, n, status)) goto err;

  /* This must be delayed until all errors have been detected, since error
   * recovery code uses this table to cleanup defs. */
  upb_strtable_uninit(&addtab);

  /* TODO(haberman) we don't properly handle errors after this point (like
   * OOM in upb_strtable_insert() below). */
  for (i = 0; i < n; i++) {
    upb_def *def = add_defs[i];
    const char *name = upb_def_fullname(def);
    upb_value v;
    bool success;

    if (upb_strtable_remove(&s->symtab, name, &v)) {
      const upb_def *def = upb_value_getptr(v);
      upb_def_unref(def, s);
    }
    success = upb_strtable_insert(&s->symtab, name, upb_value_ptr(def));
    UPB_ASSERT_VAR(success, success == true);
  }
  free(add_defs);
  return true;

oom_err:
  upb_status_seterrmsg(status, "out of memory");
err: {
    /* For defs the user passed in, we need to donate the refs back.  For defs
     * we dup'd, we need to just unref them. */
    upb_strtable_begin(&iter, &addtab);
    for (; !upb_strtable_done(&iter); upb_strtable_next(&iter)) {
      upb_def *def = upb_value_getptr(upb_strtable_iter_value(&iter));
      bool came_from_user = def->came_from_user;
      def->came_from_user = false;
      if (came_from_user) {
        upb_def_donateref(def, s, ref_donor);
      } else {
        upb_def_unref(def, s);
      }
    }
  }
  upb_strtable_uninit(&addtab);
  free(add_defs);
  assert(!upb_ok(status));
  return false;
}