Incremental progress on upb_def.

pull/13171/head
Joshua Haberman 15 years ago
parent 35e5c248be
commit 6bf58a7328
  1. 2
      src/upb_data.h
  2. 511
      src/upb_def.c
  3. 21
      src/upb_def.h
  4. 2
      src/upb_encoder.h
  5. 8
      src/upb_srcsink.h
  6. 6
      src/upb_srcsink_vtbl.h
  7. 2
      src/upb_string.h

@ -26,7 +26,7 @@
#include "upb.h"
#include "upb_atomic.h"
#include "upb_def.h"
#include "upb_sink.h"
#include "upb_srcsink.h"
#ifdef __cplusplus
extern "C" {

@ -5,10 +5,8 @@
*/
#include <stdlib.h>
#include <limits.h>
#include "descriptor.h"
#include "descriptor_const.h"
#include "upb_def.h"
#include "upb_data.h"
/* Rounds p up to the next multiple of t. */
#define ALIGN_UP(p, t) ((p) % (t) == 0 ? (p) : (p) + ((t) - ((p) % (t))))
@ -23,10 +21,10 @@ typedef struct {
upb_def **defs;
uint32_t len;
uint32_t size;
};
} upb_deflist;
static void upb_deflist_init(upb_deflist *l) {
l->size = 8
l->size = 8;
l->defs = malloc(l->size);
l->len = 0;
}
@ -34,11 +32,11 @@ static void upb_deflist_init(upb_deflist *l) {
static void upb_deflist_uninit(upb_deflist *l) { free(l->defs); }
static void upb_deflist_push(upb_deflist *l, upb_def *d) {
if(l->defs_len == l->defs_size) {
l->defs_size *= 2;
l->defs = realloc(l->defs, l->defs_size);
if(l->len == l->size) {
l->size *= 2;
l->defs = realloc(l->defs, l->size);
}
l->defs[l->defs_len++] = d;
l->defs[l->len++] = d;
}
/* upb_def ********************************************************************/
@ -171,12 +169,11 @@ void _upb_def_cyclic_ref(upb_def *def) {
cycle_ref_or_unref(upb_downcast_msgdef(def), NULL, open_defs, 0, true);
}
static void upb_def_init(upb_def *def, enum upb_def_type type,
upb_strptr fqname) {
static void upb_def_init(upb_def *def, upb_def_type type, upb_string *fqname) {
def->type = type;
def->is_cyclic = 0; // We detect this later, after resolving refs.
def->search_depth = 0;
def->fqname = NULL;
def->fqname = fqname;
upb_atomic_refcount_init(&def->refcount, 1);
}
@ -188,19 +185,15 @@ static void upb_def_uninit(upb_def *def) {
typedef struct _upb_unresolveddef {
upb_def base;
upb_strptr name;
} upb_unresolveddef;
static upb_unresolveddef *upb_unresolveddef_new(upb_strptr str) {
static upb_unresolveddef *upb_unresolveddef_new(upb_string *str) {
upb_unresolveddef *def = malloc(sizeof(*def));
upb_strptr name = upb_string_getref(str, UPB_REF_THREADUNSAFE_READONLY);
upb_def_init(&def->base, UPB_DEF_UNRESOLVED, name);
def->name = name;
upb_def_init(&def->base, UPB_DEF_UNRESOLVED, str);
return def;
}
static void unresolveddef_free(struct _upb_unresolveddef *def) {
upb_string_unref(def->name);
upb_def_uninit(&def->base);
free(def);
}
@ -215,7 +208,7 @@ static upb_fielddef *fielddef_new(upb_src *src)
upb_src_startmsg(src);
upb_fielddef *parsed_f;
while((parsed_f = upb_src_getdef(src))) {
switch(parsed_f->field_number) {
switch(parsed_f->number) {
case GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_TYPE_FIELDNUM:
CHECK(upb_src_getval(src, &f->type));
case GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_LABEL_FIELDNUM:
@ -243,92 +236,50 @@ static void fielddef_free(upb_fielddef *f) {
free(f);
}
static void fielddef_copy(upb_fielddef *dst, upb_fielddef *src)
{
*dst = *src;
dst->name = upb_string_getref(src->name, UPB_REF_FROZEN);
if(upb_hasdef(src)) {
upb_def_ref(dst->def);
dst->owned = true;
}
}
// Callback for sorting fields.
static int compare_fields(upb_fielddef *f1, upb_fielddef *f2) {
// Required fields go before non-required.
bool req1 = f1->label == GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_LABEL_REQUIRED;
bool req2 = f2->label == GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_LABEL_REQUIRED;
if(req1 != req2) {
return req2 - req1;
} else {
// Within required and non-required field lists, list in number order.
// TODO: consider ordering by data size to reduce padding. */
return f1->number - f2->number;
}
}
static int compare_fielddefs(const void *e1, const void *e2) {
return compare_fields(*(void**)e1, *(void**)e2);
}
static void fielddef_sort(upb_fielddef **defs, size_t num)
{
qsort(defs, num, sizeof(*defs), compare_fielddefs);
}
/* upb_msgdef *****************************************************************/
static upb_msgdef *msgdef_new(upb_fielddef **fields, int num_fields,
upb_strptr fqname, upb_status *status)
// Processes a google.protobuf.DescriptorProto, adding defs to "deflist."
static void upb_addmsg(upb_src *src, upb_deflist *deflist, upb_status *status)
{
if(num_fields > UPB_MAX_FIELDS) {
upb_seterr(status, UPB_STATUS_ERROR,
"Tried to create a msgdef with more than %d fields", num_fields);
free(fields);
return NULL;
}
upb_msgdef *m = malloc(sizeof(*m));
upb_def_init(&m->base, UPB_DEF_MSG, fqname);
upb_def_init(&m->base, UPB_DEF_MSG);
upb_atomic_refcount_init(&m->cycle_refcount, 0);
upb_inttable_init(&m->itof, num_fields, sizeof(upb_itof_ent));
upb_strtable_init(&m->ntof, num_fields, sizeof(upb_ntof_ent));
m->num_fields = num_fields;
m->set_flags_bytes = div_round_up(m->num_fields, 8);
// These are incremented in the loop.
m->num_required_fields = 0;
m->size = m->set_flags_bytes + 4; // 4 for the refcount.
m->num_fields = 0;
m->fields = malloc(sizeof(upb_fielddef) * num_fields);
int32_t start_count = defs->len;
size_t max_align = 0;
for(int i = 0; i < num_fields; i++) {
upb_fielddef *f = &m->fields[i];
upb_type_info *type_info = &upb_types[fields[i]->type];
fielddef_copy(f, fields[i]);
// General alignment rules are: each member must be at an address that is a
// multiple of that type's alignment. Also, the size of the structure as
// a whole must be a multiple of the greatest alignment of any member. */
f->field_index = i;
size_t offset = ALIGN_UP(m->size, type_info->align);
f->byte_offset = offset - 4; // Offsets are relative to the refcount.
m->size = offset + type_info->size;
max_align = UPB_MAX(max_align, type_info->align);
if(f->label == UPB_LABEL(REQUIRED)) {
// We currently rely on the fact that required fields are always sorted
// to occur before non-required fields.
m->num_required_fields++;
CHECK(upb_src_startmsg(src));
upb_fielddef *f;
while((f = upb_src_getdef(src)) != NULL) {
switch(f->field_number) {
case GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_NAME_FIELDNUM:
upb_string_unref(m->fqname);
CHECK(upb_src_getval(src, &m->fqname));
break;
case GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_FIELD_NUM:
CHECK(upb_addfield(src, m));
break;
case GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_NESTED_TYPE_NUM:
CHECK(upb_addmsg(src, deflist));
break;
case GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_ENUM_TYPE_NUM:
CHECK(upb_addenum(src, deflist));
break;
default:
// TODO: extensions.
upb_src_skipval(src);
}
// Insert into the tables.
upb_itof_ent itof_ent = {{f->number, 0}, f};
upb_ntof_ent ntof_ent = {{f->name, 0}, f};
upb_inttable_insert(&m->itof, &itof_ent.e);
upb_strtable_insert(&m->ntof, &ntof_ent.e);
}
if(max_align > 0) m->size = ALIGN_UP(m->size, max_align);
return m;
CHECK(upb_src_eof(src) && upb_src_endmsg(src));
if(!m->fqname) {
upb_seterr(status, UPB_STATUS_ERROR, "Encountered message with no name.");
return false;
}
upb_qualify(defs, m->fqname, start_count);
upb_deflist_push(m);
return true;
}
static void msgdef_free(upb_msgdef *m)
@ -363,6 +314,50 @@ typedef struct {
upb_strptr string;
} iton_ent;
static void upb_addenum_val(upb_src *src, upb_enumdef *e, upb_status *status)
{
upb_src_startmsg(src);
int32_t number = -1;
upb_string *name = NULL;
while((f = upb_src_getdef(src)) != NULL) {
switch(f->field_number) {
case GOOGLE_PROTOBUF_ENUMVALUEDESCRIPTORPROTO_NUMBER_FIELDNUM:
upb_src_getval(src, &number);
break;
case GOOGLE_PROTOBUF_ENUMVALUDESCRIPTORPROTO_NAME_FIELDNUM:
upb_src_getval(src, &name);
break;
default:
upb_src_skipval(src);
}
}
upb_src_endmsg(src);
ntoi_ent ntoi_ent = {{value->name, 0}, value->number};
iton_ent iton_ent = {{value->number, 0}, value->name};
upb_strtable_insert(&e->ntoi, &ntoi_ent.e);
upb_inttable_insert(&e->iton, &iton_ent.e);
}
static void upb_addenum(upb_src *src, upb_deflist *defs, upb_status *status)
{
upb_enumdef *e = malloc(sizeof(*e));
upb_def_init(&e->base, UPB_DEF_ENUM, fqname);
upb_strtable_init(&e->ntoi, 0, sizeof(ntoi_ent));
upb_inttable_init(&e->iton, 0, sizeof(iton_ent));
upb_fielddef *f;
while((f = upb_src_getdef(src)) != NULL) {
switch(f->field_number) {
case GOOGLE_PROTOBUF_ENUMDESCRIPTORPROTO_VALUE_FIELDNUM:
CHECK(upb_addenum_val(src, e, status));
break;
default:
upb_src_skipval(src);
break;
}
}
upb_deflist_push(e);
}
static void enumdef_free(upb_enumdef *e) {
upb_strtable_free(&e->ntoi);
upb_inttable_free(&e->iton);
@ -397,10 +392,37 @@ bool upb_enum_done(upb_enum_iter *iter) {
/* symtab internal ***********************************************************/
typedef struct {
upb_strtable_entry e;
upb_def *def;
} upb_symtab_ent;
// Processes a google.protobuf.FileDescriptorProto, adding the defs to "defs".
static void upb_addfd(upb_src *src, upb_deflist *defs, upb_status *status)
{
upb_string *package = NULL;
int32_t start_count = defs->len;
upb_fielddef *f;
while((f = upb_src_getdef(src)) != NULL) {
switch(f->field_number) {
case GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_NAME_FIELDNUM:
upb_string_unref(package);
CHECK(upb_src_getval(src, &package));
break;
case GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_MESSAGE_TYPE_NUM:
CHECK(upb_startmsg(src));
CHECK(upb_addmsg(src, defs));
CHECK(upb_endmsg(src));
break;
case GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_ENUM_TYPE_NUM:
CHECK(upb_startmsg(src));
CHECK(upb_addenum(src, defs));
CHECK(upb_endmsg(src));
break;
default:
// TODO: services and extensions.
upb_src_skipval(src);
}
}
CHECK(upb_src_eof(src));
upb_qualify(deflist, package, start_count);
upb_string_unref(package);
}
/* Search for a character in a string, in reverse. */
static int my_memrchr(char *data, char c, size_t len)
@ -410,6 +432,11 @@ static int my_memrchr(char *data, char c, size_t len)
return off;
}
typedef struct {
upb_strtable_entry e;
upb_def *def;
} upb_symtab_ent;
/* Given a symbol and the base symbol inside which it is defined, find the
* symbol's definition in t. */
static symtab_ent *resolve(upb_strtable *t, upb_strptr base, upb_strptr symbol)
@ -459,206 +486,15 @@ static upb_string *upb_join(upb_string *base, upb_string *name) {
return joined;
}
static void upb_addenum_val(upb_src *src, upb_enumdef *e, upb_status *status)
{
upb_src_startmsg(src);
int32_t number = -1;
upb_string *name = NULL;
while((f = upb_src_getdef(src)) != NULL) {
switch(f->field_number) {
case GOOGLE_PROTOBUF_ENUMVALUEDESCRIPTORPROTO_NUMBER_FIELDNUM:
upb_src_getval(src, &number);
break;
case GOOGLE_PROTOBUF_ENUMVALUDESCRIPTORPROTO_NAME_FIELDNUM:
upb_src_getval(src, &name);
break;
default:
upb_src_skipval(src);
}
}
upb_src_endmsg(src);
ntoi_ent ntoi_ent = {{value->name, 0}, value->number};
iton_ent iton_ent = {{value->number, 0}, value->name};
upb_strtable_insert(&e->ntoi, &ntoi_ent.e);
upb_inttable_insert(&e->iton, &iton_ent.e);
}
static void upb_addenum(upb_src *src, upb_deflist *defs, upb_status *status)
{
upb_enumdef *e = malloc(sizeof(*e));
upb_def_init(&e->base, UPB_DEF_ENUM, fqname);
upb_strtable_init(&e->ntoi, 0, sizeof(ntoi_ent));
upb_inttable_init(&e->iton, 0, sizeof(iton_ent));
CHECK(upb_src_startmsg(src));
upb_fielddef *f;
while((f = upb_src_getdef(src)) != NULL) {
switch(f->field_number) {
case GOOGLE_PROTOBUF_ENUMDESCRIPTORPROTO_VALUE_FIELDNUM:
CHECK(upb_addenum_val(src, e, status));
break;
default:
upb_src_skipval(src);
break;
}
}
upb_deflist_push(e);
}
// Processes a google.protobuf.DescriptorProto, adding defs to "deflist."
static void upb_addmsg(upb_src *src, upb_deflist *deflist, upb_status *status)
{
upb_msgdef *m = malloc(sizeof(*m));
upb_def_init(&m->base, UPB_DEF_MSG);
upb_atomic_refcount_init(&m->cycle_refcount, 0);
upb_inttable_init(&m->itof, num_fields, sizeof(upb_itof_ent));
upb_strtable_init(&m->ntof, num_fields, sizeof(upb_ntof_ent));
m->num_fields = 0;
m->fields = malloc(sizeof(upb_fielddef) * num_fields);
int32_t start_count = defs->len;
CHECK(upb_src_startmsg(src));
upb_fielddef *f;
while((f = upb_src_getdef(src)) != NULL) {
switch(f->field_number) {
case GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_NAME_FIELDNUM:
upb_string_unref(m->fqname);
CHECK(upb_src_getval(src, &m->fqname));
break;
case GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_FIELD_NUM:
CHECK(upb_addfield(src, m));
break;
case GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_NESTED_TYPE_NUM:
CHECK(upb_addmsg(src, deflist));
break;
case GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_ENUM_TYPE_NUM:
CHECK(upb_addenum(src, deflist));
break;
default:
// TODO: extensions.
upb_src_skipval(src);
}
}
CHECK(upb_src_eof(src) && upb_src_endmsg(src));
if(!m->fqname) {
upb_seterr(status, UPB_STATUS_ERROR, "Encountered message with no name.");
return false;
}
upb_qualify(defs, m->fqname, start_count);
upb_deflist_push(m);
return true;
}
// Processes a google.protobuf.FileDescriptorProto, adding the defs to "defs".
static void upb_addfd(upb_src *src, upb_deflist *defs, upb_status *status)
{
CHECK(upb_src_startmsg(src));
upb_string *package = NULL;
upb_fielddef *f;
while((f = upb_src_getdef(src)) != NULL) {
switch(f->field_number) {
case GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_NAME_FIELDNUM:
upb_string_unref(package);
CHECK(upb_src_getval(src, &package));
break;
case GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_MESSAGE_TYPE_NUM:
CHECK(upb_addmsg(src, defs));
break;
case GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_ENUM_TYPE_NUM:
CHECK(upb_addenum(src, defs));
break;
default:
// TODO: services and extensions.
upb_src_skipval(src);
}
}
CHECK(upb_src_eof(src) && upb_src_endmsg(src));
upb_qualify(deflist, package, 0);
upb_string_unref(package);
}
/* upb_symtab *****************************************************************/
upb_symtab *upb_symtab_new()
{
upb_symtab *s = malloc(sizeof(*s));
upb_atomic_refcount_init(&s->refcount, 1);
upb_rwlock_init(&s->lock);
upb_strtable_init(&s->symtab, 16, sizeof(symtab_ent));
return s;
}
static void free_symtab(upb_strtable *t)
{
symtab_ent *e;
for(e = upb_strtable_begin(t); e; e = upb_strtable_next(t, &e->e))
upb_def_unref(e->def);
upb_strtable_free(t);
}
void _upb_symtab_free(upb_symtab *s)
{
free_symtab(&s->symtab);
free_symtab(&s->psymtab);
upb_rwlock_destroy(&s->lock);
free(s);
}
upb_def **upb_symtab_getdefs(upb_symtab *s, int *count, upb_def_type_t type)
{
upb_rwlock_rdlock(&s->lock);
int total = upb_strtable_count(&s->symtab);
// We may only use part of this, depending on how many symbols are of the
// correct type.
upb_def **defs = malloc(sizeof(*defs) * total);
symtab_ent *e = upb_strtable_begin(&s->symtab);
int i = 0;
for(; e; e = upb_strtable_next(&s->symtab, &e->e)) {
upb_def *def = e->def;
assert(def);
if(type == UPB_DEF_ANY || def->type == type)
defs[i++] = def;
}
upb_rwlock_unlock(&s->lock);
*count = i;
for(i = 0; i < *count; i++)
upb_def_ref(defs[i]);
return defs;
}
upb_def *upb_symtab_lookup(upb_symtab *s, upb_strptr sym)
{
upb_rwlock_rdlock(&s->lock);
symtab_ent *e = upb_strtable_lookup(&s->symtab, sym);
upb_def *ret = NULL;
if(e) {
ret = e->def;
upb_def_ref(ret);
}
upb_rwlock_unlock(&s->lock);
return ret;
}
upb_def *upb_symtab_resolve(upb_symtab *s, upb_strptr base, upb_strptr symbol) {
upb_rwlock_rdlock(&s->lock);
symtab_ent *e = resolve(&s->symtab, base, symbol);
upb_def *ret = NULL;
if(e) {
ret = e->def;
upb_def_ref(ret);
}
upb_rwlock_unlock(&s->lock);
return ret;
}
// Performs a pass over the type graph to find all cycles that include m.
static bool upb_symtab_findcycles(upb_msgdef *m, int search_depth, upb_status *status)
{
if(search_depth > UPB_MAX_TYPE_DEPTH) {
// There are many situations in upb where we recurse over the type tree
// (like for example, right now) and an absurdly deep tree could cause us
// to stack overflow on systems with very limited stacks.
// We have found a non-cyclic path from the base of the type tree that
// exceeds the maximum allowed depth. There are many situations in upb
// where we recurse over the type tree (like for example, right now) and an
// absurdly deep tree could cause us to stack overflow on systems with very
// limited stacks.
upb_seterr(status, UPB_STATUS_ERROR, "Type " UPB_STRFMT " was found at "
"depth %d in the type graph, which exceeds the maximum type "
"depth of %d.", UPB_UPCAST(m)->fqname, search_depth,
@ -709,9 +545,8 @@ bool upb_symtab_add_defs(upb_symtab *s, upb_deflist *defs, bool allow_redef,
{
// Build a table, for duplicate detection and name resolution.
// Attempt to resolve all references.
{ // Write lock scope.
// Attempt to resolve all references.
symtab_ent *e;
for(e = upb_strtable_begin(addto); e; e = upb_strtable_next(addto, &e->e)) {
upb_msgdef *m = upb_dyncast_msgdef(e->def);
@ -742,11 +577,8 @@ bool upb_symtab_add_defs(upb_symtab *s, upb_deflist *defs, bool allow_redef,
for(e = upb_strtable_begin(addto); e; e = upb_strtable_next(addto, &e->e)) {
upb_msgdef *m = upb_dyncast_msgdef(e->def);
if(!m) continue;
// Do an initial pass over the graph to check that there are no cycles
// longer than the maximum length. We also mark all cyclic defs as such,
// and decrement refs on cyclic defs.
find_cycles(m, 0, status);
// The findcycles() call will decrement the external refcount of the
upb_symtab_findcycles(m, 0, status);
upb_msgdef *open_defs[UPB_MAX_TYPE_CYCLE_LEN];
cycle_ref_or_unref(m, NULL, open_defs, 0, true);
}
@ -755,6 +587,81 @@ bool upb_symtab_add_defs(upb_symtab *s, upb_deflist *defs, bool allow_redef,
}
}
/* upb_symtab *****************************************************************/
upb_symtab *upb_symtab_new()
{
upb_symtab *s = malloc(sizeof(*s));
upb_atomic_refcount_init(&s->refcount, 1);
upb_rwlock_init(&s->lock);
upb_strtable_init(&s->symtab, 16, sizeof(symtab_ent));
return s;
}
static void free_symtab(upb_strtable *t)
{
symtab_ent *e;
for(e = upb_strtable_begin(t); e; e = upb_strtable_next(t, &e->e))
upb_def_unref(e->def);
upb_strtable_free(t);
}
void _upb_symtab_free(upb_symtab *s)
{
free_symtab(&s->symtab);
free_symtab(&s->psymtab);
upb_rwlock_destroy(&s->lock);
free(s);
}
upb_def **upb_symtab_getdefs(upb_symtab *s, int *count, upb_def_type_t type)
{
upb_rwlock_rdlock(&s->lock);
int total = upb_strtable_count(&s->symtab);
// We may only use part of this, depending on how many symbols are of the
// correct type.
upb_def **defs = malloc(sizeof(*defs) * total);
symtab_ent *e = upb_strtable_begin(&s->symtab);
int i = 0;
for(; e; e = upb_strtable_next(&s->symtab, &e->e)) {
upb_def *def = e->def;
assert(def);
if(type == UPB_DEF_ANY || def->type == type)
defs[i++] = def;
}
upb_rwlock_unlock(&s->lock);
*count = i;
for(i = 0; i < *count; i++)
upb_def_ref(defs[i]);
return defs;
}
upb_def *upb_symtab_lookup(upb_symtab *s, upb_strptr sym)
{
upb_rwlock_rdlock(&s->lock);
symtab_ent *e = upb_strtable_lookup(&s->symtab, sym);
upb_def *ret = NULL;
if(e) {
ret = e->def;
upb_def_ref(ret);
}
upb_rwlock_unlock(&s->lock);
return ret;
}
upb_def *upb_symtab_resolve(upb_symtab *s, upb_strptr base, upb_strptr symbol) {
upb_rwlock_rdlock(&s->lock);
symtab_ent *e = resolve(&s->symtab, base, symbol);
upb_def *ret = NULL;
if(e) {
ret = e->def;
upb_def_ref(ret);
}
upb_rwlock_unlock(&s->lock);
return ret;
}
void upb_symtab_addfds(upb_symtab *s, upb_src *src, upb_status *status)
{
}

@ -27,6 +27,7 @@
#define UPB_DEF_H_
#include "upb_atomic.h"
#include "upb_srcsink.h"
#include "upb_table.h"
#ifdef __cplusplus
@ -37,7 +38,7 @@ extern "C" {
// All the different kind of defs we support. These correspond 1:1 with
// declarations in a .proto file.
enum upb_def_type {
typedef enum {
UPB_DEF_MSG = 0,
UPB_DEF_ENUM,
UPB_DEF_SVC,
@ -47,7 +48,7 @@ enum upb_def_type {
// For specifying that defs of any type are requsted from getdefs.
UPB_DEF_ANY = -1
};
} upb_def_type;
// This typedef is more space-efficient than declaring an enum var directly.
typedef int8_t upb_def_type_t;
@ -87,20 +88,22 @@ INLINE void upb_def_unref(upb_def *def) {
// It is also reference-counted.
typedef struct _upb_fielddef {
upb_atomic_refcount_t refcount;
upb_string *name;
upb_field_number_t number;
upb_field_type_t type;
upb_label_t label;
upb_field_number_t number;
upb_string *name;
upb_value default_value;
// For the case of an enum or a submessage, points to the def for that type.
upb_def *def;
// True if we own a ref on "def" (above). This is true unless this edge is
// part of a cycle.
bool owned;
// These are set only when this fielddef is part of a msgdef.
uint32_t byte_offset; // Where in a upb_msg to find the data.
upb_field_count_t field_index; // Indicates set bit.
// For the case of an enum or a submessage, points to the def for that type.
// We own a ref on this def.
bool owned;
upb_def *def;
} upb_fielddef;
// A variety of tests about the type of a field.

@ -14,7 +14,7 @@
#define UPB_ENCODER_H_
#include "upb.h"
#include "upb_sink.h"
#include "upb_srcsink.h"
#ifdef __cplusplus
extern "C" {

@ -19,13 +19,15 @@
#ifndef UPB_SRCSINK_H
#define UPB_SRCSINK_H
#include "upb_def.h"
#include "upb_srcsink_vtbl.h"
#ifdef __cplusplus
extern "C" {
#endif
// Forward-declare. We can't include upb_def.h; it would be circular.
struct _upb_fielddef;
// Note! The "eof" flags work like feof() in C; they cannot report end-of-file
// until a read has failed due to eof. They cannot preemptively tell you that
// the next call will fail due to eof. Since these are the semantics that C
@ -37,7 +39,7 @@ extern "C" {
// Retrieves the fielddef for the next field in the stream. Returns NULL on
// error or end-of-stream.
upb_fielddef *upb_src_getdef(upb_src *src);
struct _upb_fielddef *upb_src_getdef(upb_src *src);
// Retrieves and stores the next value in "val". For string types the caller
// does not own a ref to the returned type; you must ref it yourself if you
@ -62,7 +64,7 @@ INLINE bool upb_src_eof(upb_src *src) { return src->eof; }
/* upb_sink *******************************************************************/
// Puts the given fielddef into the stream.
bool upb_sink_putdef(upb_sink *sink, upb_fielddef *def);
bool upb_sink_putdef(upb_sink *sink, struct _upb_fielddef *def);
// Puts the given value into the stream.
bool upb_sink_putval(upb_sink *sink, upb_value val);

@ -11,7 +11,7 @@
#ifndef UPB_SRCSINK_VTBL_H_
#define UPB_SRCSINK_VTBL_H_
#include "upb_def.h"
#include "upb.h"
#ifdef __cplusplus
extern "C" {
@ -27,13 +27,13 @@ struct upb_bytesink;
typedef struct upb_bytesink upb_bytesink;
// Typedefs for function pointers to all of the virtual functions.
typedef upb_fielddef (*upb_src_getdef_fptr)(upb_src *src);
typedef struct _upb_fielddef (*upb_src_getdef_fptr)(upb_src *src);
typedef bool (*upb_src_getval_fptr)(upb_src *src, upb_valueptr val);
typedef bool (*upb_src_skipval_fptr)(upb_src *src);
typedef bool (*upb_src_startmsg_fptr)(upb_src *src);
typedef bool (*upb_src_endmsg_fptr)(upb_src *src);
typedef bool (*upb_sink_putdef_fptr)(upb_sink *sink, upb_fielddef *def);
typedef bool (*upb_sink_putdef_fptr)(upb_sink *sink, struct _upb_fielddef *def);
typedef bool (*upb_sink_putval_fptr)(upb_sink *sink, upb_value val);
typedef bool (*upb_sink_startmsg_fptr)(upb_sink *sink);
typedef bool (*upb_sink_endmsg_fptr)(upb_sink *sink);

@ -70,7 +70,7 @@ INLINE upb_strlen_t upb_string_len(upb_string *str) { return str->len; }
// upb_string_endread is called(). No other functions may be called on the
// string during this window except upb_string_len().
INLINE const char *upb_string_getrobuf(upb_string *str) { return str->ptr; }
INLINE void upb_string_endread(upb_string *str) {}
INLINE void upb_string_endread(upb_string *str) { (void)str; }
// Attempts to recycle the string "str" so it may be reused and have different
// data written to it. The returned string is either "str" if it could be

Loading…
Cancel
Save