aboutsummaryrefslogtreecommitdiffhomepage
path: root/php
diff options
context:
space:
mode:
authorGravatar Paul Yang <TeBoring@users.noreply.github.com>2017-10-09 12:39:13 -0700
committerGravatar GitHub <noreply@github.com>2017-10-09 12:39:13 -0700
commit6032746882ea48ff6d983df8cb77e2ebf399bf0c (patch)
tree700ba1d858ea0365401b639bd7ef613c90c89743 /php
parent77f64bb7779ec2195f9bc4dc82497d12c18fc6b7 (diff)
Reserve unknown fields in php (#3659)
* Reserve unknown fields in upb 1) For decoding, an unknownfields will be lazily created on message, which contains bytes of unknown fields. 2) For encoding, if the unknownfields is present on message, all bytes contained in it will be serialized. * Register the function to encode unknown field at decode time. * Remove upb_handlers_setaddunknown * Use upb_sink_putunknown in decoder * Remove upb_pb_encoder_encode_unknown * Do not expose encode_unknown * Implement reserve unknown field in php Implement. * Make buffer private to CodedInputStream
Diffstat (limited to 'php')
-rw-r--r--php/ext/google/protobuf/encode_decode.c44
-rw-r--r--php/ext/google/protobuf/message.c4
-rw-r--r--php/ext/google/protobuf/storage.c9
-rw-r--r--php/ext/google/protobuf/upb.c2004
-rw-r--r--php/ext/google/protobuf/upb.h815
-rw-r--r--php/src/Google/Protobuf/Internal/CodedInputStream.php7
-rw-r--r--php/src/Google/Protobuf/Internal/CodedOutputStream.php2
-rw-r--r--php/src/Google/Protobuf/Internal/Message.php22
-rw-r--r--php/tests/encode_decode_test.php27
-rwxr-xr-xphp/tests/gdb_test.sh2
-rw-r--r--php/tests/memory_leak_test.php4
-rw-r--r--php/tests/proto/test.proto2
12 files changed, 2101 insertions, 841 deletions
diff --git a/php/ext/google/protobuf/encode_decode.c b/php/ext/google/protobuf/encode_decode.c
index 93a5e9c4..7e2b3ae6 100644
--- a/php/ext/google/protobuf/encode_decode.c
+++ b/php/ext/google/protobuf/encode_decode.c
@@ -142,6 +142,23 @@ static const void* newhandlerdata(upb_handlers* h, uint32_t ofs) {
return hd_ofs;
}
+typedef size_t (*encodeunknown_handlerfunc)(void* _sink, const void* hd,
+ const char* ptr, size_t len,
+ const upb_bufhandle* handle);
+
+typedef struct {
+ encodeunknown_handlerfunc handler;
+} unknownfields_handlerdata_t;
+
+// Creates a handlerdata for unknown fields.
+static const void *newunknownfieldshandlerdata(upb_handlers* h) {
+ unknownfields_handlerdata_t* hd =
+ (unknownfields_handlerdata_t*)malloc(sizeof(unknownfields_handlerdata_t));
+ hd->handler = stringsink_string;
+ upb_handlers_addcleanup(h, hd, free);
+ return hd;
+}
+
typedef struct {
size_t ofs;
const upb_msgdef *md;
@@ -944,6 +961,24 @@ static void add_handlers_for_oneof_field(upb_handlers *h,
upb_handlerattr_uninit(&attr);
}
+static bool add_unknown_handler(void* closure, const void* hd, const char* buf,
+ size_t size) {
+ encodeunknown_handlerfunc handler =
+ ((unknownfields_handlerdata_t*)hd)->handler;
+
+ MessageHeader* msg = (MessageHeader*)closure;
+ stringsink* unknown = DEREF(message_data(msg), 0, stringsink*);
+ if (unknown == NULL) {
+ DEREF(message_data(msg), 0, stringsink*) = ALLOC(stringsink);
+ unknown = DEREF(message_data(msg), 0, stringsink*);
+ stringsink_init(unknown);
+ }
+
+ handler(unknown, NULL, buf, size, NULL);
+
+ return true;
+}
+
static void add_handlers_for_message(const void* closure,
upb_handlers* h) {
const upb_msgdef* msgdef = upb_handlers_msgdef(h);
@@ -967,6 +1002,10 @@ static void add_handlers_for_message(const void* closure,
desc->layout = create_layout(desc->msgdef);
}
+ upb_handlerattr attr = UPB_HANDLERATTR_INITIALIZER;
+ upb_handlerattr_sethandlerdata(&attr, newunknownfieldshandlerdata(h));
+ upb_handlers_setunknown(h, add_unknown_handler, &attr);
+
for (upb_msg_field_begin(&i, desc->msgdef);
!upb_msg_field_done(&i);
upb_msg_field_next(&i)) {
@@ -1278,6 +1317,11 @@ static void putrawmsg(MessageHeader* msg, const Descriptor* desc,
}
}
+ stringsink* unknown = DEREF(message_data(msg), 0, stringsink*);
+ if (unknown != NULL) {
+ upb_sink_putunknown(sink, unknown->ptr, unknown->len);
+ }
+
upb_sink_endmsg(sink, &status);
}
diff --git a/php/ext/google/protobuf/message.c b/php/ext/google/protobuf/message.c
index 6ebf1b9d..291f5c24 100644
--- a/php/ext/google/protobuf/message.c
+++ b/php/ext/google/protobuf/message.c
@@ -81,6 +81,10 @@ static HashTable* message_get_properties(zval* object TSRMLS_DC);
// Define object free method.
PHP_PROTO_OBJECT_FREE_START(MessageHeader, message)
+ if (*(void**)intern->data != NULL) {
+ stringsink_uninit(*(void**)intern->data);
+ FREE(*(void**)intern->data);
+ }
FREE(intern->data);
PHP_PROTO_OBJECT_FREE_END
diff --git a/php/ext/google/protobuf/storage.c b/php/ext/google/protobuf/storage.c
index a0488ecb..e7910c85 100644
--- a/php/ext/google/protobuf/storage.c
+++ b/php/ext/google/protobuf/storage.c
@@ -583,9 +583,12 @@ MessageLayout* create_layout(const upb_msgdef* msgdef) {
upb_msg_oneof_iter oit;
size_t off = 0;
int i = 0;
+
+ // Reserve space for unknown fields.
+ off += sizeof(void*);
+
TSRMLS_FETCH();
Descriptor* desc = UNBOX_HASHTABLE_VALUE(Descriptor, get_def_obj(msgdef));
-
layout->fields = ALLOC_N(MessageField, nfields);
for (upb_msg_field_begin(&it, msgdef); !upb_msg_field_done(&it);
@@ -744,6 +747,10 @@ void layout_init(MessageLayout* layout, void* storage,
zend_object* object PHP_PROTO_TSRMLS_DC) {
int i;
upb_msg_field_iter it;
+
+ // Init unknown fields
+ memset(storage, 0, sizeof(void*));
+
for (upb_msg_field_begin(&it, layout->msgdef), i = 0; !upb_msg_field_done(&it);
upb_msg_field_next(&it), i++) {
const upb_fielddef* field = upb_msg_iter_field(&it);
diff --git a/php/ext/google/protobuf/upb.c b/php/ext/google/protobuf/upb.c
index d701dcba..c02a5ce4 100644
--- a/php/ext/google/protobuf/upb.c
+++ b/php/ext/google/protobuf/upb.c
@@ -2,6 +2,585 @@
#include "upb.h"
+/* Maps descriptor type -> upb field type. */
+static const uint8_t upb_desctype_to_fieldtype[] = {
+ UPB_WIRE_TYPE_END_GROUP, /* ENDGROUP */
+ UPB_TYPE_DOUBLE, /* DOUBLE */
+ UPB_TYPE_FLOAT, /* FLOAT */
+ UPB_TYPE_INT64, /* INT64 */
+ UPB_TYPE_UINT64, /* UINT64 */
+ UPB_TYPE_INT32, /* INT32 */
+ UPB_TYPE_UINT64, /* FIXED64 */
+ UPB_TYPE_UINT32, /* FIXED32 */
+ UPB_TYPE_BOOL, /* BOOL */
+ UPB_TYPE_STRING, /* STRING */
+ UPB_TYPE_MESSAGE, /* GROUP */
+ UPB_TYPE_MESSAGE, /* MESSAGE */
+ UPB_TYPE_BYTES, /* BYTES */
+ UPB_TYPE_UINT32, /* UINT32 */
+ UPB_TYPE_ENUM, /* ENUM */
+ UPB_TYPE_INT32, /* SFIXED32 */
+ UPB_TYPE_INT64, /* SFIXED64 */
+ UPB_TYPE_INT32, /* SINT32 */
+ UPB_TYPE_INT64, /* SINT64 */
+};
+
+/* Data pertaining to the parse. */
+typedef struct {
+ upb_env *env;
+ /* Current decoding pointer. Points to the beginning of a field until we
+ * have finished decoding the whole field. */
+ const char *ptr;
+} upb_decstate;
+
+/* Data pertaining to a single message frame. */
+typedef struct {
+ const char *limit;
+ int32_t group_number; /* 0 if we are not parsing a group. */
+
+ /* These members are unset for an unknown group frame. */
+ char *msg;
+ const upb_msglayout_msginit_v1 *m;
+} upb_decframe;
+
+#define CHK(x) if (!(x)) { return false; }
+
+static bool upb_skip_unknowngroup(upb_decstate *d, int field_number,
+ const char *limit);
+static bool upb_decode_message(upb_decstate *d, const char *limit,
+ int group_number, char *msg,
+ const upb_msglayout_msginit_v1 *l);
+
+static bool upb_decode_varint(const char **ptr, const char *limit,
+ uint64_t *val) {
+ uint8_t byte;
+ int bitpos = 0;
+ const char *p = *ptr;
+ *val = 0;
+
+ do {
+ CHK(bitpos < 70 && p < limit);
+ byte = *p;
+ *val |= (uint64_t)(byte & 0x7F) << bitpos;
+ p++;
+ bitpos += 7;
+ } while (byte & 0x80);
+
+ *ptr = p;
+ return true;
+}
+
+static bool upb_decode_varint32(const char **ptr, const char *limit,
+ uint32_t *val) {
+ uint64_t u64;
+ CHK(upb_decode_varint(ptr, limit, &u64) && u64 <= UINT32_MAX);
+ *val = u64;
+ return true;
+}
+
+static bool upb_decode_64bit(const char **ptr, const char *limit,
+ uint64_t *val) {
+ CHK(limit - *ptr >= 8);
+ memcpy(val, *ptr, 8);
+ *ptr += 8;
+ return true;
+}
+
+static bool upb_decode_32bit(const char **ptr, const char *limit,
+ uint32_t *val) {
+ CHK(limit - *ptr >= 4);
+ memcpy(val, *ptr, 4);
+ *ptr += 4;
+ return true;
+}
+
+static bool upb_decode_tag(const char **ptr, const char *limit,
+ int *field_number, int *wire_type) {
+ uint32_t tag = 0;
+ CHK(upb_decode_varint32(ptr, limit, &tag));
+ *field_number = tag >> 3;
+ *wire_type = tag & 7;
+ return true;
+}
+
+static int32_t upb_zzdecode_32(uint32_t n) {
+ return (n >> 1) ^ -(int32_t)(n & 1);
+}
+
+static int64_t upb_zzdecode_64(uint64_t n) {
+ return (n >> 1) ^ -(int64_t)(n & 1);
+}
+
+static bool upb_decode_string(const char **ptr, const char *limit,
+ upb_stringview *val) {
+ uint32_t len;
+
+ CHK(upb_decode_varint32(ptr, limit, &len) &&
+ len < INT32_MAX &&
+ limit - *ptr >= (int32_t)len);
+
+ *val = upb_stringview_make(*ptr, len);
+ *ptr += len;
+ return true;
+}
+
+static void upb_set32(void *msg, size_t ofs, uint32_t val) {
+ memcpy((char*)msg + ofs, &val, sizeof(val));
+}
+
+static bool upb_append_unknown(upb_decstate *d, upb_decframe *frame,
+ const char *start) {
+ UPB_UNUSED(d);
+ UPB_UNUSED(frame);
+ UPB_UNUSED(start);
+ return true;
+}
+
+static bool upb_skip_unknownfielddata(upb_decstate *d, upb_decframe *frame,
+ int field_number, int wire_type) {
+ switch (wire_type) {
+ case UPB_WIRE_TYPE_VARINT: {
+ uint64_t val;
+ return upb_decode_varint(&d->ptr, frame->limit, &val);
+ }
+ case UPB_WIRE_TYPE_32BIT: {
+ uint32_t val;
+ return upb_decode_32bit(&d->ptr, frame->limit, &val);
+ }
+ case UPB_WIRE_TYPE_64BIT: {
+ uint64_t val;
+ return upb_decode_64bit(&d->ptr, frame->limit, &val);
+ }
+ case UPB_WIRE_TYPE_DELIMITED: {
+ upb_stringview val;
+ return upb_decode_string(&d->ptr, frame->limit, &val);
+ }
+ case UPB_WIRE_TYPE_START_GROUP:
+ return upb_skip_unknowngroup(d, field_number, frame->limit);
+ case UPB_WIRE_TYPE_END_GROUP:
+ CHK(field_number == frame->group_number);
+ frame->limit = d->ptr;
+ return true;
+ }
+ return false;
+}
+
+static bool upb_array_grow(upb_array *arr, size_t elements) {
+ size_t needed = arr->len + elements;
+ size_t new_size = UPB_MAX(arr->size, 8);
+ size_t new_bytes;
+ size_t old_bytes;
+ void *new_data;
+
+ while (new_size < needed) {
+ new_size *= 2;
+ }
+
+ old_bytes = arr->len * arr->element_size;
+ new_bytes = new_size * arr->element_size;
+ new_data = upb_realloc(arr->alloc, arr->data, old_bytes, new_bytes);
+ CHK(new_data);
+
+ arr->data = new_data;
+ arr->size = new_size;
+ return true;
+}
+
+static void *upb_array_reserve(upb_array *arr, size_t elements) {
+ if (arr->size - arr->len < elements) {
+ CHK(upb_array_grow(arr, elements));
+ }
+ return (char*)arr->data + (arr->len * arr->element_size);
+}
+
+static void *upb_array_add(upb_array *arr, size_t elements) {
+ void *ret = upb_array_reserve(arr, elements);
+ arr->len += elements;
+ return ret;
+}
+
+static upb_array *upb_getarr(upb_decframe *frame,
+ const upb_msglayout_fieldinit_v1 *field) {
+ UPB_ASSERT(field->label == UPB_LABEL_REPEATED);
+ return *(upb_array**)&frame->msg[field->offset];
+}
+
+static upb_array *upb_getorcreatearr(upb_decstate *d,
+ upb_decframe *frame,
+ const upb_msglayout_fieldinit_v1 *field) {
+ upb_array *arr = upb_getarr(frame, field);
+
+ if (!arr) {
+ arr = upb_env_malloc(d->env, sizeof(*arr));
+ if (!arr) {
+ return NULL;
+ }
+ upb_array_init(arr, upb_desctype_to_fieldtype[field->type],
+ upb_arena_alloc(upb_env_arena(d->env)));
+ *(upb_array**)&frame->msg[field->offset] = arr;
+ }
+
+ return arr;
+}
+
+static void upb_sethasbit(upb_decframe *frame,
+ const upb_msglayout_fieldinit_v1 *field) {
+ UPB_ASSERT(field->hasbit != UPB_NO_HASBIT);
+ frame->msg[field->hasbit / 8] |= (1 << (field->hasbit % 8));
+}
+
+static void upb_setoneofcase(upb_decframe *frame,
+ const upb_msglayout_fieldinit_v1 *field) {
+ UPB_ASSERT(field->oneof_index != UPB_NOT_IN_ONEOF);
+ upb_set32(frame->msg, frame->m->oneofs[field->oneof_index].case_offset,
+ field->number);
+}
+
+static char *upb_decode_prepareslot(upb_decstate *d,
+ upb_decframe *frame,
+ const upb_msglayout_fieldinit_v1 *field) {
+ char *field_mem = frame->msg + field->offset;
+ upb_array *arr;
+
+ if (field->label == UPB_LABEL_REPEATED) {
+ arr = upb_getorcreatearr(d, frame, field);
+ field_mem = upb_array_reserve(arr, 1);
+ }
+
+ return field_mem;
+}
+
+static void upb_decode_setpresent(upb_decframe *frame,
+ const upb_msglayout_fieldinit_v1 *field) {
+ if (field->label == UPB_LABEL_REPEATED) {
+ upb_array *arr = upb_getarr(frame, field);
+ UPB_ASSERT(arr->len < arr->size);
+ arr->len++;
+ } else if (field->oneof_index != UPB_NOT_IN_ONEOF) {
+ upb_setoneofcase(frame, field);
+ } else if (field->hasbit != UPB_NO_HASBIT) {
+ upb_sethasbit(frame, field);
+ }
+}
+
+static bool upb_decode_submsg(upb_decstate *d,
+ upb_decframe *frame,
+ const char *limit,
+ const upb_msglayout_fieldinit_v1 *field,
+ int group_number) {
+ char *submsg = *(void**)&frame->msg[field->offset];
+ const upb_msglayout_msginit_v1 *subm;
+
+ UPB_ASSERT(field->submsg_index != UPB_NO_SUBMSG);
+ subm = frame->m->submsgs[field->submsg_index];
+ UPB_ASSERT(subm);
+
+ if (!submsg) {
+ submsg = upb_env_malloc(d->env, upb_msg_sizeof((upb_msglayout *)subm));
+ CHK(submsg);
+ submsg = upb_msg_init(
+ submsg, (upb_msglayout*)subm, upb_arena_alloc(upb_env_arena(d->env)));
+ *(void**)&frame->msg[field->offset] = submsg;
+ }
+
+ upb_decode_message(d, limit, group_number, submsg, subm);
+
+ return true;
+}
+
+static bool upb_decode_varintfield(upb_decstate *d, upb_decframe *frame,
+ const char *field_start,
+ const upb_msglayout_fieldinit_v1 *field) {
+ uint64_t val;
+ void *field_mem;
+
+ field_mem = upb_decode_prepareslot(d, frame, field);
+ CHK(field_mem);
+ CHK(upb_decode_varint(&d->ptr, frame->limit, &val));
+
+ switch ((upb_descriptortype_t)field->type) {
+ case UPB_DESCRIPTOR_TYPE_INT64:
+ case UPB_DESCRIPTOR_TYPE_UINT64:
+ memcpy(field_mem, &val, sizeof(val));
+ break;
+ case UPB_DESCRIPTOR_TYPE_INT32:
+ case UPB_DESCRIPTOR_TYPE_UINT32:
+ case UPB_DESCRIPTOR_TYPE_ENUM: {
+ uint32_t val32 = val;
+ memcpy(field_mem, &val32, sizeof(val32));
+ break;
+ }
+ case UPB_DESCRIPTOR_TYPE_BOOL: {
+ bool valbool = val != 0;
+ memcpy(field_mem, &valbool, sizeof(valbool));
+ break;
+ }
+ case UPB_DESCRIPTOR_TYPE_SINT32: {
+ int32_t decoded = upb_zzdecode_32(val);
+ memcpy(field_mem, &decoded, sizeof(decoded));
+ break;
+ }
+ case UPB_DESCRIPTOR_TYPE_SINT64: {
+ int64_t decoded = upb_zzdecode_64(val);
+ memcpy(field_mem, &decoded, sizeof(decoded));
+ break;
+ }
+ default:
+ return upb_append_unknown(d, frame, field_start);
+ }
+
+ upb_decode_setpresent(frame, field);
+ return true;
+}
+
+static bool upb_decode_64bitfield(upb_decstate *d, upb_decframe *frame,
+ const char *field_start,
+ const upb_msglayout_fieldinit_v1 *field) {
+ void *field_mem;
+ uint64_t val;
+
+ field_mem = upb_decode_prepareslot(d, frame, field);
+ CHK(field_mem);
+ CHK(upb_decode_64bit(&d->ptr, frame->limit, &val));
+
+ switch ((upb_descriptortype_t)field->type) {
+ case UPB_DESCRIPTOR_TYPE_DOUBLE:
+ case UPB_DESCRIPTOR_TYPE_FIXED64:
+ case UPB_DESCRIPTOR_TYPE_SFIXED64:
+ memcpy(field_mem, &val, sizeof(val));
+ break;
+ default:
+ return upb_append_unknown(d, frame, field_start);
+ }
+
+ upb_decode_setpresent(frame, field);
+ return true;
+}
+
+static bool upb_decode_32bitfield(upb_decstate *d, upb_decframe *frame,
+ const char *field_start,
+ const upb_msglayout_fieldinit_v1 *field) {
+ void *field_mem;
+ uint32_t val;
+
+ field_mem = upb_decode_prepareslot(d, frame, field);
+ CHK(field_mem);
+ CHK(upb_decode_32bit(&d->ptr, frame->limit, &val));
+
+ switch ((upb_descriptortype_t)field->type) {
+ case UPB_DESCRIPTOR_TYPE_FLOAT:
+ case UPB_DESCRIPTOR_TYPE_FIXED32:
+ case UPB_DESCRIPTOR_TYPE_SFIXED32:
+ memcpy(field_mem, &val, sizeof(val));
+ break;
+ default:
+ return upb_append_unknown(d, frame, field_start);
+ }
+
+ upb_decode_setpresent(frame, field);
+ return true;
+}
+
+static bool upb_decode_fixedpacked(upb_array *arr, upb_stringview data,
+ int elem_size) {
+ int elements = data.size / elem_size;
+ void *field_mem;
+
+ CHK((size_t)(elements * elem_size) == data.size);
+ field_mem = upb_array_add(arr, elements);
+ CHK(field_mem);
+ memcpy(field_mem, data.data, data.size);
+ return true;
+}
+
+static bool upb_decode_toarray(upb_decstate *d, upb_decframe *frame,
+ const char *field_start,
+ const upb_msglayout_fieldinit_v1 *field,
+ upb_stringview val) {
+ upb_array *arr = upb_getorcreatearr(d, frame, field);
+
+#define VARINT_CASE(ctype, decode) { \
+ const char *ptr = val.data; \
+ const char *limit = ptr + val.size; \
+ while (ptr < limit) { \
+ uint64_t val; \
+ void *field_mem; \
+ ctype decoded; \
+ CHK(upb_decode_varint(&ptr, limit, &val)); \
+ decoded = (decode)(val); \
+ field_mem = upb_array_add(arr, 1); \
+ CHK(field_mem); \
+ memcpy(field_mem, &decoded, sizeof(ctype)); \
+ } \
+ return true; \
+}
+
+ switch ((upb_descriptortype_t)field->type) {
+ case UPB_DESCRIPTOR_TYPE_STRING:
+ case UPB_DESCRIPTOR_TYPE_BYTES: {
+ void *field_mem = upb_array_add(arr, 1);
+ CHK(field_mem);
+ memcpy(field_mem, &val, sizeof(val));
+ return true;
+ }
+ case UPB_DESCRIPTOR_TYPE_FLOAT:
+ case UPB_DESCRIPTOR_TYPE_FIXED32:
+ case UPB_DESCRIPTOR_TYPE_SFIXED32:
+ return upb_decode_fixedpacked(arr, val, sizeof(int32_t));
+ case UPB_DESCRIPTOR_TYPE_DOUBLE:
+ case UPB_DESCRIPTOR_TYPE_FIXED64:
+ case UPB_DESCRIPTOR_TYPE_SFIXED64:
+ return upb_decode_fixedpacked(arr, val, sizeof(int64_t));
+ case UPB_DESCRIPTOR_TYPE_INT32:
+ case UPB_DESCRIPTOR_TYPE_UINT32:
+ case UPB_DESCRIPTOR_TYPE_ENUM:
+ /* TODO: proto2 enum field that isn't in the enum. */
+ VARINT_CASE(uint32_t, uint32_t);
+ case UPB_DESCRIPTOR_TYPE_INT64:
+ case UPB_DESCRIPTOR_TYPE_UINT64:
+ VARINT_CASE(uint64_t, uint64_t);
+ case UPB_DESCRIPTOR_TYPE_BOOL:
+ VARINT_CASE(bool, bool);
+ case UPB_DESCRIPTOR_TYPE_SINT32:
+ VARINT_CASE(int32_t, upb_zzdecode_32);
+ case UPB_DESCRIPTOR_TYPE_SINT64:
+ VARINT_CASE(int64_t, upb_zzdecode_64);
+ case UPB_DESCRIPTOR_TYPE_MESSAGE:
+ CHK(val.size <= (size_t)(frame->limit - val.data));
+ return upb_decode_submsg(d, frame, val.data + val.size, field, 0);
+ case UPB_DESCRIPTOR_TYPE_GROUP:
+ return upb_append_unknown(d, frame, field_start);
+ }
+#undef VARINT_CASE
+ UPB_UNREACHABLE();
+}
+
+static bool upb_decode_delimitedfield(upb_decstate *d, upb_decframe *frame,
+ const char *field_start,
+ const upb_msglayout_fieldinit_v1 *field) {
+ upb_stringview val;
+
+ CHK(upb_decode_string(&d->ptr, frame->limit, &val));
+
+ if (field->label == UPB_LABEL_REPEATED) {
+ return upb_decode_toarray(d, frame, field_start, field, val);
+ } else {
+ switch ((upb_descriptortype_t)field->type) {
+ case UPB_DESCRIPTOR_TYPE_STRING:
+ case UPB_DESCRIPTOR_TYPE_BYTES: {
+ void *field_mem = upb_decode_prepareslot(d, frame, field);
+ CHK(field_mem);
+ memcpy(field_mem, &val, sizeof(val));
+ break;
+ }
+ case UPB_DESCRIPTOR_TYPE_MESSAGE:
+ CHK(val.size <= (size_t)(frame->limit - val.data));
+ CHK(upb_decode_submsg(d, frame, val.data + val.size, field, 0));
+ break;
+ default:
+ /* TODO(haberman): should we accept the last element of a packed? */
+ return upb_append_unknown(d, frame, field_start);
+ }
+ upb_decode_setpresent(frame, field);
+ return true;
+ }
+}
+
+static const upb_msglayout_fieldinit_v1 *upb_find_field(
+ const upb_msglayout_msginit_v1 *l, uint32_t field_number) {
+ /* Lots of optimization opportunities here. */
+ int i;
+ for (i = 0; i < l->field_count; i++) {
+ if (l->fields[i].number == field_number) {
+ return &l->fields[i];
+ }
+ }
+
+ return NULL; /* Unknown field. */
+}
+
+static bool upb_decode_field(upb_decstate *d, upb_decframe *frame) {
+ int field_number;
+ int wire_type;
+ const char *field_start = d->ptr;
+ const upb_msglayout_fieldinit_v1 *field;
+
+ CHK(upb_decode_tag(&d->ptr, frame->limit, &field_number, &wire_type));
+ field = upb_find_field(frame->m, field_number);
+
+ if (field) {
+ switch (wire_type) {
+ case UPB_WIRE_TYPE_VARINT:
+ return upb_decode_varintfield(d, frame, field_start, field);
+ case UPB_WIRE_TYPE_32BIT:
+ return upb_decode_32bitfield(d, frame, field_start, field);
+ case UPB_WIRE_TYPE_64BIT:
+ return upb_decode_64bitfield(d, frame, field_start, field);
+ case UPB_WIRE_TYPE_DELIMITED:
+ return upb_decode_delimitedfield(d, frame, field_start, field);
+ case UPB_WIRE_TYPE_START_GROUP:
+ CHK(field->type == UPB_DESCRIPTOR_TYPE_GROUP);
+ return upb_decode_submsg(d, frame, frame->limit, field, field_number);
+ case UPB_WIRE_TYPE_END_GROUP:
+ CHK(frame->group_number == field_number)
+ frame->limit = d->ptr;
+ return true;
+ default:
+ return false;
+ }
+ } else {
+ CHK(field_number != 0);
+ return upb_skip_unknownfielddata(d, frame, field_number, wire_type);
+ }
+}
+
+static bool upb_skip_unknowngroup(upb_decstate *d, int field_number,
+ const char *limit) {
+ upb_decframe frame;
+ frame.msg = NULL;
+ frame.m = NULL;
+ frame.group_number = field_number;
+ frame.limit = limit;
+
+ while (d->ptr < frame.limit) {
+ int wire_type;
+ int field_number;
+
+ CHK(upb_decode_tag(&d->ptr, frame.limit, &field_number, &wire_type));
+ CHK(upb_skip_unknownfielddata(d, &frame, field_number, wire_type));
+ }
+
+ return true;
+}
+
+static bool upb_decode_message(upb_decstate *d, const char *limit,
+ int group_number, char *msg,
+ const upb_msglayout_msginit_v1 *l) {
+ upb_decframe frame;
+ frame.group_number = group_number;
+ frame.limit = limit;
+ frame.msg = msg;
+ frame.m = l;
+
+ while (d->ptr < frame.limit) {
+ CHK(upb_decode_field(d, &frame));
+ }
+
+ return true;
+}
+
+bool upb_decode(upb_stringview buf, void *msg,
+ const upb_msglayout_msginit_v1 *l, upb_env *env) {
+ upb_decstate state;
+ state.ptr = buf.data;
+ state.env = env;
+
+ return upb_decode_message(&state, buf.data + buf.size, 0, msg, l);
+}
+
+#undef CHK
+
+
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
@@ -326,6 +905,7 @@ static bool assign_msg_indices(upb_msgdef *m, upb_status *s) {
v = upb_value_bool(true);
upb_inttable_insert(&t, UPB_STARTMSG_SELECTOR, v);
upb_inttable_insert(&t, UPB_ENDMSG_SELECTOR, v);
+ upb_inttable_insert(&t, UPB_UNKNOWN_SELECTOR, v);
for(upb_msg_field_begin(&j, m);
!upb_msg_field_done(&j);
upb_msg_field_next(&j)) {
@@ -2359,6 +2939,397 @@ bool upb_symtab_done(const upb_symtab_iter *iter) {
const upb_def *upb_symtab_iter_def(const upb_symtab_iter *iter) {
return upb_value_getptr(upb_strtable_iter_value(&iter->iter));
}
+/* We encode backwards, to avoid pre-computing lengths (one-pass encode). */
+
+
+#define UPB_PB_VARINT_MAX_LEN 10
+#define CHK(x) do { if (!(x)) { return false; } } while(0)
+
+/* Maps descriptor type -> upb field type. */
+static const uint8_t upb_desctype_to_fieldtype2[] = {
+ UPB_WIRE_TYPE_END_GROUP, /* ENDGROUP */
+ UPB_TYPE_DOUBLE, /* DOUBLE */
+ UPB_TYPE_FLOAT, /* FLOAT */
+ UPB_TYPE_INT64, /* INT64 */
+ UPB_TYPE_UINT64, /* UINT64 */
+ UPB_TYPE_INT32, /* INT32 */
+ UPB_TYPE_UINT64, /* FIXED64 */
+ UPB_TYPE_UINT32, /* FIXED32 */
+ UPB_TYPE_BOOL, /* BOOL */
+ UPB_TYPE_STRING, /* STRING */
+ UPB_TYPE_MESSAGE, /* GROUP */
+ UPB_TYPE_MESSAGE, /* MESSAGE */
+ UPB_TYPE_BYTES, /* BYTES */
+ UPB_TYPE_UINT32, /* UINT32 */
+ UPB_TYPE_ENUM, /* ENUM */
+ UPB_TYPE_INT32, /* SFIXED32 */
+ UPB_TYPE_INT64, /* SFIXED64 */
+ UPB_TYPE_INT32, /* SINT32 */
+ UPB_TYPE_INT64, /* SINT64 */
+};
+
+static size_t upb_encode_varint(uint64_t val, char *buf) {
+ size_t i;
+ if (val < 128) { buf[0] = val; return 1; }
+ i = 0;
+ while (val) {
+ uint8_t byte = val & 0x7fU;
+ val >>= 7;
+ if (val) byte |= 0x80U;
+ buf[i++] = byte;
+ }
+ return i;
+}
+
+static uint32_t upb_zzencode_32(int32_t n) { return (n << 1) ^ (n >> 31); }
+static uint64_t upb_zzencode_64(int64_t n) { return (n << 1) ^ (n >> 63); }
+
+typedef struct {
+ upb_env *env;
+ char *buf, *ptr, *limit;
+} upb_encstate;
+
+static size_t upb_roundup_pow2(size_t bytes) {
+ size_t ret = 128;
+ while (ret < bytes) {
+ ret *= 2;
+ }
+ return ret;
+}
+
+static bool upb_encode_growbuffer(upb_encstate *e, size_t bytes) {
+ size_t old_size = e->limit - e->buf;
+ size_t new_size = upb_roundup_pow2(bytes + (e->limit - e->ptr));
+ char *new_buf = upb_env_realloc(e->env, e->buf, old_size, new_size);
+ CHK(new_buf);
+
+ /* We want previous data at the end, realloc() put it at the beginning. */
+ memmove(e->limit - old_size, e->buf, old_size);
+
+ e->ptr = new_buf + new_size - (e->limit - e->ptr);
+ e->limit = new_buf + new_size;
+ e->buf = new_buf;
+ return true;
+}
+
+/* Call to ensure that at least "bytes" bytes are available for writing at
+ * e->ptr. Returns false if the bytes could not be allocated. */
+static bool upb_encode_reserve(upb_encstate *e, size_t bytes) {
+ CHK(UPB_LIKELY((size_t)(e->ptr - e->buf) >= bytes) ||
+ upb_encode_growbuffer(e, bytes));
+
+ e->ptr -= bytes;
+ return true;
+}
+
+/* Writes the given bytes to the buffer, handling reserve/advance. */
+static bool upb_put_bytes(upb_encstate *e, const void *data, size_t len) {
+ CHK(upb_encode_reserve(e, len));
+ memcpy(e->ptr, data, len);
+ return true;
+}
+
+static bool upb_put_fixed64(upb_encstate *e, uint64_t val) {
+ /* TODO(haberman): byte-swap for big endian. */
+ return upb_put_bytes(e, &val, sizeof(uint64_t));
+}
+
+static bool upb_put_fixed32(upb_encstate *e, uint32_t val) {
+ /* TODO(haberman): byte-swap for big endian. */
+ return upb_put_bytes(e, &val, sizeof(uint32_t));
+}
+
+static bool upb_put_varint(upb_encstate *e, uint64_t val) {
+ size_t len;
+ char *start;
+ CHK(upb_encode_reserve(e, UPB_PB_VARINT_MAX_LEN));
+ len = upb_encode_varint(val, e->ptr);
+ start = e->ptr + UPB_PB_VARINT_MAX_LEN - len;
+ memmove(start, e->ptr, len);
+ e->ptr = start;
+ return true;
+}
+
+static bool upb_put_double(upb_encstate *e, double d) {
+ uint64_t u64;
+ UPB_ASSERT(sizeof(double) == sizeof(uint64_t));
+ memcpy(&u64, &d, sizeof(uint64_t));
+ return upb_put_fixed64(e, u64);
+}
+
+static bool upb_put_float(upb_encstate *e, float d) {
+ uint32_t u32;
+ UPB_ASSERT(sizeof(float) == sizeof(uint32_t));
+ memcpy(&u32, &d, sizeof(uint32_t));
+ return upb_put_fixed32(e, u32);
+}
+
+static uint32_t upb_readcase(const char *msg, const upb_msglayout_msginit_v1 *m,
+ int oneof_index) {
+ uint32_t ret;
+ memcpy(&ret, msg + m->oneofs[oneof_index].case_offset, sizeof(ret));
+ return ret;
+}
+
+static bool upb_readhasbit(const char *msg,
+ const upb_msglayout_fieldinit_v1 *f) {
+ UPB_ASSERT(f->hasbit != UPB_NO_HASBIT);
+ return msg[f->hasbit / 8] & (1 << (f->hasbit % 8));
+}
+
+static bool upb_put_tag(upb_encstate *e, int field_number, int wire_type) {
+ return upb_put_varint(e, (field_number << 3) | wire_type);
+}
+
+static bool upb_put_fixedarray(upb_encstate *e, const upb_array *arr,
+ size_t size) {
+ size_t bytes = arr->len * size;
+ return upb_put_bytes(e, arr->data, bytes) && upb_put_varint(e, bytes);
+}
+
+bool upb_encode_message(upb_encstate *e, const char *msg,
+ const upb_msglayout_msginit_v1 *m,
+ size_t *size);
+
+static bool upb_encode_array(upb_encstate *e, const char *field_mem,
+ const upb_msglayout_msginit_v1 *m,
+ const upb_msglayout_fieldinit_v1 *f) {
+ const upb_array *arr = *(const upb_array**)field_mem;
+
+ if (arr == NULL || arr->len == 0) {
+ return true;
+ }
+
+ UPB_ASSERT(arr->type == upb_desctype_to_fieldtype2[f->type]);
+
+#define VARINT_CASE(ctype, encode) { \
+ ctype *start = arr->data; \
+ ctype *ptr = start + arr->len; \
+ size_t pre_len = e->limit - e->ptr; \
+ do { \
+ ptr--; \
+ CHK(upb_put_varint(e, encode)); \
+ } while (ptr != start); \
+ CHK(upb_put_varint(e, e->limit - e->ptr - pre_len)); \
+} \
+break; \
+do { ; } while(0)
+
+ switch (f->type) {
+ case UPB_DESCRIPTOR_TYPE_DOUBLE:
+ CHK(upb_put_fixedarray(e, arr, sizeof(double)));
+ break;
+ case UPB_DESCRIPTOR_TYPE_FLOAT:
+ CHK(upb_put_fixedarray(e, arr, sizeof(float)));
+ break;
+ case UPB_DESCRIPTOR_TYPE_SFIXED64:
+ case UPB_DESCRIPTOR_TYPE_FIXED64:
+ CHK(upb_put_fixedarray(e, arr, sizeof(uint64_t)));
+ break;
+ case UPB_DESCRIPTOR_TYPE_FIXED32:
+ case UPB_DESCRIPTOR_TYPE_SFIXED32:
+ CHK(upb_put_fixedarray(e, arr, sizeof(uint32_t)));
+ break;
+ case UPB_DESCRIPTOR_TYPE_INT64:
+ case UPB_DESCRIPTOR_TYPE_UINT64:
+ VARINT_CASE(uint64_t, *ptr);
+ case UPB_DESCRIPTOR_TYPE_UINT32:
+ case UPB_DESCRIPTOR_TYPE_INT32:
+ case UPB_DESCRIPTOR_TYPE_ENUM:
+ VARINT_CASE(uint32_t, *ptr);
+ case UPB_DESCRIPTOR_TYPE_BOOL:
+ VARINT_CASE(bool, *ptr);
+ case UPB_DESCRIPTOR_TYPE_SINT32:
+ VARINT_CASE(int32_t, upb_zzencode_32(*ptr));
+ case UPB_DESCRIPTOR_TYPE_SINT64:
+ VARINT_CASE(int64_t, upb_zzencode_64(*ptr));
+ case UPB_DESCRIPTOR_TYPE_STRING:
+ case UPB_DESCRIPTOR_TYPE_BYTES: {
+ upb_stringview *start = arr->data;
+ upb_stringview *ptr = start + arr->len;
+ do {
+ ptr--;
+ CHK(upb_put_bytes(e, ptr->data, ptr->size) &&
+ upb_put_varint(e, ptr->size) &&
+ upb_put_tag(e, f->number, UPB_WIRE_TYPE_DELIMITED));
+ } while (ptr != start);
+ return true;
+ }
+ case UPB_DESCRIPTOR_TYPE_GROUP: {
+ void **start = arr->data;
+ void **ptr = start + arr->len;
+ const upb_msglayout_msginit_v1 *subm = m->submsgs[f->submsg_index];
+ do {
+ size_t size;
+ ptr--;
+ CHK(upb_put_tag(e, f->number, UPB_WIRE_TYPE_END_GROUP) &&
+ upb_encode_message(e, *ptr, subm, &size) &&
+ upb_put_tag(e, f->number, UPB_WIRE_TYPE_START_GROUP));
+ } while (ptr != start);
+ return true;
+ }
+ case UPB_DESCRIPTOR_TYPE_MESSAGE: {
+ void **start = arr->data;
+ void **ptr = start + arr->len;
+ const upb_msglayout_msginit_v1 *subm = m->submsgs[f->submsg_index];
+ do {
+ size_t size;
+ ptr--;
+ CHK(upb_encode_message(e, *ptr, subm, &size) &&
+ upb_put_varint(e, size) &&
+ upb_put_tag(e, f->number, UPB_WIRE_TYPE_DELIMITED));
+ } while (ptr != start);
+ return true;
+ }
+ }
+#undef VARINT_CASE
+
+ /* We encode all primitive arrays as packed, regardless of what was specified
+ * in the .proto file. Could special case 1-sized arrays. */
+ CHK(upb_put_tag(e, f->number, UPB_WIRE_TYPE_DELIMITED));
+ return true;
+}
+
+static bool upb_encode_scalarfield(upb_encstate *e, const char *field_mem,
+ const upb_msglayout_msginit_v1 *m,
+ const upb_msglayout_fieldinit_v1 *f,
+ bool is_proto3) {
+ bool skip_zero_value = is_proto3 && f->oneof_index == UPB_NOT_IN_ONEOF;
+
+#define CASE(ctype, type, wire_type, encodeval) do { \
+ ctype val = *(ctype*)field_mem; \
+ if (skip_zero_value && val == 0) { \
+ return true; \
+ } \
+ return upb_put_ ## type(e, encodeval) && \
+ upb_put_tag(e, f->number, wire_type); \
+} while(0)
+
+ switch (f->type) {
+ case UPB_DESCRIPTOR_TYPE_DOUBLE:
+ CASE(double, double, UPB_WIRE_TYPE_64BIT, val);
+ case UPB_DESCRIPTOR_TYPE_FLOAT:
+ CASE(float, float, UPB_WIRE_TYPE_32BIT, val);
+ case UPB_DESCRIPTOR_TYPE_INT64:
+ case UPB_DESCRIPTOR_TYPE_UINT64:
+ CASE(uint64_t, varint, UPB_WIRE_TYPE_VARINT, val);
+ case UPB_DESCRIPTOR_TYPE_UINT32:
+ case UPB_DESCRIPTOR_TYPE_INT32:
+ case UPB_DESCRIPTOR_TYPE_ENUM:
+ CASE(uint32_t, varint, UPB_WIRE_TYPE_VARINT, val);
+ case UPB_DESCRIPTOR_TYPE_SFIXED64:
+ case UPB_DESCRIPTOR_TYPE_FIXED64:
+ CASE(uint64_t, fixed64, UPB_WIRE_TYPE_64BIT, val);
+ case UPB_DESCRIPTOR_TYPE_FIXED32:
+ case UPB_DESCRIPTOR_TYPE_SFIXED32:
+ CASE(uint32_t, fixed32, UPB_WIRE_TYPE_32BIT, val);
+ case UPB_DESCRIPTOR_TYPE_BOOL:
+ CASE(bool, varint, UPB_WIRE_TYPE_VARINT, val);
+ case UPB_DESCRIPTOR_TYPE_SINT32:
+ CASE(int32_t, varint, UPB_WIRE_TYPE_VARINT, upb_zzencode_32(val));
+ case UPB_DESCRIPTOR_TYPE_SINT64:
+ CASE(int64_t, varint, UPB_WIRE_TYPE_VARINT, upb_zzencode_64(val));
+ case UPB_DESCRIPTOR_TYPE_STRING:
+ case UPB_DESCRIPTOR_TYPE_BYTES: {
+ upb_stringview view = *(upb_stringview*)field_mem;
+ if (skip_zero_value && view.size == 0) {
+ return true;
+ }
+ return upb_put_bytes(e, view.data, view.size) &&
+ upb_put_varint(e, view.size) &&
+ upb_put_tag(e, f->number, UPB_WIRE_TYPE_DELIMITED);
+ }
+ case UPB_DESCRIPTOR_TYPE_GROUP: {
+ size_t size;
+ void *submsg = *(void**)field_mem;
+ const upb_msglayout_msginit_v1 *subm = m->submsgs[f->submsg_index];
+ if (skip_zero_value && submsg == NULL) {
+ return true;
+ }
+ return upb_put_tag(e, f->number, UPB_WIRE_TYPE_END_GROUP) &&
+ upb_encode_message(e, submsg, subm, &size) &&
+ upb_put_tag(e, f->number, UPB_WIRE_TYPE_START_GROUP);
+ }
+ case UPB_DESCRIPTOR_TYPE_MESSAGE: {
+ size_t size;
+ void *submsg = *(void**)field_mem;
+ const upb_msglayout_msginit_v1 *subm = m->submsgs[f->submsg_index];
+ if (skip_zero_value && submsg == NULL) {
+ return true;
+ }
+ return upb_encode_message(e, submsg, subm, &size) &&
+ upb_put_varint(e, size) &&
+ upb_put_tag(e, f->number, UPB_WIRE_TYPE_DELIMITED);
+ }
+ }
+#undef CASE
+ UPB_UNREACHABLE();
+}
+
+bool upb_encode_hasscalarfield(const char *msg,
+ const upb_msglayout_msginit_v1 *m,
+ const upb_msglayout_fieldinit_v1 *f) {
+ if (f->oneof_index != UPB_NOT_IN_ONEOF) {
+ return upb_readcase(msg, m, f->oneof_index) == f->number;
+ } else if (m->is_proto2) {
+ return upb_readhasbit(msg, f);
+ } else {
+ /* For proto3, we'll test for the field being empty later. */
+ return true;
+ }
+}
+
+bool upb_encode_message(upb_encstate* e, const char *msg,
+ const upb_msglayout_msginit_v1 *m,
+ size_t *size) {
+ int i;
+ char *buf_end = e->ptr;
+
+ if (msg == NULL) {
+ return true;
+ }
+
+ for (i = m->field_count - 1; i >= 0; i--) {
+ const upb_msglayout_fieldinit_v1 *f = &m->fields[i];
+
+ if (f->label == UPB_LABEL_REPEATED) {
+ CHK(upb_encode_array(e, msg + f->offset, m, f));
+ } else {
+ if (upb_encode_hasscalarfield(msg, m, f)) {
+ CHK(upb_encode_scalarfield(e, msg + f->offset, m, f, !m->is_proto2));
+ }
+ }
+ }
+
+ *size = buf_end - e->ptr;
+ return true;
+}
+
+char *upb_encode(const void *msg, const upb_msglayout_msginit_v1 *m,
+ upb_env *env, size_t *size) {
+ upb_encstate e;
+ e.env = env;
+ e.buf = NULL;
+ e.limit = NULL;
+ e.ptr = NULL;
+
+ if (!upb_encode_message(&e, msg, m, size)) {
+ *size = 0;
+ return NULL;
+ }
+
+ *size = e.limit - e.ptr;
+
+ if (*size == 0) {
+ static char ch;
+ return &ch;
+ } else {
+ UPB_ASSERT(e.ptr);
+ return e.ptr;
+ }
+}
+
+#undef CHK
/*
** TODO(haberman): it's unclear whether a lot of the consistency checks should
** UPB_ASSERT() or return false.
@@ -2730,6 +3701,12 @@ SETTER(endseq, upb_endfield_handlerfunc*, UPB_HANDLER_ENDSEQ)
#undef SETTER
+bool upb_handlers_setunknown(upb_handlers *h, upb_unknown_handlerfunc *func,
+ upb_handlerattr *attr) {
+ return doset(h, UPB_UNKNOWN_SELECTOR, NULL, UPB_HANDLER_INT32,
+ (upb_func *)func, attr);
+}
+
bool upb_handlers_setstartmsg(upb_handlers *h, upb_startmsg_handlerfunc *func,
upb_handlerattr *attr) {
return doset(h, UPB_STARTMSG_SELECTOR, NULL, UPB_HANDLER_INT32,
@@ -3079,7 +4056,8 @@ bool upb_fieldtype_mapkeyok(upb_fieldtype_t type) {
void *upb_array_pack(const upb_array *arr, void *p, size_t *ofs, size_t size);
void *upb_map_pack(const upb_map *map, void *p, size_t *ofs, size_t size);
-#define CHARPTR_AT(msg, ofs) ((char*)msg + ofs)
+#define PTR_AT(msg, ofs, type) (type*)((char*)msg + ofs)
+#define VOIDPTR_AT(msg, ofs) PTR_AT(msg, ofs, void)
#define ENCODE_MAX_NESTING 64
#define CHECK_TRUE(x) if (!(x)) { return false; }
@@ -3121,12 +4099,20 @@ static size_t upb_msgval_sizeof(upb_fieldtype_t type) {
case UPB_TYPE_MESSAGE:
return sizeof(void*);
case UPB_TYPE_STRING:
- return sizeof(char*) + sizeof(size_t);
+ return sizeof(upb_stringview);
}
UPB_UNREACHABLE();
}
-static uint8_t upb_msg_fieldsize(const upb_fielddef *f) {
+static uint8_t upb_msg_fieldsize(const upb_msglayout_fieldinit_v1 *field) {
+ if (field->label == UPB_LABEL_REPEATED) {
+ return sizeof(void*);
+ } else {
+ return upb_msgval_sizeof(field->type);
+ }
+}
+
+static uint8_t upb_msg_fielddefsize(const upb_fielddef *f) {
if (upb_fielddef_isseq(f)) {
return sizeof(void*);
} else {
@@ -3170,7 +4156,6 @@ static upb_ctype_t upb_fieldtotabtype(upb_fieldtype_t type) {
}
static upb_msgval upb_msgval_fromdefault(const upb_fielddef *f) {
- /* TODO(haberman): improve/optimize this (maybe use upb_msgval in fielddef) */
switch (upb_fielddef_type(f)) {
case UPB_TYPE_FLOAT:
return upb_msgval_float(upb_fielddef_defaultfloat(f));
@@ -3182,7 +4167,7 @@ static upb_msgval upb_msgval_fromdefault(const upb_fielddef *f) {
case UPB_TYPE_BYTES: {
size_t len;
const char *ptr = upb_fielddef_defaultstr(f, &len);
- return upb_msgval_str(ptr, len);
+ return upb_msgval_makestr(ptr, len);
}
case UPB_TYPE_MESSAGE:
return upb_msgval_msg(NULL);
@@ -3205,63 +4190,44 @@ static upb_msgval upb_msgval_fromdefault(const upb_fielddef *f) {
/** upb_msglayout *************************************************************/
struct upb_msglayout {
- upb_msgfactory *factory;
- const upb_msgdef *msgdef;
- size_t size;
- size_t extdict_offset;
- void *default_msg;
- uint32_t *field_offsets;
- uint32_t *case_offsets;
- uint32_t *hasbits;
- bool has_extdict;
- uint8_t align;
+ struct upb_msglayout_msginit_v1 data;
};
-static void upb_msg_checkfield(const upb_msglayout *l, const upb_fielddef *f) {
- UPB_ASSERT(l->msgdef == upb_fielddef_containingtype(f));
-}
-
static void upb_msglayout_free(upb_msglayout *l) {
- upb_gfree(l->default_msg);
+ upb_gfree(l->data.default_msg);
upb_gfree(l);
}
-const upb_msgdef *upb_msglayout_msgdef(const upb_msglayout *l) {
- return l->msgdef;
-}
-
static size_t upb_msglayout_place(upb_msglayout *l, size_t size) {
size_t ret;
- l->size = align_up(l->size, size);
- l->align = align_up(l->align, size);
- ret = l->size;
- l->size += size;
+ l->data.size = align_up(l->data.size, size);
+ ret = l->data.size;
+ l->data.size += size;
return ret;
}
static uint32_t upb_msglayout_offset(const upb_msglayout *l,
const upb_fielddef *f) {
- return l->field_offsets[upb_fielddef_index(f)];
+ return l->data.fields[upb_fielddef_index(f)].offset;
}
static uint32_t upb_msglayout_hasbit(const upb_msglayout *l,
const upb_fielddef *f) {
- return l->hasbits[upb_fielddef_index(f)];
+ return l->data.fields[upb_fielddef_index(f)].hasbit;
}
-static bool upb_msglayout_initdefault(upb_msglayout *l) {
- const upb_msgdef *m = l->msgdef;
+static bool upb_msglayout_initdefault(upb_msglayout *l, const upb_msgdef *m) {
upb_msg_field_iter it;
- if (upb_msgdef_syntax(m) == UPB_SYNTAX_PROTO2 && l->size) {
+ if (upb_msgdef_syntax(m) == UPB_SYNTAX_PROTO2 && l->data.size) {
/* Allocate default message and set default values in it. */
- l->default_msg = upb_gmalloc(l->size);
- if (!l->default_msg) {
+ l->data.default_msg = upb_gmalloc(l->data.size);
+ if (!l->data.default_msg) {
return false;
}
- memset(l->default_msg, 0, l->size);
+ memset(l->data.default_msg, 0, l->data.size);
for (upb_msg_field_begin(&it, m); !upb_msg_field_done(&it);
upb_msg_field_next(&it)) {
@@ -3271,10 +4237,14 @@ static bool upb_msglayout_initdefault(upb_msglayout *l) {
continue;
}
+ /* TODO(haberman): handle strings. */
if (!upb_fielddef_isstring(f) &&
!upb_fielddef_issubmsg(f) &&
!upb_fielddef_isseq(f)) {
- upb_msg_set(l->default_msg, f, upb_msgval_fromdefault(f), l);
+ upb_msg_set(l->data.default_msg,
+ upb_fielddef_index(f),
+ upb_msgval_fromdefault(f),
+ l);
}
}
}
@@ -3287,22 +4257,46 @@ static upb_msglayout *upb_msglayout_new(const upb_msgdef *m) {
upb_msg_oneof_iter oit;
upb_msglayout *l;
size_t hasbit;
- size_t array_size = upb_msgdef_numfields(m) + upb_msgdef_numoneofs(m);
+ size_t submsg_count = 0;
+ const upb_msglayout_msginit_v1 **submsgs;
+ upb_msglayout_fieldinit_v1 *fields;
+ upb_msglayout_oneofinit_v1 *oneofs;
- if (upb_msgdef_syntax(m) == UPB_SYNTAX_PROTO2) {
- array_size += upb_msgdef_numfields(m); /* hasbits. */
+ for (upb_msg_field_begin(&it, m);
+ !upb_msg_field_done(&it);
+ upb_msg_field_next(&it)) {
+ const upb_fielddef* f = upb_msg_iter_field(&it);
+ if (upb_fielddef_issubmsg(f)) {
+ submsg_count++;
+ }
}
- l = upb_gmalloc(sizeof(*l) + (sizeof(uint32_t) * array_size));
+ l = upb_gmalloc(sizeof(*l));
if (!l) return NULL;
memset(l, 0, sizeof(*l));
- l->msgdef = m;
- l->align = 1;
- l->field_offsets = (uint32_t*)CHARPTR_AT(l, sizeof(*l));
- l->case_offsets = l->field_offsets + upb_msgdef_numfields(m);
- l->hasbits = l->case_offsets + upb_msgdef_numoneofs(m);
+ fields = upb_gmalloc(upb_msgdef_numfields(m) * sizeof(*fields));
+ submsgs = upb_gmalloc(submsg_count * sizeof(*submsgs));
+ oneofs = upb_gmalloc(upb_msgdef_numoneofs(m) * sizeof(*oneofs));
+
+ if ((!fields && upb_msgdef_numfields(m)) ||
+ (!submsgs && submsg_count) ||
+ (!oneofs && upb_msgdef_numoneofs(m))) {
+ /* OOM. */
+ upb_gfree(l);
+ upb_gfree(fields);
+ upb_gfree(submsgs);
+ upb_gfree(oneofs);
+ return NULL;
+ }
+
+ l->data.field_count = upb_msgdef_numfields(m);
+ l->data.oneof_count = upb_msgdef_numoneofs(m);
+ l->data.fields = fields;
+ l->data.submsgs = submsgs;
+ l->data.oneofs = oneofs;
+ l->data.is_proto2 = (upb_msgdef_syntax(m) == UPB_SYNTAX_PROTO2);
/* Allocate data offsets in three stages:
*
@@ -3313,74 +4307,75 @@ static upb_msglayout *upb_msglayout_new(const upb_msgdef *m) {
* OPT: There is a lot of room for optimization here to minimize the size.
*/
- /* Allocate hasbits. Start at sizeof(void*) for upb_alloc*. */
- for (upb_msg_field_begin(&it, m), hasbit = sizeof(void*) * 8;
+ /* Allocate hasbits and set basic field attributes. */
+ for (upb_msg_field_begin(&it, m), hasbit = 0;
!upb_msg_field_done(&it);
upb_msg_field_next(&it)) {
const upb_fielddef* f = upb_msg_iter_field(&it);
+ upb_msglayout_fieldinit_v1 *field = &fields[upb_fielddef_index(f)];
+
+ field->number = upb_fielddef_number(f);
+ field->type = upb_fielddef_type(f);
+ field->label = upb_fielddef_label(f);
+
+ if (upb_fielddef_containingoneof(f)) {
+ field->oneof_index = upb_oneofdef_index(upb_fielddef_containingoneof(f));
+ } else {
+ field->oneof_index = UPB_NOT_IN_ONEOF;
+ }
if (upb_fielddef_haspresence(f) && !upb_fielddef_containingoneof(f)) {
- l->hasbits[upb_fielddef_index(f)] = hasbit++;
+ field->hasbit = hasbit++;
}
}
/* Account for space used by hasbits. */
- l->size = div_round_up(hasbit, 8);
+ l->data.size = div_round_up(hasbit, 8);
/* Allocate non-oneof fields. */
for (upb_msg_field_begin(&it, m); !upb_msg_field_done(&it);
upb_msg_field_next(&it)) {
const upb_fielddef* f = upb_msg_iter_field(&it);
- size_t field_size = upb_msg_fieldsize(f);
+ size_t field_size = upb_msg_fielddefsize(f);
size_t index = upb_fielddef_index(f);
-
if (upb_fielddef_containingoneof(f)) {
/* Oneofs are handled separately below. */
continue;
}
- l->field_offsets[index] = upb_msglayout_place(l, field_size);
+ fields[index].offset = upb_msglayout_place(l, field_size);
}
/* Allocate oneof fields. Each oneof field consists of a uint32 for the case
* and space for the actual data. */
for (upb_msg_oneof_begin(&oit, m); !upb_msg_oneof_done(&oit);
upb_msg_oneof_next(&oit)) {
- const upb_oneofdef* oneof = upb_msg_iter_oneof(&oit);
+ const upb_oneofdef* o = upb_msg_iter_oneof(&oit);
upb_oneof_iter fit;
+
size_t case_size = sizeof(uint32_t); /* Could potentially optimize this. */
+ upb_msglayout_oneofinit_v1 *oneof = &oneofs[upb_oneofdef_index(o)];
size_t field_size = 0;
- size_t case_offset;
- size_t val_offset;
/* Calculate field size: the max of all field sizes. */
- for (upb_oneof_begin(&fit, oneof);
+ for (upb_oneof_begin(&fit, o);
!upb_oneof_done(&fit);
upb_oneof_next(&fit)) {
const upb_fielddef* f = upb_oneof_iter_field(&fit);
- field_size = UPB_MAX(field_size, upb_msg_fieldsize(f));
+ field_size = UPB_MAX(field_size, upb_msg_fielddefsize(f));
}
/* Align and allocate case offset. */
- case_offset = upb_msglayout_place(l, case_size);
- val_offset = upb_msglayout_place(l, field_size);
-
- l->case_offsets[upb_oneofdef_index(oneof)] = case_offset;
-
- /* Assign all fields in the oneof this same offset. */
- for (upb_oneof_begin(&fit, oneof); !upb_oneof_done(&fit);
- upb_oneof_next(&fit)) {
- const upb_fielddef* f = upb_oneof_iter_field(&fit);
- l->field_offsets[upb_fielddef_index(f)] = val_offset;
- }
+ oneof->case_offset = upb_msglayout_place(l, case_size);
+ oneof->data_offset = upb_msglayout_place(l, field_size);
}
/* Size of the entire structure should be a multiple of its greatest
- * alignment. */
- l->size = align_up(l->size, l->align);
+ * alignment. TODO: track overall alignment for real? */
+ l->data.size = align_up(l->data.size, 8);
- if (upb_msglayout_initdefault(l)) {
+ if (upb_msglayout_initdefault(l, m)) {
return l;
} else {
upb_msglayout_free(l);
@@ -3388,10 +4383,6 @@ static upb_msglayout *upb_msglayout_new(const upb_msgdef *m) {
}
}
-upb_msgfactory *upb_msglayout_factory(const upb_msglayout *layout) {
- return layout->factory;
-}
-
/** upb_msgfactory ************************************************************/
@@ -3448,7 +4439,6 @@ const upb_msglayout *upb_msgfactory_getlayout(upb_msgfactory *f,
upb_msglayout *l = upb_msglayout_new(m);
upb_inttable_insertptr(&mutable_f->layouts, m, upb_value_ptr(l));
UPB_ASSERT(l);
- l->factory = f;
return l;
}
}
@@ -3457,16 +4447,15 @@ const upb_msglayout *upb_msgfactory_getlayout(upb_msgfactory *f,
void *upb_msg_startstr(void *msg, const void *hd, size_t size_hint) {
uint32_t ofs = (uintptr_t)hd;
- /* We pass NULL here because we know we can get away with it. */
- upb_alloc *alloc = upb_msg_alloc(msg, NULL);
+ upb_alloc *alloc = upb_msg_alloc(msg);
upb_msgval val;
UPB_UNUSED(size_hint);
val = upb_msgval_read(msg, ofs, upb_msgval_sizeof(UPB_TYPE_STRING));
- upb_free(alloc, (void*)val.str.ptr);
- val.str.ptr = NULL;
- val.str.len = 0;
+ upb_free(alloc, (void*)val.str.data);
+ val.str.data = NULL;
+ val.str.size = 0;
upb_msgval_write(msg, ofs, val, upb_msgval_sizeof(UPB_TYPE_STRING));
return msg;
@@ -3475,23 +4464,22 @@ void *upb_msg_startstr(void *msg, const void *hd, size_t size_hint) {
size_t upb_msg_str(void *msg, const void *hd, const char *ptr, size_t size,
const upb_bufhandle *handle) {
uint32_t ofs = (uintptr_t)hd;
- /* We pass NULL here because we know we can get away with it. */
- upb_alloc *alloc = upb_msg_alloc(msg, NULL);
+ upb_alloc *alloc = upb_msg_alloc(msg);
upb_msgval val;
size_t newsize;
UPB_UNUSED(handle);
val = upb_msgval_read(msg, ofs, upb_msgval_sizeof(UPB_TYPE_STRING));
- newsize = val.str.len + size;
- val.str.ptr = upb_realloc(alloc, (void*)val.str.ptr, val.str.len, newsize);
+ newsize = val.str.size + size;
+ val.str.data = upb_realloc(alloc, (void*)val.str.data, val.str.size, newsize);
- if (!val.str.ptr) {
+ if (!val.str.data) {
return false;
}
- memcpy((char*)val.str.ptr + val.str.len, ptr, size);
- val.str.len = newsize;
+ memcpy((char*)val.str.data + val.str.size, ptr, size);
+ val.str.size = newsize;
upb_msgval_write(msg, ofs, val, upb_msgval_sizeof(UPB_TYPE_STRING));
return size;
}
@@ -3556,13 +4544,14 @@ static upb_selector_t getsel2(const upb_fielddef *f, upb_handlertype_t type) {
static bool upb_visitor_hasfield(const upb_msg *msg, const upb_fielddef *f,
const upb_msglayout *layout) {
+ int field_index = upb_fielddef_index(f);
if (upb_fielddef_isseq(f)) {
- return upb_msgval_getarr(upb_msg_get(msg, f, layout)) != NULL;
+ return upb_msgval_getarr(upb_msg_get(msg, field_index, layout)) != NULL;
} else if (upb_msgdef_syntax(upb_fielddef_containingtype(f)) ==
UPB_SYNTAX_PROTO2) {
- return upb_msg_has(msg, f, layout);
+ return upb_msg_has(msg, field_index, layout);
} else {
- upb_msgval val = upb_msg_get(msg, f, layout);
+ upb_msgval val = upb_msg_get(msg, field_index, layout);
switch (upb_fielddef_type(f)) {
case UPB_TYPE_FLOAT:
return upb_msgval_getfloat(val) != 0;
@@ -3581,7 +4570,7 @@ static bool upb_visitor_hasfield(const upb_msg *msg, const upb_fielddef *f,
return upb_msgval_getuint64(val) != 0;
case UPB_TYPE_STRING:
case UPB_TYPE_BYTES:
- return upb_msgval_getstr(val) && upb_msgval_getstrlen(val) > 0;
+ return upb_msgval_getstr(val).size > 0;
case UPB_TYPE_MESSAGE:
return upb_msgval_getmsg(val) != NULL;
}
@@ -3592,7 +4581,7 @@ static bool upb_visitor_hasfield(const upb_msg *msg, const upb_fielddef *f,
static bool upb_visitor_visitmsg2(const upb_msg *msg,
const upb_msglayout *layout, upb_sink *sink,
int depth) {
- const upb_msgdef *md = upb_msglayout_msgdef(layout);
+ const upb_msgdef *md = upb_handlers_msgdef(sink->handlers);
upb_msg_field_iter i;
upb_status status;
@@ -3614,7 +4603,7 @@ static bool upb_visitor_visitmsg2(const upb_msg *msg,
continue;
}
- val = upb_msg_get(msg, f, layout);
+ val = upb_msg_get(msg, upb_fielddef_index(f), layout);
if (upb_fielddef_isseq(f)) {
const upb_array *arr = upb_msgval_getarr(val);
@@ -3683,194 +4672,160 @@ bool upb_visitor_visitmsg(upb_visitor *visitor, const upb_msg *msg) {
/* If we always read/write as a consistent type to each address, this shouldn't
* violate aliasing.
*/
-#define DEREF(msg, ofs, type) *(type*)CHARPTR_AT(msg, ofs)
-
-static upb_inttable *upb_msg_trygetextdict(const upb_msg *msg,
- const upb_msglayout *l) {
- return l->has_extdict ? DEREF(msg, l->extdict_offset, upb_inttable*) : NULL;
-}
+#define DEREF(msg, ofs, type) *PTR_AT(msg, ofs, type)
-static upb_inttable *upb_msg_getextdict(upb_msg *msg,
- const upb_msglayout *l,
- upb_alloc *a) {
- upb_inttable *ext_dict;
- UPB_ASSERT(l->has_extdict);
+/* Internal members of a upb_msg. We can change this without breaking binary
+ * compatibility. We put these before the user's data. The user's upb_msg*
+ * points after the upb_msg_internal. */
- ext_dict = upb_msg_trygetextdict(msg, l);
+/* Used when a message is not extendable. */
+typedef struct {
+ /* TODO(haberman): add unknown fields. */
+ upb_alloc *alloc;
+} upb_msg_internal;
- if (!ext_dict) {
- ext_dict = upb_malloc(a, sizeof(upb_inttable));
+/* Used when a message is extendable. */
+typedef struct {
+ upb_inttable *extdict;
+ upb_msg_internal base;
+} upb_msg_internal_withext;
- if (!ext_dict) {
- return NULL;
- }
+static int upb_msg_internalsize(const upb_msglayout *l) {
+ return sizeof(upb_msg_internal) - l->data.extendable * sizeof(void*);
+}
- /* Use an 8-byte type to ensure all bytes are copied. */
- if (!upb_inttable_init2(ext_dict, UPB_CTYPE_INT64, a)) {
- upb_free(a, ext_dict);
- return NULL;
- }
+static upb_msg_internal *upb_msg_getinternal(upb_msg *msg) {
+ return VOIDPTR_AT(msg, -sizeof(upb_msg_internal));
+}
- DEREF(msg, l->extdict_offset, upb_inttable*) = ext_dict;
- }
+static const upb_msg_internal *upb_msg_getinternal_const(const upb_msg *msg) {
+ return VOIDPTR_AT(msg, -sizeof(upb_msg_internal));
+}
- return ext_dict;
+static upb_msg_internal_withext *upb_msg_getinternalwithext(
+ upb_msg *msg, const upb_msglayout *l) {
+ UPB_ASSERT(l->data.extendable);
+ return VOIDPTR_AT(msg, -sizeof(upb_msg_internal_withext));
}
-static uint32_t upb_msg_getoneofint(const upb_msg *msg,
- const upb_oneofdef *o,
- const upb_msglayout *l) {
- size_t oneof_ofs = l->case_offsets[upb_oneofdef_index(o)];
- return DEREF(msg, oneof_ofs, uint8_t);
+static const upb_msglayout_fieldinit_v1 *upb_msg_checkfield(
+ int field_index, const upb_msglayout *l) {
+ UPB_ASSERT(field_index >= 0 && field_index < l->data.field_count);
+ return &l->data.fields[field_index];
}
-static void upb_msg_setoneofcase(const upb_msg *msg,
- const upb_oneofdef *o,
- const upb_msglayout *l,
- uint32_t val) {
- size_t oneof_ofs = l->case_offsets[upb_oneofdef_index(o)];
- DEREF(msg, oneof_ofs, uint8_t) = val;
+static bool upb_msg_inoneof(const upb_msglayout_fieldinit_v1 *field) {
+ return field->oneof_index != UPB_NOT_IN_ONEOF;
}
+static uint32_t *upb_msg_oneofcase(const upb_msg *msg, int field_index,
+ const upb_msglayout *l) {
+ const upb_msglayout_fieldinit_v1 *field = upb_msg_checkfield(field_index, l);
+ UPB_ASSERT(upb_msg_inoneof(field));
+ return PTR_AT(msg, l->data.oneofs[field->oneof_index].case_offset, uint32_t);
+}
-static bool upb_msg_oneofis(const upb_msg *msg, const upb_msglayout *l,
- const upb_oneofdef *o, const upb_fielddef *f) {
- return upb_msg_getoneofint(msg, o, l) == upb_fielddef_number(f);
+size_t upb_msg_sizeof(const upb_msglayout *l) {
+ return l->data.size + upb_msg_internalsize(l);
}
-size_t upb_msg_sizeof(const upb_msglayout *l) { return l->size; }
+upb_msg *upb_msg_init(void *mem, const upb_msglayout *l, upb_alloc *a) {
+ upb_msg *msg = VOIDPTR_AT(mem, upb_msg_internalsize(l));
-void upb_msg_init(upb_msg *msg, const upb_msglayout *l, upb_alloc *a) {
- if (l->default_msg) {
- memcpy(msg, l->default_msg, l->size);
+ /* Initialize normal members. */
+ if (l->data.default_msg) {
+ memcpy(msg, l->data.default_msg, l->data.size);
} else {
- memset(msg, 0, l->size);
+ memset(msg, 0, l->data.size);
}
- /* Set arena pointer. */
- memcpy(msg, &a, sizeof(a));
-}
+ /* Initialize internal members. */
+ upb_msg_getinternal(msg)->alloc = a;
-void upb_msg_uninit(upb_msg *msg, const upb_msglayout *l) {
- upb_inttable *ext_dict = upb_msg_trygetextdict(msg, l);
- if (ext_dict) {
- upb_inttable_uninit2(ext_dict, upb_msg_alloc(msg, l));
+ if (l->data.extendable) {
+ upb_msg_getinternalwithext(msg, l)->extdict = NULL;
}
-}
-upb_msg *upb_msg_new(const upb_msglayout *l, upb_alloc *a) {
- upb_msg *msg = upb_malloc(a, upb_msg_sizeof(l));
+ return msg;
+}
- if (msg) {
- upb_msg_init(msg, l, a);
+void *upb_msg_uninit(upb_msg *msg, const upb_msglayout *l) {
+ if (l->data.extendable) {
+ upb_inttable *ext_dict = upb_msg_getinternalwithext(msg, l)->extdict;
+ if (ext_dict) {
+ upb_inttable_uninit2(ext_dict, upb_msg_alloc(msg));
+ upb_free(upb_msg_alloc(msg), ext_dict);
+ }
}
- return msg;
+ return VOIDPTR_AT(msg, -upb_msg_internalsize(l));
+}
+
+upb_msg *upb_msg_new(const upb_msglayout *l, upb_alloc *a) {
+ void *mem = upb_malloc(a, upb_msg_sizeof(l));
+ return mem ? upb_msg_init(mem, l, a) : NULL;
}
void upb_msg_free(upb_msg *msg, const upb_msglayout *l) {
- upb_msg_uninit(msg, l);
- upb_free(upb_msg_alloc(msg, l), msg);
+ upb_free(upb_msg_alloc(msg), upb_msg_uninit(msg, l));
}
-upb_alloc *upb_msg_alloc(const upb_msg *msg, const upb_msglayout *l) {
- upb_alloc *alloc;
- UPB_UNUSED(l);
- memcpy(&alloc, msg, sizeof(alloc));
- return alloc;
+upb_alloc *upb_msg_alloc(const upb_msg *msg) {
+ return upb_msg_getinternal_const(msg)->alloc;
}
bool upb_msg_has(const upb_msg *msg,
- const upb_fielddef *f,
+ int field_index,
const upb_msglayout *l) {
- const upb_oneofdef *o;
- upb_msg_checkfield(l, f);
- UPB_ASSERT(upb_fielddef_haspresence(f));
+ const upb_msglayout_fieldinit_v1 *field = upb_msg_checkfield(field_index, l);
- if (upb_fielddef_isextension(f)) {
- /* Extensions are set when they are present in the extension dict. */
- upb_inttable *ext_dict = upb_msg_trygetextdict(msg, l);
- upb_value v;
- return ext_dict != NULL &&
- upb_inttable_lookup32(ext_dict, upb_fielddef_number(f), &v);
- } else if ((o = upb_fielddef_containingoneof(f)) != NULL) {
+ UPB_ASSERT(l->data.is_proto2);
+
+ if (upb_msg_inoneof(field)) {
/* Oneofs are set when the oneof number is set to this field. */
- return upb_msg_getoneofint(msg, o, l) == upb_fielddef_number(f);
+ return *upb_msg_oneofcase(msg, field_index, l) == field->number;
} else {
/* Other fields are set when their hasbit is set. */
- uint32_t hasbit = l->hasbits[upb_fielddef_index(f)];
+ uint32_t hasbit = l->data.fields[field_index].hasbit;
return DEREF(msg, hasbit / 8, char) | (1 << (hasbit % 8));
}
}
-upb_msgval upb_msg_get(const upb_msg *msg, const upb_fielddef *f,
+upb_msgval upb_msg_get(const upb_msg *msg, int field_index,
const upb_msglayout *l) {
- upb_msg_checkfield(l, f);
+ const upb_msglayout_fieldinit_v1 *field = upb_msg_checkfield(field_index, l);
+ int size = upb_msg_fieldsize(field);
- if (upb_fielddef_isextension(f)) {
- upb_inttable *ext_dict = upb_msg_trygetextdict(msg, l);
- upb_value val;
- if (upb_inttable_lookup32(ext_dict, upb_fielddef_number(f), &val)) {
- return upb_msgval_fromval(val);
+ if (upb_msg_inoneof(field)) {
+ if (*upb_msg_oneofcase(msg, field_index, l) == field->number) {
+ size_t ofs = l->data.oneofs[field->oneof_index].data_offset;
+ return upb_msgval_read(msg, ofs, size);
} else {
- return upb_msgval_fromdefault(f);
+ /* Return default. */
+ return upb_msgval_read(l->data.default_msg, field->offset, size);
}
} else {
- size_t ofs = l->field_offsets[upb_fielddef_index(f)];
- const upb_oneofdef *o = upb_fielddef_containingoneof(f);
- upb_msgval ret;
-
- if (o && !upb_msg_oneofis(msg, l, o, f)) {
- /* Oneof defaults can't come from the message because the memory is reused
- * by all types in the oneof. */
- return upb_msgval_fromdefault(f);
- }
-
- ret = upb_msgval_read(msg, ofs, upb_msg_fieldsize(f));
- return ret;
+ return upb_msgval_read(msg, field->offset, size);
}
}
-bool upb_msg_set(upb_msg *msg,
- const upb_fielddef *f,
- upb_msgval val,
+void upb_msg_set(upb_msg *msg, int field_index, upb_msgval val,
const upb_msglayout *l) {
- upb_alloc *a = upb_msg_alloc(msg, l);
- upb_msg_checkfield(l, f);
-
- if (upb_fielddef_isextension(f)) {
- /* TODO(haberman): introduce table API that can do this in one call. */
- upb_inttable *ext = upb_msg_getextdict(msg, l, a);
- upb_value val2 = upb_toval(val);
- if (!upb_inttable_replace(ext, upb_fielddef_number(f), val2) &&
- !upb_inttable_insert2(ext, upb_fielddef_number(f), val2, a)) {
- return false;
- }
- } else {
- size_t ofs = l->field_offsets[upb_fielddef_index(f)];
- const upb_oneofdef *o = upb_fielddef_containingoneof(f);
-
- if (o) {
- upb_msg_setoneofcase(msg, o, l, upb_fielddef_number(f));
- }
+ const upb_msglayout_fieldinit_v1 *field = upb_msg_checkfield(field_index, l);
+ int size = upb_msg_fieldsize(field);
- upb_msgval_write(msg, ofs, val, upb_msg_fieldsize(f));
+ if (upb_msg_inoneof(field)) {
+ size_t ofs = l->data.oneofs[field->oneof_index].data_offset;
+ *upb_msg_oneofcase(msg, field_index, l) = field->number;
+ upb_msgval_write(msg, ofs, val, size);
+ } else {
+ upb_msgval_write(msg, field->offset, val, size);
}
- return true;
}
/** upb_array *****************************************************************/
-struct upb_array {
- upb_fieldtype_t type;
- uint8_t element_size;
- void *data; /* Each element is element_size. */
- size_t len; /* Measured in elements. */
- size_t size; /* Measured in elements. */
- upb_alloc *alloc;
-};
-
#define DEREF_ARR(arr, i, type) ((type*)arr->data)[i]
size_t upb_array_sizeof(upb_fieldtype_t type) {
@@ -3965,8 +4920,8 @@ static void upb_map_tokey(upb_fieldtype_t type, upb_msgval *key,
switch (type) {
case UPB_TYPE_STRING:
/* Point to string data of the input key. */
- *out_key = key->str.ptr;
- *out_len = key->str.len;
+ *out_key = key->str.data;
+ *out_len = key->str.size;
return;
case UPB_TYPE_BOOL:
case UPB_TYPE_INT32:
@@ -3991,7 +4946,7 @@ static upb_msgval upb_map_fromkey(upb_fieldtype_t type, const char *key,
size_t len) {
switch (type) {
case UPB_TYPE_STRING:
- return upb_msgval_str(key, len);
+ return upb_msgval_makestr(key, len);
case UPB_TYPE_BOOL:
case UPB_TYPE_INT32:
case UPB_TYPE_UINT32:
@@ -6451,138 +7406,138 @@ static upb_inttable reftables[268];
#endif
static const upb_msgdef msgs[22] = {
- UPB_MSGDEF_INIT("google.protobuf.DescriptorProto", 40, 8, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[0], 11, 10), UPB_STRTABLE_INIT(10, 15, UPB_CTYPE_PTR, 4, &strentries[0]), false, UPB_SYNTAX_PROTO2, &reftables[0], &reftables[1]),
- UPB_MSGDEF_INIT("google.protobuf.DescriptorProto.ExtensionRange", 4, 0, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[11], 3, 2), UPB_STRTABLE_INIT(2, 3, UPB_CTYPE_PTR, 2, &strentries[16]), false, UPB_SYNTAX_PROTO2, &reftables[2], &reftables[3]),
- UPB_MSGDEF_INIT("google.protobuf.DescriptorProto.ReservedRange", 4, 0, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[14], 3, 2), UPB_STRTABLE_INIT(2, 3, UPB_CTYPE_PTR, 2, &strentries[20]), false, UPB_SYNTAX_PROTO2, &reftables[4], &reftables[5]),
- UPB_MSGDEF_INIT("google.protobuf.EnumDescriptorProto", 11, 2, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[17], 4, 3), UPB_STRTABLE_INIT(3, 3, UPB_CTYPE_PTR, 2, &strentries[24]), false, UPB_SYNTAX_PROTO2, &reftables[6], &reftables[7]),
- UPB_MSGDEF_INIT("google.protobuf.EnumOptions", 8, 1, UPB_INTTABLE_INIT(1, 1, UPB_CTYPE_PTR, 1, &intentries[0], &arrays[21], 4, 2), UPB_STRTABLE_INIT(3, 3, UPB_CTYPE_PTR, 2, &strentries[28]), false, UPB_SYNTAX_PROTO2, &reftables[8], &reftables[9]),
- UPB_MSGDEF_INIT("google.protobuf.EnumValueDescriptorProto", 8, 1, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[25], 4, 3), UPB_STRTABLE_INIT(3, 3, UPB_CTYPE_PTR, 2, &strentries[32]), false, UPB_SYNTAX_PROTO2, &reftables[10], &reftables[11]),
- UPB_MSGDEF_INIT("google.protobuf.EnumValueOptions", 7, 1, UPB_INTTABLE_INIT(1, 1, UPB_CTYPE_PTR, 1, &intentries[2], &arrays[29], 2, 1), UPB_STRTABLE_INIT(2, 3, UPB_CTYPE_PTR, 2, &strentries[36]), false, UPB_SYNTAX_PROTO2, &reftables[12], &reftables[13]),
- UPB_MSGDEF_INIT("google.protobuf.FieldDescriptorProto", 23, 1, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[31], 11, 10), UPB_STRTABLE_INIT(10, 15, UPB_CTYPE_PTR, 4, &strentries[40]), false, UPB_SYNTAX_PROTO2, &reftables[14], &reftables[15]),
- UPB_MSGDEF_INIT("google.protobuf.FieldOptions", 12, 1, UPB_INTTABLE_INIT(1, 1, UPB_CTYPE_PTR, 1, &intentries[4], &arrays[42], 11, 6), UPB_STRTABLE_INIT(7, 15, UPB_CTYPE_PTR, 4, &strentries[56]), false, UPB_SYNTAX_PROTO2, &reftables[16], &reftables[17]),
- UPB_MSGDEF_INIT("google.protobuf.FileDescriptorProto", 42, 6, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[53], 13, 12), UPB_STRTABLE_INIT(12, 15, UPB_CTYPE_PTR, 4, &strentries[72]), false, UPB_SYNTAX_PROTO2, &reftables[18], &reftables[19]),
- UPB_MSGDEF_INIT("google.protobuf.FileDescriptorSet", 6, 1, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[66], 2, 1), UPB_STRTABLE_INIT(1, 3, UPB_CTYPE_PTR, 2, &strentries[88]), false, UPB_SYNTAX_PROTO2, &reftables[20], &reftables[21]),
- UPB_MSGDEF_INIT("google.protobuf.FileOptions", 37, 1, UPB_INTTABLE_INIT(1, 1, UPB_CTYPE_PTR, 1, &intentries[6], &arrays[68], 42, 17), UPB_STRTABLE_INIT(18, 31, UPB_CTYPE_PTR, 5, &strentries[92]), false, UPB_SYNTAX_PROTO2, &reftables[22], &reftables[23]),
- UPB_MSGDEF_INIT("google.protobuf.MessageOptions", 10, 1, UPB_INTTABLE_INIT(1, 1, UPB_CTYPE_PTR, 1, &intentries[8], &arrays[110], 8, 4), UPB_STRTABLE_INIT(5, 7, UPB_CTYPE_PTR, 3, &strentries[124]), false, UPB_SYNTAX_PROTO2, &reftables[24], &reftables[25]),
- UPB_MSGDEF_INIT("google.protobuf.MethodDescriptorProto", 15, 1, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[118], 7, 6), UPB_STRTABLE_INIT(6, 7, UPB_CTYPE_PTR, 3, &strentries[132]), false, UPB_SYNTAX_PROTO2, &reftables[26], &reftables[27]),
- UPB_MSGDEF_INIT("google.protobuf.MethodOptions", 7, 1, UPB_INTTABLE_INIT(2, 3, UPB_CTYPE_PTR, 2, &intentries[10], &arrays[125], 1, 0), UPB_STRTABLE_INIT(2, 3, UPB_CTYPE_PTR, 2, &strentries[140]), false, UPB_SYNTAX_PROTO2, &reftables[28], &reftables[29]),
- UPB_MSGDEF_INIT("google.protobuf.OneofDescriptorProto", 5, 0, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[126], 2, 1), UPB_STRTABLE_INIT(1, 3, UPB_CTYPE_PTR, 2, &strentries[144]), false, UPB_SYNTAX_PROTO2, &reftables[30], &reftables[31]),
- UPB_MSGDEF_INIT("google.protobuf.ServiceDescriptorProto", 11, 2, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[128], 4, 3), UPB_STRTABLE_INIT(3, 3, UPB_CTYPE_PTR, 2, &strentries[148]), false, UPB_SYNTAX_PROTO2, &reftables[32], &reftables[33]),
- UPB_MSGDEF_INIT("google.protobuf.ServiceOptions", 7, 1, UPB_INTTABLE_INIT(2, 3, UPB_CTYPE_PTR, 2, &intentries[14], &arrays[132], 1, 0), UPB_STRTABLE_INIT(2, 3, UPB_CTYPE_PTR, 2, &strentries[152]), false, UPB_SYNTAX_PROTO2, &reftables[34], &reftables[35]),
- UPB_MSGDEF_INIT("google.protobuf.SourceCodeInfo", 6, 1, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[133], 2, 1), UPB_STRTABLE_INIT(1, 3, UPB_CTYPE_PTR, 2, &strentries[156]), false, UPB_SYNTAX_PROTO2, &reftables[36], &reftables[37]),
- UPB_MSGDEF_INIT("google.protobuf.SourceCodeInfo.Location", 19, 0, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[135], 7, 5), UPB_STRTABLE_INIT(5, 7, UPB_CTYPE_PTR, 3, &strentries[160]), false, UPB_SYNTAX_PROTO2, &reftables[38], &reftables[39]),
- UPB_MSGDEF_INIT("google.protobuf.UninterpretedOption", 18, 1, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[142], 9, 7), UPB_STRTABLE_INIT(7, 15, UPB_CTYPE_PTR, 4, &strentries[168]), false, UPB_SYNTAX_PROTO2, &reftables[40], &reftables[41]),
- UPB_MSGDEF_INIT("google.protobuf.UninterpretedOption.NamePart", 6, 0, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[151], 3, 2), UPB_STRTABLE_INIT(2, 3, UPB_CTYPE_PTR, 2, &strentries[184]), false, UPB_SYNTAX_PROTO2, &reftables[42], &reftables[43]),
+ UPB_MSGDEF_INIT("google.protobuf.DescriptorProto", 41, 8, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[0], 11, 10), UPB_STRTABLE_INIT(10, 15, UPB_CTYPE_PTR, 4, &strentries[0]), false, UPB_SYNTAX_PROTO2, &reftables[0], &reftables[1]),
+ UPB_MSGDEF_INIT("google.protobuf.DescriptorProto.ExtensionRange", 5, 0, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[11], 3, 2), UPB_STRTABLE_INIT(2, 3, UPB_CTYPE_PTR, 2, &strentries[16]), false, UPB_SYNTAX_PROTO2, &reftables[2], &reftables[3]),
+ UPB_MSGDEF_INIT("google.protobuf.DescriptorProto.ReservedRange", 5, 0, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[14], 3, 2), UPB_STRTABLE_INIT(2, 3, UPB_CTYPE_PTR, 2, &strentries[20]), false, UPB_SYNTAX_PROTO2, &reftables[4], &reftables[5]),
+ UPB_MSGDEF_INIT("google.protobuf.EnumDescriptorProto", 12, 2, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[17], 4, 3), UPB_STRTABLE_INIT(3, 3, UPB_CTYPE_PTR, 2, &strentries[24]), false, UPB_SYNTAX_PROTO2, &reftables[6], &reftables[7]),
+ UPB_MSGDEF_INIT("google.protobuf.EnumOptions", 9, 1, UPB_INTTABLE_INIT(1, 1, UPB_CTYPE_PTR, 1, &intentries[0], &arrays[21], 4, 2), UPB_STRTABLE_INIT(3, 3, UPB_CTYPE_PTR, 2, &strentries[28]), false, UPB_SYNTAX_PROTO2, &reftables[8], &reftables[9]),
+ UPB_MSGDEF_INIT("google.protobuf.EnumValueDescriptorProto", 9, 1, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[25], 4, 3), UPB_STRTABLE_INIT(3, 3, UPB_CTYPE_PTR, 2, &strentries[32]), false, UPB_SYNTAX_PROTO2, &reftables[10], &reftables[11]),
+ UPB_MSGDEF_INIT("google.protobuf.EnumValueOptions", 8, 1, UPB_INTTABLE_INIT(1, 1, UPB_CTYPE_PTR, 1, &intentries[2], &arrays[29], 2, 1), UPB_STRTABLE_INIT(2, 3, UPB_CTYPE_PTR, 2, &strentries[36]), false, UPB_SYNTAX_PROTO2, &reftables[12], &reftables[13]),
+ UPB_MSGDEF_INIT("google.protobuf.FieldDescriptorProto", 24, 1, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[31], 11, 10), UPB_STRTABLE_INIT(10, 15, UPB_CTYPE_PTR, 4, &strentries[40]), false, UPB_SYNTAX_PROTO2, &reftables[14], &reftables[15]),
+ UPB_MSGDEF_INIT("google.protobuf.FieldOptions", 13, 1, UPB_INTTABLE_INIT(1, 1, UPB_CTYPE_PTR, 1, &intentries[4], &arrays[42], 11, 6), UPB_STRTABLE_INIT(7, 15, UPB_CTYPE_PTR, 4, &strentries[56]), false, UPB_SYNTAX_PROTO2, &reftables[16], &reftables[17]),
+ UPB_MSGDEF_INIT("google.protobuf.FileDescriptorProto", 43, 6, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[53], 13, 12), UPB_STRTABLE_INIT(12, 15, UPB_CTYPE_PTR, 4, &strentries[72]), false, UPB_SYNTAX_PROTO2, &reftables[18], &reftables[19]),
+ UPB_MSGDEF_INIT("google.protobuf.FileDescriptorSet", 7, 1, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[66], 2, 1), UPB_STRTABLE_INIT(1, 3, UPB_CTYPE_PTR, 2, &strentries[88]), false, UPB_SYNTAX_PROTO2, &reftables[20], &reftables[21]),
+ UPB_MSGDEF_INIT("google.protobuf.FileOptions", 38, 1, UPB_INTTABLE_INIT(1, 1, UPB_CTYPE_PTR, 1, &intentries[6], &arrays[68], 42, 17), UPB_STRTABLE_INIT(18, 31, UPB_CTYPE_PTR, 5, &strentries[92]), false, UPB_SYNTAX_PROTO2, &reftables[22], &reftables[23]),
+ UPB_MSGDEF_INIT("google.protobuf.MessageOptions", 11, 1, UPB_INTTABLE_INIT(1, 1, UPB_CTYPE_PTR, 1, &intentries[8], &arrays[110], 8, 4), UPB_STRTABLE_INIT(5, 7, UPB_CTYPE_PTR, 3, &strentries[124]), false, UPB_SYNTAX_PROTO2, &reftables[24], &reftables[25]),
+ UPB_MSGDEF_INIT("google.protobuf.MethodDescriptorProto", 16, 1, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[118], 7, 6), UPB_STRTABLE_INIT(6, 7, UPB_CTYPE_PTR, 3, &strentries[132]), false, UPB_SYNTAX_PROTO2, &reftables[26], &reftables[27]),
+ UPB_MSGDEF_INIT("google.protobuf.MethodOptions", 8, 1, UPB_INTTABLE_INIT(2, 3, UPB_CTYPE_PTR, 2, &intentries[10], &arrays[125], 1, 0), UPB_STRTABLE_INIT(2, 3, UPB_CTYPE_PTR, 2, &strentries[140]), false, UPB_SYNTAX_PROTO2, &reftables[28], &reftables[29]),
+ UPB_MSGDEF_INIT("google.protobuf.OneofDescriptorProto", 6, 0, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[126], 2, 1), UPB_STRTABLE_INIT(1, 3, UPB_CTYPE_PTR, 2, &strentries[144]), false, UPB_SYNTAX_PROTO2, &reftables[30], &reftables[31]),
+ UPB_MSGDEF_INIT("google.protobuf.ServiceDescriptorProto", 12, 2, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[128], 4, 3), UPB_STRTABLE_INIT(3, 3, UPB_CTYPE_PTR, 2, &strentries[148]), false, UPB_SYNTAX_PROTO2, &reftables[32], &reftables[33]),
+ UPB_MSGDEF_INIT("google.protobuf.ServiceOptions", 8, 1, UPB_INTTABLE_INIT(2, 3, UPB_CTYPE_PTR, 2, &intentries[14], &arrays[132], 1, 0), UPB_STRTABLE_INIT(2, 3, UPB_CTYPE_PTR, 2, &strentries[152]), false, UPB_SYNTAX_PROTO2, &reftables[34], &reftables[35]),
+ UPB_MSGDEF_INIT("google.protobuf.SourceCodeInfo", 7, 1, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[133], 2, 1), UPB_STRTABLE_INIT(1, 3, UPB_CTYPE_PTR, 2, &strentries[156]), false, UPB_SYNTAX_PROTO2, &reftables[36], &reftables[37]),
+ UPB_MSGDEF_INIT("google.protobuf.SourceCodeInfo.Location", 20, 0, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[135], 7, 5), UPB_STRTABLE_INIT(5, 7, UPB_CTYPE_PTR, 3, &strentries[160]), false, UPB_SYNTAX_PROTO2, &reftables[38], &reftables[39]),
+ UPB_MSGDEF_INIT("google.protobuf.UninterpretedOption", 19, 1, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[142], 9, 7), UPB_STRTABLE_INIT(7, 15, UPB_CTYPE_PTR, 4, &strentries[168]), false, UPB_SYNTAX_PROTO2, &reftables[40], &reftables[41]),
+ UPB_MSGDEF_INIT("google.protobuf.UninterpretedOption.NamePart", 7, 0, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[151], 3, 2), UPB_STRTABLE_INIT(2, 3, UPB_CTYPE_PTR, 2, &strentries[184]), false, UPB_SYNTAX_PROTO2, &reftables[42], &reftables[43]),
};
static const upb_fielddef fields[107] = {
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "aggregate_value", 8, &msgs[20], NULL, 15, 6, {0},&reftables[44], &reftables[45]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "allow_alias", 2, &msgs[4], NULL, 6, 1, {0},&reftables[46], &reftables[47]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "cc_enable_arenas", 31, &msgs[11], NULL, 23, 12, {0},&reftables[48], &reftables[49]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "cc_generic_services", 16, &msgs[11], NULL, 17, 6, {0},&reftables[50], &reftables[51]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "client_streaming", 5, &msgs[13], NULL, 13, 4, {0},&reftables[52], &reftables[53]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "csharp_namespace", 37, &msgs[11], NULL, 27, 14, {0},&reftables[54], &reftables[55]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_ENUM, 0, false, false, false, false, "ctype", 1, &msgs[8], (const upb_def*)(&enums[2]), 6, 1, {0},&reftables[56], &reftables[57]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "default_value", 7, &msgs[7], NULL, 16, 7, {0},&reftables[58], &reftables[59]),
- UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_STRING, 0, false, false, false, false, "dependency", 3, &msgs[9], NULL, 30, 8, {0},&reftables[60], &reftables[61]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "deprecated", 3, &msgs[8], NULL, 8, 3, {0},&reftables[62], &reftables[63]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "deprecated", 33, &msgs[14], NULL, 6, 1, {0},&reftables[64], &reftables[65]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "deprecated", 3, &msgs[12], NULL, 8, 3, {0},&reftables[66], &reftables[67]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "deprecated", 23, &msgs[11], NULL, 21, 10, {0},&reftables[68], &reftables[69]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "deprecated", 1, &msgs[6], NULL, 6, 1, {0},&reftables[70], &reftables[71]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "deprecated", 3, &msgs[4], NULL, 7, 2, {0},&reftables[72], &reftables[73]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "deprecated", 33, &msgs[17], NULL, 6, 1, {0},&reftables[74], &reftables[75]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_DOUBLE, 0, false, false, false, false, "double_value", 6, &msgs[20], NULL, 11, 4, {0},&reftables[76], &reftables[77]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_INT32, UPB_INTFMT_VARIABLE, false, false, false, false, "end", 2, &msgs[2], NULL, 3, 1, {0},&reftables[78], &reftables[79]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_INT32, UPB_INTFMT_VARIABLE, false, false, false, false, "end", 2, &msgs[1], NULL, 3, 1, {0},&reftables[80], &reftables[81]),
- UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "enum_type", 5, &msgs[9], (const upb_def*)(&msgs[3]), 13, 1, {0},&reftables[82], &reftables[83]),
- UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "enum_type", 4, &msgs[0], (const upb_def*)(&msgs[3]), 18, 2, {0},&reftables[84], &reftables[85]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "extendee", 2, &msgs[7], NULL, 7, 2, {0},&reftables[86], &reftables[87]),
- UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "extension", 6, &msgs[0], (const upb_def*)(&msgs[7]), 24, 4, {0},&reftables[88], &reftables[89]),
- UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "extension", 7, &msgs[9], (const upb_def*)(&msgs[7]), 19, 3, {0},&reftables[90], &reftables[91]),
- UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "extension_range", 5, &msgs[0], (const upb_def*)(&msgs[1]), 21, 3, {0},&reftables[92], &reftables[93]),
- UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "field", 2, &msgs[0], (const upb_def*)(&msgs[7]), 12, 0, {0},&reftables[94], &reftables[95]),
- UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "file", 1, &msgs[10], (const upb_def*)(&msgs[9]), 5, 0, {0},&reftables[96], &reftables[97]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "go_package", 11, &msgs[11], NULL, 14, 5, {0},&reftables[98], &reftables[99]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "identifier_value", 3, &msgs[20], NULL, 6, 1, {0},&reftables[100], &reftables[101]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "input_type", 2, &msgs[13], NULL, 7, 2, {0},&reftables[102], &reftables[103]),
- UPB_FIELDDEF_INIT(UPB_LABEL_REQUIRED, UPB_TYPE_BOOL, 0, false, false, false, false, "is_extension", 2, &msgs[21], NULL, 5, 1, {0},&reftables[104], &reftables[105]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "java_generate_equals_and_hash", 20, &msgs[11], NULL, 20, 9, {0},&reftables[106], &reftables[107]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "java_generic_services", 17, &msgs[11], NULL, 18, 7, {0},&reftables[108], &reftables[109]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "java_multiple_files", 10, &msgs[11], NULL, 13, 4, {0},&reftables[110], &reftables[111]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "java_outer_classname", 8, &msgs[11], NULL, 9, 2, {0},&reftables[112], &reftables[113]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "java_package", 1, &msgs[11], NULL, 6, 1, {0},&reftables[114], &reftables[115]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "java_string_check_utf8", 27, &msgs[11], NULL, 22, 11, {0},&reftables[116], &reftables[117]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "javanano_use_deprecated_package", 38, &msgs[11], NULL, 30, 15, {0},&reftables[118], &reftables[119]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "json_name", 10, &msgs[7], NULL, 20, 9, {0},&reftables[120], &reftables[121]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_ENUM, 0, false, false, false, false, "jstype", 6, &msgs[8], (const upb_def*)(&enums[3]), 10, 5, {0},&reftables[122], &reftables[123]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_ENUM, 0, false, false, false, false, "label", 4, &msgs[7], (const upb_def*)(&enums[0]), 11, 4, {0},&reftables[124], &reftables[125]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "lazy", 5, &msgs[8], NULL, 9, 4, {0},&reftables[126], &reftables[127]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "leading_comments", 3, &msgs[19], NULL, 8, 2, {0},&reftables[128], &reftables[129]),
- UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_STRING, 0, false, false, false, false, "leading_detached_comments", 6, &msgs[19], NULL, 16, 4, {0},&reftables[130], &reftables[131]),
- UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "location", 1, &msgs[18], (const upb_def*)(&msgs[19]), 5, 0, {0},&reftables[132], &reftables[133]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "map_entry", 7, &msgs[12], NULL, 9, 4, {0},&reftables[134], &reftables[135]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "message_set_wire_format", 1, &msgs[12], NULL, 6, 1, {0},&reftables[136], &reftables[137]),
- UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "message_type", 4, &msgs[9], (const upb_def*)(&msgs[0]), 10, 0, {0},&reftables[138], &reftables[139]),
- UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "method", 2, &msgs[16], (const upb_def*)(&msgs[13]), 6, 0, {0},&reftables[140], &reftables[141]),
- UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "name", 2, &msgs[20], (const upb_def*)(&msgs[21]), 5, 0, {0},&reftables[142], &reftables[143]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "name", 1, &msgs[5], NULL, 4, 1, {0},&reftables[144], &reftables[145]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "name", 1, &msgs[9], NULL, 22, 6, {0},&reftables[146], &reftables[147]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "name", 1, &msgs[3], NULL, 8, 2, {0},&reftables[148], &reftables[149]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "name", 1, &msgs[16], NULL, 8, 2, {0},&reftables[150], &reftables[151]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "name", 1, &msgs[15], NULL, 2, 0, {0},&reftables[152], &reftables[153]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "name", 1, &msgs[13], NULL, 4, 1, {0},&reftables[154], &reftables[155]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "name", 1, &msgs[7], NULL, 4, 1, {0},&reftables[156], &reftables[157]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "name", 1, &msgs[0], NULL, 32, 8, {0},&reftables[158], &reftables[159]),
- UPB_FIELDDEF_INIT(UPB_LABEL_REQUIRED, UPB_TYPE_STRING, 0, false, false, false, false, "name_part", 1, &msgs[21], NULL, 2, 0, {0},&reftables[160], &reftables[161]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_INT64, UPB_INTFMT_VARIABLE, false, false, false, false, "negative_int_value", 5, &msgs[20], NULL, 10, 3, {0},&reftables[162], &reftables[163]),
- UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "nested_type", 3, &msgs[0], (const upb_def*)(&msgs[0]), 15, 1, {0},&reftables[164], &reftables[165]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "no_standard_descriptor_accessor", 2, &msgs[12], NULL, 7, 2, {0},&reftables[166], &reftables[167]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_INT32, UPB_INTFMT_VARIABLE, false, false, false, false, "number", 3, &msgs[7], NULL, 10, 3, {0},&reftables[168], &reftables[169]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_INT32, UPB_INTFMT_VARIABLE, false, false, false, false, "number", 2, &msgs[5], NULL, 7, 2, {0},&reftables[170], &reftables[171]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "objc_class_prefix", 36, &msgs[11], NULL, 24, 13, {0},&reftables[172], &reftables[173]),
- UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "oneof_decl", 8, &msgs[0], (const upb_def*)(&msgs[15]), 28, 6, {0},&reftables[174], &reftables[175]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_INT32, UPB_INTFMT_VARIABLE, false, false, false, false, "oneof_index", 9, &msgs[7], NULL, 19, 8, {0},&reftables[176], &reftables[177]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_ENUM, 0, false, false, false, false, "optimize_for", 9, &msgs[11], (const upb_def*)(&enums[4]), 12, 3, {0},&reftables[178], &reftables[179]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_MESSAGE, 0, false, false, false, false, "options", 7, &msgs[0], (const upb_def*)(&msgs[12]), 25, 5, {0},&reftables[180], &reftables[181]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_MESSAGE, 0, false, false, false, false, "options", 8, &msgs[9], (const upb_def*)(&msgs[11]), 20, 4, {0},&reftables[182], &reftables[183]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_MESSAGE, 0, false, false, false, false, "options", 8, &msgs[7], (const upb_def*)(&msgs[8]), 3, 0, {0},&reftables[184], &reftables[185]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_MESSAGE, 0, false, false, false, false, "options", 4, &msgs[13], (const upb_def*)(&msgs[14]), 3, 0, {0},&reftables[186], &reftables[187]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_MESSAGE, 0, false, false, false, false, "options", 3, &msgs[16], (const upb_def*)(&msgs[17]), 7, 1, {0},&reftables[188], &reftables[189]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_MESSAGE, 0, false, false, false, false, "options", 3, &msgs[3], (const upb_def*)(&msgs[4]), 7, 1, {0},&reftables[190], &reftables[191]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_MESSAGE, 0, false, false, false, false, "options", 3, &msgs[5], (const upb_def*)(&msgs[6]), 3, 0, {0},&reftables[192], &reftables[193]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "output_type", 3, &msgs[13], NULL, 10, 3, {0},&reftables[194], &reftables[195]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "package", 2, &msgs[9], NULL, 25, 7, {0},&reftables[196], &reftables[197]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "packed", 2, &msgs[8], NULL, 7, 2, {0},&reftables[198], &reftables[199]),
- UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_INT32, UPB_INTFMT_VARIABLE, false, false, false, true, "path", 1, &msgs[19], NULL, 4, 0, {0},&reftables[200], &reftables[201]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "php_class_prefix", 40, &msgs[11], NULL, 31, 16, {0},&reftables[202], &reftables[203]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "php_namespace", 41, &msgs[11], NULL, 34, 17, {0},&reftables[204], &reftables[205]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_UINT64, UPB_INTFMT_VARIABLE, false, false, false, false, "positive_int_value", 4, &msgs[20], NULL, 9, 2, {0},&reftables[206], &reftables[207]),
- UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_INT32, UPB_INTFMT_VARIABLE, false, false, false, false, "public_dependency", 10, &msgs[9], NULL, 35, 9, {0},&reftables[208], &reftables[209]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "py_generic_services", 18, &msgs[11], NULL, 19, 8, {0},&reftables[210], &reftables[211]),
- UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_STRING, 0, false, false, false, false, "reserved_name", 10, &msgs[0], NULL, 37, 9, {0},&reftables[212], &reftables[213]),
- UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "reserved_range", 9, &msgs[0], (const upb_def*)(&msgs[2]), 31, 7, {0},&reftables[214], &reftables[215]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "server_streaming", 6, &msgs[13], NULL, 14, 5, {0},&reftables[216], &reftables[217]),
- UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "service", 6, &msgs[9], (const upb_def*)(&msgs[16]), 16, 2, {0},&reftables[218], &reftables[219]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_MESSAGE, 0, false, false, false, false, "source_code_info", 9, &msgs[9], (const upb_def*)(&msgs[18]), 21, 5, {0},&reftables[220], &reftables[221]),
- UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_INT32, UPB_INTFMT_VARIABLE, false, false, false, true, "span", 2, &msgs[19], NULL, 7, 1, {0},&reftables[222], &reftables[223]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_INT32, UPB_INTFMT_VARIABLE, false, false, false, false, "start", 1, &msgs[2], NULL, 2, 0, {0},&reftables[224], &reftables[225]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_INT32, UPB_INTFMT_VARIABLE, false, false, false, false, "start", 1, &msgs[1], NULL, 2, 0, {0},&reftables[226], &reftables[227]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BYTES, 0, false, false, false, false, "string_value", 7, &msgs[20], NULL, 12, 5, {0},&reftables[228], &reftables[229]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "syntax", 12, &msgs[9], NULL, 39, 11, {0},&reftables[230], &reftables[231]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "trailing_comments", 4, &msgs[19], NULL, 11, 3, {0},&reftables[232], &reftables[233]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_ENUM, 0, false, false, false, false, "type", 5, &msgs[7], (const upb_def*)(&enums[1]), 12, 5, {0},&reftables[234], &reftables[235]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "type_name", 6, &msgs[7], NULL, 13, 6, {0},&reftables[236], &reftables[237]),
- UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "uninterpreted_option", 999, &msgs[12], (const upb_def*)(&msgs[20]), 5, 0, {0},&reftables[238], &reftables[239]),
- UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "uninterpreted_option", 999, &msgs[17], (const upb_def*)(&msgs[20]), 5, 0, {0},&reftables[240], &reftables[241]),
- UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "uninterpreted_option", 999, &msgs[11], (const upb_def*)(&msgs[20]), 5, 0, {0},&reftables[242], &reftables[243]),
- UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "uninterpreted_option", 999, &msgs[14], (const upb_def*)(&msgs[20]), 5, 0, {0},&reftables[244], &reftables[245]),
- UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "uninterpreted_option", 999, &msgs[8], (const upb_def*)(&msgs[20]), 5, 0, {0},&reftables[246], &reftables[247]),
- UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "uninterpreted_option", 999, &msgs[6], (const upb_def*)(&msgs[20]), 5, 0, {0},&reftables[248], &reftables[249]),
- UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "uninterpreted_option", 999, &msgs[4], (const upb_def*)(&msgs[20]), 5, 0, {0},&reftables[250], &reftables[251]),
- UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "value", 2, &msgs[3], (const upb_def*)(&msgs[5]), 6, 0, {0},&reftables[252], &reftables[253]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "weak", 10, &msgs[8], NULL, 11, 6, {0},&reftables[254], &reftables[255]),
- UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_INT32, UPB_INTFMT_VARIABLE, false, false, false, false, "weak_dependency", 11, &msgs[9], NULL, 38, 10, {0},&reftables[256], &reftables[257]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "aggregate_value", 8, &msgs[20], NULL, 16, 6, {0},&reftables[44], &reftables[45]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "allow_alias", 2, &msgs[4], NULL, 7, 1, {0},&reftables[46], &reftables[47]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "cc_enable_arenas", 31, &msgs[11], NULL, 24, 12, {0},&reftables[48], &reftables[49]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "cc_generic_services", 16, &msgs[11], NULL, 18, 6, {0},&reftables[50], &reftables[51]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "client_streaming", 5, &msgs[13], NULL, 14, 4, {0},&reftables[52], &reftables[53]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "csharp_namespace", 37, &msgs[11], NULL, 28, 14, {0},&reftables[54], &reftables[55]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_ENUM, 0, false, false, false, false, "ctype", 1, &msgs[8], (const upb_def*)(&enums[2]), 7, 1, {0},&reftables[56], &reftables[57]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "default_value", 7, &msgs[7], NULL, 17, 7, {0},&reftables[58], &reftables[59]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_STRING, 0, false, false, false, false, "dependency", 3, &msgs[9], NULL, 31, 8, {0},&reftables[60], &reftables[61]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "deprecated", 3, &msgs[8], NULL, 9, 3, {0},&reftables[62], &reftables[63]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "deprecated", 33, &msgs[14], NULL, 7, 1, {0},&reftables[64], &reftables[65]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "deprecated", 3, &msgs[12], NULL, 9, 3, {0},&reftables[66], &reftables[67]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "deprecated", 23, &msgs[11], NULL, 22, 10, {0},&reftables[68], &reftables[69]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "deprecated", 1, &msgs[6], NULL, 7, 1, {0},&reftables[70], &reftables[71]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "deprecated", 3, &msgs[4], NULL, 8, 2, {0},&reftables[72], &reftables[73]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "deprecated", 33, &msgs[17], NULL, 7, 1, {0},&reftables[74], &reftables[75]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_DOUBLE, 0, false, false, false, false, "double_value", 6, &msgs[20], NULL, 12, 4, {0},&reftables[76], &reftables[77]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_INT32, UPB_INTFMT_VARIABLE, false, false, false, false, "end", 2, &msgs[2], NULL, 4, 1, {0},&reftables[78], &reftables[79]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_INT32, UPB_INTFMT_VARIABLE, false, false, false, false, "end", 2, &msgs[1], NULL, 4, 1, {0},&reftables[80], &reftables[81]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "enum_type", 5, &msgs[9], (const upb_def*)(&msgs[3]), 14, 1, {0},&reftables[82], &reftables[83]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "enum_type", 4, &msgs[0], (const upb_def*)(&msgs[3]), 19, 2, {0},&reftables[84], &reftables[85]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "extendee", 2, &msgs[7], NULL, 8, 2, {0},&reftables[86], &reftables[87]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "extension", 6, &msgs[0], (const upb_def*)(&msgs[7]), 25, 4, {0},&reftables[88], &reftables[89]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "extension", 7, &msgs[9], (const upb_def*)(&msgs[7]), 20, 3, {0},&reftables[90], &reftables[91]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "extension_range", 5, &msgs[0], (const upb_def*)(&msgs[1]), 22, 3, {0},&reftables[92], &reftables[93]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "field", 2, &msgs[0], (const upb_def*)(&msgs[7]), 13, 0, {0},&reftables[94], &reftables[95]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "file", 1, &msgs[10], (const upb_def*)(&msgs[9]), 6, 0, {0},&reftables[96], &reftables[97]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "go_package", 11, &msgs[11], NULL, 15, 5, {0},&reftables[98], &reftables[99]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "identifier_value", 3, &msgs[20], NULL, 7, 1, {0},&reftables[100], &reftables[101]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "input_type", 2, &msgs[13], NULL, 8, 2, {0},&reftables[102], &reftables[103]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_REQUIRED, UPB_TYPE_BOOL, 0, false, false, false, false, "is_extension", 2, &msgs[21], NULL, 6, 1, {0},&reftables[104], &reftables[105]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "java_generate_equals_and_hash", 20, &msgs[11], NULL, 21, 9, {0},&reftables[106], &reftables[107]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "java_generic_services", 17, &msgs[11], NULL, 19, 7, {0},&reftables[108], &reftables[109]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "java_multiple_files", 10, &msgs[11], NULL, 14, 4, {0},&reftables[110], &reftables[111]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "java_outer_classname", 8, &msgs[11], NULL, 10, 2, {0},&reftables[112], &reftables[113]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "java_package", 1, &msgs[11], NULL, 7, 1, {0},&reftables[114], &reftables[115]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "java_string_check_utf8", 27, &msgs[11], NULL, 23, 11, {0},&reftables[116], &reftables[117]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "javanano_use_deprecated_package", 38, &msgs[11], NULL, 31, 15, {0},&reftables[118], &reftables[119]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "json_name", 10, &msgs[7], NULL, 21, 9, {0},&reftables[120], &reftables[121]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_ENUM, 0, false, false, false, false, "jstype", 6, &msgs[8], (const upb_def*)(&enums[3]), 11, 5, {0},&reftables[122], &reftables[123]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_ENUM, 0, false, false, false, false, "label", 4, &msgs[7], (const upb_def*)(&enums[0]), 12, 4, {0},&reftables[124], &reftables[125]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "lazy", 5, &msgs[8], NULL, 10, 4, {0},&reftables[126], &reftables[127]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "leading_comments", 3, &msgs[19], NULL, 9, 2, {0},&reftables[128], &reftables[129]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_STRING, 0, false, false, false, false, "leading_detached_comments", 6, &msgs[19], NULL, 17, 4, {0},&reftables[130], &reftables[131]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "location", 1, &msgs[18], (const upb_def*)(&msgs[19]), 6, 0, {0},&reftables[132], &reftables[133]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "map_entry", 7, &msgs[12], NULL, 10, 4, {0},&reftables[134], &reftables[135]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "message_set_wire_format", 1, &msgs[12], NULL, 7, 1, {0},&reftables[136], &reftables[137]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "message_type", 4, &msgs[9], (const upb_def*)(&msgs[0]), 11, 0, {0},&reftables[138], &reftables[139]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "method", 2, &msgs[16], (const upb_def*)(&msgs[13]), 7, 0, {0},&reftables[140], &reftables[141]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "name", 2, &msgs[20], (const upb_def*)(&msgs[21]), 6, 0, {0},&reftables[142], &reftables[143]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "name", 1, &msgs[5], NULL, 5, 1, {0},&reftables[144], &reftables[145]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "name", 1, &msgs[9], NULL, 23, 6, {0},&reftables[146], &reftables[147]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "name", 1, &msgs[3], NULL, 9, 2, {0},&reftables[148], &reftables[149]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "name", 1, &msgs[16], NULL, 9, 2, {0},&reftables[150], &reftables[151]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "name", 1, &msgs[15], NULL, 3, 0, {0},&reftables[152], &reftables[153]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "name", 1, &msgs[13], NULL, 5, 1, {0},&reftables[154], &reftables[155]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "name", 1, &msgs[7], NULL, 5, 1, {0},&reftables[156], &reftables[157]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "name", 1, &msgs[0], NULL, 33, 8, {0},&reftables[158], &reftables[159]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_REQUIRED, UPB_TYPE_STRING, 0, false, false, false, false, "name_part", 1, &msgs[21], NULL, 3, 0, {0},&reftables[160], &reftables[161]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_INT64, UPB_INTFMT_VARIABLE, false, false, false, false, "negative_int_value", 5, &msgs[20], NULL, 11, 3, {0},&reftables[162], &reftables[163]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "nested_type", 3, &msgs[0], (const upb_def*)(&msgs[0]), 16, 1, {0},&reftables[164], &reftables[165]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "no_standard_descriptor_accessor", 2, &msgs[12], NULL, 8, 2, {0},&reftables[166], &reftables[167]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_INT32, UPB_INTFMT_VARIABLE, false, false, false, false, "number", 3, &msgs[7], NULL, 11, 3, {0},&reftables[168], &reftables[169]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_INT32, UPB_INTFMT_VARIABLE, false, false, false, false, "number", 2, &msgs[5], NULL, 8, 2, {0},&reftables[170], &reftables[171]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "objc_class_prefix", 36, &msgs[11], NULL, 25, 13, {0},&reftables[172], &reftables[173]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "oneof_decl", 8, &msgs[0], (const upb_def*)(&msgs[15]), 29, 6, {0},&reftables[174], &reftables[175]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_INT32, UPB_INTFMT_VARIABLE, false, false, false, false, "oneof_index", 9, &msgs[7], NULL, 20, 8, {0},&reftables[176], &reftables[177]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_ENUM, 0, false, false, false, false, "optimize_for", 9, &msgs[11], (const upb_def*)(&enums[4]), 13, 3, {0},&reftables[178], &reftables[179]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_MESSAGE, 0, false, false, false, false, "options", 7, &msgs[0], (const upb_def*)(&msgs[12]), 26, 5, {0},&reftables[180], &reftables[181]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_MESSAGE, 0, false, false, false, false, "options", 8, &msgs[9], (const upb_def*)(&msgs[11]), 21, 4, {0},&reftables[182], &reftables[183]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_MESSAGE, 0, false, false, false, false, "options", 8, &msgs[7], (const upb_def*)(&msgs[8]), 4, 0, {0},&reftables[184], &reftables[185]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_MESSAGE, 0, false, false, false, false, "options", 4, &msgs[13], (const upb_def*)(&msgs[14]), 4, 0, {0},&reftables[186], &reftables[187]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_MESSAGE, 0, false, false, false, false, "options", 3, &msgs[16], (const upb_def*)(&msgs[17]), 8, 1, {0},&reftables[188], &reftables[189]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_MESSAGE, 0, false, false, false, false, "options", 3, &msgs[3], (const upb_def*)(&msgs[4]), 8, 1, {0},&reftables[190], &reftables[191]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_MESSAGE, 0, false, false, false, false, "options", 3, &msgs[5], (const upb_def*)(&msgs[6]), 4, 0, {0},&reftables[192], &reftables[193]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "output_type", 3, &msgs[13], NULL, 11, 3, {0},&reftables[194], &reftables[195]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "package", 2, &msgs[9], NULL, 26, 7, {0},&reftables[196], &reftables[197]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "packed", 2, &msgs[8], NULL, 8, 2, {0},&reftables[198], &reftables[199]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_INT32, UPB_INTFMT_VARIABLE, false, false, false, true, "path", 1, &msgs[19], NULL, 5, 0, {0},&reftables[200], &reftables[201]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "php_class_prefix", 40, &msgs[11], NULL, 32, 16, {0},&reftables[202], &reftables[203]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "php_namespace", 41, &msgs[11], NULL, 35, 17, {0},&reftables[204], &reftables[205]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_UINT64, UPB_INTFMT_VARIABLE, false, false, false, false, "positive_int_value", 4, &msgs[20], NULL, 10, 2, {0},&reftables[206], &reftables[207]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_INT32, UPB_INTFMT_VARIABLE, false, false, false, false, "public_dependency", 10, &msgs[9], NULL, 36, 9, {0},&reftables[208], &reftables[209]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "py_generic_services", 18, &msgs[11], NULL, 20, 8, {0},&reftables[210], &reftables[211]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_STRING, 0, false, false, false, false, "reserved_name", 10, &msgs[0], NULL, 38, 9, {0},&reftables[212], &reftables[213]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "reserved_range", 9, &msgs[0], (const upb_def*)(&msgs[2]), 32, 7, {0},&reftables[214], &reftables[215]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "server_streaming", 6, &msgs[13], NULL, 15, 5, {0},&reftables[216], &reftables[217]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "service", 6, &msgs[9], (const upb_def*)(&msgs[16]), 17, 2, {0},&reftables[218], &reftables[219]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_MESSAGE, 0, false, false, false, false, "source_code_info", 9, &msgs[9], (const upb_def*)(&msgs[18]), 22, 5, {0},&reftables[220], &reftables[221]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_INT32, UPB_INTFMT_VARIABLE, false, false, false, true, "span", 2, &msgs[19], NULL, 8, 1, {0},&reftables[222], &reftables[223]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_INT32, UPB_INTFMT_VARIABLE, false, false, false, false, "start", 1, &msgs[2], NULL, 3, 0, {0},&reftables[224], &reftables[225]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_INT32, UPB_INTFMT_VARIABLE, false, false, false, false, "start", 1, &msgs[1], NULL, 3, 0, {0},&reftables[226], &reftables[227]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BYTES, 0, false, false, false, false, "string_value", 7, &msgs[20], NULL, 13, 5, {0},&reftables[228], &reftables[229]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "syntax", 12, &msgs[9], NULL, 40, 11, {0},&reftables[230], &reftables[231]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "trailing_comments", 4, &msgs[19], NULL, 12, 3, {0},&reftables[232], &reftables[233]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_ENUM, 0, false, false, false, false, "type", 5, &msgs[7], (const upb_def*)(&enums[1]), 13, 5, {0},&reftables[234], &reftables[235]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "type_name", 6, &msgs[7], NULL, 14, 6, {0},&reftables[236], &reftables[237]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "uninterpreted_option", 999, &msgs[12], (const upb_def*)(&msgs[20]), 6, 0, {0},&reftables[238], &reftables[239]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "uninterpreted_option", 999, &msgs[17], (const upb_def*)(&msgs[20]), 6, 0, {0},&reftables[240], &reftables[241]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "uninterpreted_option", 999, &msgs[11], (const upb_def*)(&msgs[20]), 6, 0, {0},&reftables[242], &reftables[243]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "uninterpreted_option", 999, &msgs[14], (const upb_def*)(&msgs[20]), 6, 0, {0},&reftables[244], &reftables[245]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "uninterpreted_option", 999, &msgs[8], (const upb_def*)(&msgs[20]), 6, 0, {0},&reftables[246], &reftables[247]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "uninterpreted_option", 999, &msgs[6], (const upb_def*)(&msgs[20]), 6, 0, {0},&reftables[248], &reftables[249]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "uninterpreted_option", 999, &msgs[4], (const upb_def*)(&msgs[20]), 6, 0, {0},&reftables[250], &reftables[251]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "value", 2, &msgs[3], (const upb_def*)(&msgs[5]), 7, 0, {0},&reftables[252], &reftables[253]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "weak", 10, &msgs[8], NULL, 12, 6, {0},&reftables[254], &reftables[255]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_INT32, UPB_INTFMT_VARIABLE, false, false, false, false, "weak_dependency", 11, &msgs[9], NULL, 39, 10, {0},&reftables[256], &reftables[257]),
};
static const upb_enumdef enums[5] = {
@@ -7401,6 +8356,7 @@ typedef struct {
struct upb_descreader {
upb_sink sink;
upb_inttable files;
+ upb_strtable files_by_name;
upb_filedef *file; /* The last file in files. */
upb_descreader_frame stack[UPB_MAX_MESSAGE_NESTING];
int stack_len;
@@ -7567,6 +8523,7 @@ static size_t file_onname(void *closure, const void *hd, const char *buf,
UPB_UNUSED(handle);
name = upb_gstrndup(buf, n);
+ upb_strtable_insert(&r->files_by_name, name, upb_value_ptr(r->file));
/* XXX: see comment at the top of the file. */
ok = upb_filedef_setname(r->file, name, NULL);
upb_gfree(name);
@@ -7680,6 +8637,18 @@ static void *file_startext(void *closure, const void *hd) {
return r;
}
+static size_t file_ondep(void *closure, const void *hd, const char *buf,
+ size_t n, const upb_bufhandle *handle) {
+ upb_descreader *r = closure;
+ upb_value val;
+ if (upb_strtable_lookup2(&r->files_by_name, buf, n, &val)) {
+ upb_filedef_adddep(r->file, upb_value_getptr(val));
+ }
+ UPB_UNUSED(hd);
+ UPB_UNUSED(handle);
+ return n;
+}
+
/** Handlers for google.protobuf.EnumValueDescriptorProto. *********************/
static bool enumval_startmsg(void *closure, const void *hd) {
@@ -8124,6 +9093,8 @@ static void reghandlers(const void *closure, upb_handlers *h) {
&file_startenum, NULL);
upb_handlers_setstartsubmsg(h, F(FileDescriptorProto, extension),
&file_startext, NULL);
+ upb_handlers_setstring(h, F(FileDescriptorProto, dependency),
+ &file_ondep, NULL);
} else if (upbdefs_google_protobuf_EnumValueDescriptorProto_is(m)) {
upb_handlers_setstartmsg(h, &enumval_startmsg, NULL);
upb_handlers_setendmsg(h, &enumval_endmsg, NULL);
@@ -8183,6 +9154,7 @@ void descreader_cleanup(void *_r) {
upb_gfree(r->name);
upb_inttable_uninit(&r->files);
+ upb_strtable_uninit(&r->files_by_name);
upb_inttable_uninit(&r->oneofs);
upb_gfree(r->default_string);
while (r->stack_len > 0) {
@@ -8201,6 +9173,7 @@ upb_descreader *upb_descreader_create(upb_env *e, const upb_handlers *h) {
}
upb_inttable_init(&r->files, UPB_CTYPE_PTR);
+ upb_strtable_init(&r->files_by_name, UPB_CTYPE_PTR);
upb_inttable_init(&r->oneofs, UPB_CTYPE_PTR);
upb_sink_reset(upb_descreader_input(r), h, r);
r->stack_len = 0;
@@ -8500,7 +9473,7 @@ static void put32(compiler *c, uint32_t v) {
*c->pc++ = v;
}
-static void putop(compiler *c, opcode op, ...) {
+static void putop(compiler *c, int op, ...) {
va_list ap;
va_start(ap, op);
@@ -9783,7 +10756,6 @@ have_tag:
return upb_pbdecoder_suspend(d);
}
- /* TODO: deliver to unknown field callback. */
switch (wire_type) {
case UPB_WIRE_TYPE_32BIT:
CHECK_RETURN(skip(d, 4));
@@ -9821,6 +10793,8 @@ have_tag:
}
if (d->top->groupnum >= 0) {
+ /* TODO: More code needed for handling unknown groups. */
+ upb_sink_putunknown(&d->top->sink, d->checkpoint, d->ptr - d->checkpoint);
return DECODE_OK;
}
@@ -10676,6 +11650,12 @@ static void *encode_startdelimfield(void *c, const void *hd) {
return ok ? c : UPB_BREAK;
}
+static bool encode_unknown(void *c, const void *hd, const char *buf,
+ size_t len) {
+ UPB_UNUSED(hd);
+ return encode_bytes(c, buf, len) && commit(c);
+}
+
static bool encode_enddelimfield(void *c, const void *hd) {
UPB_UNUSED(hd);
return end_delim(c);
@@ -10738,6 +11718,7 @@ static void newhandlers_callback(const void *closure, upb_handlers *h) {
upb_handlers_setstartmsg(h, startmsg, NULL);
upb_handlers_setendmsg(h, endmsg, NULL);
+ upb_handlers_setunknown(h, encode_unknown, NULL);
m = upb_handlers_msgdef(h);
for(upb_msg_field_begin(&i, m);
@@ -11350,8 +12331,9 @@ done:
** - handling of keys/escape-sequences/etc that span input buffers.
*/
-#include <assert.h>
#include <errno.h>
+#include <float.h>
+#include <math.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
@@ -11936,103 +12918,160 @@ static void start_number(upb_json_parser *p, const char *ptr) {
capture_begin(p, ptr);
}
-static bool parse_number(upb_json_parser *p);
+static bool parse_number(upb_json_parser *p, bool is_quoted);
static bool end_number(upb_json_parser *p, const char *ptr) {
if (!capture_end(p, ptr)) {
return false;
}
- return parse_number(p);
+ return parse_number(p, false);
}
-static bool parse_number(upb_json_parser *p) {
- size_t len;
- const char *buf;
- const char *myend;
+/* |buf| is NULL-terminated. |buf| itself will never include quotes;
+ * |is_quoted| tells us whether this text originally appeared inside quotes. */
+static bool parse_number_from_buffer(upb_json_parser *p, const char *buf,
+ bool is_quoted) {
+ size_t len = strlen(buf);
+ const char *bufend = buf + len;
char *end;
+ upb_fieldtype_t type = upb_fielddef_type(p->top->f);
+ double val;
+ double dummy;
+ double inf = 1.0 / 0.0; /* C89 does not have an INFINITY macro. */
- /* strtol() and friends unfortunately do not support specifying the length of
- * the input string, so we need to force a copy into a NULL-terminated buffer. */
- if (!multipart_text(p, "\0", 1, false)) {
+ errno = 0;
+
+ if (len == 0 || buf[0] == ' ') {
return false;
}
- buf = accumulate_getptr(p, &len);
- myend = buf + len - 1; /* One for NULL. */
-
- /* XXX: We are using strtol to parse integers, but this is wrong as even
- * integers can be represented as 1e6 (for example), which strtol can't
- * handle correctly.
- *
- * XXX: Also, we can't handle large integers properly because strto[u]ll
- * isn't in C89.
- *
- * XXX: Also, we don't properly check floats for overflow, since strtof
- * isn't in C89. */
- switch (upb_fielddef_type(p->top->f)) {
+ /* For integer types, first try parsing with integer-specific routines.
+ * If these succeed, they will be more accurate for int64/uint64 than
+ * strtod().
+ */
+ switch (type) {
case UPB_TYPE_ENUM:
case UPB_TYPE_INT32: {
- long val = strtol(p->accumulated, &end, 0);
- if (val > INT32_MAX || val < INT32_MIN || errno == ERANGE || end != myend)
- goto err;
- else
+ long val = strtol(buf, &end, 0);
+ if (errno == ERANGE || end != bufend) {
+ break;
+ } else if (val > INT32_MAX || val < INT32_MIN) {
+ return false;
+ } else {
upb_sink_putint32(&p->top->sink, parser_getsel(p), val);
- break;
- }
- case UPB_TYPE_INT64: {
- long long val = strtol(p->accumulated, &end, 0);
- if (val > INT64_MAX || val < INT64_MIN || errno == ERANGE || end != myend)
- goto err;
- else
- upb_sink_putint64(&p->top->sink, parser_getsel(p), val);
- break;
+ return true;
+ }
}
case UPB_TYPE_UINT32: {
- unsigned long val = strtoul(p->accumulated, &end, 0);
- if (val > UINT32_MAX || errno == ERANGE || end != myend)
- goto err;
- else
+ unsigned long val = strtoul(buf, &end, 0);
+ if (end != bufend) {
+ break;
+ } else if (val > UINT32_MAX || errno == ERANGE) {
+ return false;
+ } else {
upb_sink_putuint32(&p->top->sink, parser_getsel(p), val);
- break;
+ return true;
+ }
+ }
+ /* XXX: We can't handle [u]int64 properly on 32-bit machines because
+ * strto[u]ll isn't in C89. */
+ case UPB_TYPE_INT64: {
+ long val = strtol(buf, &end, 0);
+ if (errno == ERANGE || end != bufend) {
+ break;
+ } else {
+ upb_sink_putint64(&p->top->sink, parser_getsel(p), val);
+ return true;
+ }
}
case UPB_TYPE_UINT64: {
- unsigned long long val = strtoul(p->accumulated, &end, 0);
- if (val > UINT64_MAX || errno == ERANGE || end != myend)
- goto err;
- else
+ unsigned long val = strtoul(p->accumulated, &end, 0);
+ if (end != bufend) {
+ break;
+ } else if (errno == ERANGE) {
+ return false;
+ } else {
upb_sink_putuint64(&p->top->sink, parser_getsel(p), val);
- break;
+ return true;
+ }
}
- case UPB_TYPE_DOUBLE: {
- double val = strtod(p->accumulated, &end);
- if (errno == ERANGE || end != myend)
- goto err;
- else
- upb_sink_putdouble(&p->top->sink, parser_getsel(p), val);
+ default:
break;
+ }
+
+ if (type != UPB_TYPE_DOUBLE && type != UPB_TYPE_FLOAT && is_quoted) {
+ /* Quoted numbers for integer types are not allowed to be in double form. */
+ return false;
+ }
+
+ if (len == strlen("Infinity") && strcmp(buf, "Infinity") == 0) {
+ /* C89 does not have an INFINITY macro. */
+ val = inf;
+ } else if (len == strlen("-Infinity") && strcmp(buf, "-Infinity") == 0) {
+ val = -inf;
+ } else {
+ val = strtod(buf, &end);
+ if (errno == ERANGE || end != bufend) {
+ return false;
}
- case UPB_TYPE_FLOAT: {
- float val = strtod(p->accumulated, &end);
- if (errno == ERANGE || end != myend)
- goto err;
- else
- upb_sink_putfloat(&p->top->sink, parser_getsel(p), val);
- break;
+ }
+
+ switch (type) {
+#define CASE(capitaltype, smalltype, ctype, min, max) \
+ case UPB_TYPE_ ## capitaltype: { \
+ if (modf(val, &dummy) != 0 || val > max || val < min) { \
+ return false; \
+ } else { \
+ upb_sink_put ## smalltype(&p->top->sink, parser_getsel(p), \
+ (ctype)val); \
+ return true; \
+ } \
+ break; \
}
+ case UPB_TYPE_ENUM:
+ CASE(INT32, int32, int32_t, INT32_MIN, INT32_MAX);
+ CASE(INT64, int64, int64_t, INT64_MIN, INT64_MAX);
+ CASE(UINT32, uint32, uint32_t, 0, UINT32_MAX);
+ CASE(UINT64, uint64, uint64_t, 0, UINT64_MAX);
+#undef CASE
+
+ case UPB_TYPE_DOUBLE:
+ upb_sink_putdouble(&p->top->sink, parser_getsel(p), val);
+ return true;
+ case UPB_TYPE_FLOAT:
+ if ((val > FLT_MAX || val < -FLT_MAX) && val != inf && val != -inf) {
+ return false;
+ } else {
+ upb_sink_putfloat(&p->top->sink, parser_getsel(p), val);
+ return true;
+ }
default:
- UPB_ASSERT(false);
+ return false;
}
+}
- multipart_end(p);
+static bool parse_number(upb_json_parser *p, bool is_quoted) {
+ size_t len;
+ const char *buf;
- return true;
+ /* strtol() and friends unfortunately do not support specifying the length of
+ * the input string, so we need to force a copy into a NULL-terminated buffer. */
+ if (!multipart_text(p, "\0", 1, false)) {
+ return false;
+ }
-err:
- upb_status_seterrf(&p->status, "error parsing number: %s", buf);
- upb_env_reporterror(p->env, &p->status);
- multipart_end(p);
- return false;
+ buf = accumulate_getptr(p, &len);
+
+ if (parse_number_from_buffer(p, buf, is_quoted)) {
+ multipart_end(p);
+ return true;
+ } else {
+ upb_status_seterrf(&p->status, "error parsing number: %s", buf);
+ upb_env_reporterror(p->env, &p->status);
+ multipart_end(p);
+ return false;
+ }
}
static bool parser_putbool(upb_json_parser *p, bool val) {
@@ -12085,17 +13124,16 @@ static bool start_stringval(upb_json_parser *p) {
multipart_startaccum(p);
return true;
}
- } else if (upb_fielddef_type(p->top->f) == UPB_TYPE_ENUM) {
- /* No need to push a frame -- symbolic enum names in quotes remain in the
- * current parser frame.
- *
- * Enum string values must accumulate so we can look up the value in a table
- * once it is complete. */
+ } else if (upb_fielddef_type(p->top->f) != UPB_TYPE_BOOL &&
+ upb_fielddef_type(p->top->f) != UPB_TYPE_MESSAGE) {
+ /* No need to push a frame -- numeric values in quotes remain in the
+ * current parser frame. These values must accmulate so we can convert
+ * them all at once at the end. */
multipart_startaccum(p);
return true;
} else {
upb_status_seterrf(&p->status,
- "String specified for non-string/non-enum field: %s",
+ "String specified for bool or submessage field: %s",
upb_fielddef_name(p->top->f));
upb_env_reporterror(p->env, &p->status);
return false;
@@ -12142,6 +13180,15 @@ static bool end_stringval(upb_json_parser *p) {
break;
}
+ case UPB_TYPE_INT32:
+ case UPB_TYPE_INT64:
+ case UPB_TYPE_UINT32:
+ case UPB_TYPE_UINT64:
+ case UPB_TYPE_DOUBLE:
+ case UPB_TYPE_FLOAT:
+ ok = parse_number(p, true);
+ break;
+
default:
UPB_ASSERT(false);
upb_status_seterrmsg(&p->status, "Internal error in JSON decoder");
@@ -12185,7 +13232,7 @@ static bool parse_mapentry_key(upb_json_parser *p) {
case UPB_TYPE_UINT32:
case UPB_TYPE_UINT64:
/* Invoke end_number. The accum buffer has the number's text already. */
- if (!parse_number(p)) {
+ if (!parse_number(p, true)) {
return false;
}
break;
@@ -12476,11 +13523,11 @@ static void end_object(upb_json_parser *p) {
* final state once, when the closing '"' is seen. */
-#line 1244 "upb/json/parser.rl"
+#line 1310 "upb/json/parser.rl"
-#line 1156 "upb/json/parser.c"
+#line 1222 "upb/json/parser.c"
static const char _json_actions[] = {
0, 1, 0, 1, 2, 1, 3, 1,
5, 1, 6, 1, 7, 1, 8, 1,
@@ -12629,7 +13676,7 @@ static const int json_en_value_machine = 27;
static const int json_en_main = 1;
-#line 1247 "upb/json/parser.rl"
+#line 1313 "upb/json/parser.rl"
size_t parse(void *closure, const void *hd, const char *buf, size_t size,
const upb_bufhandle *handle) {
@@ -12651,7 +13698,7 @@ size_t parse(void *closure, const void *hd, const char *buf, size_t size,
capture_resume(parser, buf);
-#line 1327 "upb/json/parser.c"
+#line 1393 "upb/json/parser.c"
{
int _klen;
unsigned int _trans;
@@ -12726,118 +13773,118 @@ _match:
switch ( *_acts++ )
{
case 0:
-#line 1159 "upb/json/parser.rl"
+#line 1225 "upb/json/parser.rl"
{ p--; {cs = stack[--top]; goto _again;} }
break;
case 1:
-#line 1160 "upb/json/parser.rl"
+#line 1226 "upb/json/parser.rl"
{ p--; {stack[top++] = cs; cs = 10; goto _again;} }
break;
case 2:
-#line 1164 "upb/json/parser.rl"
+#line 1230 "upb/json/parser.rl"
{ start_text(parser, p); }
break;
case 3:
-#line 1165 "upb/json/parser.rl"
+#line 1231 "upb/json/parser.rl"
{ CHECK_RETURN_TOP(end_text(parser, p)); }
break;
case 4:
-#line 1171 "upb/json/parser.rl"
+#line 1237 "upb/json/parser.rl"
{ start_hex(parser); }
break;
case 5:
-#line 1172 "upb/json/parser.rl"
+#line 1238 "upb/json/parser.rl"
{ hexdigit(parser, p); }
break;
case 6:
-#line 1173 "upb/json/parser.rl"
+#line 1239 "upb/json/parser.rl"
{ CHECK_RETURN_TOP(end_hex(parser)); }
break;
case 7:
-#line 1179 "upb/json/parser.rl"
+#line 1245 "upb/json/parser.rl"
{ CHECK_RETURN_TOP(escape(parser, p)); }
break;
case 8:
-#line 1185 "upb/json/parser.rl"
+#line 1251 "upb/json/parser.rl"
{ p--; {cs = stack[--top]; goto _again;} }
break;
case 9:
-#line 1188 "upb/json/parser.rl"
+#line 1254 "upb/json/parser.rl"
{ {stack[top++] = cs; cs = 19; goto _again;} }
break;
case 10:
-#line 1190 "upb/json/parser.rl"
+#line 1256 "upb/json/parser.rl"
{ p--; {stack[top++] = cs; cs = 27; goto _again;} }
break;
case 11:
-#line 1195 "upb/json/parser.rl"
+#line 1261 "upb/json/parser.rl"
{ start_member(parser); }
break;
case 12:
-#line 1196 "upb/json/parser.rl"
+#line 1262 "upb/json/parser.rl"
{ CHECK_RETURN_TOP(end_membername(parser)); }
break;
case 13:
-#line 1199 "upb/json/parser.rl"
+#line 1265 "upb/json/parser.rl"
{ end_member(parser); }
break;
case 14:
-#line 1205 "upb/json/parser.rl"
+#line 1271 "upb/json/parser.rl"
{ start_object(parser); }
break;
case 15:
-#line 1208 "upb/json/parser.rl"
+#line 1274 "upb/json/parser.rl"
{ end_object(parser); }
break;
case 16:
-#line 1214 "upb/json/parser.rl"
+#line 1280 "upb/json/parser.rl"
{ CHECK_RETURN_TOP(start_array(parser)); }
break;
case 17:
-#line 1218 "upb/json/parser.rl"
+#line 1284 "upb/json/parser.rl"
{ end_array(parser); }
break;
case 18:
-#line 1223 "upb/json/parser.rl"
+#line 1289 "upb/json/parser.rl"
{ start_number(parser, p); }
break;
case 19:
-#line 1224 "upb/json/parser.rl"
+#line 1290 "upb/json/parser.rl"
{ CHECK_RETURN_TOP(end_number(parser, p)); }
break;
case 20:
-#line 1226 "upb/json/parser.rl"
+#line 1292 "upb/json/parser.rl"
{ CHECK_RETURN_TOP(start_stringval(parser)); }
break;
case 21:
-#line 1227 "upb/json/parser.rl"
+#line 1293 "upb/json/parser.rl"
{ CHECK_RETURN_TOP(end_stringval(parser)); }
break;
case 22:
-#line 1229 "upb/json/parser.rl"
+#line 1295 "upb/json/parser.rl"
{ CHECK_RETURN_TOP(parser_putbool(parser, true)); }
break;
case 23:
-#line 1231 "upb/json/parser.rl"
+#line 1297 "upb/json/parser.rl"
{ CHECK_RETURN_TOP(parser_putbool(parser, false)); }
break;
case 24:
-#line 1233 "upb/json/parser.rl"
+#line 1299 "upb/json/parser.rl"
{ /* null value */ }
break;
case 25:
-#line 1235 "upb/json/parser.rl"
+#line 1301 "upb/json/parser.rl"
{ CHECK_RETURN_TOP(start_subobject(parser)); }
break;
case 26:
-#line 1236 "upb/json/parser.rl"
+#line 1302 "upb/json/parser.rl"
{ end_subobject(parser); }
break;
case 27:
-#line 1241 "upb/json/parser.rl"
+#line 1307 "upb/json/parser.rl"
{ p--; {cs = stack[--top]; goto _again;} }
break;
-#line 1513 "upb/json/parser.c"
+#line 1579 "upb/json/parser.c"
}
}
@@ -12850,7 +13897,7 @@ _again:
_out: {}
}
-#line 1268 "upb/json/parser.rl"
+#line 1334 "upb/json/parser.rl"
if (p != pe) {
upb_status_seterrf(&parser->status, "Parse error at '%.*s'\n", pe - p, p);
@@ -12891,13 +13938,13 @@ static void json_parser_reset(upb_json_parser *p) {
/* Emit Ragel initialization of the parser. */
-#line 1567 "upb/json/parser.c"
+#line 1633 "upb/json/parser.c"
{
cs = json_start;
top = 0;
}
-#line 1308 "upb/json/parser.rl"
+#line 1374 "upb/json/parser.rl"
p->current_state = cs;
p->parser_top = top;
accumulate_clear(p);
@@ -13194,10 +14241,23 @@ static void putstring(upb_json_printer *p, const char *buf, unsigned int len) {
* Right now we use %.8g and %.17g for float/double, respectively, to match
* proto2::util::JsonFormat's defaults. May want to change this later. */
+const char neginf[] = "\"-Infinity\"";
+const char inf[] = "\"Infinity\"";
+
static size_t fmt_double(double val, char* buf, size_t length) {
- size_t n = _upb_snprintf(buf, length, "%.17g", val);
- CHKLENGTH(n > 0 && n < length);
- return n;
+ if (val == (1.0 / 0.0)) {
+ CHKLENGTH(length >= strlen(inf));
+ strcpy(buf, inf);
+ return strlen(inf);
+ } else if (val == (-1.0 / 0.0)) {
+ CHKLENGTH(length >= strlen(neginf));
+ strcpy(buf, neginf);
+ return strlen(neginf);
+ } else {
+ size_t n = _upb_snprintf(buf, length, "%.17g", val);
+ CHKLENGTH(n > 0 && n < length);
+ return n;
+ }
}
static size_t fmt_float(float val, char* buf, size_t length) {
diff --git a/php/ext/google/protobuf/upb.h b/php/ext/google/protobuf/upb.h
index 4b51275d..10371e8b 100644
--- a/php/ext/google/protobuf/upb.h
+++ b/php/ext/google/protobuf/upb.h
@@ -1,66 +1,13 @@
// Amalgamated source file
/*
-** Defs are upb's internal representation of the constructs that can appear
-** in a .proto file:
-**
-** - upb::MessageDef (upb_msgdef): describes a "message" construct.
-** - upb::FieldDef (upb_fielddef): describes a message field.
-** - upb::FileDef (upb_filedef): describes a .proto file and its defs.
-** - upb::EnumDef (upb_enumdef): describes an enum.
-** - upb::OneofDef (upb_oneofdef): describes a oneof.
-** - upb::Def (upb_def): base class of all the others.
-**
-** TODO: definitions of services.
-**
-** Like upb_refcounted objects, defs are mutable only until frozen, and are
-** only thread-safe once frozen.
-**
-** This is a mixed C/C++ interface that offers a full API to both languages.
-** See the top-level README for more information.
-*/
-
-#ifndef UPB_DEF_H_
-#define UPB_DEF_H_
-
-/*
-** upb::RefCounted (upb_refcounted)
-**
-** A refcounting scheme that supports circular refs. It accomplishes this by
-** partitioning the set of objects into groups such that no cycle spans groups;
-** we can then reference-count the group as a whole and ignore refs within the
-** group. When objects are mutable, these groups are computed very
-** conservatively; we group any objects that have ever had a link between them.
-** When objects are frozen, we compute strongly-connected components which
-** allows us to be precise and only group objects that are actually cyclic.
+** This file contains shared definitions that are widely used across upb.
**
** This is a mixed C/C++ interface that offers a full API to both languages.
** See the top-level README for more information.
*/
-#ifndef UPB_REFCOUNTED_H_
-#define UPB_REFCOUNTED_H_
-
-/*
-** upb_table
-**
-** This header is INTERNAL-ONLY! Its interfaces are not public or stable!
-** This file defines very fast int->upb_value (inttable) and string->upb_value
-** (strtable) hash tables.
-**
-** The table uses chained scatter with Brent's variation (inspired by the Lua
-** implementation of hash tables). The hash function for strings is Austin
-** Appleby's "MurmurHash."
-**
-** The inttable uses uintptr_t as its key, which guarantees it can be used to
-** store pointers or integers of at least 32 bits (upb isn't really useful on
-** systems where sizeof(void*) < 4).
-**
-** The table must be homogenous (all values of the same type). In debug
-** mode, we check this on insert and lookup.
-*/
-
-#ifndef UPB_TABLE_H_
-#define UPB_TABLE_H_
+#ifndef UPB_H_
+#define UPB_H_
// php.h intentionally defined NDEBUG. We have to define this macro in order to
// be used together with php.h
@@ -68,18 +15,6 @@
#define NDEBUG
#endif
-#include <stdint.h>
-#include <string.h>
-/*
-** This file contains shared definitions that are widely used across upb.
-**
-** This is a mixed C/C++ interface that offers a full API to both languages.
-** See the top-level README for more information.
-*/
-
-#ifndef UPB_H_
-#define UPB_H_
-
#include <assert.h>
#include <stdarg.h>
#include <stdbool.h>
@@ -106,6 +41,9 @@ template <int N> class InlinedEnvironment;
#define UPB_INLINE static
#endif
+/* Hints to the compiler about likely/unlikely branches. */
+#define UPB_LIKELY(x) __builtin_expect((x),1)
+
/* Define UPB_BIG_ENDIAN manually if you're on big endian and your compiler
* doesn't provide these preprocessor symbols. */
#if defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)
@@ -367,6 +305,16 @@ class PointerBase2 : public PointerBase<T, Base> {
#endif
+/* A list of types as they are encoded on-the-wire. */
+typedef enum {
+ UPB_WIRE_TYPE_VARINT = 0,
+ UPB_WIRE_TYPE_64BIT = 1,
+ UPB_WIRE_TYPE_DELIMITED = 2,
+ UPB_WIRE_TYPE_START_GROUP = 3,
+ UPB_WIRE_TYPE_END_GROUP = 4,
+ UPB_WIRE_TYPE_32BIT = 5
+} upb_wiretype_t;
+
/* upb::ErrorSpace ************************************************************/
@@ -695,7 +643,7 @@ void upb_env_uninit(upb_env *e);
void upb_env_initonly(upb_env *e);
-upb_arena *upb_env_arena(upb_env *e);
+UPB_INLINE upb_arena *upb_env_arena(upb_env *e) { return (upb_arena*)e; }
bool upb_env_ok(const upb_env *e);
void upb_env_seterrorfunc(upb_env *e, upb_error_func *func, void *ud);
@@ -795,6 +743,106 @@ template <int N> class upb::InlinedEnvironment : public upb::Environment {
#endif /* UPB_H_ */
+/*
+** upb_decode: parsing into a upb_msg using a upb_msglayout.
+*/
+
+#ifndef UPB_DECODE_H_
+#define UPB_DECODE_H_
+
+/*
+** upb::Message is a representation for protobuf messages.
+**
+** However it differs from other common representations like
+** google::protobuf::Message in one key way: it does not prescribe any
+** ownership between messages and submessages, and it relies on the
+** client to delete each message/submessage/array/map at the appropriate
+** time.
+**
+** A client can access a upb::Message without knowing anything about
+** ownership semantics, but to create or mutate a message a user needs
+** to implement the memory management themselves.
+**
+** Currently all messages, arrays, and maps store a upb_alloc* internally.
+** Mutating operations use this when they require dynamically-allocated
+** memory. We could potentially eliminate this size overhead later by
+** letting the user flip a bit on the factory that prevents this from
+** being stored. The user would then need to use separate functions where
+** the upb_alloc* is passed explicitly. However for handlers to populate
+** such structures, they would need a place to store this upb_alloc* during
+** parsing; upb_handlers don't currently have a good way to accommodate this.
+**
+** TODO: UTF-8 checking?
+**/
+
+#ifndef UPB_MSG_H_
+#define UPB_MSG_H_
+
+/*
+** Defs are upb's internal representation of the constructs that can appear
+** in a .proto file:
+**
+** - upb::MessageDef (upb_msgdef): describes a "message" construct.
+** - upb::FieldDef (upb_fielddef): describes a message field.
+** - upb::FileDef (upb_filedef): describes a .proto file and its defs.
+** - upb::EnumDef (upb_enumdef): describes an enum.
+** - upb::OneofDef (upb_oneofdef): describes a oneof.
+** - upb::Def (upb_def): base class of all the others.
+**
+** TODO: definitions of services.
+**
+** Like upb_refcounted objects, defs are mutable only until frozen, and are
+** only thread-safe once frozen.
+**
+** This is a mixed C/C++ interface that offers a full API to both languages.
+** See the top-level README for more information.
+*/
+
+#ifndef UPB_DEF_H_
+#define UPB_DEF_H_
+
+/*
+** upb::RefCounted (upb_refcounted)
+**
+** A refcounting scheme that supports circular refs. It accomplishes this by
+** partitioning the set of objects into groups such that no cycle spans groups;
+** we can then reference-count the group as a whole and ignore refs within the
+** group. When objects are mutable, these groups are computed very
+** conservatively; we group any objects that have ever had a link between them.
+** When objects are frozen, we compute strongly-connected components which
+** allows us to be precise and only group objects that are actually cyclic.
+**
+** This is a mixed C/C++ interface that offers a full API to both languages.
+** See the top-level README for more information.
+*/
+
+#ifndef UPB_REFCOUNTED_H_
+#define UPB_REFCOUNTED_H_
+
+/*
+** upb_table
+**
+** This header is INTERNAL-ONLY! Its interfaces are not public or stable!
+** This file defines very fast int->upb_value (inttable) and string->upb_value
+** (strtable) hash tables.
+**
+** The table uses chained scatter with Brent's variation (inspired by the Lua
+** implementation of hash tables). The hash function for strings is Austin
+** Appleby's "MurmurHash."
+**
+** The inttable uses uintptr_t as its key, which guarantees it can be used to
+** store pointers or integers of at least 32 bits (upb isn't really useful on
+** systems where sizeof(void*) < 4).
+**
+** The table must be homogenous (all values of the same type). In debug
+** mode, we check this on insert and lookup.
+*/
+
+#ifndef UPB_TABLE_H_
+#define UPB_TABLE_H_
+
+#include <stdint.h>
+#include <string.h>
#ifdef __cplusplus
extern "C" {
@@ -3857,196 +3905,6 @@ inline bool FileDef::AddDependency(const FileDef* file) {
#endif /* UPB_DEF_H_ */
/*
-** This file contains definitions of structs that should be considered private
-** and NOT stable across versions of upb.
-**
-** The only reason they are declared here and not in .c files is to allow upb
-** and the application (if desired) to embed statically-initialized instances
-** of structures like defs.
-**
-** If you include this file, all guarantees of ABI compatibility go out the
-** window! Any code that includes this file needs to recompile against the
-** exact same version of upb that they are linking against.
-**
-** You also need to recompile if you change the value of the UPB_DEBUG_REFS
-** flag.
-*/
-
-
-#ifndef UPB_STATICINIT_H_
-#define UPB_STATICINIT_H_
-
-#ifdef __cplusplus
-/* Because of how we do our typedefs, this header can't be included from C++. */
-#error This file cannot be included from C++
-#endif
-
-/* upb_refcounted *************************************************************/
-
-
-/* upb_def ********************************************************************/
-
-struct upb_def {
- upb_refcounted base;
-
- const char *fullname;
- const upb_filedef* file;
- char type; /* A upb_deftype_t (char to save space) */
-
- /* Used as a flag during the def's mutable stage. Must be false unless
- * it is currently being used by a function on the stack. This allows
- * us to easily determine which defs were passed into the function's
- * current invocation. */
- bool came_from_user;
-};
-
-#define UPB_DEF_INIT(name, type, vtbl, refs, ref2s) \
- { UPB_REFCOUNT_INIT(vtbl, refs, ref2s), name, NULL, type, false }
-
-
-/* upb_fielddef ***************************************************************/
-
-struct upb_fielddef {
- upb_def base;
-
- union {
- int64_t sint;
- uint64_t uint;
- double dbl;
- float flt;
- void *bytes;
- } defaultval;
- union {
- const upb_msgdef *def; /* If !msg_is_symbolic. */
- char *name; /* If msg_is_symbolic. */
- } msg;
- union {
- const upb_def *def; /* If !subdef_is_symbolic. */
- char *name; /* If subdef_is_symbolic. */
- } sub; /* The msgdef or enumdef for this field, if upb_hassubdef(f). */
- bool subdef_is_symbolic;
- bool msg_is_symbolic;
- const upb_oneofdef *oneof;
- bool default_is_string;
- bool type_is_set_; /* False until type is explicitly set. */
- bool is_extension_;
- bool lazy_;
- bool packed_;
- upb_intfmt_t intfmt;
- bool tagdelim;
- upb_fieldtype_t type_;
- upb_label_t label_;
- uint32_t number_;
- uint32_t selector_base; /* Used to index into a upb::Handlers table. */
- uint32_t index_;
-};
-
-extern const struct upb_refcounted_vtbl upb_fielddef_vtbl;
-
-#define UPB_FIELDDEF_INIT(label, type, intfmt, tagdelim, is_extension, lazy, \
- packed, name, num, msgdef, subdef, selector_base, \
- index, defaultval, refs, ref2s) \
- { \
- UPB_DEF_INIT(name, UPB_DEF_FIELD, &upb_fielddef_vtbl, refs, ref2s), \
- defaultval, {msgdef}, {subdef}, NULL, false, false, \
- type == UPB_TYPE_STRING || type == UPB_TYPE_BYTES, true, is_extension, \
- lazy, packed, intfmt, tagdelim, type, label, num, selector_base, index \
- }
-
-
-/* upb_msgdef *****************************************************************/
-
-struct upb_msgdef {
- upb_def base;
-
- size_t selector_count;
- uint32_t submsg_field_count;
-
- /* Tables for looking up fields by number and name. */
- upb_inttable itof; /* int to field */
- upb_strtable ntof; /* name to field/oneof */
-
- /* Is this a map-entry message? */
- bool map_entry;
-
- /* Whether this message has proto2 or proto3 semantics. */
- upb_syntax_t syntax;
-
- /* TODO(haberman): proper extension ranges (there can be multiple). */
-};
-
-extern const struct upb_refcounted_vtbl upb_msgdef_vtbl;
-
-/* TODO: also support static initialization of the oneofs table. This will be
- * needed if we compile in descriptors that contain oneofs. */
-#define UPB_MSGDEF_INIT(name, selector_count, submsg_field_count, itof, ntof, \
- map_entry, syntax, refs, ref2s) \
- { \
- UPB_DEF_INIT(name, UPB_DEF_MSG, &upb_fielddef_vtbl, refs, ref2s), \
- selector_count, submsg_field_count, itof, ntof, map_entry, syntax \
- }
-
-
-/* upb_enumdef ****************************************************************/
-
-struct upb_enumdef {
- upb_def base;
-
- upb_strtable ntoi;
- upb_inttable iton;
- int32_t defaultval;
-};
-
-extern const struct upb_refcounted_vtbl upb_enumdef_vtbl;
-
-#define UPB_ENUMDEF_INIT(name, ntoi, iton, defaultval, refs, ref2s) \
- { UPB_DEF_INIT(name, UPB_DEF_ENUM, &upb_enumdef_vtbl, refs, ref2s), ntoi, \
- iton, defaultval }
-
-
-/* upb_oneofdef ***************************************************************/
-
-struct upb_oneofdef {
- upb_refcounted base;
-
- uint32_t index; /* Index within oneofs. */
- const char *name;
- upb_strtable ntof;
- upb_inttable itof;
- const upb_msgdef *parent;
-};
-
-extern const struct upb_refcounted_vtbl upb_oneofdef_vtbl;
-
-#define UPB_ONEOFDEF_INIT(name, ntof, itof, refs, ref2s) \
- { UPB_REFCOUNT_INIT(&upb_oneofdef_vtbl, refs, ref2s), 0, name, ntof, itof }
-
-
-/* upb_symtab *****************************************************************/
-
-struct upb_symtab {
- upb_refcounted base;
-
- upb_strtable symtab;
-};
-
-struct upb_filedef {
- upb_refcounted base;
-
- const char *name;
- const char *package;
- const char *phpprefix;
- const char *phpnamespace;
- upb_syntax_t syntax;
-
- upb_inttable defs;
- upb_inttable deps;
-};
-
-extern const struct upb_refcounted_vtbl upb_filedef_vtbl;
-
-#endif /* UPB_STATICINIT_H_ */
-/*
** upb::Handlers (upb_handlers)
**
** A upb_handlers is like a virtual table for a upb_msgdef. Each field of the
@@ -4150,7 +4008,8 @@ UPB_END_EXTERN_C
/* Static selectors for upb::Handlers. */
#define UPB_STARTMSG_SELECTOR 0
#define UPB_ENDMSG_SELECTOR 1
-#define UPB_STATIC_SELECTOR_COUNT 2
+#define UPB_UNKNOWN_SELECTOR 2
+#define UPB_STATIC_SELECTOR_COUNT 3
/* Static selectors for upb::BytesHandler. */
#define UPB_STARTSTR_SELECTOR 0
@@ -4679,6 +4538,8 @@ UPB_BEGIN_EXTERN_C
/* Native C API. */
/* Handler function typedefs. */
+typedef bool upb_unknown_handlerfunc(void *c, const void *hd, const char *buf,
+ size_t n);
typedef bool upb_startmsg_handlerfunc(void *c, const void*);
typedef bool upb_endmsg_handlerfunc(void *c, const void *, upb_status *status);
typedef void* upb_startfield_handlerfunc(void *c, const void *hd);
@@ -4732,6 +4593,8 @@ const upb_status *upb_handlers_status(upb_handlers *h);
void upb_handlers_clearerr(upb_handlers *h);
const upb_msgdef *upb_handlers_msgdef(const upb_handlers *h);
bool upb_handlers_addcleanup(upb_handlers *h, void *p, upb_handlerfree *hfree);
+bool upb_handlers_setunknown(upb_handlers *h, upb_unknown_handlerfunc *func,
+ upb_handlerattr *attr);
bool upb_handlers_setstartmsg(upb_handlers *h, upb_startmsg_handlerfunc *func,
upb_handlerattr *attr);
@@ -6301,6 +6164,18 @@ UPB_INLINE size_t upb_sink_putstring(upb_sink *s, upb_selector_t sel,
return handler(s->closure, hd, buf, n, handle);
}
+UPB_INLINE bool upb_sink_putunknown(upb_sink *s, const char *buf, size_t n) {
+ typedef upb_unknown_handlerfunc func;
+ func *handler;
+ const void *hd;
+ if (!s->handlers) return true;
+ handler = (func *)upb_handlers_gethandler(s->handlers, UPB_UNKNOWN_SELECTOR);
+
+ if (!handler) return n;
+ hd = upb_handlers_gethandlerdata(s->handlers, UPB_UNKNOWN_SELECTOR);
+ return handler(s->closure, hd, buf, n);
+}
+
UPB_INLINE bool upb_sink_startmsg(upb_sink *s) {
typedef upb_startmsg_handlerfunc func;
func *startmsg;
@@ -6505,34 +6380,6 @@ inline bool BufferSource::PutBuffer(const char *buf, size_t len,
#endif
#endif
-/*
-** upb::Message is a representation for protobuf messages.
-**
-** However it differs from other common representations like
-** google::protobuf::Message in one key way: it does not prescribe any
-** ownership between messages and submessages, and it relies on the
-** client to delete each message/submessage/array/map at the appropriate
-** time.
-**
-** A client can access a upb::Message without knowing anything about
-** ownership semantics, but to create or mutate a message a user needs
-** to implement the memory management themselves.
-**
-** Currently all messages, arrays, and maps store a upb_alloc* internally.
-** Mutating operations use this when they require dynamically-allocated
-** memory. We could potentially eliminate this size overhead later by
-** letting the user flip a bit on the factory that prevents this from
-** being stored. The user would then need to use separate functions where
-** the upb_alloc* is passed explicitly. However for handlers to populate
-** such structures, they would need a place to store this upb_alloc* during
-** parsing; upb_handlers don't currently have a good way to accommodate this.
-**
-** TODO: UTF-8 checking?
-**/
-
-#ifndef UPB_MSG_H_
-#define UPB_MSG_H_
-
#ifdef __cplusplus
@@ -6569,21 +6416,6 @@ typedef void upb_msg;
* instances of this from a upb_msgfactory, and the factory always owns the
* msglayout. */
-/* Gets the factory for this layout */
-upb_msgfactory *upb_msglayout_factory(const upb_msglayout *l);
-
-/* Get the msglayout for a submessage. This requires that this field is a
- * submessage, ie. upb_fielddef_issubmsg(upb_msglayout_msgdef(l)) == true.
- *
- * Since map entry messages don't have layouts, if upb_fielddef_ismap(f) == true
- * then this function will return the layout for the map's value. It requires
- * that the value type of the map field is a submessage. */
-const upb_msglayout *upb_msglayout_sublayout(const upb_msglayout *l,
- const upb_fielddef *f);
-
-/* Returns the msgdef for this msglayout. */
-const upb_msgdef *upb_msglayout_msgdef(const upb_msglayout *l);
-
/** upb_visitor ***************************************************************/
@@ -6629,6 +6461,23 @@ const upb_visitorplan *upb_msgfactory_getvisitorplan(upb_msgfactory *f,
const upb_handlers *h);
+/** upb_stringview ************************************************************/
+
+typedef struct {
+ const char *data;
+ size_t size;
+} upb_stringview;
+
+UPB_INLINE upb_stringview upb_stringview_make(const char *data, size_t size) {
+ upb_stringview ret;
+ ret.data = data;
+ ret.size = size;
+ return ret;
+}
+
+#define UPB_STRINGVIEW_INIT(ptr, len) {ptr, len}
+
+
/** upb_msgval ****************************************************************/
/* A union representing all possible protobuf values. Used for generic get/set
@@ -6646,10 +6495,7 @@ typedef union {
const upb_msg* msg;
const upb_array* arr;
const void* ptr;
- struct {
- const char *ptr;
- size_t len;
- } str;
+ upb_stringview str;
} upb_msgval;
#define ACCESSORS(name, membername, ctype) \
@@ -6676,22 +6522,12 @@ ACCESSORS(map, map, const upb_map*)
ACCESSORS(msg, msg, const upb_msg*)
ACCESSORS(ptr, ptr, const void*)
ACCESSORS(arr, arr, const upb_array*)
+ACCESSORS(str, str, upb_stringview)
#undef ACCESSORS
-UPB_INLINE upb_msgval upb_msgval_str(const char *ptr, size_t len) {
- upb_msgval ret;
- ret.str.ptr = ptr;
- ret.str.len = len;
- return ret;
-}
-
-UPB_INLINE const char* upb_msgval_getstr(upb_msgval val) {
- return val.str.ptr;
-}
-
-UPB_INLINE size_t upb_msgval_getstrlen(upb_msgval val) {
- return val.str.len;
+UPB_INLINE upb_msgval upb_msgval_makestr(const char *data, size_t size) {
+ return upb_msgval_str(upb_stringview_make(data, size));
}
@@ -6716,19 +6552,29 @@ size_t upb_msg_sizeof(const upb_msglayout *l);
* upb_msg_uninit() must be called to release internally-allocated memory
* unless the allocator is an arena that does not require freeing.
*
+ * Please note that upb_msg_init() may return a value that is different than
+ * |msg|, so you must assign the return value and not cast your memory block
+ * to upb_msg* directly!
+ *
* Please note that upb_msg_uninit() does *not* free any submessages, maps,
* or arrays referred to by this message's fields. You must free them manually
- * yourself. */
-void upb_msg_init(upb_msg *msg, const upb_msglayout *l, upb_alloc *a);
-void upb_msg_uninit(upb_msg *msg, const upb_msglayout *l);
+ * yourself.
+ *
+ * upb_msg_uninit returns the original memory block, which may be useful if
+ * you dynamically allocated it (though upb_msg_new() would normally be more
+ * appropriate in this case). */
+upb_msg *upb_msg_init(void *msg, const upb_msglayout *l, upb_alloc *a);
+void *upb_msg_uninit(upb_msg *msg, const upb_msglayout *l);
/* Like upb_msg_init() / upb_msg_uninit(), except the message's memory is
* allocated / freed from the given upb_alloc. */
upb_msg *upb_msg_new(const upb_msglayout *l, upb_alloc *a);
void upb_msg_free(upb_msg *msg, const upb_msglayout *l);
-/* Returns the upb_alloc for the given message. */
-upb_alloc *upb_msg_alloc(const upb_msg *msg, const upb_msglayout *l);
+/* Returns the upb_alloc for the given message.
+ * TODO(haberman): get rid of this? Not sure we want to be storing this
+ * for every message. */
+upb_alloc *upb_msg_alloc(const upb_msg *msg);
/* Packs the tree of messages rooted at "msg" into a single hunk of memory,
* allocated from the given allocator. */
@@ -6748,25 +6594,14 @@ void *upb_msg_pack(const upb_msg *msg, const upb_msglayout *l,
* arenas).
*/
upb_msgval upb_msg_get(const upb_msg *msg,
- const upb_fielddef *f,
+ int field_index,
const upb_msglayout *l);
/* May only be called for fields where upb_fielddef_haspresence(f) == true. */
bool upb_msg_has(const upb_msg *msg,
- const upb_fielddef *f,
+ int field_index,
const upb_msglayout *l);
-/* Returns NULL if no field in the oneof is set. */
-const upb_fielddef *upb_msg_getoneofcase(const upb_msg *msg,
- const upb_oneofdef *o,
- const upb_msglayout *l);
-
-/* Returns true if any field in the oneof is set. */
-bool upb_msg_hasoneof(const upb_msg *msg,
- const upb_oneofdef *o,
- const upb_msglayout *l);
-
-
/* Mutable message API. May only be called by the owner of the message who
* knows its ownership scheme and how to keep it consistent. */
@@ -6774,8 +6609,8 @@ bool upb_msg_hasoneof(const upb_msg *msg,
* management: if you overwrite a pointer to a msg/array/map/string without
* cleaning it up (or using an arena) it will leak.
*/
-bool upb_msg_set(upb_msg *msg,
- const upb_fielddef *f,
+void upb_msg_set(upb_msg *msg,
+ int field_index,
upb_msgval val,
const upb_msglayout *l);
@@ -6786,12 +6621,7 @@ bool upb_msg_set(upb_msg *msg,
* arrays/maps/strings/msgs that this field may have pointed to.
*/
bool upb_msg_clearfield(upb_msg *msg,
- const upb_fielddef *f,
- const upb_msglayout *l);
-
-/* Clears all fields in the oneof such that none of them are set. */
-bool upb_msg_clearoneof(upb_msg *msg,
- const upb_oneofdef *o,
+ int field_index,
const upb_msglayout *l);
/* TODO(haberman): copyfrom()/mergefrom()? */
@@ -6904,9 +6734,288 @@ bool upb_msg_getscalarhandlerdata(const upb_handlers *h,
size_t *offset,
int32_t *hasbit);
+
+/** Interfaces for generated code *********************************************/
+
+#define UPB_NOT_IN_ONEOF UINT16_MAX
+#define UPB_NO_HASBIT UINT16_MAX
+#define UPB_NO_SUBMSG UINT16_MAX
+
+typedef struct {
+ uint32_t number;
+ uint32_t offset; /* If in a oneof, offset of default in default_msg below. */
+ uint16_t hasbit; /* UPB_NO_HASBIT if no hasbit. */
+ uint16_t oneof_index; /* UPB_NOT_IN_ONEOF if not in a oneof. */
+ uint16_t submsg_index; /* UPB_NO_SUBMSG if no submsg. */
+ uint8_t type;
+ uint8_t label;
+} upb_msglayout_fieldinit_v1;
+
+typedef struct {
+ uint32_t data_offset;
+ uint32_t case_offset;
+} upb_msglayout_oneofinit_v1;
+
+typedef struct upb_msglayout_msginit_v1 {
+ const struct upb_msglayout_msginit_v1 *const* submsgs;
+ const upb_msglayout_fieldinit_v1 *fields;
+ const upb_msglayout_oneofinit_v1 *oneofs;
+ void *default_msg;
+ /* Must be aligned to sizeof(void*). Doesn't include internal members like
+ * unknown fields, extension dict, pointer to msglayout, etc. */
+ uint32_t size;
+ uint16_t field_count;
+ uint16_t oneof_count;
+ bool extendable;
+ bool is_proto2;
+} upb_msglayout_msginit_v1;
+
+#define UPB_ALIGN_UP_TO(val, align) ((val + (align - 1)) & -align)
+#define UPB_ALIGNED_SIZEOF(type) UPB_ALIGN_UP_TO(sizeof(type), sizeof(void*))
+
+/* Initialize/uninitialize a msglayout from a msginit. If upb uses v1
+ * internally, this will not allocate any memory. Should only be used by
+ * generated code. */
+upb_msglayout *upb_msglayout_frominit_v1(
+ const upb_msglayout_msginit_v1 *init, upb_alloc *a);
+void upb_msglayout_uninit_v1(upb_msglayout *layout, upb_alloc *a);
+
UPB_END_EXTERN_C
#endif /* UPB_MSG_H_ */
+
+UPB_BEGIN_EXTERN_C
+
+bool upb_decode(upb_stringview buf, void *msg,
+ const upb_msglayout_msginit_v1 *l, upb_env *env);
+
+UPB_END_EXTERN_C
+
+#endif /* UPB_DECODE_H_ */
+/*
+** structs.int.h: structures definitions that are internal to upb.
+*/
+
+#ifndef UPB_STRUCTS_H_
+#define UPB_STRUCTS_H_
+
+struct upb_array {
+ upb_fieldtype_t type;
+ uint8_t element_size;
+ void *data; /* Each element is element_size. */
+ size_t len; /* Measured in elements. */
+ size_t size; /* Measured in elements. */
+ upb_alloc *alloc;
+};
+
+#endif /* UPB_STRUCTS_H_ */
+
+/*
+** This file contains definitions of structs that should be considered private
+** and NOT stable across versions of upb.
+**
+** The only reason they are declared here and not in .c files is to allow upb
+** and the application (if desired) to embed statically-initialized instances
+** of structures like defs.
+**
+** If you include this file, all guarantees of ABI compatibility go out the
+** window! Any code that includes this file needs to recompile against the
+** exact same version of upb that they are linking against.
+**
+** You also need to recompile if you change the value of the UPB_DEBUG_REFS
+** flag.
+*/
+
+
+#ifndef UPB_STATICINIT_H_
+#define UPB_STATICINIT_H_
+
+#ifdef __cplusplus
+/* Because of how we do our typedefs, this header can't be included from C++. */
+#error This file cannot be included from C++
+#endif
+
+/* upb_refcounted *************************************************************/
+
+
+/* upb_def ********************************************************************/
+
+struct upb_def {
+ upb_refcounted base;
+
+ const char *fullname;
+ const upb_filedef* file;
+ char type; /* A upb_deftype_t (char to save space) */
+
+ /* Used as a flag during the def's mutable stage. Must be false unless
+ * it is currently being used by a function on the stack. This allows
+ * us to easily determine which defs were passed into the function's
+ * current invocation. */
+ bool came_from_user;
+};
+
+#define UPB_DEF_INIT(name, type, vtbl, refs, ref2s) \
+ { UPB_REFCOUNT_INIT(vtbl, refs, ref2s), name, NULL, type, false }
+
+
+/* upb_fielddef ***************************************************************/
+
+struct upb_fielddef {
+ upb_def base;
+
+ union {
+ int64_t sint;
+ uint64_t uint;
+ double dbl;
+ float flt;
+ void *bytes;
+ } defaultval;
+ union {
+ const upb_msgdef *def; /* If !msg_is_symbolic. */
+ char *name; /* If msg_is_symbolic. */
+ } msg;
+ union {
+ const upb_def *def; /* If !subdef_is_symbolic. */
+ char *name; /* If subdef_is_symbolic. */
+ } sub; /* The msgdef or enumdef for this field, if upb_hassubdef(f). */
+ bool subdef_is_symbolic;
+ bool msg_is_symbolic;
+ const upb_oneofdef *oneof;
+ bool default_is_string;
+ bool type_is_set_; /* False until type is explicitly set. */
+ bool is_extension_;
+ bool lazy_;
+ bool packed_;
+ upb_intfmt_t intfmt;
+ bool tagdelim;
+ upb_fieldtype_t type_;
+ upb_label_t label_;
+ uint32_t number_;
+ uint32_t selector_base; /* Used to index into a upb::Handlers table. */
+ uint32_t index_;
+};
+
+extern const struct upb_refcounted_vtbl upb_fielddef_vtbl;
+
+#define UPB_FIELDDEF_INIT(label, type, intfmt, tagdelim, is_extension, lazy, \
+ packed, name, num, msgdef, subdef, selector_base, \
+ index, defaultval, refs, ref2s) \
+ { \
+ UPB_DEF_INIT(name, UPB_DEF_FIELD, &upb_fielddef_vtbl, refs, ref2s), \
+ defaultval, {msgdef}, {subdef}, NULL, false, false, \
+ type == UPB_TYPE_STRING || type == UPB_TYPE_BYTES, true, is_extension, \
+ lazy, packed, intfmt, tagdelim, type, label, num, selector_base, index \
+ }
+
+
+/* upb_msgdef *****************************************************************/
+
+struct upb_msgdef {
+ upb_def base;
+
+ size_t selector_count;
+ uint32_t submsg_field_count;
+
+ /* Tables for looking up fields by number and name. */
+ upb_inttable itof; /* int to field */
+ upb_strtable ntof; /* name to field/oneof */
+
+ /* Is this a map-entry message? */
+ bool map_entry;
+
+ /* Whether this message has proto2 or proto3 semantics. */
+ upb_syntax_t syntax;
+
+ /* TODO(haberman): proper extension ranges (there can be multiple). */
+};
+
+extern const struct upb_refcounted_vtbl upb_msgdef_vtbl;
+
+/* TODO: also support static initialization of the oneofs table. This will be
+ * needed if we compile in descriptors that contain oneofs. */
+#define UPB_MSGDEF_INIT(name, selector_count, submsg_field_count, itof, ntof, \
+ map_entry, syntax, refs, ref2s) \
+ { \
+ UPB_DEF_INIT(name, UPB_DEF_MSG, &upb_fielddef_vtbl, refs, ref2s), \
+ selector_count, submsg_field_count, itof, ntof, map_entry, syntax \
+ }
+
+
+/* upb_enumdef ****************************************************************/
+
+struct upb_enumdef {
+ upb_def base;
+
+ upb_strtable ntoi;
+ upb_inttable iton;
+ int32_t defaultval;
+};
+
+extern const struct upb_refcounted_vtbl upb_enumdef_vtbl;
+
+#define UPB_ENUMDEF_INIT(name, ntoi, iton, defaultval, refs, ref2s) \
+ { UPB_DEF_INIT(name, UPB_DEF_ENUM, &upb_enumdef_vtbl, refs, ref2s), ntoi, \
+ iton, defaultval }
+
+
+/* upb_oneofdef ***************************************************************/
+
+struct upb_oneofdef {
+ upb_refcounted base;
+
+ uint32_t index; /* Index within oneofs. */
+ const char *name;
+ upb_strtable ntof;
+ upb_inttable itof;
+ const upb_msgdef *parent;
+};
+
+extern const struct upb_refcounted_vtbl upb_oneofdef_vtbl;
+
+#define UPB_ONEOFDEF_INIT(name, ntof, itof, refs, ref2s) \
+ { UPB_REFCOUNT_INIT(&upb_oneofdef_vtbl, refs, ref2s), 0, name, ntof, itof }
+
+
+/* upb_symtab *****************************************************************/
+
+struct upb_symtab {
+ upb_refcounted base;
+
+ upb_strtable symtab;
+};
+
+struct upb_filedef {
+ upb_refcounted base;
+
+ const char *name;
+ const char *package;
+ const char *phpprefix;
+ const char *phpnamespace;
+ upb_syntax_t syntax;
+
+ upb_inttable defs;
+ upb_inttable deps;
+};
+
+extern const struct upb_refcounted_vtbl upb_filedef_vtbl;
+
+#endif /* UPB_STATICINIT_H_ */
+/*
+** upb_encode: parsing into a upb_msg using a upb_msglayout.
+*/
+
+#ifndef UPB_ENCODE_H_
+#define UPB_ENCODE_H_
+
+
+UPB_BEGIN_EXTERN_C
+
+char *upb_encode(const void *msg, const upb_msglayout_msginit_v1 *l,
+ upb_env *env, size_t *size);
+
+UPB_END_EXTERN_C
+
+#endif /* UPB_ENCODE_H_ */
/*
** upb::descriptor::Reader (upb_descreader)
**
@@ -8296,21 +8405,9 @@ UPB_INLINE void upb_pbdecoder_unpackdispatch(uint64_t dispatch, uint64_t *ofs,
extern "C" {
#endif
-/* A list of types as they are encoded on-the-wire. */
-typedef enum {
- UPB_WIRE_TYPE_VARINT = 0,
- UPB_WIRE_TYPE_64BIT = 1,
- UPB_WIRE_TYPE_DELIMITED = 2,
- UPB_WIRE_TYPE_START_GROUP = 3,
- UPB_WIRE_TYPE_END_GROUP = 4,
- UPB_WIRE_TYPE_32BIT = 5
-} upb_wiretype_t;
-
#define UPB_MAX_WIRE_TYPE 5
-/* The maximum number of bytes that it takes to encode a 64-bit varint.
- * Note that with a better encoding this could be 9 (TODO: write up a
- * wiki document about this). */
+/* The maximum number of bytes that it takes to encode a 64-bit varint. */
#define UPB_PB_VARINT_MAX_LEN 10
/* Array of the "native" (ie. non-packed-repeated) wire type for the given a
diff --git a/php/src/Google/Protobuf/Internal/CodedInputStream.php b/php/src/Google/Protobuf/Internal/CodedInputStream.php
index 6131d5d1..b612da5b 100644
--- a/php/src/Google/Protobuf/Internal/CodedInputStream.php
+++ b/php/src/Google/Protobuf/Internal/CodedInputStream.php
@@ -78,13 +78,18 @@ class CodedInputStream
return $this->buffer_end - $this->current;
}
- private function current()
+ public function current()
{
return $this->total_bytes_read -
($this->buffer_end - $this->current +
$this->buffer_size_after_limit);
}
+ public function substr($start, $end)
+ {
+ return substr($this->buffer, $start, $end - $start);
+ }
+
private function recomputeBufferLimits()
{
$this->buffer_end += $this->buffer_size_after_limit;
diff --git a/php/src/Google/Protobuf/Internal/CodedOutputStream.php b/php/src/Google/Protobuf/Internal/CodedOutputStream.php
index 4525d8dd..f75e9c66 100644
--- a/php/src/Google/Protobuf/Internal/CodedOutputStream.php
+++ b/php/src/Google/Protobuf/Internal/CodedOutputStream.php
@@ -101,7 +101,7 @@ class CodedOutputStream
return true;
}
- private static function writeVarintToArray($value, &$buffer, $trim = false)
+ public static function writeVarintToArray($value, &$buffer, $trim = false)
{
$current = 0;
diff --git a/php/src/Google/Protobuf/Internal/Message.php b/php/src/Google/Protobuf/Internal/Message.php
index c0a3218b..b3c4e6f1 100644
--- a/php/src/Google/Protobuf/Internal/Message.php
+++ b/php/src/Google/Protobuf/Internal/Message.php
@@ -57,6 +57,7 @@ class Message
* @ignore
*/
private $desc;
+ private $unknown = "";
/**
* @ignore
@@ -226,13 +227,14 @@ class Message
/**
* @ignore
*/
- private static function skipField($input, $tag)
+ private function skipField($input, $tag)
{
$number = GPBWire::getTagFieldNumber($tag);
if ($number === 0) {
throw new GPBDecodeException("Illegal field number zero.");
}
+ $start = $input->current();
switch (GPBWire::getTagWireType($tag)) {
case GPBWireType::VARINT:
$uint64 = 0;
@@ -240,21 +242,21 @@ class Message
throw new GPBDecodeException(
"Unexpected EOF inside varint.");
}
- return;
+ break;
case GPBWireType::FIXED64:
$uint64 = 0;
if (!$input->readLittleEndian64($uint64)) {
throw new GPBDecodeException(
"Unexpected EOF inside fixed64.");
}
- return;
+ break;
case GPBWireType::FIXED32:
$uint32 = 0;
if (!$input->readLittleEndian32($uint32)) {
throw new GPBDecodeException(
"Unexpected EOF inside fixed32.");
}
- return;
+ break;
case GPBWireType::LENGTH_DELIMITED:
$length = 0;
if (!$input->readVarint32($length)) {
@@ -266,13 +268,18 @@ class Message
throw new GPBDecodeException(
"Unexpected EOF inside length delimited data.");
}
- return;
+ break;
case GPBWireType::START_GROUP:
case GPBWireType::END_GROUP:
throw new GPBDecodeException("Unexpected wire type.");
default:
throw new GPBDecodeException("Unexpected wire type.");
}
+ $end = $input->current();
+
+ $bytes = str_repeat(chr(0), CodedOutputStream::MAX_VARINT64_BYTES);
+ $size = CodedOutputStream::writeVarintToArray($tag, $bytes, true);
+ $this->unknown .= substr($bytes, 0, $size) . $input->substr($start, $end);
}
/**
@@ -423,7 +430,7 @@ class Message
}
if ($value_format === GPBWire::UNKNOWN) {
- self::skipField($input, $tag);
+ $this->skipField($input, $tag);
return;
} elseif ($value_format === GPBWire::NORMAL_FORMAT) {
self::parseFieldFromStreamNoTag($input, $field, $value);
@@ -461,6 +468,7 @@ class Message
*/
public function clear()
{
+ $this->unknown = "";
foreach ($this->desc->getField() as $field) {
$setter = $field->getSetter();
if ($field->isMap()) {
@@ -1043,6 +1051,7 @@ class Message
return false;
}
}
+ $output->writeRaw($this->unknown, strlen($this->unknown));
return true;
}
@@ -1428,6 +1437,7 @@ class Message
foreach ($fields as $field) {
$size += $this->fieldByteSize($field);
}
+ $size += strlen($this->unknown);
return $size;
}
diff --git a/php/tests/encode_decode_test.php b/php/tests/encode_decode_test.php
index b43dffb4..4dca922b 100644
--- a/php/tests/encode_decode_test.php
+++ b/php/tests/encode_decode_test.php
@@ -441,6 +441,33 @@ class EncodeDecodeTest extends TestBase
$m->mergeFromString(hex2bin('D205'));
}
+ public function testUnknown()
+ {
+ $m = new TestMessage();
+ $from = hex2bin('F80601');
+ $m->mergeFromString($from);
+ $to = $m->serializeToString();
+ $this->assertSame(bin2hex($from), bin2hex($to));
+
+ $m = new TestMessage();
+ $from = hex2bin('F9060000000000000000');
+ $m->mergeFromString($from);
+ $to = $m->serializeToString();
+ $this->assertSame(bin2hex($from), bin2hex($to));
+
+ $m = new TestMessage();
+ $from = hex2bin('FA0600');
+ $m->mergeFromString($from);
+ $to = $m->serializeToString();
+ $this->assertSame(bin2hex($from), bin2hex($to));
+
+ $m = new TestMessage();
+ $from = hex2bin('FD0600000000');
+ $m->mergeFromString($from);
+ $to = $m->serializeToString();
+ $this->assertSame(bin2hex($from), bin2hex($to));
+ }
+
public function testJsonEncode()
{
$from = new TestMessage();
diff --git a/php/tests/gdb_test.sh b/php/tests/gdb_test.sh
index 0809bef3..484e2edf 100755
--- a/php/tests/gdb_test.sh
+++ b/php/tests/gdb_test.sh
@@ -3,7 +3,7 @@
# gdb --args php -dextension=../ext/google/protobuf/modules/protobuf.so `which
# phpunit` --bootstrap autoload.php tmp_test.php
#
-gdb --args php -dextension=../ext/google/protobuf/modules/protobuf.so `which phpunit` --bootstrap autoload.php well_known_test.php
+gdb --args php -dextension=../ext/google/protobuf/modules/protobuf.so `which phpunit` --bootstrap autoload.php encode_decode_test.php
#
# gdb --args php -dextension=../ext/google/protobuf/modules/protobuf.so memory_leak_test.php
#
diff --git a/php/tests/memory_leak_test.php b/php/tests/memory_leak_test.php
index 7c3a1801..b76c8bff 100644
--- a/php/tests/memory_leak_test.php
+++ b/php/tests/memory_leak_test.php
@@ -101,6 +101,10 @@ $n = new TestMessage();
$n->mergeFromString($data);
assert(1 === $n->getOneofMessage()->getA());
+$m = new TestMessage();
+$m->mergeFromString(hex2bin('F80601'));
+assert('F80601', bin2hex($m->serializeToString()));
+
# $from = new TestMessage();
# $to = new TestMessage();
# TestUtil::setTestMessage($from);
diff --git a/php/tests/proto/test.proto b/php/tests/proto/test.proto
index 56cba446..d0109d83 100644
--- a/php/tests/proto/test.proto
+++ b/php/tests/proto/test.proto
@@ -115,6 +115,8 @@ message TestMessage {
message Empty {
int32 a = 1;
}
+
+ reserved 111;
}
enum TestEnum {