diff options
Diffstat (limited to 'upb')
-rw-r--r-- | upb/def.c | 70 | ||||
-rw-r--r-- | upb/generated_util.h | 78 | ||||
-rw-r--r-- | upb/msg.h | 25 | ||||
-rw-r--r-- | upb/structs.int.h | 2 |
4 files changed, 119 insertions, 56 deletions
@@ -1138,13 +1138,25 @@ static bool create_fielddef( upb_value v = upb_value_constptr(f); const char *full_name; const char *shortname; - int oneof_index; + uint32_t field_number; + + if (!google_protobuf_FieldDescriptorProto_has_name(field_proto)) { + upb_status_seterrmsg(ctx->status, "field has no name"); + return false; + } name = google_protobuf_FieldDescriptorProto_name(field_proto); CHK(upb_isident(name, false, ctx->status)); full_name = makefullname(prefix, name); shortname = shortdefname(full_name); + field_number = google_protobuf_FieldDescriptorProto_number(field_proto); + + if (field_number == 0 || field_number > UPB_MAX_FIELDNUMBER) { + upb_status_seterrf(ctx->status, "invalid field number (%u)", field_number); + return false; + } + if (m) { /* direct message field. */ f = (upb_fielddef*)&m->fields[m->field_count++]; @@ -1156,7 +1168,7 @@ static bool create_fielddef( return false; } - if (!upb_inttable_insert2(&m->itof, f->number_, v, alloc)) { + if (!upb_inttable_insert2(&m->itof, field_number, v, alloc)) { upb_status_seterrf(ctx->status, "duplicate field number (%u)", f->number_); return false; } @@ -1171,45 +1183,41 @@ static bool create_fielddef( f->file = ctx->file; f->type_ = (int)google_protobuf_FieldDescriptorProto_type(field_proto); f->label_ = (int)google_protobuf_FieldDescriptorProto_label(field_proto); - f->number_ = google_protobuf_FieldDescriptorProto_number(field_proto); + f->number_ = field_number; f->oneof = NULL; - /* TODO(haberman): use hazzers. */ - if (name.size == 0 || f->number_ == 0) { - upb_status_seterrmsg(ctx->status, "field name or number were not set"); - return false; - } - /* We can't resolve the subdef or (in the case of extensions) the containing * message yet, because it may not have been defined yet. We stash a pointer * to the field_proto until later when we can properly resolve it. */ f->sub.unresolved = field_proto; - if (m) { - /* XXX: need hazzers. */ - oneof_index = google_protobuf_FieldDescriptorProto_oneof_index(field_proto); - if (oneof_index) { - if (upb_fielddef_label(f) != UPB_LABEL_OPTIONAL) { - upb_status_seterrf(ctx->status, - "fields in oneof must have OPTIONAL label (%s)", - f->full_name); - return false; - } + if (google_protobuf_FieldDescriptorProto_has_oneof_index(field_proto)) { + int oneof_index = + google_protobuf_FieldDescriptorProto_oneof_index(field_proto); - if (oneof_index >= m->oneof_count) { - upb_status_seterrf(ctx->status, "oneof_index out of range (%s)", - f->full_name); - return false; - } - f->oneof = &m->oneofs[oneof_index]; - } else { - f->oneof = NULL; + if (upb_fielddef_label(f) != UPB_LABEL_OPTIONAL) { + upb_status_seterrf(ctx->status, + "fields in oneof must have OPTIONAL label (%s)", + f->full_name); + return false; } - } - if (f->number_ == 0 || f->number_ > UPB_MAX_FIELDNUMBER) { - upb_status_seterrf(ctx->status, "invalid field number (%u)", f->number_); - return false; + if (!m) { + upb_status_seterrf(ctx->status, + "oneof_index provided for extension field (%s)", + f->full_name); + return false; + } + + if (oneof_index >= m->oneof_count) { + upb_status_seterrf(ctx->status, "oneof_index out of range (%s)", + f->full_name); + return false; + } + + f->oneof = &m->oneofs[oneof_index]; + } else { + f->oneof = NULL; } defaultval = google_protobuf_FieldDescriptorProto_default_value(field_proto); diff --git a/upb/generated_util.h b/upb/generated_util.h new file mode 100644 index 0000000..0a10099 --- /dev/null +++ b/upb/generated_util.h @@ -0,0 +1,78 @@ +/* +** Functions for use by generated code. These are not public and users must +** not call them directly. +*/ + +#ifndef UPB_GENERATED_UTIL_H_ +#define UPB_GENERATED_UTIL_H_ + +#include <stdint.h> +#include "upb/msg.h" +#include "upb/structs.int.h" + +#define PTR_AT(msg, ofs, type) (type*)((const char*)msg + ofs) + +UPB_INLINE const void *_upb_array_accessor(const void *msg, size_t ofs, + size_t *size) { + const upb_array *arr = *PTR_AT(msg, ofs, const upb_array*); + if (arr) { + if (size) *size = arr->size; + return arr->data; + } else { + if (size) *size = 0; + return NULL; + } +} + +UPB_INLINE void *_upb_array_mutable_accessor(void *msg, size_t ofs, + size_t *size) { + upb_array *arr = *PTR_AT(msg, ofs, upb_array*); + if (arr) { + if (size) *size = arr->size; + return arr->data; + } else { + if (size) size = 0; + return NULL; + } +} + +/* TODO(haberman): this is a mess. It will improve when upb_array no longer + * carries reflective state (type, elem_size). */ +UPB_INLINE void *_upb_array_resize_accessor(void *msg, size_t ofs, size_t size, + size_t elem_size, + upb_fieldtype_t type, + upb_arena *arena) { + upb_array *arr = *PTR_AT(msg, ofs, upb_array*); + if (!arr) { + arr = upb_array_new(type, arena); + if (!arr) return NULL; + } + + if (size > arr->size) { + size_t new_size = UPB_MAX(arr->size, 4); + size_t old_bytes = arr->size * elem_size; + size_t new_bytes; + upb_alloc *alloc = upb_arena_alloc(arr->arena); + while (new_size < size) new_size *= 2; + new_bytes = new_size * elem_size; + arr->data = upb_realloc(alloc, arr->data, old_bytes, new_bytes); + if (!arr->data) { + return NULL; + } + arr->size = new_size; + } + arr->len = size; + return arr->data; +} + +UPB_INLINE bool _upb_has_field(const void *msg, size_t idx) { + return (*PTR_AT(msg, idx / 8, const char) & (idx % 8)) != 0; +} + +UPB_INLINE bool _upb_has_oneof_field(const void *msg, size_t case_ofs, int32_t num) { + return *PTR_AT(msg, case_ofs, int32_t) == num; +} + +#undef PTR_AT + +#endif /* UPB_GENERATED_UTIL_H_ */ @@ -218,31 +218,6 @@ bool upb_msg_clearfield(upb_msg *msg, * semantics are the same as upb_msg. A upb_array allocates dynamic * memory internally for the array elements. */ -UPB_INLINE const void *_upb_array_accessor(const upb_array *arr, size_t *size) { - if (size) *size = arr->size; - return arr->data; -} - -UPB_INLINE void *_upb_array_mutable_accessor(upb_array *arr, size_t *size) { - if (size) *size = arr->size; - return arr->data; -} - -UPB_INLINE void *_upb_array_resize_accessor(upb_array *arr, size_t size, - size_t elem_size) { - if (size > arr->size) { - size_t new_size = UPB_MAX(arr->size, 4); - size_t old_bytes = arr->size * elem_size; - size_t new_bytes; - upb_alloc *alloc = upb_arena_alloc(arr->arena); - while (new_size < size) new_size *= 2; - new_bytes = new_size * elem_size; - arr->data = upb_realloc(alloc, arr->data, old_bytes, new_bytes); - } - arr->len = size; - return arr->data; -} - upb_array *upb_array_new(upb_fieldtype_t type, upb_arena *a); upb_fieldtype_t upb_array_type(const upb_array *arr); diff --git a/upb/structs.int.h b/upb/structs.int.h index 6bc502e..ec7a4ae 100644 --- a/upb/structs.int.h +++ b/upb/structs.int.h @@ -5,6 +5,8 @@ #ifndef UPB_STRUCTS_H_ #define UPB_STRUCTS_H_ +#include "upb/upb.h" + struct upb_array { upb_fieldtype_t type; uint8_t element_size; |