summaryrefslogtreecommitdiff
path: root/upb
diff options
context:
space:
mode:
authorJoshua Haberman <jhaberman@gmail.com>2018-12-13 10:19:17 -0800
committerJoshua Haberman <jhaberman@gmail.com>2018-12-13 10:19:17 -0800
commit101aeba0fb7522880e2164c733c0218293384f50 (patch)
treed0e68b344f92b6ccd078e986af746ac03bd3f76d /upb
parentcf0a89ed69561d73210056566272b27844a95782 (diff)
parent10e682cf2a0e8dcfd79f9dfbad5367f6b6bf8a61 (diff)
Merge branch 'arrayapi' into defcleanup
Diffstat (limited to 'upb')
-rw-r--r--upb/def.c70
-rw-r--r--upb/generated_util.h78
-rw-r--r--upb/msg.h25
-rw-r--r--upb/structs.int.h2
4 files changed, 119 insertions, 56 deletions
diff --git a/upb/def.c b/upb/def.c
index 8029c92..ab8a8b7 100644
--- a/upb/def.c
+++ b/upb/def.c
@@ -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_ */
diff --git a/upb/msg.h b/upb/msg.h
index 6456797..9faf789 100644
--- a/upb/msg.h
+++ b/upb/msg.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;
generated by cgit on debian on lair
contact matthew@masot.net with questions or feedback