diff --git a/upb/def.c b/upb/def.c index aff8401f8d..27de875e3b 100644 --- a/upb/def.c +++ b/upb/def.c @@ -295,7 +295,7 @@ static bool assign_msg_indices(upb_msgdef *m, upb_status *s) { for(upb_msg_oneof_begin(&k, m), i = 0; !upb_msg_oneof_done(&k); upb_msg_oneof_next(&k), i++) { - upb_oneofdef *o = upb_msg_iter_oneof(&k); + upb_oneofdef *o = (upb_oneofdef*)upb_msg_iter_oneof(&k); o->index = i; } @@ -570,8 +570,13 @@ const char *upb_fielddef_defaultstr(const upb_fielddef *f, size_t *len) { UPB_ASSERT(upb_fielddef_type(f) == UPB_TYPE_STRING || upb_fielddef_type(f) == UPB_TYPE_BYTES || upb_fielddef_type(f) == UPB_TYPE_ENUM); - if (len) *len = str->len; - return str->str; + if (str) { + if (len) *len = str->len; + return str->str; + } else { + if (len) *len = 0; + return NULL; + } } const upb_msgdef *upb_fielddef_msgsubdef(const upb_fielddef *f) { @@ -759,8 +764,8 @@ bool upb_msg_oneof_done(const upb_msg_oneof_iter *iter) { return upb_strtable_done(iter); } -upb_oneofdef *upb_msg_iter_oneof(const upb_msg_oneof_iter *iter) { - return (upb_oneofdef *)upb_value_getconstptr(upb_strtable_iter_value(iter)); +const upb_oneofdef *upb_msg_iter_oneof(const upb_msg_oneof_iter *iter) { + return unpack_def(upb_strtable_iter_value(iter), UPB_DEFTYPE_ONEOF); } void upb_msg_oneof_iter_setdone(upb_msg_oneof_iter *iter) { @@ -1026,13 +1031,15 @@ static bool create_oneofdef( const google_protobuf_OneofDescriptorProto *oneof_proto) { upb_oneofdef *o; upb_stringview name = google_protobuf_OneofDescriptorProto_name(oneof_proto); + upb_value v; o = (upb_oneofdef*)&m->oneofs[m->oneof_count++]; o->parent = m; o->full_name = makefullname(ctx, m->full_name, name); - CHK_OOM(symtab_add(ctx, o->full_name, pack_def(o, UPB_DEFTYPE_ONEOF))); - CHK_OOM(upb_strtable_insert3(&m->ntof, name.data, name.size, upb_value_ptr(o), - ctx->alloc)); + + v = pack_def(o, UPB_DEFTYPE_ONEOF); + CHK_OOM(symtab_add(ctx, o->full_name, v)); + CHK_OOM(upb_strtable_insert3(&m->ntof, name.data, name.size, v, ctx->alloc)); CHK_OOM(upb_inttable_init2(&o->itof, UPB_CTYPE_CONSTPTR, ctx->alloc)); CHK_OOM(upb_strtable_init2(&o->ntof, UPB_CTYPE_CONSTPTR, ctx->alloc)); @@ -1113,6 +1120,33 @@ static bool parse_default(const symtab_addctx *ctx, const char *str, size_t len, return true; } +static void set_default_default(const symtab_addctx *ctx, upb_fielddef *f) { + switch (upb_fielddef_type(f)) { + case UPB_TYPE_INT32: + case UPB_TYPE_INT64: + case UPB_TYPE_ENUM: + f->defaultval.sint = 0; + break; + case UPB_TYPE_UINT64: + case UPB_TYPE_UINT32: + f->defaultval.uint = 0; + break; + case UPB_TYPE_DOUBLE: + case UPB_TYPE_FLOAT: + f->defaultval.dbl = 0; + break; + case UPB_TYPE_STRING: + case UPB_TYPE_BYTES: + f->defaultval.str = newstr(ctx->alloc, NULL, 0); + break; + case UPB_TYPE_BOOL: + f->defaultval.boolean = false; + break; + case UPB_TYPE_MESSAGE: + break; + } +} + static bool create_fielddef( const symtab_addctx *ctx, const char *prefix, upb_msgdef *m, const google_protobuf_FieldDescriptorProto *field_proto) { @@ -1190,6 +1224,8 @@ static bool create_fielddef( if (google_protobuf_FieldDescriptorProto_has_oneof_index(field_proto)) { int oneof_index = google_protobuf_FieldDescriptorProto_oneof_index(field_proto); + upb_oneofdef *oneof; + upb_value v = upb_value_constptr(f); if (upb_fielddef_label(f) != UPB_LABEL_OPTIONAL) { upb_status_seterrf(ctx->status, @@ -1211,7 +1247,11 @@ static bool create_fielddef( return false; } - f->oneof = &m->oneofs[oneof_index]; + oneof = (upb_oneofdef*)&m->oneofs[oneof_index]; + f->oneof = oneof; + + CHK(upb_inttable_insert2(&oneof->itof, f->number_, v, alloc)); + CHK(upb_strtable_insert3(&oneof->ntof, name.data, name.size, v, alloc)); } else { f->oneof = NULL; } @@ -1246,6 +1286,7 @@ static bool create_enumdef( CHK_OOM(upb_strtable_init2(&e->ntoi, UPB_CTYPE_INT32, ctx->alloc)); CHK_OOM(upb_inttable_init2(&e->iton, UPB_CTYPE_CSTR, ctx->alloc)); + e->file = ctx->file; e->defaultval = 0; values = google_protobuf_EnumDescriptorProto_value(enum_proto, &n); @@ -1456,6 +1497,8 @@ static bool resolve_fielddef(const symtab_addctx *ctx, const char *prefix, UPB_STRINGVIEW_ARGS(defaultval), f->full_name); return false; } + } else { + set_default_default(ctx, f); } return true; diff --git a/upb/def.h b/upb/def.h index bd36d92191..81b5659d1e 100644 --- a/upb/def.h +++ b/upb/def.h @@ -429,7 +429,7 @@ void upb_msg_field_iter_setdone(upb_msg_field_iter *iter); void upb_msg_oneof_begin(upb_msg_oneof_iter *iter, const upb_msgdef *m); void upb_msg_oneof_next(upb_msg_oneof_iter *iter); bool upb_msg_oneof_done(const upb_msg_oneof_iter *iter); -upb_oneofdef *upb_msg_iter_oneof(const upb_msg_oneof_iter *iter); +const upb_oneofdef *upb_msg_iter_oneof(const upb_msg_oneof_iter *iter); void upb_msg_oneof_iter_setdone(upb_msg_oneof_iter *iter); UPB_END_EXTERN_C