diff --git a/php/ext/google/protobuf/map.c b/php/ext/google/protobuf/map.c index 1878a0ae6779..2dded9224e1c 100644 --- a/php/ext/google/protobuf/map.c +++ b/php/ext/google/protobuf/map.c @@ -516,8 +516,8 @@ bool map_done(MapIter *iter) { } const char *map_iter_key(MapIter *iter, int *len) { - *len = upb_strtable_iter_keylength(&iter->it); - return upb_strtable_iter_key(&iter->it); + *len = upb_strtable_iter_key(&iter->it).size; + return upb_strtable_iter_key(&iter->it).data; } upb_value map_iter_value(MapIter *iter, int *len) { diff --git a/php/ext/google/protobuf/upb.c b/php/ext/google/protobuf/upb.c index 7608fe727c8f..cf27432f03da 100644 --- a/php/ext/google/protobuf/upb.c +++ b/php/ext/google/protobuf/upb.c @@ -22,9 +22,8 @@ * * This file is private and must not be included by users! */ -#ifndef UINTPTR_MAX -#error must include stdint.h first -#endif +#include +#include #if UINTPTR_MAX == 0xffffffff #define UPB_SIZE(size32, size64) size32 @@ -32,17 +31,21 @@ #define UPB_SIZE(size32, size64) size64 #endif -#define UPB_FIELD_AT(msg, fieldtype, offset) \ - *(fieldtype*)((const char*)(msg) + offset) +/* If we always read/write as a consistent type to each address, this shouldn't + * violate aliasing. + */ +#define UPB_PTR_AT(msg, ofs, type) ((type*)((char*)(msg) + (ofs))) #define UPB_READ_ONEOF(msg, fieldtype, offset, case_offset, case_val, default) \ - UPB_FIELD_AT(msg, int, case_offset) == case_val \ - ? UPB_FIELD_AT(msg, fieldtype, offset) \ + *UPB_PTR_AT(msg, case_offset, int) == case_val \ + ? *UPB_PTR_AT(msg, offset, fieldtype) \ : default #define UPB_WRITE_ONEOF(msg, fieldtype, offset, value, case_offset, case_val) \ - UPB_FIELD_AT(msg, int, case_offset) = case_val; \ - UPB_FIELD_AT(msg, fieldtype, offset) = value; + *UPB_PTR_AT(msg, case_offset, int) = case_val; \ + *UPB_PTR_AT(msg, offset, fieldtype) = value; + +#define UPB_MAPTYPE_STRING 0 /* UPB_INLINE: inline if possible, emit standalone code if required. */ #ifdef __cplusplus @@ -53,6 +56,11 @@ #define UPB_INLINE static #endif +#define UPB_ALIGN_UP(size, align) (((size) + (align) - 1) / (align) * (align)) +#define UPB_ALIGN_DOWN(size, align) ((size) / (align) * (align)) +#define UPB_ALIGN_MALLOC(size) UPB_ALIGN_UP(size, 16) +#define UPB_ALIGN_OF(type) offsetof (struct { char c; type member; }, member) + /* Hints to the compiler about likely/unlikely branches. */ #if defined (__GNUC__) || defined(__clang__) #define UPB_LIKELY(x) __builtin_expect((x),1) @@ -127,6 +135,18 @@ int msvc_vsnprintf(char* s, size_t n, const char* format, va_list arg); #define UPB_UNUSED(var) (void)var +/* UPB_ASSUME(): in release mode, we tell the compiler to assume this is true. + */ +#ifdef NDEBUG +#ifdef __GNUC__ +#define UPB_ASSUME(expr) if (!(expr)) __builtin_unreachable() +#else +#define UPB_ASSUME(expr) do {} if (false && (expr)) +#endif +#else +#define UPB_ASSUME(expr) assert(expr) +#endif + /* UPB_ASSERT(): in release mode, we use the expression without letting it be * evaluated. This prevents "unused variable" warnings. */ #ifdef NDEBUG @@ -153,607 +173,572 @@ int msvc_vsnprintf(char* s, size_t n, const char* format, va_list arg); #define UPB_INFINITY (1.0 / 0.0) #endif +#include #include + /* Maps descriptor type -> upb field type. */ -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 */ +static const uint8_t desctype_to_fieldtype[] = { + -1, /* invalid descriptor type */ + 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 */ +}; + +/* Maps descriptor type -> upb map size. */ +static const uint8_t desctype_to_mapsize[] = { + -1, /* invalid descriptor type */ + 8, /* DOUBLE */ + 4, /* FLOAT */ + 8, /* INT64 */ + 8, /* UINT64 */ + 4, /* INT32 */ + 8, /* FIXED64 */ + 4, /* FIXED32 */ + 1, /* BOOL */ + UPB_MAPTYPE_STRING, /* STRING */ + sizeof(void *), /* GROUP */ + sizeof(void *), /* MESSAGE */ + UPB_MAPTYPE_STRING, /* BYTES */ + 4, /* UINT32 */ + 4, /* ENUM */ + 4, /* SFIXED32 */ + 8, /* SFIXED64 */ + 4, /* SINT32 */ + 8, /* SINT64 */ +}; + +static const unsigned fixed32_ok = (1 << UPB_DTYPE_FLOAT) | + (1 << UPB_DTYPE_FIXED32) | + (1 << UPB_DTYPE_SFIXED32); + +static const unsigned fixed64_ok = (1 << UPB_DTYPE_DOUBLE) | + (1 << UPB_DTYPE_FIXED64) | + (1 << UPB_DTYPE_SFIXED64); + +/* Op: an action to be performed for a wire-type/field-type combination. */ +#define OP_SCALAR_LG2(n) (n) +#define OP_FIXPCK_LG2(n) (n + 4) +#define OP_VARPCK_LG2(n) (n + 8) +#define OP_STRING 4 +#define OP_SUBMSG 5 + +static const int8_t varint_ops[19] = { + -1, /* field not found */ + -1, /* DOUBLE */ + -1, /* FLOAT */ + OP_SCALAR_LG2(3), /* INT64 */ + OP_SCALAR_LG2(3), /* UINT64 */ + OP_SCALAR_LG2(2), /* INT32 */ + -1, /* FIXED64 */ + -1, /* FIXED32 */ + OP_SCALAR_LG2(0), /* BOOL */ + -1, /* STRING */ + -1, /* GROUP */ + -1, /* MESSAGE */ + -1, /* BYTES */ + OP_SCALAR_LG2(2), /* UINT32 */ + OP_SCALAR_LG2(2), /* ENUM */ + -1, /* SFIXED32 */ + -1, /* SFIXED64 */ + OP_SCALAR_LG2(2), /* SINT32 */ + OP_SCALAR_LG2(3), /* SINT64 */ +}; + +static const int8_t delim_ops[37] = { + /* For non-repeated field type. */ + -1, /* field not found */ + -1, /* DOUBLE */ + -1, /* FLOAT */ + -1, /* INT64 */ + -1, /* UINT64 */ + -1, /* INT32 */ + -1, /* FIXED64 */ + -1, /* FIXED32 */ + -1, /* BOOL */ + OP_STRING, /* STRING */ + -1, /* GROUP */ + OP_SUBMSG, /* MESSAGE */ + OP_STRING, /* BYTES */ + -1, /* UINT32 */ + -1, /* ENUM */ + -1, /* SFIXED32 */ + -1, /* SFIXED64 */ + -1, /* SINT32 */ + -1, /* SINT64 */ + /* For repeated field type. */ + OP_FIXPCK_LG2(3), /* REPEATED DOUBLE */ + OP_FIXPCK_LG2(2), /* REPEATED FLOAT */ + OP_VARPCK_LG2(3), /* REPEATED INT64 */ + OP_VARPCK_LG2(3), /* REPEATED UINT64 */ + OP_VARPCK_LG2(2), /* REPEATED INT32 */ + OP_FIXPCK_LG2(3), /* REPEATED FIXED64 */ + OP_FIXPCK_LG2(2), /* REPEATED FIXED32 */ + OP_VARPCK_LG2(0), /* REPEATED BOOL */ + OP_STRING, /* REPEATED STRING */ + OP_SUBMSG, /* REPEATED GROUP */ + OP_SUBMSG, /* REPEATED MESSAGE */ + OP_STRING, /* REPEATED BYTES */ + OP_VARPCK_LG2(2), /* REPEATED UINT32 */ + OP_VARPCK_LG2(2), /* REPEATED ENUM */ + OP_FIXPCK_LG2(2), /* REPEATED SFIXED32 */ + OP_FIXPCK_LG2(3), /* REPEATED SFIXED64 */ + OP_VARPCK_LG2(2), /* REPEATED SINT32 */ + OP_VARPCK_LG2(3), /* REPEATED SINT64 */ }; /* Data pertaining to the parse. */ typedef struct { - const char *ptr; /* Current parsing position. */ - const char *field_start; /* Start of this field. */ - const char *limit; /* End of delimited region or end of buffer. */ + const char *limit; /* End of delimited region or end of buffer. */ upb_arena *arena; int depth; - uint32_t end_group; /* Set to field number of END_GROUP tag, if any. */ + uint32_t end_group; /* Set to field number of END_GROUP tag, if any. */ + jmp_buf err; } upb_decstate; -/* Data passed by value to each parsing function. */ -typedef struct { - char *msg; - const upb_msglayout *layout; - upb_decstate *state; -} upb_decframe; +typedef union { + bool bool_val; + int32_t int32_val; + int64_t int64_val; + uint32_t uint32_val; + uint64_t uint64_val; + upb_strview str_val; +} wireval; -#define CHK(x) if (!(x)) { return 0; } +static const char *decode_msg(upb_decstate *d, const char *ptr, upb_msg *msg, + const upb_msglayout *layout); -static bool upb_skip_unknowngroup(upb_decstate *d, int field_number); -static bool upb_decode_message(upb_decstate *d, char *msg, - const upb_msglayout *l); +UPB_NORETURN static void decode_err(upb_decstate *d) { longjmp(d->err, 1); } + +static bool decode_reserve(upb_decstate *d, upb_array *arr, int elem) { + bool need_realloc = arr->size - arr->len < elem; + if (need_realloc && !_upb_array_realloc(arr, arr->len + elem, d->arena)) { + decode_err(d); + } + return need_realloc; +} -static bool upb_decode_varint(const char **ptr, const char *limit, - uint64_t *val) { +UPB_NOINLINE +static const char *decode_longvarint64(upb_decstate *d, const char *ptr, + const char *limit, uint64_t *val) { uint8_t byte; int bitpos = 0; - const char *p = *ptr; - *val = 0; + uint64_t out = 0; do { - CHK(bitpos < 70 && p < limit); - byte = *p; - *val |= (uint64_t)(byte & 0x7F) << bitpos; - p++; + if (bitpos >= 70 || ptr == limit) decode_err(d); + byte = *ptr; + out |= (uint64_t)(byte & 0x7F) << bitpos; + ptr++; 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 = (uint32_t)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 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); + *val = out; + return ptr; } -static bool upb_decode_string(const char **ptr, const char *limit, - int *outlen) { - uint32_t len; - - CHK(upb_decode_varint32(ptr, limit, &len) && - len < INT32_MAX && - limit - *ptr >= (int32_t)len); - - *outlen = len; - return true; -} - -static void upb_set32(void *msg, size_t ofs, uint32_t val) { - memcpy((char*)msg + ofs, &val, sizeof(val)); +UPB_FORCEINLINE +static const char *decode_varint64(upb_decstate *d, const char *ptr, + const char *limit, uint64_t *val) { + if (UPB_LIKELY(ptr < limit && (*ptr & 0x80) == 0)) { + *val = (uint8_t)*ptr; + return ptr + 1; + } else { + return decode_longvarint64(d, ptr, limit, val); + } } -static bool upb_append_unknown(upb_decstate *d, upb_decframe *frame) { - upb_msg_addunknown(frame->msg, d->field_start, d->ptr - d->field_start, - d->arena); - return true; +static const char *decode_varint32(upb_decstate *d, const char *ptr, + const char *limit, uint32_t *val) { + uint64_t u64; + ptr = decode_varint64(d, ptr, limit, &u64); + if (u64 > UINT32_MAX) decode_err(d); + *val = (uint32_t)u64; + return ptr; } - -static bool upb_skip_unknownfielddata(upb_decstate *d, uint32_t tag, - uint32_t group_fieldnum) { - switch (tag & 7) { - case UPB_WIRE_TYPE_VARINT: { - uint64_t val; - return upb_decode_varint(&d->ptr, d->limit, &val); - } - case UPB_WIRE_TYPE_32BIT: { - uint32_t val; - return upb_decode_32bit(&d->ptr, d->limit, &val); - } - case UPB_WIRE_TYPE_64BIT: { - uint64_t val; - return upb_decode_64bit(&d->ptr, d->limit, &val); +static void decode_munge(int type, wireval *val) { + switch (type) { + case UPB_DESCRIPTOR_TYPE_BOOL: + val->bool_val = val->uint64_val != 0; + break; + case UPB_DESCRIPTOR_TYPE_SINT32: { + uint32_t n = val->uint32_val; + val->int32_val = (n >> 1) ^ -(int32_t)(n & 1); + break; } - case UPB_WIRE_TYPE_DELIMITED: { - int len; - CHK(upb_decode_string(&d->ptr, d->limit, &len)); - d->ptr += len; - return true; + case UPB_DESCRIPTOR_TYPE_SINT64: { + uint64_t n = val->uint64_val; + val->int64_val = (n >> 1) ^ -(int64_t)(n & 1); + break; } - case UPB_WIRE_TYPE_START_GROUP: - return upb_skip_unknowngroup(d, tag >> 3); - case UPB_WIRE_TYPE_END_GROUP: - return (tag >> 3) == group_fieldnum; - } - return false; -} - -static bool upb_skip_unknowngroup(upb_decstate *d, int field_number) { - while (d->ptr < d->limit && d->end_group == 0) { - uint32_t tag = 0; - CHK(upb_decode_varint32(&d->ptr, d->limit, &tag)); - CHK(upb_skip_unknownfielddata(d, tag, field_number)); } - - CHK(d->end_group == field_number); - d->end_group = 0; - return true; } -static bool upb_array_grow(upb_array *arr, size_t elements, size_t elem_size, - upb_arena *arena) { - 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; - upb_alloc *alloc = upb_arena_alloc(arena); +static const upb_msglayout_field *upb_find_field(const upb_msglayout *l, + uint32_t field_number) { + static upb_msglayout_field none = {0}; - while (new_size < needed) { - new_size *= 2; + /* Lots of optimization opportunities here. */ + int i; + if (l == NULL) return &none; + for (i = 0; i < l->field_count; i++) { + if (l->fields[i].number == field_number) { + return &l->fields[i]; + } } - old_bytes = arr->len * elem_size; - new_bytes = new_size * elem_size; - new_data = upb_realloc(alloc, arr->data, old_bytes, new_bytes); - CHK(new_data); - - arr->data = new_data; - arr->size = new_size; - return true; + return &none; /* Unknown field. */ } -static void *upb_array_reserve(upb_array *arr, size_t elements, - size_t elem_size, upb_arena *arena) { - if (arr->size - arr->len < elements) { - CHK(upb_array_grow(arr, elements, elem_size, arena)); - } - return (char*)arr->data + (arr->len * elem_size); +static upb_msg *decode_newsubmsg(upb_decstate *d, const upb_msglayout *layout, + const upb_msglayout_field *field) { + const upb_msglayout *subl = layout->submsgs[field->submsg_index]; + return _upb_msg_new(subl, d->arena); } -bool upb_array_add(upb_array *arr, size_t elements, size_t elem_size, - const void *data, upb_arena *arena) { - void *dest = upb_array_reserve(arr, elements, elem_size, arena); - - CHK(dest); - arr->len += elements; - memcpy(dest, data, elements * elem_size); +static void decode_tosubmsg(upb_decstate *d, upb_msg *submsg, + const upb_msglayout *layout, + const upb_msglayout_field *field, upb_strview val) { + const upb_msglayout *subl = layout->submsgs[field->submsg_index]; + const char *saved_limit = d->limit; + if (--d->depth < 0) decode_err(d); + d->limit = val.data + val.size; + decode_msg(d, val.data, submsg, subl); + d->limit = saved_limit; + if (d->end_group != 0) decode_err(d); + d->depth++; +} - return true; +static const char *decode_group(upb_decstate *d, const char *ptr, + upb_msg *submsg, const upb_msglayout *subl, + uint32_t number) { + if (--d->depth < 0) decode_err(d); + ptr = decode_msg(d, ptr, submsg, subl); + if (d->end_group != number) decode_err(d); + d->end_group = 0; + d->depth++; + return ptr; } -static upb_array *upb_getarr(upb_decframe *frame, - const upb_msglayout_field *field) { - UPB_ASSERT(field->label == UPB_LABEL_REPEATED); - return *(upb_array**)&frame->msg[field->offset]; +static const char *decode_togroup(upb_decstate *d, const char *ptr, + upb_msg *submsg, const upb_msglayout *layout, + const upb_msglayout_field *field) { + const upb_msglayout *subl = layout->submsgs[field->submsg_index]; + return decode_group(d, ptr, submsg, subl, field->number); } -static upb_array *upb_getorcreatearr(upb_decframe *frame, - const upb_msglayout_field *field) { - upb_array *arr = upb_getarr(frame, field); +static const char *decode_toarray(upb_decstate *d, const char *ptr, + upb_msg *msg, const upb_msglayout *layout, + const upb_msglayout_field *field, wireval val, + int op) { + upb_array **arrp = UPB_PTR_AT(msg, field->offset, void); + upb_array *arr = *arrp; + void *mem; if (!arr) { - arr = upb_array_new(frame->state->arena); - CHK(arr); - *(upb_array**)&frame->msg[field->offset] = arr; + upb_fieldtype_t type = desctype_to_fieldtype[field->descriptortype]; + arr = _upb_array_new(d->arena, type); + if (!arr) decode_err(d); + *arrp = arr; } - return arr; -} - -static upb_msg *upb_getorcreatemsg(upb_decframe *frame, - const upb_msglayout_field *field, - const upb_msglayout **subm) { - upb_msg **submsg = (void*)(frame->msg + field->offset); - *subm = frame->layout->submsgs[field->submsg_index]; - - UPB_ASSERT(field->label != UPB_LABEL_REPEATED); + decode_reserve(d, arr, 1); - if (!*submsg) { - *submsg = upb_msg_new(*subm, frame->state->arena); - CHK(*submsg); + switch (op) { + case OP_SCALAR_LG2(0): + case OP_SCALAR_LG2(2): + case OP_SCALAR_LG2(3): + /* Append scalar value. */ + mem = UPB_PTR_AT(_upb_array_ptr(arr), arr->len << op, void); + arr->len++; + memcpy(mem, &val, 1 << op); + return ptr; + case OP_STRING: + /* Append string. */ + mem = + UPB_PTR_AT(_upb_array_ptr(arr), arr->len * sizeof(upb_strview), void); + arr->len++; + memcpy(mem, &val, sizeof(upb_strview)); + return ptr; + case OP_SUBMSG: { + /* Append submessage / group. */ + upb_msg *submsg = decode_newsubmsg(d, layout, field); + *UPB_PTR_AT(_upb_array_ptr(arr), arr->len * sizeof(void *), upb_msg *) = + submsg; + arr->len++; + if (UPB_UNLIKELY(field->descriptortype == UPB_DTYPE_GROUP)) { + ptr = decode_togroup(d, ptr, submsg, layout, field); + } else { + decode_tosubmsg(d, submsg, layout, field, val.str_val); + } + return ptr; + } + case OP_FIXPCK_LG2(2): + case OP_FIXPCK_LG2(3): { + /* Fixed packed. */ + int lg2 = op - OP_FIXPCK_LG2(0); + int mask = (1 << lg2) - 1; + int count = val.str_val.size >> lg2; + if ((val.str_val.size & mask) != 0) { + decode_err(d); /* Length isn't a round multiple of elem size. */ + } + decode_reserve(d, arr, count); + mem = UPB_PTR_AT(_upb_array_ptr(arr), arr->len << lg2, void); + arr->len += count; + memcpy(mem, val.str_val.data, val.str_val.size); + return ptr; + } + case OP_VARPCK_LG2(0): + case OP_VARPCK_LG2(2): + case OP_VARPCK_LG2(3): { + /* Varint packed. */ + int lg2 = op - OP_VARPCK_LG2(0); + int scale = 1 << lg2; + const char *ptr = val.str_val.data; + const char *end = ptr + val.str_val.size; + char *out = UPB_PTR_AT(_upb_array_ptr(arr), arr->len << lg2, void); + while (ptr < end) { + wireval elem; + ptr = decode_varint64(d, ptr, end, &elem.uint64_val); + decode_munge(field->descriptortype, &elem); + if (decode_reserve(d, arr, 1)) { + out = UPB_PTR_AT(_upb_array_ptr(arr), arr->len << lg2, void); + } + arr->len++; + memcpy(out, &elem, scale); + out += scale; + } + if (ptr != end) decode_err(d); + return ptr; + } + default: + UPB_UNREACHABLE(); } - - return *submsg; } -static upb_msg *upb_addmsg(upb_decframe *frame, - const upb_msglayout_field *field, - const upb_msglayout **subm) { - upb_msg *submsg; - upb_array *arr = upb_getorcreatearr(frame, field); - - *subm = frame->layout->submsgs[field->submsg_index]; - submsg = upb_msg_new(*subm, frame->state->arena); - CHK(submsg); - upb_array_add(arr, 1, sizeof(submsg), &submsg, frame->state->arena); - - return submsg; -} - -static void upb_sethasbit(upb_decframe *frame, - const upb_msglayout_field *field) { - int32_t hasbit = field->presence; - UPB_ASSERT(field->presence > 0); - frame->msg[hasbit / 8] |= (1 << (hasbit % 8)); -} - -static void upb_setoneofcase(upb_decframe *frame, - const upb_msglayout_field *field) { - UPB_ASSERT(field->presence < 0); - upb_set32(frame->msg, ~field->presence, field->number); -} - -static bool upb_decode_addval(upb_decframe *frame, - const upb_msglayout_field *field, void *val, - size_t size) { - char *field_mem = frame->msg + field->offset; - upb_array *arr; +static void decode_tomap(upb_decstate *d, upb_msg *msg, + const upb_msglayout *layout, + const upb_msglayout_field *field, wireval val) { + upb_map **map_p = UPB_PTR_AT(msg, field->offset, upb_map *); + upb_map *map = *map_p; + upb_map_entry ent; + const upb_msglayout *entry = layout->submsgs[field->submsg_index]; - if (field->label == UPB_LABEL_REPEATED) { - arr = upb_getorcreatearr(frame, field); - CHK(arr); - field_mem = upb_array_reserve(arr, 1, size, frame->state->arena); - CHK(field_mem); + if (!map) { + /* Lazily create map. */ + const upb_msglayout *entry = layout->submsgs[field->submsg_index]; + const upb_msglayout_field *key_field = &entry->fields[0]; + const upb_msglayout_field *val_field = &entry->fields[1]; + char key_size = desctype_to_mapsize[key_field->descriptortype]; + char val_size = desctype_to_mapsize[val_field->descriptortype]; + UPB_ASSERT(key_field->offset == 0); + UPB_ASSERT(val_field->offset == sizeof(upb_strview)); + map = _upb_map_new(d->arena, key_size, val_size); + *map_p = map; } - memcpy(field_mem, val, size); - return true; -} + /* Parse map entry. */ + memset(&ent, 0, sizeof(ent)); -static void upb_decode_setpresent(upb_decframe *frame, - const upb_msglayout_field *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->presence < 0) { - upb_setoneofcase(frame, field); - } else if (field->presence > 0) { - upb_sethasbit(frame, field); + if (entry->fields[1].descriptortype == UPB_DESCRIPTOR_TYPE_MESSAGE || + entry->fields[1].descriptortype == UPB_DESCRIPTOR_TYPE_GROUP) { + /* Create proactively to handle the case where it doesn't appear. */ + ent.v.val.val = (uint64_t)_upb_msg_new(entry->submsgs[0], d->arena); } -} -static bool upb_decode_msgfield(upb_decstate *d, upb_msg *msg, - const upb_msglayout *layout, int limit) { - const char* saved_limit = d->limit; - d->limit = d->ptr + limit; - CHK(--d->depth >= 0); - upb_decode_message(d, msg, layout); - d->depth++; - d->limit = saved_limit; - CHK(d->end_group == 0); - return true; -} + decode_tosubmsg(d, &ent.k, layout, field, val.str_val); -static bool upb_decode_groupfield(upb_decstate *d, upb_msg *msg, - const upb_msglayout *layout, - int field_number) { - CHK(--d->depth >= 0); - upb_decode_message(d, msg, layout); - d->depth++; - CHK(d->end_group == field_number); - d->end_group = 0; - return true; + /* Insert into map. */ + _upb_map_set(map, &ent.k, map->key_size, &ent.v, map->val_size, d->arena); } -static bool upb_decode_varintfield(upb_decstate *d, upb_decframe *frame, - const upb_msglayout_field *field) { - uint64_t val; - CHK(upb_decode_varint(&d->ptr, d->limit, &val)); +static const char *decode_tomsg(upb_decstate *d, const char *ptr, upb_msg *msg, + const upb_msglayout *layout, + const upb_msglayout_field *field, wireval val, + int op) { + void *mem = UPB_PTR_AT(msg, field->offset, void); + int type = field->descriptortype; - switch (field->descriptortype) { - case UPB_DESCRIPTOR_TYPE_INT64: - case UPB_DESCRIPTOR_TYPE_UINT64: - CHK(upb_decode_addval(frame, field, &val, sizeof(val))); - break; - case UPB_DESCRIPTOR_TYPE_INT32: - case UPB_DESCRIPTOR_TYPE_UINT32: - case UPB_DESCRIPTOR_TYPE_ENUM: { - uint32_t val32 = (uint32_t)val; - CHK(upb_decode_addval(frame, field, &val32, sizeof(val32))); - break; - } - case UPB_DESCRIPTOR_TYPE_BOOL: { - bool valbool = val != 0; - CHK(upb_decode_addval(frame, field, &valbool, sizeof(valbool))); + /* Set presence if necessary. */ + if (field->presence < 0) { + /* Oneof case */ + *UPB_PTR_AT(msg, -field->presence, int32_t) = field->number; + } else if (field->presence > 0) { + /* Hasbit */ + uint32_t hasbit = field->presence; + *UPB_PTR_AT(msg, hasbit / 8, uint8_t) |= (1 << (hasbit % 8)); + } + + /* Store into message. */ + switch (op) { + case OP_SUBMSG: { + upb_msg **submsgp = mem; + upb_msg *submsg = *submsgp; + if (!submsg) { + submsg = decode_newsubmsg(d, layout, field); + *submsgp = submsg; + } + if (UPB_UNLIKELY(type == UPB_DTYPE_GROUP)) { + ptr = decode_togroup(d, ptr, submsg, layout, field); + } else { + decode_tosubmsg(d, submsg, layout, field, val.str_val); + } break; } - case UPB_DESCRIPTOR_TYPE_SINT32: { - int32_t decoded = upb_zzdecode_32((uint32_t)val); - CHK(upb_decode_addval(frame, field, &decoded, sizeof(decoded))); + case OP_STRING: + memcpy(mem, &val, sizeof(upb_strview)); break; - } - case UPB_DESCRIPTOR_TYPE_SINT64: { - int64_t decoded = upb_zzdecode_64(val); - CHK(upb_decode_addval(frame, field, &decoded, sizeof(decoded))); + case OP_SCALAR_LG2(3): + memcpy(mem, &val, 8); break; - } - default: - return upb_append_unknown(d, frame); - } - - upb_decode_setpresent(frame, field); - return true; -} - -static bool upb_decode_64bitfield(upb_decstate *d, upb_decframe *frame, - const upb_msglayout_field *field) { - uint64_t val; - CHK(upb_decode_64bit(&d->ptr, d->limit, &val)); - - switch (field->descriptortype) { - case UPB_DESCRIPTOR_TYPE_DOUBLE: - case UPB_DESCRIPTOR_TYPE_FIXED64: - case UPB_DESCRIPTOR_TYPE_SFIXED64: - CHK(upb_decode_addval(frame, field, &val, sizeof(val))); + case OP_SCALAR_LG2(2): + memcpy(mem, &val, 4); break; - default: - return upb_append_unknown(d, frame); - } - - upb_decode_setpresent(frame, field); - return true; -} - -static bool upb_decode_32bitfield(upb_decstate *d, upb_decframe *frame, - const upb_msglayout_field *field) { - uint32_t val; - CHK(upb_decode_32bit(&d->ptr, d->limit, &val)); - - switch (field->descriptortype) { - case UPB_DESCRIPTOR_TYPE_FLOAT: - case UPB_DESCRIPTOR_TYPE_FIXED32: - case UPB_DESCRIPTOR_TYPE_SFIXED32: - CHK(upb_decode_addval(frame, field, &val, sizeof(val))); + case OP_SCALAR_LG2(0): + memcpy(mem, &val, 1); break; default: - return upb_append_unknown(d, frame); + UPB_UNREACHABLE(); } - upb_decode_setpresent(frame, field); - return true; + return ptr; } -static bool upb_decode_fixedpacked(upb_decstate *d, upb_array *arr, - uint32_t len, int elem_size) { - size_t elements = len / elem_size; - - CHK((size_t)(elements * elem_size) == len); - CHK(upb_array_add(arr, elements, elem_size, d->ptr, d->arena)); - d->ptr += len; - - return true; -} - -static upb_strview upb_decode_strfield(upb_decstate *d, uint32_t len) { - upb_strview ret; - ret.data = d->ptr; - ret.size = len; - d->ptr += len; - return ret; -} - -static bool upb_decode_toarray(upb_decstate *d, upb_decframe *frame, - const upb_msglayout_field *field, int len) { - upb_array *arr = upb_getorcreatearr(frame, field); - CHK(arr); - -#define VARINT_CASE(ctype, decode) \ - VARINT_CASE_EX(ctype, decode, decode) - -#define VARINT_CASE_EX(ctype, decode, dtype) \ - { \ - const char *ptr = d->ptr; \ - const char *limit = ptr + len; \ - while (ptr < limit) { \ - uint64_t val; \ - ctype decoded; \ - CHK(upb_decode_varint(&ptr, limit, &val)); \ - decoded = (decode)((dtype)val); \ - CHK(upb_array_add(arr, 1, sizeof(decoded), &decoded, d->arena)); \ - } \ - d->ptr = ptr; \ - return true; \ - } - - switch (field->descriptortype) { - case UPB_DESCRIPTOR_TYPE_STRING: - case UPB_DESCRIPTOR_TYPE_BYTES: { - upb_strview str = upb_decode_strfield(d, len); - return upb_array_add(arr, 1, sizeof(str), &str, d->arena); - } - case UPB_DESCRIPTOR_TYPE_FLOAT: - case UPB_DESCRIPTOR_TYPE_FIXED32: - case UPB_DESCRIPTOR_TYPE_SFIXED32: - return upb_decode_fixedpacked(d, arr, len, sizeof(int32_t)); - case UPB_DESCRIPTOR_TYPE_DOUBLE: - case UPB_DESCRIPTOR_TYPE_FIXED64: - case UPB_DESCRIPTOR_TYPE_SFIXED64: - return upb_decode_fixedpacked(d, arr, len, sizeof(int64_t)); - case UPB_DESCRIPTOR_TYPE_INT32: - case UPB_DESCRIPTOR_TYPE_UINT32: - case UPB_DESCRIPTOR_TYPE_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_EX(int32_t, upb_zzdecode_32, uint32_t); - case UPB_DESCRIPTOR_TYPE_SINT64: - VARINT_CASE_EX(int64_t, upb_zzdecode_64, uint64_t); - case UPB_DESCRIPTOR_TYPE_MESSAGE: { - const upb_msglayout *subm; - upb_msg *submsg = upb_addmsg(frame, field, &subm); - CHK(submsg); - return upb_decode_msgfield(d, submsg, subm, len); - } - case UPB_DESCRIPTOR_TYPE_GROUP: - return upb_append_unknown(d, frame); - } -#undef VARINT_CASE - UPB_UNREACHABLE(); -} - -static bool upb_decode_delimitedfield(upb_decstate *d, upb_decframe *frame, - const upb_msglayout_field *field) { - int len; - - CHK(upb_decode_string(&d->ptr, d->limit, &len)); - - if (field->label == UPB_LABEL_REPEATED) { - return upb_decode_toarray(d, frame, field, len); - } else { - switch (field->descriptortype) { - case UPB_DESCRIPTOR_TYPE_STRING: - case UPB_DESCRIPTOR_TYPE_BYTES: { - upb_strview str = upb_decode_strfield(d, len); - CHK(upb_decode_addval(frame, field, &str, sizeof(str))); - break; - } - case UPB_DESCRIPTOR_TYPE_MESSAGE: { - const upb_msglayout *subm; - upb_msg *submsg = upb_getorcreatemsg(frame, field, &subm); - CHK(submsg); - CHK(upb_decode_msgfield(d, submsg, subm, len)); - break; - } - default: - /* TODO(haberman): should we accept the last element of a packed? */ - d->ptr += len; - return upb_append_unknown(d, frame); - } - upb_decode_setpresent(frame, field); - return true; - } -} - -static const upb_msglayout_field *upb_find_field(const upb_msglayout *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]; - } - } +static const char *decode_msg(upb_decstate *d, const char *ptr, upb_msg *msg, + const upb_msglayout *layout) { + while (ptr < d->limit) { + uint32_t tag; + const upb_msglayout_field *field; + int field_number; + int wire_type; + const char *field_start = ptr; + wireval val; + int op; - return NULL; /* Unknown field. */ -} + ptr = decode_varint32(d, ptr, d->limit, &tag); + field_number = tag >> 3; + wire_type = tag & 7; -static bool upb_decode_field(upb_decstate *d, upb_decframe *frame) { - uint32_t tag; - const upb_msglayout_field *field; - int field_number; + field = upb_find_field(layout, field_number); - d->field_start = d->ptr; - CHK(upb_decode_varint32(&d->ptr, d->limit, &tag)); - field_number = tag >> 3; - field = upb_find_field(frame->layout, field_number); - - if (field) { - switch (tag & 7) { + switch (wire_type) { case UPB_WIRE_TYPE_VARINT: - return upb_decode_varintfield(d, frame, field); + ptr = decode_varint64(d, ptr, d->limit, &val.uint64_val); + op = varint_ops[field->descriptortype]; + decode_munge(field->descriptortype, &val); + break; case UPB_WIRE_TYPE_32BIT: - return upb_decode_32bitfield(d, frame, field); + if (d->limit - ptr < 4) decode_err(d); + memcpy(&val, ptr, 4); + ptr += 4; + op = OP_SCALAR_LG2(2); + if (((1 << field->descriptortype) & fixed32_ok) == 0) goto unknown; + break; case UPB_WIRE_TYPE_64BIT: - return upb_decode_64bitfield(d, frame, field); - case UPB_WIRE_TYPE_DELIMITED: - return upb_decode_delimitedfield(d, frame, field); - case UPB_WIRE_TYPE_START_GROUP: { - const upb_msglayout *layout; - upb_msg *group; - - if (field->label == UPB_LABEL_REPEATED) { - group = upb_addmsg(frame, field, &layout); - } else { - group = upb_getorcreatemsg(frame, field, &layout); + if (d->limit - ptr < 8) decode_err(d); + memcpy(&val, ptr, 8); + ptr += 8; + op = OP_SCALAR_LG2(3); + if (((1 << field->descriptortype) & fixed64_ok) == 0) goto unknown; + break; + case UPB_WIRE_TYPE_DELIMITED: { + uint32_t size; + int ndx = field->descriptortype; + if (_upb_isrepeated(field)) ndx += 18; + ptr = decode_varint32(d, ptr, d->limit, &size); + if (size >= INT32_MAX || (size_t)(d->limit - ptr) < size) { + decode_err(d); /* Length overflow. */ } - - return upb_decode_groupfield(d, group, layout, field_number); + val.str_val.data = ptr; + val.str_val.size = size; + ptr += size; + op = delim_ops[ndx]; + break; } + case UPB_WIRE_TYPE_START_GROUP: + val.int32_val = field_number; + op = OP_SUBMSG; + if (field->descriptortype != UPB_DTYPE_GROUP) goto unknown; + break; case UPB_WIRE_TYPE_END_GROUP: d->end_group = field_number; - return true; + return ptr; default: - CHK(false); + decode_err(d); + } + + if (op >= 0) { + /* Parse, using op for dispatch. */ + switch (field->label) { + case UPB_LABEL_REPEATED: + case _UPB_LABEL_PACKED: + ptr = decode_toarray(d, ptr, msg, layout, field, val, op); + break; + case _UPB_LABEL_MAP: + decode_tomap(d, msg, layout, field, val); + break; + default: + ptr = decode_tomsg(d, ptr, msg, layout, field, val, op); + break; + } + } else { + unknown: + /* Skip unknown field. */ + if (field_number == 0) decode_err(d); + if (wire_type == UPB_WIRE_TYPE_START_GROUP) { + ptr = decode_group(d, ptr, NULL, NULL, field_number); + } + if (msg) { + if (!_upb_msg_addunknown(msg, field_start, ptr - field_start, + d->arena)) { + decode_err(d); + } + } } - } else { - CHK(field_number != 0); - CHK(upb_skip_unknownfielddata(d, tag, -1)); - CHK(upb_append_unknown(d, frame)); - return true; - } - UPB_UNREACHABLE(); -} - -static bool upb_decode_message(upb_decstate *d, char *msg, const upb_msglayout *l) { - upb_decframe frame; - frame.msg = msg; - frame.layout = l; - frame.state = d; - - while (d->ptr < d->limit) { - CHK(upb_decode_field(d, &frame)); } - return true; + if (ptr != d->limit) decode_err(d); + return ptr; } bool upb_decode(const char *buf, size_t size, void *msg, const upb_msglayout *l, upb_arena *arena) { upb_decstate state; - state.ptr = buf; state.limit = buf + size; state.arena = arena; state.depth = 64; state.end_group = 0; - CHK(upb_decode_message(&state, msg, l)); + if (setjmp(state.err)) return false; + + if (size == 0) return true; + decode_msg(&state, buf, msg, l); + return state.end_group == 0; } -#undef CHK +#undef OP_SCALAR_LG2 +#undef OP_FIXPCK_LG2 +#undef OP_VARPCK_LG2 +#undef OP_STRING +#undef OP_SUBMSG /* We encode backwards, to avoid pre-computing lengths (one-pass encode). */ @@ -822,6 +807,7 @@ static bool upb_encode_reserve(upb_encstate *e, size_t bytes) { /* Writes the given bytes to the buffer, handling reserve/advance. */ static bool upb_put_bytes(upb_encstate *e, const void *data, size_t len) { + if (len == 0) return true; CHK(upb_encode_reserve(e, len)); memcpy(e->ptr, data, len); return true; @@ -864,15 +850,14 @@ static bool upb_put_float(upb_encstate *e, float d) { static uint32_t upb_readcase(const char *msg, const upb_msglayout_field *f) { uint32_t ret; - uint32_t offset = ~f->presence; - memcpy(&ret, msg + offset, sizeof(ret)); + memcpy(&ret, msg - f->presence, sizeof(ret)); return ret; } static bool upb_readhasbit(const char *msg, const upb_msglayout_field *f) { uint32_t hasbit = f->presence; UPB_ASSERT(f->presence > 0); - return msg[hasbit / 8] & (1 << (hasbit % 8)); + return (*UPB_PTR_AT(msg, hasbit / 8, uint8_t)) & (1 << (hasbit % 8)); } static bool upb_put_tag(upb_encstate *e, int field_number, int wire_type) { @@ -880,116 +865,30 @@ static bool upb_put_tag(upb_encstate *e, int field_number, int 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); + size_t elem_size, uint32_t tag) { + size_t bytes = arr->len * elem_size; + const char* data = _upb_array_constptr(arr); + const char* ptr = data + bytes - elem_size; + if (tag) { + while (true) { + CHK(upb_put_bytes(e, ptr, elem_size) && upb_put_varint(e, tag)); + if (ptr == data) break; + ptr -= elem_size; + } + return true; + } else { + return upb_put_bytes(e, data, bytes) && upb_put_varint(e, bytes); + } } bool upb_encode_message(upb_encstate *e, const char *msg, const upb_msglayout *m, size_t *size); -static bool upb_encode_array(upb_encstate *e, const char *field_mem, - const upb_msglayout *m, - const upb_msglayout_field *f) { - const upb_array *arr = *(const upb_array**)field_mem; - - if (arr == NULL || arr->len == 0) { - return true; - } - -#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->descriptortype) { - 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: - VARINT_CASE(uint32_t, *ptr); - case UPB_DESCRIPTOR_TYPE_INT32: - case UPB_DESCRIPTOR_TYPE_ENUM: - VARINT_CASE(int32_t, (int64_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_strview *start = arr->data; - upb_strview *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 *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 *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, +static bool upb_encode_scalarfield(upb_encstate *e, const void *_field_mem, const upb_msglayout *m, const upb_msglayout_field *f, bool skip_zero_value) { + const char *field_mem = _field_mem; #define CASE(ctype, type, wire_type, encodeval) do { \ ctype val = *(ctype*)field_mem; \ if (skip_zero_value && val == 0) { \ @@ -1038,29 +937,169 @@ static bool upb_encode_scalarfield(upb_encstate *e, const char *field_mem, size_t size; void *submsg = *(void **)field_mem; const upb_msglayout *subm = m->submsgs[f->submsg_index]; - if (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); + if (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 *subm = m->submsgs[f->submsg_index]; + if (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(); +} + +static bool upb_encode_array(upb_encstate *e, const char *field_mem, + const upb_msglayout *m, + const upb_msglayout_field *f) { + const upb_array *arr = *(const upb_array**)field_mem; + bool packed = f->label == _UPB_LABEL_PACKED; + + if (arr == NULL || arr->len == 0) { + return true; + } + +#define VARINT_CASE(ctype, encode) \ + { \ + const ctype *start = _upb_array_constptr(arr); \ + const ctype *ptr = start + arr->len; \ + size_t pre_len = e->limit - e->ptr; \ + uint32_t tag = packed ? 0 : (f->number << 3) | UPB_WIRE_TYPE_VARINT; \ + do { \ + ptr--; \ + CHK(upb_put_varint(e, encode)); \ + if (tag) CHK(upb_put_varint(e, tag)); \ + } while (ptr != start); \ + if (!tag) CHK(upb_put_varint(e, e->limit - e->ptr - pre_len)); \ + } \ + break; \ + do { \ + ; \ + } while (0) + +#define TAG(wire_type) (packed ? 0 : (f->number << 3 | wire_type)) + + switch (f->descriptortype) { + case UPB_DESCRIPTOR_TYPE_DOUBLE: + CHK(upb_put_fixedarray(e, arr, sizeof(double), TAG(UPB_WIRE_TYPE_64BIT))); + break; + case UPB_DESCRIPTOR_TYPE_FLOAT: + CHK(upb_put_fixedarray(e, arr, sizeof(float), TAG(UPB_WIRE_TYPE_32BIT))); + break; + case UPB_DESCRIPTOR_TYPE_SFIXED64: + case UPB_DESCRIPTOR_TYPE_FIXED64: + CHK(upb_put_fixedarray(e, arr, sizeof(uint64_t), TAG(UPB_WIRE_TYPE_64BIT))); + break; + case UPB_DESCRIPTOR_TYPE_FIXED32: + case UPB_DESCRIPTOR_TYPE_SFIXED32: + CHK(upb_put_fixedarray(e, arr, sizeof(uint32_t), TAG(UPB_WIRE_TYPE_32BIT))); + break; + case UPB_DESCRIPTOR_TYPE_INT64: + case UPB_DESCRIPTOR_TYPE_UINT64: + VARINT_CASE(uint64_t, *ptr); + case UPB_DESCRIPTOR_TYPE_UINT32: + VARINT_CASE(uint32_t, *ptr); + case UPB_DESCRIPTOR_TYPE_INT32: + case UPB_DESCRIPTOR_TYPE_ENUM: + VARINT_CASE(int32_t, (int64_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: { + const upb_strview *start = _upb_array_constptr(arr); + const upb_strview *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: { + const void *const*start = _upb_array_constptr(arr); + const void *const*ptr = start + arr->len; + const upb_msglayout *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: { - size_t size; - void *submsg = *(void **)field_mem; + const void *const*start = _upb_array_constptr(arr); + const void *const*ptr = start + arr->len; const upb_msglayout *subm = m->submsgs[f->submsg_index]; - if (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); + 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 CASE - UPB_UNREACHABLE(); +#undef VARINT_CASE + + if (packed) { + CHK(upb_put_tag(e, f->number, UPB_WIRE_TYPE_DELIMITED)); + } + return true; +} + +static bool upb_encode_map(upb_encstate *e, const char *field_mem, + const upb_msglayout *m, + const upb_msglayout_field *f) { + const upb_map *map = *(const upb_map**)field_mem; + const upb_msglayout *entry = m->submsgs[f->submsg_index]; + const upb_msglayout_field *key_field = &entry->fields[0]; + const upb_msglayout_field *val_field = &entry->fields[1]; + upb_strtable_iter i; + if (map == NULL) { + return true; + } + + upb_strtable_begin(&i, &map->table); + for(; !upb_strtable_done(&i); upb_strtable_next(&i)) { + size_t pre_len = e->limit - e->ptr; + size_t size; + upb_strview key = upb_strtable_iter_key(&i); + const upb_value val = upb_strtable_iter_value(&i); + const void *keyp = + map->key_size == UPB_MAPTYPE_STRING ? (void *)&key : key.data; + const void *valp = + map->val_size == UPB_MAPTYPE_STRING ? upb_value_getptr(val) : &val; + + CHK(upb_encode_scalarfield(e, valp, entry, val_field, false)); + CHK(upb_encode_scalarfield(e, keyp, entry, key_field, false)); + size = (e->limit - e->ptr) - pre_len; + CHK(upb_put_varint(e, size)); + CHK(upb_put_tag(e, f->number, UPB_WIRE_TYPE_DELIMITED)); + } + + return true; } + bool upb_encode_message(upb_encstate *e, const char *msg, const upb_msglayout *m, size_t *size) { int i; @@ -1068,11 +1107,19 @@ bool upb_encode_message(upb_encstate *e, const char *msg, const char *unknown; size_t unknown_size; + unknown = upb_msg_getunknown(msg, &unknown_size); + + if (unknown) { + upb_put_bytes(e, unknown, unknown_size); + } + for (i = m->field_count - 1; i >= 0; i--) { const upb_msglayout_field *f = &m->fields[i]; - if (f->label == UPB_LABEL_REPEATED) { + if (_upb_isrepeated(f)) { CHK(upb_encode_array(e, msg + f->offset, m, f)); + } else if (f->label == _UPB_LABEL_MAP) { + CHK(upb_encode_map(e, msg + f->offset, m, f)); } else { bool skip_empty = false; if (f->presence == 0) { @@ -1093,12 +1140,6 @@ bool upb_encode_message(upb_encstate *e, const char *msg, } } - unknown = upb_msg_getunknown(msg, &unknown_size); - - if (unknown) { - upb_put_bytes(e, unknown, unknown_size); - } - *size = (e->limit - e->ptr) - pre_len; return true; } @@ -1132,24 +1173,27 @@ char *upb_encode(const void *msg, const upb_msglayout *m, upb_arena *arena, -#define VOIDPTR_AT(msg, ofs) (void*)((char*)msg + (int)ofs) - -/* 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. */ +/** upb_msg *******************************************************************/ -/* Used when a message is not extendable. */ -typedef struct { - char *unknown; - size_t unknown_len; - size_t unknown_size; -} upb_msg_internal; +static const char _upb_fieldtype_to_sizelg2[12] = { + 0, + 0, /* UPB_TYPE_BOOL */ + 2, /* UPB_TYPE_FLOAT */ + 2, /* UPB_TYPE_INT32 */ + 2, /* UPB_TYPE_UINT32 */ + 2, /* UPB_TYPE_ENUM */ + UPB_SIZE(2, 3), /* UPB_TYPE_MESSAGE */ + 3, /* UPB_TYPE_DOUBLE */ + 3, /* UPB_TYPE_INT64 */ + 3, /* UPB_TYPE_UINT64 */ + UPB_SIZE(3, 4), /* UPB_TYPE_STRING */ + UPB_SIZE(3, 4), /* UPB_TYPE_BYTES */ +}; -/* Used when a message is extendable. */ -typedef struct { - upb_inttable *extdict; - upb_msg_internal base; -} upb_msg_internal_withext; +static uintptr_t tag_arrptr(void* ptr, int elem_size_lg2) { + UPB_ASSERT(elem_size_lg2 <= 4); + return (uintptr_t)ptr | elem_size_lg2; +} static int upb_msg_internalsize(const upb_msglayout *l) { return sizeof(upb_msg_internal) - l->extendable * sizeof(void *); @@ -1160,22 +1204,22 @@ static size_t upb_msg_sizeof(const upb_msglayout *l) { } static upb_msg_internal *upb_msg_getinternal(upb_msg *msg) { - return VOIDPTR_AT(msg, -sizeof(upb_msg_internal)); + return UPB_PTR_AT(msg, -sizeof(upb_msg_internal), upb_msg_internal); } static const upb_msg_internal *upb_msg_getinternal_const(const upb_msg *msg) { - return VOIDPTR_AT(msg, -sizeof(upb_msg_internal)); + return UPB_PTR_AT(msg, -sizeof(upb_msg_internal), upb_msg_internal); } static upb_msg_internal_withext *upb_msg_getinternalwithext( upb_msg *msg, const upb_msglayout *l) { UPB_ASSERT(l->extendable); - return VOIDPTR_AT(msg, -sizeof(upb_msg_internal_withext)); + return UPB_PTR_AT(msg, -sizeof(upb_msg_internal_withext), + upb_msg_internal_withext); } -upb_msg *upb_msg_new(const upb_msglayout *l, upb_arena *a) { - upb_alloc *alloc = upb_arena_alloc(a); - void *mem = upb_malloc(alloc, upb_msg_sizeof(l)); +upb_msg *_upb_msg_new(const upb_msglayout *l, upb_arena *a) { + void *mem = upb_arena_malloc(a, upb_msg_sizeof(l)); upb_msg_internal *in; upb_msg *msg; @@ -1183,7 +1227,7 @@ upb_msg *upb_msg_new(const upb_msglayout *l, upb_arena *a) { return NULL; } - msg = VOIDPTR_AT(mem, upb_msg_internalsize(l)); + msg = UPB_PTR_AT(mem, upb_msg_internalsize(l), upb_msg); /* Initialize normal members. */ memset(msg, 0, l->size); @@ -1201,66 +1245,122 @@ upb_msg *upb_msg_new(const upb_msglayout *l, upb_arena *a) { return msg; } -upb_array *upb_array_new(upb_arena *a) { - upb_array *ret = upb_arena_malloc(a, sizeof(upb_array)); - - if (!ret) { - return NULL; - } - - ret->data = NULL; - ret->len = 0; - ret->size = 0; - - return ret; -} - -void upb_msg_addunknown(upb_msg *msg, const char *data, size_t len, - upb_arena *arena) { +bool _upb_msg_addunknown(upb_msg *msg, const char *data, size_t len, + upb_arena *arena) { upb_msg_internal *in = upb_msg_getinternal(msg); if (len > in->unknown_size - in->unknown_len) { upb_alloc *alloc = upb_arena_alloc(arena); size_t need = in->unknown_size + len; size_t newsize = UPB_MAX(in->unknown_size * 2, need); - in->unknown = upb_realloc(alloc, in->unknown, in->unknown_size, newsize); + void *mem = upb_realloc(alloc, in->unknown, in->unknown_size, newsize); + if (!mem) return false; + in->unknown = mem; in->unknown_size = newsize; } memcpy(in->unknown + in->unknown_len, data, len); in->unknown_len += len; + return true; } const char *upb_msg_getunknown(const upb_msg *msg, size_t *len) { - const upb_msg_internal* in = upb_msg_getinternal_const(msg); + const upb_msg_internal *in = upb_msg_getinternal_const(msg); *len = in->unknown_len; return in->unknown; } -#undef VOIDPTR_AT +/** upb_array *****************************************************************/ +upb_array *_upb_array_new(upb_arena *a, upb_fieldtype_t type) { + upb_array *arr = upb_arena_malloc(a, sizeof(upb_array)); -#ifdef UPB_MSVC_VSNPRINTF -/* Visual C++ earlier than 2015 doesn't have standard C99 snprintf and - * vsnprintf. To support them, missing functions are manually implemented - * using the existing secure functions. */ -int msvc_vsnprintf(char* s, size_t n, const char* format, va_list arg) { - if (!s) { - return _vscprintf(format, arg); + if (!arr) { + return NULL; } - int ret = _vsnprintf_s(s, n, _TRUNCATE, format, arg); - if (ret < 0) { - ret = _vscprintf(format, arg); + + arr->data = tag_arrptr(NULL, _upb_fieldtype_to_sizelg2[type]); + arr->len = 0; + arr->size = 0; + + return arr; +} + +bool _upb_array_realloc(upb_array *arr, size_t min_size, upb_arena *arena) { + size_t new_size = UPB_MAX(arr->size, 4); + int elem_size_lg2 = arr->data & 7; + size_t old_bytes = arr->size << elem_size_lg2; + size_t new_bytes; + void* ptr = _upb_array_ptr(arr); + + /* Log2 ceiling of size. */ + while (new_size < min_size) new_size *= 2; + + new_bytes = new_size << elem_size_lg2; + ptr = upb_arena_realloc(arena, ptr, old_bytes, new_bytes); + + if (!ptr) { + return false; } - return ret; + + arr->data = tag_arrptr(ptr, elem_size_lg2); + arr->size = new_size; + return true; } -int msvc_snprintf(char* s, size_t n, const char* format, ...) { - va_list arg; - va_start(arg, format); - int ret = msvc_vsnprintf(s, n, format, arg); - va_end(arg); - return ret; +static upb_array *getorcreate_array(upb_array **arr_ptr, upb_fieldtype_t type, + upb_arena *arena) { + upb_array *arr = *arr_ptr; + if (!arr) { + arr = _upb_array_new(arena, type); + if (!arr) return NULL; + *arr_ptr = arr; + } + return arr; +} + +static bool resize_array(upb_array *arr, size_t size, upb_arena *arena) { + if (size > arr->size && !_upb_array_realloc(arr, size, arena)) { + return false; + } + + arr->len = size; + return true; +} + +void *_upb_array_resize_fallback(upb_array **arr_ptr, size_t size, + upb_fieldtype_t type, upb_arena *arena) { + upb_array *arr = getorcreate_array(arr_ptr, type, arena); + return arr && resize_array(arr, size, arena) ? _upb_array_ptr(arr) : NULL; +} + +bool _upb_array_append_fallback(upb_array **arr_ptr, const void *value, + upb_fieldtype_t type, upb_arena *arena) { + upb_array *arr = getorcreate_array(arr_ptr, type, arena); + size_t elem = arr->len; + int lg2 = _upb_fieldtype_to_sizelg2[type]; + char *data; + + if (!arr || !resize_array(arr, elem + 1, arena)) return false; + + data = _upb_array_ptr(arr); + memcpy(data + (elem << lg2), value, 1 << lg2); + return true; +} + +/** upb_map *******************************************************************/ + +upb_map *_upb_map_new(upb_arena *a, size_t key_size, size_t value_size) { + upb_map *map = upb_arena_malloc(a, sizeof(upb_map)); + + if (!map) { + return NULL; + } + + upb_strtable_init2(&map->table, UPB_CTYPE_INT32, upb_arena_alloc(a)); + map->key_size = key_size; + map->val_size = value_size; + + return map; } -#endif /* ** upb_table Implementation ** @@ -1277,12 +1377,6 @@ int msvc_snprintf(char* s, size_t n, const char* format, ...) { #define ARRAY_SIZE(x) \ ((sizeof(x)/sizeof(0[x])) / ((size_t)(!(sizeof(x) % sizeof(0[x]))))) -static void upb_check_alloc(upb_table *t, upb_alloc *a) { - UPB_UNUSED(t); - UPB_UNUSED(a); - UPB_ASSERT_DEBUGVAR(t->alloc == a); -} - static const double MAX_LOAD = 0.85; /* The minimum utilization of the array part of a mixed hash/array table. This @@ -1361,17 +1455,12 @@ static bool isfull(upb_table *t) { } } -static bool init(upb_table *t, upb_ctype_t ctype, uint8_t size_lg2, - upb_alloc *a) { +static bool init(upb_table *t, uint8_t size_lg2, upb_alloc *a) { size_t bytes; t->count = 0; - t->ctype = ctype; t->size_lg2 = size_lg2; t->mask = upb_table_size(t) ? upb_table_size(t) - 1 : 0; -#ifndef NDEBUG - t->alloc = a; -#endif bytes = upb_table_size(t) * sizeof(upb_tabent); if (bytes > 0) { t->entries = upb_malloc(a, bytes); @@ -1384,7 +1473,6 @@ static bool init(upb_table *t, upb_ctype_t ctype, uint8_t size_lg2, } static void uninit(upb_table *t, upb_alloc *a) { - upb_check_alloc(t, a); upb_free(a, mutable_entries(t)); } @@ -1420,7 +1508,7 @@ static bool lookup(const upb_table *t, lookupkey_t key, upb_value *v, const upb_tabent *e = findentry(t, key, hash, eql); if (e) { if (v) { - _upb_value_setval(v, e->val.val, t->ctype); + _upb_value_setval(v, e->val.val); } return true; } else { @@ -1436,7 +1524,6 @@ static void insert(upb_table *t, lookupkey_t key, upb_tabkey tabkey, upb_tabent *our_e; UPB_ASSERT(findentry(t, key, hash, eql) == NULL); - UPB_ASSERT_DEBUGVAR(val.ctype == t->ctype); t->count++; mainpos_e = getentry_mutable(t, hash); @@ -1482,7 +1569,7 @@ static bool rm(upb_table *t, lookupkey_t key, upb_value *val, if (eql(chain->key, key)) { /* Element to remove is at the head of its chain. */ t->count--; - if (val) _upb_value_setval(val, chain->val.val, t->ctype); + if (val) _upb_value_setval(val, chain->val.val); if (removed) *removed = chain->key; if (chain->next) { upb_tabent *move = (upb_tabent*)chain->next; @@ -1502,7 +1589,7 @@ static bool rm(upb_table *t, lookupkey_t key, upb_value *val, /* Found element to remove. */ upb_tabent *rm = (upb_tabent*)chain->next; t->count--; - if (val) _upb_value_setval(val, chain->next->val.val, t->ctype); + if (val) _upb_value_setval(val, chain->next->val.val); if (removed) *removed = rm->key; rm->key = 0; /* Make the slot empty. */ chain->next = rm->next; @@ -1555,7 +1642,13 @@ static bool streql(upb_tabkey k1, lookupkey_t k2) { } bool upb_strtable_init2(upb_strtable *t, upb_ctype_t ctype, upb_alloc *a) { - return init(&t->t, ctype, 2, a); + return init(&t->t, 2, a); +} + +void upb_strtable_clear(upb_strtable *t) { + size_t bytes = upb_table_size(&t->t) * sizeof(upb_tabent); + t->t.count = 0; + memset((char*)t->t.entries, 0, bytes); } void upb_strtable_uninit2(upb_strtable *t, upb_alloc *a) { @@ -1569,18 +1662,14 @@ bool upb_strtable_resize(upb_strtable *t, size_t size_lg2, upb_alloc *a) { upb_strtable new_table; upb_strtable_iter i; - upb_check_alloc(&t->t, a); - - if (!init(&new_table.t, t->t.ctype, size_lg2, a)) + if (!init(&new_table.t, size_lg2, a)) return false; upb_strtable_begin(&i, t); for ( ; !upb_strtable_done(&i); upb_strtable_next(&i)) { + upb_strview key = upb_strtable_iter_key(&i); upb_strtable_insert3( - &new_table, - upb_strtable_iter_key(&i), - upb_strtable_iter_keylength(&i), - upb_strtable_iter_value(&i), - a); + &new_table, key.data, key.size, + upb_strtable_iter_value(&i), a); } upb_strtable_uninit2(t, a); *t = new_table; @@ -1593,8 +1682,6 @@ bool upb_strtable_insert3(upb_strtable *t, const char *k, size_t len, upb_tabkey tabkey; uint32_t hash; - upb_check_alloc(&t->t, a); - if (isfull(&t->t)) { /* Need to resize. New table of double the size, add old elements to it. */ if (!upb_strtable_resize(t, t->t.size_lg2 + 1, a)) { @@ -1622,7 +1709,10 @@ bool upb_strtable_remove3(upb_strtable *t, const char *key, size_t len, uint32_t hash = upb_murmur_hash2(key, len, 0); upb_tabkey tabkey; if (rm(&t->t, strkey2(key, len), val, &tabkey, hash, &streql)) { - upb_free(alloc, (void*)tabkey); + if (alloc) { + /* Arena-based allocs don't need to free and won't pass this. */ + upb_free(alloc, (void*)tabkey); + } return true; } else { return false; @@ -1631,10 +1721,6 @@ bool upb_strtable_remove3(upb_strtable *t, const char *key, size_t len, /* Iteration */ -static const upb_tabent *str_tabent(const upb_strtable_iter *i) { - return &i->t->t.entries[i->index]; -} - void upb_strtable_begin(upb_strtable_iter *i, const upb_strtable *t) { i->t = t; i->index = begin(&t->t); @@ -1650,21 +1736,18 @@ bool upb_strtable_done(const upb_strtable_iter *i) { upb_tabent_isempty(str_tabent(i)); } -const char *upb_strtable_iter_key(const upb_strtable_iter *i) { - UPB_ASSERT(!upb_strtable_done(i)); - return upb_tabstr(str_tabent(i)->key, NULL); -} - -size_t upb_strtable_iter_keylength(const upb_strtable_iter *i) { +upb_strview upb_strtable_iter_key(const upb_strtable_iter *i) { + upb_strview key; uint32_t len; UPB_ASSERT(!upb_strtable_done(i)); - upb_tabstr(str_tabent(i)->key, &len); - return len; + key.data = upb_tabstr(str_tabent(i)->key, &len); + key.size = len; + return key; } upb_value upb_strtable_iter_value(const upb_strtable_iter *i) { UPB_ASSERT(!upb_strtable_done(i)); - return _upb_value_val(str_tabent(i)->val.val, i->t->t.ctype); + return _upb_value_val(str_tabent(i)->val.val); } void upb_strtable_iter_setdone(upb_strtable_iter *i) { @@ -1730,11 +1813,11 @@ static void check(upb_inttable *t) { #endif } -bool upb_inttable_sizedinit(upb_inttable *t, upb_ctype_t ctype, - size_t asize, int hsize_lg2, upb_alloc *a) { +bool upb_inttable_sizedinit(upb_inttable *t, size_t asize, int hsize_lg2, + upb_alloc *a) { size_t array_bytes; - if (!init(&t->t, ctype, hsize_lg2, a)) return false; + if (!init(&t->t, hsize_lg2, a)) return false; /* Always make the array part at least 1 long, so that we know key 0 * won't be in the hash part, which simplifies things. */ t->array_size = UPB_MAX(1, asize); @@ -1751,7 +1834,7 @@ bool upb_inttable_sizedinit(upb_inttable *t, upb_ctype_t ctype, } bool upb_inttable_init2(upb_inttable *t, upb_ctype_t ctype, upb_alloc *a) { - return upb_inttable_sizedinit(t, ctype, 0, 4, a); + return upb_inttable_sizedinit(t, 0, 4, a); } void upb_inttable_uninit2(upb_inttable *t, upb_alloc *a) { @@ -1765,8 +1848,6 @@ bool upb_inttable_insert2(upb_inttable *t, uintptr_t key, upb_value val, tabval.val = val.val; UPB_ASSERT(upb_arrhas(tabval)); /* This will reject (uint64_t)-1. Fix this. */ - upb_check_alloc(&t->t, a); - if (key < t->array_size) { UPB_ASSERT(!upb_arrhas(t->array[key])); t->array_count++; @@ -1777,7 +1858,7 @@ bool upb_inttable_insert2(upb_inttable *t, uintptr_t key, upb_value val, size_t i; upb_table new_table; - if (!init(&new_table, t->t.ctype, t->t.size_lg2 + 1, a)) { + if (!init(&new_table, t->t.size_lg2 + 1, a)) { return false; } @@ -1786,7 +1867,7 @@ bool upb_inttable_insert2(upb_inttable *t, uintptr_t key, upb_value val, uint32_t hash; upb_value v; - _upb_value_setval(&v, e->val.val, t->t.ctype); + _upb_value_setval(&v, e->val.val); hash = upb_inthash(e->key); insert(&new_table, intkey(e->key), e->key, v, hash, &inthash, &inteql); } @@ -1805,7 +1886,7 @@ bool upb_inttable_insert2(upb_inttable *t, uintptr_t key, upb_value val, bool upb_inttable_lookup(const upb_inttable *t, uintptr_t key, upb_value *v) { const upb_tabval *table_v = inttable_val_const(t, key); if (!table_v) return false; - if (v) _upb_value_setval(v, table_v->val, t->t.ctype); + if (v) _upb_value_setval(v, table_v->val); return true; } @@ -1823,7 +1904,7 @@ bool upb_inttable_remove(upb_inttable *t, uintptr_t key, upb_value *val) { upb_tabval empty = UPB_TABVALUE_EMPTY_INIT; t->array_count--; if (val) { - _upb_value_setval(val, t->array[key].val, t->t.ctype); + _upb_value_setval(val, t->array[key].val); } mutable_array(t)[key] = empty; success = true; @@ -1838,7 +1919,6 @@ bool upb_inttable_remove(upb_inttable *t, uintptr_t key, upb_value *val) { } bool upb_inttable_push2(upb_inttable *t, upb_value val, upb_alloc *a) { - upb_check_alloc(&t->t, a); return upb_inttable_insert2(t, upb_inttable_count(t), val, a); } @@ -1851,7 +1931,6 @@ upb_value upb_inttable_pop(upb_inttable *t) { bool upb_inttable_insertptr2(upb_inttable *t, const void *key, upb_value val, upb_alloc *a) { - upb_check_alloc(&t->t, a); return upb_inttable_insert2(t, (uintptr_t)key, val, a); } @@ -1876,8 +1955,6 @@ void upb_inttable_compact2(upb_inttable *t, upb_alloc *a) { int size_lg2; upb_inttable new_t; - upb_check_alloc(&t->t, a); - upb_inttable_begin(&i, t); for (; !upb_inttable_done(&i); upb_inttable_next(&i)) { uintptr_t key = upb_inttable_iter_key(&i); @@ -1910,7 +1987,7 @@ void upb_inttable_compact2(upb_inttable *t, upb_alloc *a) { size_t hash_size = hash_count ? (hash_count / MAX_LOAD) + 1 : 0; int hashsize_lg2 = log2ceil(hash_size); - upb_inttable_sizedinit(&new_t, t->t.ctype, arr_size, hashsize_lg2, a); + upb_inttable_sizedinit(&new_t, arr_size, hashsize_lg2, a); upb_inttable_begin(&i, t); for (; !upb_inttable_done(&i); upb_inttable_next(&i)) { uintptr_t k = upb_inttable_iter_key(&i); @@ -1976,8 +2053,7 @@ uintptr_t upb_inttable_iter_key(const upb_inttable_iter *i) { upb_value upb_inttable_iter_value(const upb_inttable_iter *i) { UPB_ASSERT(!upb_inttable_done(i)); return _upb_value_val( - i->array_part ? i->t->array[i->index].val : int_tabent(i)->val.val, - i->t->t.ctype); + i->array_part ? i->t->array[i->index].val : int_tabent(i)->val.val); } void upb_inttable_iter_setdone(upb_inttable_iter *i) { @@ -2017,7 +2093,8 @@ uint32_t upb_murmur_hash2(const void *key, size_t len, uint32_t seed) { /* Mix 4 bytes at a time into the hash */ const uint8_t * data = (const uint8_t *)key; while(len >= 4) { - uint32_t k = *(uint32_t *)data; + uint32_t k; + memcpy(&k, data, sizeof(k)); k *= m; k ^= k >> r; @@ -2182,17 +2259,6 @@ uint32_t upb_murmur_hash2(const void * key, size_t len, uint32_t seed) { #include -/* Guarantee null-termination and provide ellipsis truncation. - * It may be tempting to "optimize" this by initializing these final - * four bytes up-front and then being careful never to overwrite them, - * this is safer and simpler. */ -static void nullz(upb_status *status) { - const char *ellipsis = "..."; - size_t len = strlen(ellipsis); - UPB_ASSERT(sizeof(status->msg) > len); - memcpy(status->msg + sizeof(status->msg) - len, ellipsis, len); -} - /* upb_status *****************************************************************/ void upb_status_clear(upb_status *status) { @@ -2208,8 +2274,8 @@ const char *upb_status_errmsg(const upb_status *status) { return status->msg; } void upb_status_seterrmsg(upb_status *status, const char *msg) { if (!status) return; status->ok = false; - strncpy(status->msg, msg, sizeof(status->msg)); - nullz(status); + strncpy(status->msg, msg, UPB_STATUS_MAX_MESSAGE - 1); + status->msg[UPB_STATUS_MAX_MESSAGE - 1] = '\0'; } void upb_status_seterrf(upb_status *status, const char *fmt, ...) { @@ -2223,7 +2289,7 @@ void upb_status_vseterrf(upb_status *status, const char *fmt, va_list args) { if (!status) return; status->ok = false; _upb_vsnprintf(status->msg, sizeof(status->msg), fmt, args); - nullz(status); + status->msg[UPB_STATUS_MAX_MESSAGE - 1] = '\0'; } /* upb_alloc ******************************************************************/ @@ -2245,190 +2311,216 @@ upb_alloc upb_alloc_global = {&upb_global_allocfunc}; /* upb_arena ******************************************************************/ /* Be conservative and choose 16 in case anyone is using SSE. */ -static const size_t maxalign = 16; -static size_t align_up_max(size_t size) { - return ((size + maxalign - 1) / maxalign) * maxalign; -} +typedef struct mem_block { + struct mem_block *next; + uint32_t size; + uint32_t cleanups; + /* Data follows. */ +} mem_block; + +typedef struct cleanup_ent { + upb_cleanup_func *cleanup; + void *ud; +} cleanup_ent; struct upb_arena { - /* We implement the allocator interface. - * This must be the first member of upb_arena! */ - upb_alloc alloc; + _upb_arena_head head; + uint32_t *cleanups; /* Allocator to allocate arena blocks. We are responsible for freeing these * when we are destroyed. */ upb_alloc *block_alloc; + uint32_t last_size; - size_t bytes_allocated; - size_t next_block_size; - size_t max_block_size; - - /* Linked list of blocks. Points to an arena_block, defined in env.c */ - void *block_head; + /* When multiple arenas are fused together, each arena points to a parent + * arena (root points to itself). The root tracks how many live arenas + * reference it. */ + uint32_t refcount; /* Only used when a->parent == a */ + struct upb_arena *parent; - /* Cleanup entries. Pointer to a cleanup_ent, defined in env.c */ - void *cleanup_head; + /* Linked list of blocks to free/cleanup. */ + mem_block *freelist, *freelist_tail; }; -typedef struct mem_block { - struct mem_block *next; - size_t size; - size_t used; - bool owned; - /* Data follows. */ -} mem_block; - -typedef struct cleanup_ent { - struct cleanup_ent *next; - upb_cleanup_func *cleanup; - void *ud; -} cleanup_ent; +static const size_t memblock_reserve = UPB_ALIGN_UP(sizeof(mem_block), 16); -static void upb_arena_addblock(upb_arena *a, void *ptr, size_t size, - bool owned) { +static void upb_arena_addblock(upb_arena *a, void *ptr, size_t size) { mem_block *block = ptr; - block->next = a->block_head; + block->next = a->freelist; block->size = size; - block->used = align_up_max(sizeof(mem_block)); - block->owned = owned; + block->cleanups = 0; + a->freelist = block; + a->last_size = size; + if (!a->freelist_tail) a->freelist_tail = block; - a->block_head = block; + a->head.ptr = UPB_PTR_AT(block, memblock_reserve, char); + a->head.end = UPB_PTR_AT(block, size, char); + a->cleanups = &block->cleanups; /* TODO(haberman): ASAN poison. */ } -static mem_block *upb_arena_allocblock(upb_arena *a, size_t size) { - size_t block_size = UPB_MAX(size, a->next_block_size) + sizeof(mem_block); +static bool upb_arena_allocblock(upb_arena *a, size_t size) { + size_t block_size = UPB_MAX(size, a->last_size * 2) + memblock_reserve; mem_block *block = upb_malloc(a->block_alloc, block_size); - if (!block) { - return NULL; - } + if (!block) return false; + upb_arena_addblock(a, block, block_size); + return true; +} - upb_arena_addblock(a, block, block_size, true); - a->next_block_size = UPB_MIN(block_size * 2, a->max_block_size); +static bool arena_has(upb_arena *a, size_t size) { + _upb_arena_head *h = (_upb_arena_head*)a; + return (size_t)(h->end - h->ptr) >= size; +} - return block; +void *_upb_arena_slowmalloc(upb_arena *a, size_t size) { + if (!upb_arena_allocblock(a, size)) return NULL; /* Out of memory. */ + UPB_ASSERT(arena_has(a, size)); + return upb_arena_malloc(a, size); } static void *upb_arena_doalloc(upb_alloc *alloc, void *ptr, size_t oldsize, size_t size) { upb_arena *a = (upb_arena*)alloc; /* upb_alloc is initial member. */ - mem_block *block = a->block_head; - void *ret; + return upb_arena_realloc(a, ptr, oldsize, size); +} - if (size == 0) { - return NULL; /* We are an arena, don't need individual frees. */ +static upb_arena *arena_findroot(upb_arena *a) { + /* Path splitting keeps time complexity down, see: + * https://en.wikipedia.org/wiki/Disjoint-set_data_structure */ + while (a->parent != a) { + upb_arena *next = a->parent; + a->parent = next->parent; + a = next; } + return a; +} - size = align_up_max(size); - - /* TODO(haberman): special-case if this is a realloc of the last alloc? */ +/* Public Arena API ***********************************************************/ - if (!block || block->size - block->used < size) { - /* Slow path: have to allocate a new block. */ - block = upb_arena_allocblock(a, size); +upb_arena *arena_initslow(void *mem, size_t n, upb_alloc *alloc) { + const size_t first_block_overhead = sizeof(upb_arena) + memblock_reserve; + upb_arena *a; - if (!block) { - return NULL; /* Out of memory. */ - } + /* We need to malloc the initial block. */ + n = first_block_overhead + 256; + if (!alloc || !(mem = upb_malloc(alloc, n))) { + return NULL; } - ret = (char*)block + block->used; - block->used += size; + a = UPB_PTR_AT(mem, n - sizeof(*a), upb_arena); + n -= sizeof(*a); - if (oldsize > 0) { - memcpy(ret, ptr, oldsize); /* Preserve existing data. */ - } + a->head.alloc.func = &upb_arena_doalloc; + a->block_alloc = alloc; + a->parent = a; + a->refcount = 1; + a->freelist = NULL; + a->freelist_tail = NULL; - /* TODO(haberman): ASAN unpoison. */ + upb_arena_addblock(a, mem, n); - a->bytes_allocated += size; - return ret; + return a; } -/* Public Arena API ***********************************************************/ - -#define upb_alignof(type) offsetof (struct { char c; type member; }, member) - upb_arena *upb_arena_init(void *mem, size_t n, upb_alloc *alloc) { - const size_t first_block_overhead = sizeof(upb_arena) + sizeof(mem_block); upb_arena *a; - bool owned = false; /* Round block size down to alignof(*a) since we will allocate the arena * itself at the end. */ - n &= ~(upb_alignof(upb_arena) - 1); + n = UPB_ALIGN_DOWN(n, UPB_ALIGN_OF(upb_arena)); - if (n < first_block_overhead) { - /* We need to malloc the initial block. */ - n = first_block_overhead + 256; - owned = true; - if (!alloc || !(mem = upb_malloc(alloc, n))) { - return NULL; - } + if (UPB_UNLIKELY(n < sizeof(upb_arena))) { + return arena_initslow(mem, n, alloc); } - a = (void*)((char*)mem + n - sizeof(*a)); + a = UPB_PTR_AT(mem, n - sizeof(*a), upb_arena); n -= sizeof(*a); - a->alloc.func = &upb_arena_doalloc; - a->block_alloc = &upb_alloc_global; - a->bytes_allocated = 0; - a->next_block_size = 256; - a->max_block_size = 16384; - a->cleanup_head = NULL; - a->block_head = NULL; + a->head.alloc.func = &upb_arena_doalloc; a->block_alloc = alloc; - - upb_arena_addblock(a, mem, n, owned); + a->parent = a; + a->refcount = 1; + a->last_size = 128; + a->head.ptr = mem; + a->head.end = UPB_PTR_AT(mem, n, char); + a->freelist = NULL; + a->cleanups = NULL; return a; } -#undef upb_alignof - -void upb_arena_free(upb_arena *a) { - cleanup_ent *ent = a->cleanup_head; - mem_block *block = a->block_head; - - while (ent) { - ent->cleanup(ent->ud); - ent = ent->next; - } +static void arena_dofree(upb_arena *a) { + mem_block *block = a->freelist; + UPB_ASSERT(a->parent == a); + UPB_ASSERT(a->refcount == 0); - /* Must do this after running cleanup functions, because this will delete - * the memory we store our cleanup entries in! */ while (block) { /* Load first since we are deleting block. */ mem_block *next = block->next; - if (block->owned) { - upb_free(a->block_alloc, block); + if (block->cleanups > 0) { + cleanup_ent *end = UPB_PTR_AT(block, block->size, void); + cleanup_ent *ptr = end - block->cleanups; + + for (; ptr < end; ptr++) { + ptr->cleanup(ptr->ud); + } } + upb_free(a->block_alloc, block); block = next; } } +void upb_arena_free(upb_arena *a) { + a = arena_findroot(a); + if (--a->refcount == 0) arena_dofree(a); +} + bool upb_arena_addcleanup(upb_arena *a, void *ud, upb_cleanup_func *func) { - cleanup_ent *ent = upb_malloc(&a->alloc, sizeof(cleanup_ent)); - if (!ent) { - return false; /* Out of memory. */ + cleanup_ent *ent; + + if (!a->cleanups || !arena_has(a, sizeof(cleanup_ent))) { + if (!upb_arena_allocblock(a, 128)) return false; /* Out of memory. */ + UPB_ASSERT(arena_has(a, sizeof(cleanup_ent))); } + a->head.end -= sizeof(cleanup_ent); + ent = (cleanup_ent*)a->head.end; + (*a->cleanups)++; + ent->cleanup = func; ent->ud = ud; - ent->next = a->cleanup_head; - a->cleanup_head = ent; return true; } -size_t upb_arena_bytesallocated(const upb_arena *a) { - return a->bytes_allocated; +void upb_arena_fuse(upb_arena *a1, upb_arena *a2) { + upb_arena *r1 = arena_findroot(a1); + upb_arena *r2 = arena_findroot(a2); + + if (r1 == r2) return; /* Already fused. */ + + /* We want to join the smaller tree to the larger tree. + * So swap first if they are backwards. */ + if (r1->refcount < r2->refcount) { + upb_arena *tmp = r1; + r1 = r2; + r2 = tmp; + } + + /* r1 takes over r2's freelist and refcount. */ + r1->refcount += r2->refcount; + if (r2->freelist_tail) { + UPB_ASSERT(r2->freelist_tail->next == NULL); + r2->freelist_tail->next = r1->freelist; + r1->freelist = r2->freelist; + } + r2->parent = r1; } /* This file was generated by upbc (the upb compiler) from the input * file: @@ -2559,23 +2651,24 @@ static const upb_msglayout *const google_protobuf_FieldDescriptorProto_submsgs[1 &google_protobuf_FieldOptions_msginit, }; -static const upb_msglayout_field google_protobuf_FieldDescriptorProto__fields[10] = { - {1, UPB_SIZE(32, 32), 5, 0, 9, 1}, - {2, UPB_SIZE(40, 48), 6, 0, 9, 1}, +static const upb_msglayout_field google_protobuf_FieldDescriptorProto__fields[11] = { + {1, UPB_SIZE(36, 40), 6, 0, 9, 1}, + {2, UPB_SIZE(44, 56), 7, 0, 9, 1}, {3, UPB_SIZE(24, 24), 3, 0, 5, 1}, {4, UPB_SIZE(8, 8), 1, 0, 14, 1}, {5, UPB_SIZE(16, 16), 2, 0, 14, 1}, - {6, UPB_SIZE(48, 64), 7, 0, 9, 1}, - {7, UPB_SIZE(56, 80), 8, 0, 9, 1}, - {8, UPB_SIZE(72, 112), 10, 0, 11, 1}, + {6, UPB_SIZE(52, 72), 8, 0, 9, 1}, + {7, UPB_SIZE(60, 88), 9, 0, 9, 1}, + {8, UPB_SIZE(76, 120), 11, 0, 11, 1}, {9, UPB_SIZE(28, 28), 4, 0, 5, 1}, - {10, UPB_SIZE(64, 96), 9, 0, 9, 1}, + {10, UPB_SIZE(68, 104), 10, 0, 9, 1}, + {17, UPB_SIZE(32, 32), 5, 0, 8, 1}, }; const upb_msglayout google_protobuf_FieldDescriptorProto_msginit = { &google_protobuf_FieldDescriptorProto_submsgs[0], &google_protobuf_FieldDescriptorProto__fields[0], - UPB_SIZE(80, 128), 10, false, + UPB_SIZE(80, 128), 11, false, }; static const upb_msglayout *const google_protobuf_OneofDescriptorProto_submsgs[1] = { @@ -2870,8 +2963,8 @@ const upb_msglayout google_protobuf_SourceCodeInfo_msginit = { }; static const upb_msglayout_field google_protobuf_SourceCodeInfo_Location__fields[5] = { - {1, UPB_SIZE(20, 40), 0, 0, 5, 3}, - {2, UPB_SIZE(24, 48), 0, 0, 5, 3}, + {1, UPB_SIZE(20, 40), 0, 0, 5, _UPB_LABEL_PACKED}, + {2, UPB_SIZE(24, 48), 0, 0, 5, _UPB_LABEL_PACKED}, {3, UPB_SIZE(4, 8), 1, 0, 9, 1}, {4, UPB_SIZE(12, 24), 2, 0, 9, 1}, {6, UPB_SIZE(28, 56), 0, 0, 9, 3}, @@ -2898,7 +2991,7 @@ const upb_msglayout google_protobuf_GeneratedCodeInfo_msginit = { }; static const upb_msglayout_field google_protobuf_GeneratedCodeInfo_Annotation__fields[4] = { - {1, UPB_SIZE(20, 32), 0, 0, 5, 3}, + {1, UPB_SIZE(20, 32), 0, 0, 5, _UPB_LABEL_PACKED}, {2, UPB_SIZE(12, 16), 3, 0, 9, 1}, {3, UPB_SIZE(4, 4), 1, 0, 5, 1}, {4, UPB_SIZE(8, 8), 2, 0, 5, 1}, @@ -2937,6 +3030,7 @@ struct upb_fielddef { const upb_filedef *file; const upb_msgdef *msgdef; const char *full_name; + const char *json_name; union { int64_t sint; uint64_t uint; @@ -2952,16 +3046,19 @@ struct upb_fielddef { const google_protobuf_FieldDescriptorProto *unresolved; } sub; uint32_t number_; - uint32_t index_; + uint16_t index_; + uint16_t layout_index; uint32_t selector_base; /* Used to index into a upb::Handlers table. */ bool is_extension_; bool lazy_; bool packed_; + bool proto3_optional_; upb_descriptortype_t type_; upb_label_t label_; }; struct upb_msgdef { + const upb_msglayout *layout; const upb_filedef *file; const char *full_name; uint32_t selector_count; @@ -2975,6 +3072,7 @@ struct upb_msgdef { const upb_oneofdef *oneofs; int field_count; int oneof_count; + int real_oneof_count; /* Is this a map-entry message? */ bool map_entry; @@ -3025,10 +3123,15 @@ struct upb_symtab { /* Inside a symtab we store tagged pointers to specific def types. */ typedef enum { - UPB_DEFTYPE_MSG = 0, - UPB_DEFTYPE_ENUM = 1, - UPB_DEFTYPE_FIELD = 2, - UPB_DEFTYPE_ONEOF = 3 + UPB_DEFTYPE_FIELD = 0, + + /* Only inside symtab table. */ + UPB_DEFTYPE_MSG = 1, + UPB_DEFTYPE_ENUM = 2, + + /* Only inside message table. */ + UPB_DEFTYPE_ONEOF = 1, + UPB_DEFTYPE_FIELD_JSONNAME = 2 } upb_deftype_t; static const void *unpack_def(upb_value v, upb_deftype_t type) { @@ -3141,11 +3244,14 @@ static uint32_t upb_handlers_selectorcount(const upb_fielddef *f) { return ret; } +static void upb_status_setoom(upb_status *status) { + upb_status_seterrmsg(status, "out of memory"); +} + static bool assign_msg_indices(upb_msgdef *m, upb_status *s) { /* Sort fields. upb internally relies on UPB_TYPE_MESSAGE fields having the * lowest indexes, but we do not publicly guarantee this. */ upb_msg_field_iter j; - upb_msg_oneof_iter k; int i; uint32_t selector; int n = upb_msgdef_numfields(m); @@ -3186,14 +3292,38 @@ static bool assign_msg_indices(upb_msgdef *m, upb_status *s) { } m->selector_count = selector; - for(upb_msg_oneof_begin(&k, m), i = 0; - !upb_msg_oneof_done(&k); - upb_msg_oneof_next(&k), i++) { - upb_oneofdef *o = (upb_oneofdef*)upb_msg_iter_oneof(&k); - o->index = i; + upb_gfree(fields); + return true; +} + +static bool check_oneofs(upb_msgdef *m, upb_status *s) { + int i; + int first_synthetic = -1; + upb_oneofdef *mutable_oneofs = (upb_oneofdef*)m->oneofs; + + for (i = 0; i < m->oneof_count; i++) { + mutable_oneofs[i].index = i; + + if (upb_oneofdef_issynthetic(&mutable_oneofs[i])) { + if (first_synthetic == -1) { + first_synthetic = i; + } + } else { + if (first_synthetic != -1) { + upb_status_seterrf( + s, "Synthetic oneofs must be after all other oneofs: %s", + upb_oneofdef_name(&mutable_oneofs[i])); + return false; + } + } + } + + if (first_synthetic == -1) { + m->real_oneof_count = m->oneof_count; + } else { + m->real_oneof_count = first_synthetic; } - upb_gfree(fields); return true; } @@ -3261,7 +3391,7 @@ int32_t upb_enumdef_default(const upb_enumdef *e) { } int upb_enumdef_numvals(const upb_enumdef *e) { - return upb_strtable_count(&e->ntoi); + return (int)upb_strtable_count(&e->ntoi); } void upb_enum_begin(upb_enum_iter *i, const upb_enumdef *e) { @@ -3289,7 +3419,7 @@ const char *upb_enumdef_iton(const upb_enumdef *def, int32_t num) { } const char *upb_enum_iter_name(upb_enum_iter *iter) { - return upb_strtable_iter_key(iter); + return upb_strtable_iter_key(iter).data; } int32_t upb_enum_iter_number(upb_enum_iter *iter) { @@ -3364,53 +3494,22 @@ bool upb_fielddef_lazy(const upb_fielddef *f) { bool upb_fielddef_packed(const upb_fielddef *f) { return f->packed_; -} - -const char *upb_fielddef_name(const upb_fielddef *f) { - return shortdefname(f->full_name); -} - -uint32_t upb_fielddef_selectorbase(const upb_fielddef *f) { - return f->selector_base; -} - -size_t upb_fielddef_getjsonname(const upb_fielddef *f, char *buf, size_t len) { - const char *name = upb_fielddef_name(f); - size_t src, dst = 0; - bool ucase_next = false; - -#define WRITE(byte) \ - ++dst; \ - if (dst < len) buf[dst - 1] = byte; \ - else if (dst == len) buf[dst - 1] = '\0' - - if (!name) { - WRITE('\0'); - return 0; - } +} - /* Implement the transformation as described in the spec: - * 1. upper case all letters after an underscore. - * 2. remove all underscores. - */ - for (src = 0; name[src]; src++) { - if (name[src] == '_') { - ucase_next = true; - continue; - } +const char *upb_fielddef_name(const upb_fielddef *f) { + return shortdefname(f->full_name); +} - if (ucase_next) { - WRITE(toupper(name[src])); - ucase_next = false; - } else { - WRITE(name[src]); - } - } +const char *upb_fielddef_jsonname(const upb_fielddef *f) { + return f->json_name; +} - WRITE('\0'); - return dst; +uint32_t upb_fielddef_selectorbase(const upb_fielddef *f) { + return f->selector_base; +} -#undef WRITE +const upb_filedef *upb_fielddef_file(const upb_fielddef *f) { + return f->file; } const upb_msgdef *upb_fielddef_containingtype(const upb_fielddef *f) { @@ -3421,6 +3520,11 @@ const upb_oneofdef *upb_fielddef_containingoneof(const upb_fielddef *f) { return f->oneof; } +const upb_oneofdef *upb_fielddef_realcontainingoneof(const upb_fielddef *f) { + if (!f->oneof || upb_oneofdef_issynthetic(f->oneof)) return NULL; + return f->oneof; +} + static void chkdefaulttype(const upb_fielddef *f, int ctype) { UPB_UNUSED(f); UPB_UNUSED(ctype); @@ -3433,7 +3537,7 @@ int64_t upb_fielddef_defaultint64(const upb_fielddef *f) { int32_t upb_fielddef_defaultint32(const upb_fielddef *f) { chkdefaulttype(f, UPB_TYPE_INT32); - return f->defaultval.sint; + return (int32_t)f->defaultval.sint; } uint64_t upb_fielddef_defaultuint64(const upb_fielddef *f) { @@ -3443,7 +3547,7 @@ uint64_t upb_fielddef_defaultuint64(const upb_fielddef *f) { uint32_t upb_fielddef_defaultuint32(const upb_fielddef *f) { chkdefaulttype(f, UPB_TYPE_UINT32); - return f->defaultval.uint; + return (uint32_t)f->defaultval.uint; } bool upb_fielddef_defaultbool(const upb_fielddef *f) { @@ -3485,6 +3589,10 @@ const upb_enumdef *upb_fielddef_enumsubdef(const upb_fielddef *f) { return f->sub.enumdef; } +const upb_msglayout_field *upb_fielddef_layout(const upb_fielddef *f) { + return &f->msgdef->layout->fields[f->layout_index]; +} + bool upb_fielddef_issubmsg(const upb_fielddef *f) { return upb_fielddef_type(f) == UPB_TYPE_MESSAGE; } @@ -3513,8 +3621,8 @@ bool upb_fielddef_hassubdef(const upb_fielddef *f) { bool upb_fielddef_haspresence(const upb_fielddef *f) { if (upb_fielddef_isseq(f)) return false; - if (upb_fielddef_issubmsg(f)) return true; - return f->file->syntax == UPB_SYNTAX_PROTO2; + return upb_fielddef_issubmsg(f) || upb_fielddef_containingoneof(f) || + f->file->syntax == UPB_SYNTAX_PROTO2; } static bool between(int32_t x, int32_t low, int32_t high) { @@ -3593,18 +3701,43 @@ bool upb_msgdef_lookupname(const upb_msgdef *m, const char *name, size_t len, *o = unpack_def(val, UPB_DEFTYPE_ONEOF); *f = unpack_def(val, UPB_DEFTYPE_FIELD); - UPB_ASSERT((*o != NULL) ^ (*f != NULL)); /* Exactly one of the two should be set. */ - return true; + return *o || *f; /* False if this was a JSON name. */ +} + +const upb_fielddef *upb_msgdef_lookupjsonname(const upb_msgdef *m, + const char *name, size_t len) { + upb_value val; + const upb_fielddef* f; + + if (!upb_strtable_lookup2(&m->ntof, name, len, &val)) { + return NULL; + } + + f = unpack_def(val, UPB_DEFTYPE_FIELD); + if (!f) f = unpack_def(val, UPB_DEFTYPE_FIELD_JSONNAME); + + return f; } int upb_msgdef_numfields(const upb_msgdef *m) { - /* The number table contains only fields. */ - return upb_inttable_count(&m->itof); + return m->field_count; } int upb_msgdef_numoneofs(const upb_msgdef *m) { - /* The name table includes oneofs, and the number table does not. */ - return upb_strtable_count(&m->ntof) - upb_inttable_count(&m->itof); + return m->oneof_count; +} + +int upb_msgdef_numrealoneofs(const upb_msgdef *m) { + return m->real_oneof_count; +} + +const upb_msglayout *upb_msgdef_layout(const upb_msgdef *m) { + return m->layout; +} + +const upb_fielddef *_upb_msgdef_field(const upb_msgdef *m, int i) { + if (i >= m->field_count) return NULL; + return &m->fields[i]; } bool upb_msgdef_mapentry(const upb_msgdef *m) { @@ -3689,13 +3822,23 @@ const upb_msgdef *upb_oneofdef_containingtype(const upb_oneofdef *o) { } int upb_oneofdef_numfields(const upb_oneofdef *o) { - return upb_strtable_count(&o->ntof); + return (int)upb_strtable_count(&o->ntof); } uint32_t upb_oneofdef_index(const upb_oneofdef *o) { return o->index; } +bool upb_oneofdef_issynthetic(const upb_oneofdef *o) { + upb_inttable_iter iter; + const upb_fielddef *f; + upb_inttable_begin(&iter, &o->itof); + if (upb_oneofdef_numfields(o) != 1) return false; + f = upb_value_getptr(upb_inttable_iter_value(&iter)); + UPB_ASSERT(f); + return f->proto3_optional_; +} + const upb_fielddef *upb_oneofdef_ntof(const upb_oneofdef *o, const char *name, size_t length) { upb_value val; @@ -3729,6 +3872,215 @@ void upb_oneof_iter_setdone(upb_oneof_iter *iter) { upb_inttable_iter_setdone(iter); } +/* Dynamic Layout Generation. *************************************************/ + +static size_t div_round_up(size_t n, size_t d) { + return (n + d - 1) / d; +} + +static size_t upb_msgval_sizeof(upb_fieldtype_t type) { + switch (type) { + case UPB_TYPE_DOUBLE: + case UPB_TYPE_INT64: + case UPB_TYPE_UINT64: + return 8; + case UPB_TYPE_ENUM: + case UPB_TYPE_INT32: + case UPB_TYPE_UINT32: + case UPB_TYPE_FLOAT: + return 4; + case UPB_TYPE_BOOL: + return 1; + case UPB_TYPE_MESSAGE: + return sizeof(void*); + case UPB_TYPE_BYTES: + case UPB_TYPE_STRING: + return sizeof(upb_strview); + } + UPB_UNREACHABLE(); +} + +static uint8_t upb_msg_fielddefsize(const upb_fielddef *f) { + if (upb_msgdef_mapentry(upb_fielddef_containingtype(f))) { + upb_map_entry ent; + UPB_ASSERT(sizeof(ent.k) == sizeof(ent.v)); + return sizeof(ent.k); + } else if (upb_fielddef_isseq(f)) { + return sizeof(void*); + } else { + return upb_msgval_sizeof(upb_fielddef_type(f)); + } +} + +static uint32_t upb_msglayout_place(upb_msglayout *l, size_t size) { + uint32_t ret; + + l->size = UPB_ALIGN_UP(l->size, size); + ret = l->size; + l->size += size; + return ret; +} + +/* This function is the dynamic equivalent of message_layout.{cc,h} in upbc. + * It computes a dynamic layout for all of the fields in |m|. */ +static bool make_layout(const upb_symtab *symtab, const upb_msgdef *m) { + upb_msglayout *l = (upb_msglayout*)m->layout; + upb_msg_field_iter it; + upb_msg_oneof_iter oit; + size_t hasbit; + size_t submsg_count = m->submsg_field_count; + const upb_msglayout **submsgs; + upb_msglayout_field *fields; + upb_alloc *alloc = upb_arena_alloc(symtab->arena); + + memset(l, 0, sizeof(*l)); + + fields = upb_malloc(alloc, upb_msgdef_numfields(m) * sizeof(*fields)); + submsgs = upb_malloc(alloc, submsg_count * sizeof(*submsgs)); + + if ((!fields && upb_msgdef_numfields(m)) || + (!submsgs && submsg_count)) { + /* OOM. */ + return false; + } + + l->field_count = upb_msgdef_numfields(m); + l->fields = fields; + l->submsgs = submsgs; + + if (upb_msgdef_mapentry(m)) { + /* TODO(haberman): refactor this method so this special case is more + * elegant. */ + const upb_fielddef *key = upb_msgdef_itof(m, 1); + const upb_fielddef *val = upb_msgdef_itof(m, 2); + fields[0].number = 1; + fields[1].number = 2; + fields[0].label = UPB_LABEL_OPTIONAL; + fields[1].label = UPB_LABEL_OPTIONAL; + fields[0].presence = 0; + fields[1].presence = 0; + fields[0].descriptortype = upb_fielddef_descriptortype(key); + fields[1].descriptortype = upb_fielddef_descriptortype(val); + fields[0].offset = 0; + fields[1].offset = sizeof(upb_strview); + fields[1].submsg_index = 0; + + if (upb_fielddef_type(val) == UPB_TYPE_MESSAGE) { + submsgs[0] = upb_fielddef_msgsubdef(val)->layout; + } + + l->field_count = 2; + l->size = 2 * sizeof(upb_strview); + l->size = UPB_ALIGN_UP(l->size, 8); + return true; + } + + /* Allocate data offsets in three stages: + * + * 1. hasbits. + * 2. regular fields. + * 3. oneof fields. + * + * OPT: There is a lot of room for optimization here to minimize the size. + */ + + /* Allocate hasbits and set basic field attributes. */ + submsg_count = 0; + for (upb_msg_field_begin(&it, m), hasbit = 0; + !upb_msg_field_done(&it); + upb_msg_field_next(&it)) { + upb_fielddef* f = upb_msg_iter_field(&it); + upb_msglayout_field *field = &fields[upb_fielddef_index(f)]; + + field->number = upb_fielddef_number(f); + field->descriptortype = upb_fielddef_descriptortype(f); + field->label = upb_fielddef_label(f); + + if (upb_fielddef_ismap(f)) { + field->label = _UPB_LABEL_MAP; + } else if (upb_fielddef_packed(f)) { + field->label = _UPB_LABEL_PACKED; + } + + /* TODO: we probably should sort the fields by field number to match the + * output of upbc, and to improve search speed for the table parser. */ + f->layout_index = f->index_; + + if (upb_fielddef_issubmsg(f)) { + const upb_msgdef *subm = upb_fielddef_msgsubdef(f); + field->submsg_index = submsg_count++; + submsgs[field->submsg_index] = subm->layout; + } + + if (upb_fielddef_haspresence(f) && !upb_fielddef_realcontainingoneof(f)) { + /* We don't use hasbit 0, so that 0 can indicate "no presence" in the + * table. This wastes one hasbit, but we don't worry about it for now. */ + field->presence = ++hasbit; + } else { + field->presence = 0; + } + } + + /* Account for space used by hasbits. */ + l->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_fielddefsize(f); + size_t index = upb_fielddef_index(f); + + if (upb_fielddef_realcontainingoneof(f)) { + /* Oneofs are handled separately below. */ + continue; + } + + 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* o = upb_msg_iter_oneof(&oit); + upb_oneof_iter fit; + + size_t case_size = sizeof(uint32_t); /* Could potentially optimize this. */ + size_t field_size = 0; + uint32_t case_offset; + uint32_t data_offset; + + if (upb_oneofdef_issynthetic(o)) continue; + + /* Calculate field size: the max of all field sizes. */ + 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_fielddefsize(f)); + } + + /* Align and allocate case offset. */ + case_offset = upb_msglayout_place(l, case_size); + data_offset = upb_msglayout_place(l, field_size); + + for (upb_oneof_begin(&fit, o); + !upb_oneof_done(&fit); + upb_oneof_next(&fit)) { + const upb_fielddef* f = upb_oneof_iter_field(&fit); + fields[upb_fielddef_index(f)].offset = data_offset; + fields[upb_fielddef_index(f)].presence = ~case_offset; + } + } + + /* Size of the entire structure should be a multiple of its greatest + * alignment. TODO: track overall alignment for real? */ + l->size = UPB_ALIGN_UP(l->size, 8); + + return true; +} + /* Code to build defs from descriptor protos. *********************************/ /* There is a question of how much validation to do here. It will be difficult @@ -3741,11 +4093,12 @@ void upb_oneof_iter_setdone(upb_oneof_iter *iter) { typedef struct { const upb_symtab *symtab; - upb_filedef *file; /* File we are building. */ - upb_alloc *alloc; /* Allocate defs here. */ - upb_alloc *tmp; /* Alloc for addtab and any other tmp data. */ - upb_strtable *addtab; /* full_name -> packed def ptr for new defs. */ - upb_status *status; /* Record errors here. */ + upb_filedef *file; /* File we are building. */ + upb_alloc *alloc; /* Allocate defs here. */ + upb_alloc *tmp; /* Alloc for addtab and any other tmp data. */ + upb_strtable *addtab; /* full_name -> packed def ptr for new defs */ + const upb_msglayout **layouts; /* NULL if we should build layouts. */ + upb_status *status; /* Record errors here. */ } symtab_addctx; static char* strviewdup(const symtab_addctx *ctx, upb_strview view) { @@ -3777,6 +4130,51 @@ static const char *makefullname(const symtab_addctx *ctx, const char *prefix, } } +size_t getjsonname(const char *name, char *buf, size_t len) { + size_t src, dst = 0; + bool ucase_next = false; + +#define WRITE(byte) \ + ++dst; \ + if (dst < len) buf[dst - 1] = byte; \ + else if (dst == len) buf[dst - 1] = '\0' + + if (!name) { + WRITE('\0'); + return 0; + } + + /* Implement the transformation as described in the spec: + * 1. upper case all letters after an underscore. + * 2. remove all underscores. + */ + for (src = 0; name[src]; src++) { + if (name[src] == '_') { + ucase_next = true; + continue; + } + + if (ucase_next) { + WRITE(toupper(name[src])); + ucase_next = false; + } else { + WRITE(name[src]); + } + } + + WRITE('\0'); + return dst; + +#undef WRITE +} + +static char* makejsonname(const char* name, upb_alloc *alloc) { + size_t size = getjsonname(name, NULL, 0); + char* json_name = upb_malloc(alloc, size); + getjsonname(name, json_name, size); + return json_name; +} + static bool symtab_add(const symtab_addctx *ctx, const char *name, upb_value v) { upb_value tmp; @@ -3900,7 +4298,7 @@ static bool parse_default(const symtab_addctx *ctx, const char *str, size_t len, } case UPB_TYPE_INT64: { /* XXX: Need to write our own strtoll, since it's not available in c89. */ - long long val = strtol(str, &end, 0); + int64_t val = strtol(str, &end, 0); CHK(val <= INT64_MAX && val >= INT64_MIN && errno != ERANGE && !*end); f->defaultval.sint = val; break; @@ -3913,7 +4311,7 @@ static bool parse_default(const symtab_addctx *ctx, const char *str, size_t len, } case UPB_TYPE_UINT64: { /* XXX: Need to write our own strtoull, since it's not available in c89. */ - unsigned long long val = strtoul(str, &end, 0); + uint64_t val = strtoul(str, &end, 0); CHK(val <= UINT64_MAX && errno != ERANGE && !*end); f->defaultval.uint = val; break; @@ -3990,6 +4388,7 @@ static bool create_fielddef( const google_protobuf_FieldOptions *options; upb_strview name; const char *full_name; + const char *json_name; const char *shortname; uint32_t field_number; @@ -4003,6 +4402,13 @@ static bool create_fielddef( full_name = makefullname(ctx, prefix, name); shortname = shortdefname(full_name); + if (google_protobuf_FieldDescriptorProto_has_json_name(field_proto)) { + json_name = strviewdup( + ctx, google_protobuf_FieldDescriptorProto_json_name(field_proto)); + } else { + json_name = makejsonname(shortname, ctx->alloc); + } + field_number = google_protobuf_FieldDescriptorProto_number(field_proto); if (field_number == 0 || field_number > UPB_MAX_FIELDNUMBER) { @@ -4012,38 +4418,72 @@ static bool create_fielddef( if (m) { /* direct message field. */ - upb_value v, packed_v; + upb_value v, field_v, json_v; + size_t json_size; f = (upb_fielddef*)&m->fields[m->field_count++]; f->msgdef = m; f->is_extension_ = false; - packed_v = pack_def(f, UPB_DEFTYPE_FIELD); - v = upb_value_constptr(f); - - if (!upb_strtable_insert3(&m->ntof, name.data, name.size, packed_v, alloc)) { + if (upb_strtable_lookup(&m->ntof, shortname, NULL)) { upb_status_seterrf(ctx->status, "duplicate field name (%s)", shortname); return false; } - if (!upb_inttable_insert2(&m->itof, field_number, v, alloc)) { + if (upb_strtable_lookup(&m->ntof, json_name, NULL)) { + upb_status_seterrf(ctx->status, "duplicate json_name (%s)", json_name); + return false; + } + + if (upb_inttable_lookup(&m->itof, field_number, NULL)) { upb_status_seterrf(ctx->status, "duplicate field number (%u)", field_number); return false; } + + field_v = pack_def(f, UPB_DEFTYPE_FIELD); + json_v = pack_def(f, UPB_DEFTYPE_FIELD_JSONNAME); + v = upb_value_constptr(f); + json_size = strlen(json_name); + + CHK_OOM( + upb_strtable_insert3(&m->ntof, name.data, name.size, field_v, alloc)); + CHK_OOM(upb_inttable_insert2(&m->itof, field_number, v, alloc)); + + if (strcmp(shortname, json_name) != 0) { + upb_strtable_insert3(&m->ntof, json_name, json_size, json_v, alloc); + } + + if (ctx->layouts) { + const upb_msglayout_field *fields = m->layout->fields; + int count = m->layout->field_count; + bool found = false; + int i; + for (i = 0; i < count; i++) { + if (fields[i].number == field_number) { + f->layout_index = i; + found = true; + break; + } + } + UPB_ASSERT(found); + } } else { /* extension field. */ - f = (upb_fielddef*)&ctx->file->exts[ctx->file->ext_count]; + f = (upb_fielddef*)&ctx->file->exts[ctx->file->ext_count++]; f->is_extension_ = true; CHK_OOM(symtab_add(ctx, full_name, pack_def(f, UPB_DEFTYPE_FIELD))); } f->full_name = full_name; + f->json_name = json_name; f->file = ctx->file; f->type_ = (int)google_protobuf_FieldDescriptorProto_type(field_proto); f->label_ = (int)google_protobuf_FieldDescriptorProto_label(field_proto); f->number_ = field_number; f->oneof = NULL; + f->proto3_optional_ = + google_protobuf_FieldDescriptorProto_proto3_optional(field_proto); /* We can't resolve the subdef or (in the case of extensions) the containing * message yet, because it may not have been defined yet. We stash a pointer @@ -4167,7 +4607,7 @@ static bool create_enumdef( return true; } -static bool create_msgdef(const symtab_addctx *ctx, const char *prefix, +static bool create_msgdef(symtab_addctx *ctx, const char *prefix, const google_protobuf_DescriptorProto *msg_proto) { upb_msgdef *m; const google_protobuf_MessageOptions *options; @@ -4197,6 +4637,14 @@ static bool create_msgdef(const symtab_addctx *ctx, const char *prefix, m->map_entry = google_protobuf_MessageOptions_map_entry(options); } + if (ctx->layouts) { + m->layout = *ctx->layouts; + ctx->layouts++; + } else { + /* Allocate now (to allow cross-linking), populate later. */ + m->layout = upb_malloc(ctx->alloc, sizeof(*m->layout)); + } + oneofs = google_protobuf_DescriptorProto_oneof_decl(msg_proto, &n); m->oneof_count = 0; m->oneofs = upb_malloc(ctx->alloc, sizeof(*m->oneofs) * n); @@ -4212,6 +4660,7 @@ static bool create_msgdef(const symtab_addctx *ctx, const char *prefix, } CHK(assign_msg_indices(m, ctx->status)); + CHK(check_oneofs(m, ctx->status)); assign_msg_wellknowntype(m); upb_inttable_compact2(&m->itof, ctx->alloc); @@ -4343,7 +4792,7 @@ static bool resolve_fielddef(const symtab_addctx *ctx, const char *prefix, } static bool build_filedef( - const symtab_addctx *ctx, upb_filedef *file, + symtab_addctx *ctx, upb_filedef *file, const google_protobuf_FileDescriptorProto *file_proto) { upb_alloc *alloc = ctx->alloc; const google_protobuf_FileOptions *file_options_proto; @@ -4397,7 +4846,8 @@ static bool build_filedef( } else if (streql_view(syntax, "proto3")) { file->syntax = UPB_SYNTAX_PROTO3; } else { - upb_status_seterrf(ctx->status, "Invalid syntax '%s'", syntax); + upb_status_seterrf(ctx->status, "Invalid syntax '" UPB_STRVIEW_FORMAT "'", + UPB_STRVIEW_ARGS(syntax)); return false; } } else { @@ -4457,7 +4907,7 @@ static bool build_filedef( CHK(create_fielddef(ctx, file->package, NULL, exts[i])); } - /* Now that all names are in the table, resolve references. */ + /* Now that all names are in the table, build layouts and resolve refs. */ for (i = 0; i < file->ext_count; i++) { CHK(resolve_fielddef(ctx, file->package, (upb_fielddef*)&file->exts[i])); } @@ -4470,6 +4920,13 @@ static bool build_filedef( } } + if (!ctx->layouts) { + for (i = 0; i < file->msg_count; i++) { + const upb_msgdef *m = &file->msgs[i]; + make_layout(ctx->symtab, m); + } + } + return true; } @@ -4484,10 +4941,9 @@ static bool upb_symtab_addtotabs(upb_symtab *s, symtab_addctx *ctx, upb_strtable_begin(&iter, ctx->addtab); for (; !upb_strtable_done(&iter); upb_strtable_next(&iter)) { - const char *key = upb_strtable_iter_key(&iter); - size_t keylen = upb_strtable_iter_keylength(&iter); + upb_strview key = upb_strtable_iter_key(&iter); upb_value value = upb_strtable_iter_value(&iter); - CHK_OOM(upb_strtable_insert3(&s->syms, key, keylen, value, alloc)); + CHK_OOM(upb_strtable_insert3(&s->syms, key.data, key.size, value, alloc)); } return true; @@ -4596,9 +5052,13 @@ const upb_filedef *upb_symtab_lookupfile2( upb_value_getconstptr(v) : NULL; } -const upb_filedef *upb_symtab_addfile( +int upb_symtab_filecount(const upb_symtab *s) { + return (int)upb_strtable_count(&s->files); +} + +static const upb_filedef *_upb_symtab_addfile( upb_symtab *s, const google_protobuf_FileDescriptorProto *file_proto, - upb_status *status) { + const upb_msglayout **layouts, upb_status *status) { upb_arena *tmparena = upb_arena_new(); upb_strtable addtab; upb_alloc *alloc = upb_arena_alloc(s->arena); @@ -4611,6 +5071,7 @@ const upb_filedef *upb_symtab_addfile( ctx.alloc = alloc; ctx.tmp = upb_arena_alloc(tmparena); ctx.addtab = &addtab; + ctx.layouts = layouts; ctx.status = status; ok = file && @@ -4622,6 +5083,12 @@ const upb_filedef *upb_symtab_addfile( return ok ? file : NULL; } +const upb_filedef *upb_symtab_addfile( + upb_symtab *s, const google_protobuf_FileDescriptorProto *file_proto, + upb_status *status) { + return _upb_symtab_addfile(s, file_proto, NULL, status); +} + /* Include here since we want most of this file to be stdio-free. */ #include @@ -4657,7 +5124,7 @@ bool _upb_symtab_loaddefinit(upb_symtab *s, const upb_def_init *init) { goto err; } - if (!upb_symtab_addfile(s, file, &status)) goto err; + if (!_upb_symtab_addfile(s, file, init->layouts, &status)) goto err; upb_arena_free(arena); return true; @@ -4673,250 +5140,311 @@ bool _upb_symtab_loaddefinit(upb_symtab *s, const upb_def_init *init) { #undef CHK_OOM +#include + + +static char field_size[] = { + 0,/* 0 */ + 8, /* UPB_DESCRIPTOR_TYPE_DOUBLE */ + 4, /* UPB_DESCRIPTOR_TYPE_FLOAT */ + 8, /* UPB_DESCRIPTOR_TYPE_INT64 */ + 8, /* UPB_DESCRIPTOR_TYPE_UINT64 */ + 4, /* UPB_DESCRIPTOR_TYPE_INT32 */ + 8, /* UPB_DESCRIPTOR_TYPE_FIXED64 */ + 4, /* UPB_DESCRIPTOR_TYPE_FIXED32 */ + 1, /* UPB_DESCRIPTOR_TYPE_BOOL */ + sizeof(upb_strview), /* UPB_DESCRIPTOR_TYPE_STRING */ + sizeof(void*), /* UPB_DESCRIPTOR_TYPE_GROUP */ + sizeof(void*), /* UPB_DESCRIPTOR_TYPE_MESSAGE */ + sizeof(upb_strview), /* UPB_DESCRIPTOR_TYPE_BYTES */ + 4, /* UPB_DESCRIPTOR_TYPE_UINT32 */ + 4, /* UPB_DESCRIPTOR_TYPE_ENUM */ + 4, /* UPB_DESCRIPTOR_TYPE_SFIXED32 */ + 8, /* UPB_DESCRIPTOR_TYPE_SFIXED64 */ + 4, /* UPB_DESCRIPTOR_TYPE_SINT32 */ + 8, /* UPB_DESCRIPTOR_TYPE_SINT64 */ +}; + +/* Strings/bytes are special-cased in maps. */ +static char _upb_fieldtype_to_mapsize[12] = { + 0, + 1, /* UPB_TYPE_BOOL */ + 4, /* UPB_TYPE_FLOAT */ + 4, /* UPB_TYPE_INT32 */ + 4, /* UPB_TYPE_UINT32 */ + 4, /* UPB_TYPE_ENUM */ + sizeof(void*), /* UPB_TYPE_MESSAGE */ + 8, /* UPB_TYPE_DOUBLE */ + 8, /* UPB_TYPE_INT64 */ + 8, /* UPB_TYPE_UINT64 */ + 0, /* UPB_TYPE_STRING */ + 0, /* UPB_TYPE_BYTES */ +}; + +/** upb_msg *******************************************************************/ -static bool is_power_of_two(size_t val) { - return (val & (val - 1)) == 0; +upb_msg *upb_msg_new(const upb_msgdef *m, upb_arena *a) { + return _upb_msg_new(upb_msgdef_layout(m), a); } -/* Align up to the given power of 2. */ -static size_t align_up(size_t val, size_t align) { - UPB_ASSERT(is_power_of_two(align)); - return (val + align - 1) & ~(align - 1); +static bool in_oneof(const upb_msglayout_field *field) { + return field->presence < 0; } -static size_t div_round_up(size_t n, size_t d) { - return (n + d - 1) / d; +static uint32_t *oneofcase(const upb_msg *msg, + const upb_msglayout_field *field) { + UPB_ASSERT(in_oneof(field)); + return UPB_PTR_AT(msg, -field->presence, uint32_t); } -static size_t upb_msgval_sizeof2(upb_fieldtype_t type) { - switch (type) { - case UPB_TYPE_DOUBLE: - case UPB_TYPE_INT64: - case UPB_TYPE_UINT64: - return 8; - case UPB_TYPE_ENUM: - case UPB_TYPE_INT32: - case UPB_TYPE_UINT32: - case UPB_TYPE_FLOAT: - return 4; - case UPB_TYPE_BOOL: - return 1; - case UPB_TYPE_MESSAGE: - return sizeof(void*); - case UPB_TYPE_BYTES: - case UPB_TYPE_STRING: - return sizeof(upb_strview); - } - UPB_UNREACHABLE(); +static upb_msgval _upb_msg_getraw(const upb_msg *msg, const upb_fielddef *f) { + const upb_msglayout_field *field = upb_fielddef_layout(f); + const char *mem = UPB_PTR_AT(msg, field->offset, char); + upb_msgval val = {0}; + int size = upb_fielddef_isseq(f) ? sizeof(void *) + : field_size[field->descriptortype]; + memcpy(&val, mem, size); + return val; } -static uint8_t upb_msg_fielddefsize(const upb_fielddef *f) { - if (upb_fielddef_isseq(f)) { - return sizeof(void*); +bool upb_msg_has(const upb_msg *msg, const upb_fielddef *f) { + const upb_msglayout_field *field = upb_fielddef_layout(f); + if (in_oneof(field)) { + return *oneofcase(msg, field) == field->number; + } else if (field->presence > 0) { + uint32_t hasbit = field->presence; + return *UPB_PTR_AT(msg, hasbit / 8, uint8_t) & (1 << (hasbit % 8)); } else { - return upb_msgval_sizeof2(upb_fielddef_type(f)); + UPB_ASSERT(field->descriptortype == UPB_DESCRIPTOR_TYPE_MESSAGE || + field->descriptortype == UPB_DESCRIPTOR_TYPE_GROUP); + return _upb_msg_getraw(msg, f).msg_val != NULL; } } +bool upb_msg_hasoneof(const upb_msg *msg, const upb_oneofdef *o) { + upb_oneof_iter i; + const upb_fielddef *f; + const upb_msglayout_field *field; -/** upb_msglayout *************************************************************/ - -static void upb_msglayout_free(upb_msglayout *l) { - upb_gfree(l); -} - -static size_t upb_msglayout_place(upb_msglayout *l, size_t size) { - size_t ret; - - l->size = align_up(l->size, size); - ret = l->size; - l->size += size; - return ret; + upb_oneof_begin(&i, o); + if (upb_oneof_done(&i)) return false; + f = upb_oneof_iter_field(&i); + field = upb_fielddef_layout(f); + return *oneofcase(msg, field) != 0; } -static bool upb_msglayout_init(const upb_msgdef *m, - upb_msglayout *l, - upb_msgfactory *factory) { - upb_msg_field_iter it; - upb_msg_oneof_iter oit; - size_t hasbit; - size_t submsg_count = 0; - const upb_msglayout **submsgs; - upb_msglayout_field *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); - if (upb_fielddef_issubmsg(f)) { - submsg_count++; +upb_msgval upb_msg_get(const upb_msg *msg, const upb_fielddef *f) { + if (!upb_fielddef_haspresence(f) || upb_msg_has(msg, f)) { + return _upb_msg_getraw(msg, f); + } else { + /* TODO(haberman): change upb_fielddef to not require this switch(). */ + upb_msgval val = {0}; + switch (upb_fielddef_type(f)) { + case UPB_TYPE_INT32: + case UPB_TYPE_ENUM: + val.int32_val = upb_fielddef_defaultint32(f); + break; + case UPB_TYPE_INT64: + val.int64_val = upb_fielddef_defaultint64(f); + break; + case UPB_TYPE_UINT32: + val.uint32_val = upb_fielddef_defaultuint32(f); + break; + case UPB_TYPE_UINT64: + val.uint64_val = upb_fielddef_defaultuint64(f); + break; + case UPB_TYPE_FLOAT: + val.float_val = upb_fielddef_defaultfloat(f); + break; + case UPB_TYPE_DOUBLE: + val.double_val = upb_fielddef_defaultdouble(f); + break; + case UPB_TYPE_BOOL: + val.double_val = upb_fielddef_defaultbool(f); + break; + case UPB_TYPE_STRING: + case UPB_TYPE_BYTES: + val.str_val.data = upb_fielddef_defaultstr(f, &val.str_val.size); + break; + case UPB_TYPE_MESSAGE: + val.msg_val = NULL; + break; } + return val; } +} - memset(l, 0, sizeof(*l)); - - fields = upb_gmalloc(upb_msgdef_numfields(m) * sizeof(*fields)); - submsgs = upb_gmalloc(submsg_count * sizeof(*submsgs)); - - if ((!fields && upb_msgdef_numfields(m)) || - (!submsgs && submsg_count)) { - /* OOM. */ - upb_gfree(fields); - upb_gfree(submsgs); - return false; - } - - l->field_count = upb_msgdef_numfields(m); - l->fields = fields; - l->submsgs = submsgs; - - /* Allocate data offsets in three stages: - * - * 1. hasbits. - * 2. regular fields. - * 3. oneof fields. - * - * OPT: There is a lot of room for optimization here to minimize the size. - */ - - /* Allocate hasbits and set basic field attributes. */ - submsg_count = 0; - 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_field *field = &fields[upb_fielddef_index(f)]; +upb_mutmsgval upb_msg_mutable(upb_msg *msg, const upb_fielddef *f, + upb_arena *a) { + const upb_msglayout_field *field = upb_fielddef_layout(f); + upb_mutmsgval ret; + char *mem = UPB_PTR_AT(msg, field->offset, char); + bool wrong_oneof = in_oneof(field) && *oneofcase(msg, field) != field->number; - field->number = upb_fielddef_number(f); - field->descriptortype = upb_fielddef_descriptortype(f); - field->label = upb_fielddef_label(f); + memcpy(&ret, mem, sizeof(void*)); - if (upb_fielddef_issubmsg(f)) { - const upb_msglayout *sub_layout = - upb_msgfactory_getlayout(factory, upb_fielddef_msgsubdef(f)); - field->submsg_index = submsg_count++; - submsgs[field->submsg_index] = sub_layout; + if (a && (!ret.msg || wrong_oneof)) { + if (upb_fielddef_ismap(f)) { + const upb_msgdef *entry = upb_fielddef_msgsubdef(f); + const upb_fielddef *key = upb_msgdef_itof(entry, UPB_MAPENTRY_KEY); + const upb_fielddef *value = upb_msgdef_itof(entry, UPB_MAPENTRY_VALUE); + ret.map = upb_map_new(a, upb_fielddef_type(key), upb_fielddef_type(value)); + } else if (upb_fielddef_isseq(f)) { + ret.array = upb_array_new(a, upb_fielddef_type(f)); + } else { + UPB_ASSERT(upb_fielddef_issubmsg(f)); + ret.msg = upb_msg_new(upb_fielddef_msgsubdef(f), a); } - if (upb_fielddef_haspresence(f) && !upb_fielddef_containingoneof(f)) { - field->presence = (hasbit++); - } else { - field->presence = 0; + memcpy(mem, &ret, sizeof(void*)); + + if (wrong_oneof) { + *oneofcase(msg, field) = field->number; } } + return ret; +} - /* Account for space used by hasbits. */ - l->size = div_round_up(hasbit, 8); +void upb_msg_set(upb_msg *msg, const upb_fielddef *f, upb_msgval val, + upb_arena *a) { + const upb_msglayout_field *field = upb_fielddef_layout(f); + char *mem = UPB_PTR_AT(msg, field->offset, char); + int size = upb_fielddef_isseq(f) ? sizeof(void *) + : field_size[field->descriptortype]; + memcpy(mem, &val, size); + if (in_oneof(field)) { + *oneofcase(msg, field) = field->number; + } +} - /* 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_fielddefsize(f); - size_t index = upb_fielddef_index(f); +bool upb_msg_next(const upb_msg *msg, const upb_msgdef *m, + const upb_symtab *ext_pool, const upb_fielddef **out_f, + upb_msgval *out_val, size_t *iter) { + size_t i = *iter; + const upb_msgval zero = {0}; + const upb_fielddef *f; + while ((f = _upb_msgdef_field(m, (int)++i)) != NULL) { + upb_msgval val = _upb_msg_getraw(msg, f); - if (upb_fielddef_containingoneof(f)) { - /* Oneofs are handled separately below. */ - continue; + /* Skip field if unset or empty. */ + if (upb_fielddef_haspresence(f)) { + if (!upb_msg_has(msg, f)) continue; + } else { + upb_msgval test = val; + if (upb_fielddef_isstring(f) && !upb_fielddef_isseq(f)) { + /* Clear string pointer, only size matters (ptr could be non-NULL). */ + test.str_val.data = NULL; + } + /* Continue if NULL or 0. */ + if (memcmp(&test, &zero, sizeof(test)) == 0) continue; + + /* Continue on empty array or map. */ + if (upb_fielddef_ismap(f)) { + if (upb_map_size(test.map_val) == 0) continue; + } else if (upb_fielddef_isseq(f)) { + if (upb_array_size(test.array_val) == 0) continue; + } } - fields[index].offset = upb_msglayout_place(l, field_size); + *out_val = val; + *out_f = f; + *iter = i; + return true; } + *iter = i; + return false; +} - /* 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* o = upb_msg_iter_oneof(&oit); - upb_oneof_iter fit; - - size_t case_size = sizeof(uint32_t); /* Could potentially optimize this. */ - size_t field_size = 0; - uint32_t case_offset; - uint32_t data_offset; +/** upb_array *****************************************************************/ - /* Calculate field size: the max of all field sizes. */ - 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_fielddefsize(f)); - } +upb_array *upb_array_new(upb_arena *a, upb_fieldtype_t type) { + return _upb_array_new(a, type); +} - /* Align and allocate case offset. */ - case_offset = upb_msglayout_place(l, case_size); - data_offset = upb_msglayout_place(l, field_size); +size_t upb_array_size(const upb_array *arr) { + return arr->len; +} - for (upb_oneof_begin(&fit, o); - !upb_oneof_done(&fit); - upb_oneof_next(&fit)) { - const upb_fielddef* f = upb_oneof_iter_field(&fit); - fields[upb_fielddef_index(f)].offset = data_offset; - fields[upb_fielddef_index(f)].presence = ~case_offset; - } - } +upb_msgval upb_array_get(const upb_array *arr, size_t i) { + upb_msgval ret; + const char* data = _upb_array_constptr(arr); + int lg2 = arr->data & 7; + UPB_ASSERT(i < arr->len); + memcpy(&ret, data + (i << lg2), 1 << lg2); + return ret; +} - /* Size of the entire structure should be a multiple of its greatest - * alignment. TODO: track overall alignment for real? */ - l->size = align_up(l->size, 8); +void upb_array_set(upb_array *arr, size_t i, upb_msgval val) { + char* data = _upb_array_ptr(arr); + int lg2 = arr->data & 7; + UPB_ASSERT(i < arr->len); + memcpy(data + (i << lg2), &val, 1 << lg2); +} +bool upb_array_append(upb_array *arr, upb_msgval val, upb_arena *arena) { + if (!_upb_array_realloc(arr, arr->len + 1, arena)) { + return false; + } + arr->len++; + upb_array_set(arr, arr->len - 1, val); return true; } +/* Resizes the array to the given size, reallocating if necessary, and returns a + * pointer to the new array elements. */ +bool upb_array_resize(upb_array *arr, size_t size, upb_arena *arena) { + return _upb_array_realloc(arr, size, arena); +} -/** upb_msgfactory ************************************************************/ - -struct upb_msgfactory { - const upb_symtab *symtab; /* We own a ref. */ - upb_inttable layouts; -}; +/** upb_map *******************************************************************/ -upb_msgfactory *upb_msgfactory_new(const upb_symtab *symtab) { - upb_msgfactory *ret = upb_gmalloc(sizeof(*ret)); +upb_map *upb_map_new(upb_arena *a, upb_fieldtype_t key_type, + upb_fieldtype_t value_type) { + return _upb_map_new(a, _upb_fieldtype_to_mapsize[key_type], + _upb_fieldtype_to_mapsize[value_type]); +} - ret->symtab = symtab; - upb_inttable_init(&ret->layouts, UPB_CTYPE_PTR); +size_t upb_map_size(const upb_map *map) { + return _upb_map_size(map); +} - return ret; +bool upb_map_get(const upb_map *map, upb_msgval key, upb_msgval *val) { + return _upb_map_get(map, &key, map->key_size, val, map->val_size); } -void upb_msgfactory_free(upb_msgfactory *f) { - upb_inttable_iter i; - upb_inttable_begin(&i, &f->layouts); - for(; !upb_inttable_done(&i); upb_inttable_next(&i)) { - upb_msglayout *l = upb_value_getptr(upb_inttable_iter_value(&i)); - upb_msglayout_free(l); - } +bool upb_map_set(upb_map *map, upb_msgval key, upb_msgval val, + upb_arena *arena) { + return _upb_map_set(map, &key, map->key_size, &val, map->val_size, arena); +} - upb_inttable_uninit(&f->layouts); - upb_gfree(f); +bool upb_map_delete(upb_map *map, upb_msgval key) { + return _upb_map_delete(map, &key, map->key_size); } -const upb_symtab *upb_msgfactory_symtab(const upb_msgfactory *f) { - return f->symtab; +bool upb_mapiter_next(const upb_map *map, size_t *iter) { + return _upb_map_next(map, iter); } -const upb_msglayout *upb_msgfactory_getlayout(upb_msgfactory *f, - const upb_msgdef *m) { - upb_value v; - UPB_ASSERT(upb_symtab_lookupmsg(f->symtab, upb_msgdef_fullname(m)) == m); - UPB_ASSERT(!upb_msgdef_mapentry(m)); +/* Returns the key and value for this entry of the map. */ +upb_msgval upb_mapiter_key(const upb_map *map, size_t iter) { + upb_strtable_iter i; + upb_msgval ret; + i.t = &map->table; + i.index = iter; + _upb_map_fromkey(upb_strtable_iter_key(&i), &ret, map->key_size); + return ret; +} - if (upb_inttable_lookupptr(&f->layouts, m, &v)) { - UPB_ASSERT(upb_value_getptr(v)); - return upb_value_getptr(v); - } else { - /* In case of circular dependency, layout has to be inserted first. */ - upb_msglayout *l = upb_gmalloc(sizeof(*l)); - upb_msgfactory *mutable_f = (void*)f; - upb_inttable_insertptr(&mutable_f->layouts, m, upb_value_ptr(l)); - UPB_ASSERT(l); - if (!upb_msglayout_init(m, l, f)) { - upb_msglayout_free(l); - } - return l; - } +upb_msgval upb_mapiter_value(const upb_map *map, size_t iter) { + upb_strtable_iter i; + upb_msgval ret; + i.t = &map->table; + i.index = iter; + _upb_map_fromvalue(upb_strtable_iter_value(&i), &ret, map->val_size); + return ret; } + +/* void upb_mapiter_setvalue(upb_map *map, size_t iter, upb_msgval value); */ /* ** TODO(haberman): it's unclear whether a lot of the consistency checks should ** UPB_ASSERT() or return false. @@ -5096,7 +5624,8 @@ static upb_handlers *upb_handlers_new(const upb_msgdef *md, int extra; upb_handlers *h; - extra = sizeof(upb_handlers_tabent) * (upb_msgdef_selectorcount(md) - 1); + extra = + (int)(sizeof(upb_handlers_tabent) * (upb_msgdef_selectorcount(md) - 1)); h = upb_calloc(arena, sizeof(*h) + extra); if (!h) return NULL; @@ -5497,6 +6026,31 @@ bool upb_bufsrc_putbuf(const char *buf, size_t len, upb_bytessink sink) { } return ret; } + + +#ifdef UPB_MSVC_VSNPRINTF +/* Visual C++ earlier than 2015 doesn't have standard C99 snprintf and + * vsnprintf. To support them, missing functions are manually implemented + * using the existing secure functions. */ +int msvc_vsnprintf(char* s, size_t n, const char* format, va_list arg) { + if (!s) { + return _vscprintf(format, arg); + } + int ret = _vsnprintf_s(s, n, _TRUNCATE, format, arg); + if (ret < 0) { + ret = _vscprintf(format, arg); + } + return ret; +} + +int msvc_snprintf(char* s, size_t n, const char* format, ...) { + va_list arg; + va_start(arg, format); + int ret = msvc_vsnprintf(s, n, format, arg); + va_end(arg); + return ret; +} +#endif /* ** protobuf decoder bytecode compiler ** @@ -5652,7 +6206,9 @@ static void setofs(uint32_t *instruction, int32_t ofs) { UPB_ASSERT(getofs(*instruction) == ofs); /* Would fail in cases of overflow. */ } -static uint32_t pcofs(compiler *c) { return c->pc - c->group->bytecode; } +static uint32_t pcofs(compiler *c) { + return (uint32_t)(c->pc - c->group->bytecode); +} /* Defines a local label at the current PC location. All previous forward * references are updated to point to this location. The location is noted @@ -5666,7 +6222,7 @@ static void label(compiler *c, unsigned int label) { codep = (val == EMPTYLABEL) ? NULL : c->group->bytecode + val; while (codep) { int ofs = getofs(*codep); - setofs(codep, c->pc - codep - instruction_len(*codep)); + setofs(codep, (int32_t)(c->pc - codep - instruction_len(*codep))); codep = ofs ? codep + ofs : NULL; } c->fwd_labels[label] = EMPTYLABEL; @@ -5688,7 +6244,7 @@ static int32_t labelref(compiler *c, int label) { return 0; } else if (label < 0) { /* Backward local label. Relative to the next instruction. */ - uint32_t from = (c->pc + 1) - c->group->bytecode; + uint32_t from = (uint32_t)((c->pc + 1) - c->group->bytecode); return c->back_labels[-label] - from; } else { /* Forward local label: prepend to (possibly-empty) linked list. */ @@ -5722,7 +6278,7 @@ static void putop(compiler *c, int op, ...) { case OP_SETDISPATCH: { uintptr_t ptr = (uintptr_t)va_arg(ap, void*); put32(c, OP_SETDISPATCH); - put32(c, ptr); + put32(c, (uint32_t)ptr); if (sizeof(uintptr_t) > sizeof(uint32_t)) put32(c, (uint64_t)ptr >> 32); break; @@ -5781,7 +6337,7 @@ static void putop(compiler *c, int op, ...) { case OP_TAG2: { int label = va_arg(ap, int); uint64_t tag = va_arg(ap, uint64_t); - uint32_t instruction = op | (tag << 16); + uint32_t instruction = (uint32_t)(op | (tag << 16)); UPB_ASSERT(tag <= 0xffff); setofs(&instruction, labelref(c, label)); put32(c, instruction); @@ -5793,7 +6349,7 @@ static void putop(compiler *c, int op, ...) { uint32_t instruction = op | (upb_value_size(tag) << 16); setofs(&instruction, labelref(c, label)); put32(c, instruction); - put32(c, tag); + put32(c, (uint32_t)tag); put32(c, tag >> 32); break; } @@ -6406,11 +6962,11 @@ const upb_pbdecodermethod *upb_pbcodecache_get(upb_pbcodecache *c, } else { g = mgroup_new(h, c->lazy); ok = upb_inttable_insertptr(&c->groups, md, upb_value_constptr(g)); - UPB_ASSERT(ok); + UPB_ASSUME(ok); } ok = upb_inttable_lookupptr(&g->methods, h, &v); - UPB_ASSERT(ok); + UPB_ASSUME(ok); return upb_value_getptr(v); } /* @@ -6597,7 +7153,7 @@ static int32_t skip(upb_pbdecoder *d, size_t bytes) { UPB_ASSERT(d->skip == 0); if (bytes > delim_remaining(d)) { seterr(d, "Skipped value extended beyond enclosing submessage."); - return upb_pbdecoder_suspend(d); + return (int32_t)upb_pbdecoder_suspend(d); } else if (bufleft(d) >= bytes) { /* Skipped data is all in current buffer, and more is still available. */ advance(d, bytes); @@ -6610,7 +7166,7 @@ static int32_t skip(upb_pbdecoder *d, size_t bytes) { d->bufstart_ofs += (d->end - d->buf); d->residual_end = d->residual; switchtobuf(d, d->residual, d->residual_end); - return d->size_param + d->skip; + return (int32_t)(d->size_param + d->skip); } } @@ -6650,7 +7206,7 @@ int32_t upb_pbdecoder_resume(upb_pbdecoder *d, void *p, const char *buf, /* NULL buf is ok if its entire span is covered by the "skip" above, but * by this point we know that "skip" doesn't cover the buffer. */ seterr(d, "Passed NULL buffer over non-skippable region."); - return upb_pbdecoder_suspend(d); + return (int32_t)upb_pbdecoder_suspend(d); } if (d->residual_end > d->residual) { @@ -6760,9 +7316,9 @@ UPB_NOINLINE static int32_t getbytes_slow(upb_pbdecoder *d, void *buf, return DECODE_OK; } else if (d->data_end == d->delim_end) { seterr(d, "Submessage ended in the middle of a value or group"); - return upb_pbdecoder_suspend(d); + return (int32_t)upb_pbdecoder_suspend(d); } else { - return suspend_save(d); + return (int32_t)suspend_save(d); } } @@ -6818,7 +7374,7 @@ UPB_NOINLINE int32_t upb_pbdecoder_decode_varint_slow(upb_pbdecoder *d, } if(bitpos == 70 && (byte & 0x80)) { seterr(d, kUnterminatedVarint); - return upb_pbdecoder_suspend(d); + return (int32_t)upb_pbdecoder_suspend(d); } return DECODE_OK; } @@ -6835,7 +7391,7 @@ UPB_FORCEINLINE static int32_t decode_varint(upb_pbdecoder *d, uint64_t *u64) { upb_decoderet r = upb_vdecode_fast(d->ptr); if (r.p == NULL) { seterr(d, kUnterminatedVarint); - return upb_pbdecoder_suspend(d); + return (int32_t)upb_pbdecoder_suspend(d); } advance(d, r.p - d->ptr); *u64 = r.val; @@ -6859,9 +7415,9 @@ UPB_FORCEINLINE static int32_t decode_v32(upb_pbdecoder *d, uint32_t *u32) { * Right now the size_t -> int32_t can overflow and produce negative values. */ *u32 = 0; - return upb_pbdecoder_suspend(d); + return (int32_t)upb_pbdecoder_suspend(d); } - *u32 = u64; + *u32 = (uint32_t)u64; return DECODE_OK; } @@ -6937,7 +7493,7 @@ UPB_NOINLINE int32_t upb_pbdecoder_checktag_slow(upb_pbdecoder *d, UPB_ASSERT(ok < 0); return DECODE_OK; } else if (read < bytes && memcmp(&data, &expected, read) == 0) { - return suspend_save(d); + return (int32_t)suspend_save(d); } else { return DECODE_MISMATCH; } @@ -6957,7 +7513,7 @@ int32_t upb_pbdecoder_skipunknown(upb_pbdecoder *d, int32_t fieldnum, have_tag: if (fieldnum == 0) { seterr(d, "Saw invalid field number (0)"); - return upb_pbdecoder_suspend(d); + return (int32_t)upb_pbdecoder_suspend(d); } switch (wire_type) { @@ -6979,7 +7535,9 @@ int32_t upb_pbdecoder_skipunknown(upb_pbdecoder *d, int32_t fieldnum, break; } case UPB_WIRE_TYPE_START_GROUP: - CHECK_SUSPEND(pushtagdelim(d, -fieldnum)); + if (!pushtagdelim(d, -fieldnum)) { + return (int32_t)upb_pbdecoder_suspend(d); + } break; case UPB_WIRE_TYPE_END_GROUP: if (fieldnum == -d->top->groupnum) { @@ -6988,12 +7546,12 @@ int32_t upb_pbdecoder_skipunknown(upb_pbdecoder *d, int32_t fieldnum, return DECODE_ENDGROUP; } else { seterr(d, "Unmatched ENDGROUP tag."); - return upb_pbdecoder_suspend(d); + return (int32_t)upb_pbdecoder_suspend(d); } break; default: seterr(d, "Invalid wire type"); - return upb_pbdecoder_suspend(d); + return (int32_t)upb_pbdecoder_suspend(d); } if (d->top->groupnum >= 0) { @@ -7165,7 +7723,7 @@ size_t run_decoder_vm(upb_pbdecoder *d, const mgroup *group, CHECK_SUSPEND(upb_sink_endsubmsg(d->top->sink, subsink, arg)); ) VMCASE(OP_STARTSTR, - uint32_t len = delim_remaining(d); + uint32_t len = (uint32_t)delim_remaining(d); upb_pbdecoder_frame *outer = outer_frame(d); CHECK_SUSPEND(upb_sink_startstr(outer->sink, arg, len, &d->top->sink)); if (len == 0) { @@ -7173,7 +7731,7 @@ size_t run_decoder_vm(upb_pbdecoder *d, const mgroup *group, } ) VMCASE(OP_STRING, - uint32_t len = curbufleft(d); + uint32_t len = (uint32_t)curbufleft(d); size_t n = upb_sink_putstring(d->top->sink, arg, d->ptr, len, handle); if (n > len) { if (n > delim_remaining(d)) { @@ -7379,9 +7937,6 @@ void upb_pbdecoder_reset(upb_pbdecoder *d) { upb_pbdecoder *upb_pbdecoder_create(upb_arena *a, const upb_pbdecodermethod *m, upb_sink sink, upb_status *status) { const size_t default_max_nesting = 64; -#ifndef NDEBUG - size_t size_before = upb_arena_bytesallocated(a); -#endif upb_pbdecoder *d = upb_arena_malloc(a, sizeof(upb_pbdecoder)); if (!d) return NULL; @@ -7407,9 +7962,6 @@ upb_pbdecoder *upb_pbdecoder_create(upb_arena *a, const upb_pbdecodermethod *m, } d->top->sink = sink; - /* If this fails, increase the value in decoder.h. */ - UPB_ASSERT_DEBUGVAR(upb_arena_bytesallocated(a) - size_before <= - UPB_PB_DECODER_SIZE); return d; } @@ -7708,7 +8260,7 @@ static bool start_delim(upb_pb_encoder *e) { e->runbegin = e->ptr; } - *e->top = e->segptr - e->segbuf; + *e->top = (int)(e->segptr - e->segbuf); e->segptr->seglen = 0; e->segptr->msglen = 0; @@ -7994,9 +8546,6 @@ upb_pb_encoder *upb_pb_encoder_create(upb_arena *arena, const upb_handlers *h, const size_t initial_segbufsize = 16; /* TODO(haberman): make this configurable. */ const size_t stack_size = 64; -#ifndef NDEBUG - const size_t size_before = upb_arena_bytesallocated(arena); -#endif upb_pb_encoder *e = upb_arena_malloc(arena, sizeof(upb_pb_encoder)); if (!e) return NULL; @@ -8021,9 +8570,6 @@ upb_pb_encoder *upb_pb_encoder_create(upb_arena *arena, const upb_handlers *h, e->subc = output.closure; e->ptr = e->buf; - /* If this fails, increase the value in encoder.h. */ - UPB_ASSERT_DEBUGVAR(upb_arena_bytesallocated(arena) - size_before <= - UPB_PB_ENCODER_SIZE); return e; } @@ -8439,7 +8985,7 @@ upb_decoderet upb_vdecode_max8_branch64(upb_decoderet r) { return r; } -// #line 1 "upb/json/parser.rl" +#line 1 "upb/json/parser.rl" /* ** upb::json::Parser (upb_json_parser) ** @@ -8828,7 +9374,7 @@ static upb_selector_t getsel_for_handlertype(upb_json_parser *p, upb_handlertype_t type) { upb_selector_t sel; bool ok = upb_handlers_getselector(p->top->f, type, &sel); - UPB_ASSERT(ok); + UPB_ASSUME(ok); return sel; } @@ -8853,7 +9399,7 @@ static void set_name_table(upb_json_parser *p, upb_jsonparser_frame *frame) { const upb_json_parsermethod *method; ok = upb_inttable_lookupptr(&cache->methods, frame->m, &v); - UPB_ASSERT(ok); + UPB_ASSUME(ok); method = upb_value_getconstptr(v); frame->name_table = &method->name_table; @@ -9172,7 +9718,9 @@ static bool multipart_text(upb_json_parser *p, const char *buf, size_t len, /* Note: this invalidates the accumulate buffer! Call only after reading its * contents. */ static void multipart_end(upb_json_parser *p) { - UPB_ASSERT(p->multipart_state != MULTIPART_INACTIVE); + /* This is false sometimes. Probably a bug of some sort, but this code is + * intended for deletion soon. */ + /* UPB_ASSERT(p->multipart_state != MULTIPART_INACTIVE); */ p->multipart_state = MULTIPART_INACTIVE; accumulate_clear(p); } @@ -9407,7 +9955,7 @@ static bool parse_number_from_buffer(upb_json_parser *p, const char *buf, } else if (val > INT32_MAX || val < INT32_MIN) { return false; } else { - upb_sink_putint32(p->top->sink, parser_getsel(p), val); + upb_sink_putint32(p->top->sink, parser_getsel(p), (int32_t)val); return true; } } @@ -9418,7 +9966,7 @@ static bool parse_number_from_buffer(upb_json_parser *p, const char *buf, } else if (val > UINT32_MAX || errno == ERANGE) { return false; } else { - upb_sink_putuint32(p->top->sink, parser_getsel(p), val); + upb_sink_putuint32(p->top->sink, parser_getsel(p), (uint32_t)val); return true; } } @@ -9706,7 +10254,7 @@ static bool start_stringval(upb_json_parser *p) { } 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 accumulate so we can convert + * current parser frame. These values must accmulate so we can convert * them all at once at the end. */ multipart_startaccum(p); return true; @@ -9807,7 +10355,12 @@ static bool end_stringval_nontop(upb_json_parser *p) { upb_selector_t sel = parser_getsel(p); upb_sink_putint32(p->top->sink, sel, int_val); } else { - upb_status_seterrf(p->status, "Enum value unknown: '%.*s'", len, buf); + if (p->ignore_json_unknown) { + ok = true; + /* TODO(teboring): Should also clean this field. */ + } else { + upb_status_seterrf(p->status, "Enum value unknown: '%.*s'", len, buf); + } } break; @@ -10458,7 +11011,7 @@ static void end_member(upb_json_parser *p) { /* send ENDSUBMSG in repeated-field-of-mapentries frame. */ p->top--; ok = upb_handlers_getselector(mapfield, UPB_HANDLER_ENDSUBMSG, &sel); - UPB_ASSERT(ok); + UPB_ASSUME(ok); upb_sink_endsubmsg(p->top->sink, (p->top + 1)->sink, sel); } @@ -11012,11 +11565,11 @@ static bool does_fieldmask_end(upb_json_parser *p) { * final state once, when the closing '"' is seen. */ -// #line 2780 "upb/json/parser.rl" +#line 2787 "upb/json/parser.rl" -// #line 2583 "upb/json/parser.c" +#line 2590 "upb/json/parser.c" static const char _json_actions[] = { 0, 1, 0, 1, 1, 1, 3, 1, 4, 1, 6, 1, 7, 1, 8, 1, @@ -11271,7 +11824,7 @@ static const int json_en_value_machine = 78; static const int json_en_main = 1; -// #line 2783 "upb/json/parser.rl" +#line 2790 "upb/json/parser.rl" size_t parse(void *closure, const void *hd, const char *buf, size_t size, const upb_bufhandle *handle) { @@ -11294,7 +11847,7 @@ size_t parse(void *closure, const void *hd, const char *buf, size_t size, capture_resume(parser, buf); -// #line 2861 "upb/json/parser.c" +#line 2868 "upb/json/parser.c" { int _klen; unsigned int _trans; @@ -11369,147 +11922,147 @@ size_t parse(void *closure, const void *hd, const char *buf, size_t size, switch ( *_acts++ ) { case 1: -// #line 2588 "upb/json/parser.rl" +#line 2595 "upb/json/parser.rl" { p--; {cs = stack[--top]; goto _again;} } break; case 2: -// #line 2590 "upb/json/parser.rl" +#line 2597 "upb/json/parser.rl" { p--; {stack[top++] = cs; cs = 23;goto _again;} } break; case 3: -// #line 2594 "upb/json/parser.rl" +#line 2601 "upb/json/parser.rl" { start_text(parser, p); } break; case 4: -// #line 2595 "upb/json/parser.rl" +#line 2602 "upb/json/parser.rl" { CHECK_RETURN_TOP(end_text(parser, p)); } break; case 5: -// #line 2601 "upb/json/parser.rl" +#line 2608 "upb/json/parser.rl" { start_hex(parser); } break; case 6: -// #line 2602 "upb/json/parser.rl" +#line 2609 "upb/json/parser.rl" { hexdigit(parser, p); } break; case 7: -// #line 2603 "upb/json/parser.rl" +#line 2610 "upb/json/parser.rl" { CHECK_RETURN_TOP(end_hex(parser)); } break; case 8: -// #line 2609 "upb/json/parser.rl" +#line 2616 "upb/json/parser.rl" { CHECK_RETURN_TOP(escape(parser, p)); } break; case 9: -// #line 2615 "upb/json/parser.rl" +#line 2622 "upb/json/parser.rl" { p--; {cs = stack[--top]; goto _again;} } break; case 10: -// #line 2620 "upb/json/parser.rl" +#line 2627 "upb/json/parser.rl" { start_year(parser, p); } break; case 11: -// #line 2621 "upb/json/parser.rl" +#line 2628 "upb/json/parser.rl" { CHECK_RETURN_TOP(end_year(parser, p)); } break; case 12: -// #line 2625 "upb/json/parser.rl" +#line 2632 "upb/json/parser.rl" { start_month(parser, p); } break; case 13: -// #line 2626 "upb/json/parser.rl" +#line 2633 "upb/json/parser.rl" { CHECK_RETURN_TOP(end_month(parser, p)); } break; case 14: -// #line 2630 "upb/json/parser.rl" +#line 2637 "upb/json/parser.rl" { start_day(parser, p); } break; case 15: -// #line 2631 "upb/json/parser.rl" +#line 2638 "upb/json/parser.rl" { CHECK_RETURN_TOP(end_day(parser, p)); } break; case 16: -// #line 2635 "upb/json/parser.rl" +#line 2642 "upb/json/parser.rl" { start_hour(parser, p); } break; case 17: -// #line 2636 "upb/json/parser.rl" +#line 2643 "upb/json/parser.rl" { CHECK_RETURN_TOP(end_hour(parser, p)); } break; case 18: -// #line 2640 "upb/json/parser.rl" +#line 2647 "upb/json/parser.rl" { start_minute(parser, p); } break; case 19: -// #line 2641 "upb/json/parser.rl" +#line 2648 "upb/json/parser.rl" { CHECK_RETURN_TOP(end_minute(parser, p)); } break; case 20: -// #line 2645 "upb/json/parser.rl" +#line 2652 "upb/json/parser.rl" { start_second(parser, p); } break; case 21: -// #line 2646 "upb/json/parser.rl" +#line 2653 "upb/json/parser.rl" { CHECK_RETURN_TOP(end_second(parser, p)); } break; case 22: -// #line 2651 "upb/json/parser.rl" +#line 2658 "upb/json/parser.rl" { start_duration_base(parser, p); } break; case 23: -// #line 2652 "upb/json/parser.rl" +#line 2659 "upb/json/parser.rl" { CHECK_RETURN_TOP(end_duration_base(parser, p)); } break; case 24: -// #line 2654 "upb/json/parser.rl" +#line 2661 "upb/json/parser.rl" { p--; {cs = stack[--top]; goto _again;} } break; case 25: -// #line 2659 "upb/json/parser.rl" +#line 2666 "upb/json/parser.rl" { start_timestamp_base(parser); } break; case 26: -// #line 2661 "upb/json/parser.rl" +#line 2668 "upb/json/parser.rl" { start_timestamp_fraction(parser, p); } break; case 27: -// #line 2662 "upb/json/parser.rl" +#line 2669 "upb/json/parser.rl" { CHECK_RETURN_TOP(end_timestamp_fraction(parser, p)); } break; case 28: -// #line 2664 "upb/json/parser.rl" +#line 2671 "upb/json/parser.rl" { start_timestamp_zone(parser, p); } break; case 29: -// #line 2665 "upb/json/parser.rl" +#line 2672 "upb/json/parser.rl" { CHECK_RETURN_TOP(end_timestamp_zone(parser, p)); } break; case 30: -// #line 2667 "upb/json/parser.rl" +#line 2674 "upb/json/parser.rl" { p--; {cs = stack[--top]; goto _again;} } break; case 31: -// #line 2672 "upb/json/parser.rl" +#line 2679 "upb/json/parser.rl" { start_fieldmask_path_text(parser, p); } break; case 32: -// #line 2673 "upb/json/parser.rl" +#line 2680 "upb/json/parser.rl" { end_fieldmask_path_text(parser, p); } break; case 33: -// #line 2678 "upb/json/parser.rl" +#line 2685 "upb/json/parser.rl" { start_fieldmask_path(parser); } break; case 34: -// #line 2679 "upb/json/parser.rl" +#line 2686 "upb/json/parser.rl" { end_fieldmask_path(parser); } break; case 35: -// #line 2685 "upb/json/parser.rl" +#line 2692 "upb/json/parser.rl" { p--; {cs = stack[--top]; goto _again;} } break; case 36: -// #line 2690 "upb/json/parser.rl" +#line 2697 "upb/json/parser.rl" { if (is_wellknown_msg(parser, UPB_WELLKNOWN_TIMESTAMP)) { {stack[top++] = cs; cs = 47;goto _again;} @@ -11523,11 +12076,11 @@ size_t parse(void *closure, const void *hd, const char *buf, size_t size, } break; case 37: -// #line 2703 "upb/json/parser.rl" +#line 2710 "upb/json/parser.rl" { p--; {stack[top++] = cs; cs = 78;goto _again;} } break; case 38: -// #line 2708 "upb/json/parser.rl" +#line 2715 "upb/json/parser.rl" { if (is_wellknown_msg(parser, UPB_WELLKNOWN_ANY)) { start_any_member(parser, p); @@ -11537,11 +12090,11 @@ size_t parse(void *closure, const void *hd, const char *buf, size_t size, } break; case 39: -// #line 2715 "upb/json/parser.rl" +#line 2722 "upb/json/parser.rl" { CHECK_RETURN_TOP(end_membername(parser)); } break; case 40: -// #line 2718 "upb/json/parser.rl" +#line 2725 "upb/json/parser.rl" { if (is_wellknown_msg(parser, UPB_WELLKNOWN_ANY)) { end_any_member(parser, p); @@ -11551,7 +12104,7 @@ size_t parse(void *closure, const void *hd, const char *buf, size_t size, } break; case 41: -// #line 2729 "upb/json/parser.rl" +#line 2736 "upb/json/parser.rl" { if (is_wellknown_msg(parser, UPB_WELLKNOWN_ANY)) { start_any_object(parser, p); @@ -11561,7 +12114,7 @@ size_t parse(void *closure, const void *hd, const char *buf, size_t size, } break; case 42: -// #line 2738 "upb/json/parser.rl" +#line 2745 "upb/json/parser.rl" { if (is_wellknown_msg(parser, UPB_WELLKNOWN_ANY)) { CHECK_RETURN_TOP(end_any_object(parser, p)); @@ -11571,54 +12124,54 @@ size_t parse(void *closure, const void *hd, const char *buf, size_t size, } break; case 43: -// #line 2750 "upb/json/parser.rl" +#line 2757 "upb/json/parser.rl" { CHECK_RETURN_TOP(start_array(parser)); } break; case 44: -// #line 2754 "upb/json/parser.rl" +#line 2761 "upb/json/parser.rl" { end_array(parser); } break; case 45: -// #line 2759 "upb/json/parser.rl" +#line 2766 "upb/json/parser.rl" { CHECK_RETURN_TOP(start_number(parser, p)); } break; case 46: -// #line 2760 "upb/json/parser.rl" +#line 2767 "upb/json/parser.rl" { CHECK_RETURN_TOP(end_number(parser, p)); } break; case 47: -// #line 2762 "upb/json/parser.rl" +#line 2769 "upb/json/parser.rl" { CHECK_RETURN_TOP(start_stringval(parser)); } break; case 48: -// #line 2763 "upb/json/parser.rl" +#line 2770 "upb/json/parser.rl" { CHECK_RETURN_TOP(end_stringval(parser)); } break; case 49: -// #line 2765 "upb/json/parser.rl" +#line 2772 "upb/json/parser.rl" { CHECK_RETURN_TOP(end_bool(parser, true)); } break; case 50: -// #line 2767 "upb/json/parser.rl" +#line 2774 "upb/json/parser.rl" { CHECK_RETURN_TOP(end_bool(parser, false)); } break; case 51: -// #line 2769 "upb/json/parser.rl" +#line 2776 "upb/json/parser.rl" { CHECK_RETURN_TOP(end_null(parser)); } break; case 52: -// #line 2771 "upb/json/parser.rl" +#line 2778 "upb/json/parser.rl" { CHECK_RETURN_TOP(start_subobject_full(parser)); } break; case 53: -// #line 2772 "upb/json/parser.rl" +#line 2779 "upb/json/parser.rl" { end_subobject_full(parser); } break; case 54: -// #line 2777 "upb/json/parser.rl" +#line 2784 "upb/json/parser.rl" { p--; {cs = stack[--top]; goto _again;} } break; -// #line 3185 "upb/json/parser.c" +#line 3192 "upb/json/parser.c" } } @@ -11635,32 +12188,32 @@ size_t parse(void *closure, const void *hd, const char *buf, size_t size, while ( __nacts-- > 0 ) { switch ( *__acts++ ) { case 0: -// #line 2586 "upb/json/parser.rl" +#line 2593 "upb/json/parser.rl" { p--; {cs = stack[--top]; if ( p == pe ) goto _test_eof; goto _again;} } break; case 46: -// #line 2760 "upb/json/parser.rl" +#line 2767 "upb/json/parser.rl" { CHECK_RETURN_TOP(end_number(parser, p)); } break; case 49: -// #line 2765 "upb/json/parser.rl" +#line 2772 "upb/json/parser.rl" { CHECK_RETURN_TOP(end_bool(parser, true)); } break; case 50: -// #line 2767 "upb/json/parser.rl" +#line 2774 "upb/json/parser.rl" { CHECK_RETURN_TOP(end_bool(parser, false)); } break; case 51: -// #line 2769 "upb/json/parser.rl" +#line 2776 "upb/json/parser.rl" { CHECK_RETURN_TOP(end_null(parser)); } break; case 53: -// #line 2772 "upb/json/parser.rl" +#line 2779 "upb/json/parser.rl" { end_subobject_full(parser); } break; -// #line 3227 "upb/json/parser.c" +#line 3234 "upb/json/parser.c" } } } @@ -11668,7 +12221,7 @@ goto _again;} } _out: {} } -// #line 2805 "upb/json/parser.rl" +#line 2812 "upb/json/parser.rl" if (p != pe) { upb_status_seterrf(parser->status, "Parse error at '%.*s'\n", pe - p, p); @@ -11711,13 +12264,13 @@ static void json_parser_reset(upb_json_parser *p) { /* Emit Ragel initialization of the parser. */ -// #line 3278 "upb/json/parser.c" +#line 3285 "upb/json/parser.c" { cs = json_start; top = 0; } -// #line 2847 "upb/json/parser.rl" +#line 2854 "upb/json/parser.rl" p->current_state = cs; p->parser_top = top; accumulate_clear(p); @@ -11748,15 +12301,13 @@ static upb_json_parsermethod *parsermethod_new(upb_json_codecache *c, upb_msg_field_next(&i)) { const upb_fielddef *f = upb_msg_iter_field(&i); upb_value v = upb_value_constptr(f); - char *buf; + const char *name; /* Add an entry for the JSON name. */ - size_t len = upb_fielddef_getjsonname(f, NULL, 0); - buf = upb_malloc(alloc, len); - upb_fielddef_getjsonname(f, buf, len); - upb_strtable_insert3(&m->name_table, buf, strlen(buf), v, alloc); + name = upb_fielddef_jsonname(f); + upb_strtable_insert3(&m->name_table, name, strlen(name), v, alloc); - if (strcmp(buf, upb_fielddef_name(f)) != 0) { + if (strcmp(name, upb_fielddef_name(f)) != 0) { /* Since the JSON name is different from the regular field name, add an * entry for the raw name (compliant proto3 JSON parsers must accept * both). */ @@ -11776,9 +12327,6 @@ upb_json_parser *upb_json_parser_create(upb_arena *arena, upb_sink output, upb_status *status, bool ignore_json_unknown) { -#ifndef NDEBUG - const size_t size_before = upb_arena_bytesallocated(arena); -#endif upb_json_parser *p = upb_arena_malloc(arena, sizeof(upb_json_parser)); if (!p) return false; @@ -11805,10 +12353,6 @@ upb_json_parser *upb_json_parser_create(upb_arena *arena, p->ignore_json_unknown = ignore_json_unknown; - /* If this fails, uncomment and increase the value in parser.h. */ - /* fprintf(stderr, "%zd\n", upb_arena_bytesallocated(arena) - size_before); */ - UPB_ASSERT_DEBUGVAR(upb_arena_bytesallocated(arena) - size_before <= - UPB_JSON_PARSER_SIZE); return p; } @@ -11882,6 +12426,7 @@ const upb_json_parsermethod *upb_json_codecache_get(upb_json_codecache *c, #include +#include #include #include #include @@ -11939,12 +12484,8 @@ strpc *newstrpc(upb_handlers *h, const upb_fielddef *f, ret->ptr = upb_gstrdup(upb_fielddef_name(f)); ret->len = strlen(ret->ptr); } else { - size_t len; - ret->len = upb_fielddef_getjsonname(f, NULL, 0); - ret->ptr = upb_gmalloc(ret->len); - len = upb_fielddef_getjsonname(f, ret->ptr, ret->len); - UPB_ASSERT(len == ret->len); - ret->len--; /* NULL */ + ret->ptr = upb_gstrdup(upb_fielddef_jsonname(f)); + ret->len = strlen(ret->ptr); } upb_handlers_addcleanup(h, ret, freestrpc); @@ -11963,7 +12504,7 @@ strpc *newstrpc_str(upb_handlers *h, const char * str) { /* ------------ JSON string printing: values, maps, arrays ------------------ */ static void print_data( - upb_json_printer *p, const char *buf, unsigned int len) { + upb_json_printer *p, const char *buf, size_t len) { /* TODO: Will need to change if we support pushback from the sink. */ size_t n = upb_bytessink_putbuf(p->output_, p->subc_, buf, len, NULL); UPB_ASSERT(n == len); @@ -12003,7 +12544,7 @@ UPB_INLINE const char* json_nice_escape(char c) { /* Write a properly escaped string chunk. The surrounding quotes are *not* * printed; this is so that the caller has the option of emitting the string * content in chunks. */ -static void putstring(upb_json_printer *p, const char *buf, unsigned int len) { +static void putstring(upb_json_printer *p, const char *buf, size_t len) { const char* unescaped_run = NULL; unsigned int i; for (i = 0; i < len; i++) { @@ -12083,28 +12624,26 @@ static size_t fmt_bool(bool val, char* buf, size_t length) { return n; } -static size_t fmt_int64_as_number(long long val, char* buf, size_t length) { - size_t n = _upb_snprintf(buf, length, "%lld", val); +static size_t fmt_int64_as_number(int64_t val, char* buf, size_t length) { + size_t n = _upb_snprintf(buf, length, "%" PRId64, val); CHKLENGTH(n > 0 && n < length); return n; } -static size_t fmt_uint64_as_number( - unsigned long long val, char* buf, size_t length) { - size_t n = _upb_snprintf(buf, length, "%llu", val); +static size_t fmt_uint64_as_number(uint64_t val, char* buf, size_t length) { + size_t n = _upb_snprintf(buf, length, "%" PRIu64, val); CHKLENGTH(n > 0 && n < length); return n; } -static size_t fmt_int64_as_string(long long val, char* buf, size_t length) { - size_t n = _upb_snprintf(buf, length, "\"%lld\"", val); +static size_t fmt_int64_as_string(int64_t val, char* buf, size_t length) { + size_t n = _upb_snprintf(buf, length, "\"%" PRId64 "\"", val); CHKLENGTH(n > 0 && n < length); return n; } -static size_t fmt_uint64_as_string( - unsigned long long val, char* buf, size_t length) { - size_t n = _upb_snprintf(buf, length, "\"%llu\"", val); +static size_t fmt_uint64_as_string(uint64_t val, char* buf, size_t length) { + size_t n = _upb_snprintf(buf, length, "\"%" PRIu64 "\"", val); CHKLENGTH(n > 0 && n < length); return n; } @@ -13247,10 +13786,6 @@ static void json_printer_reset(upb_json_printer *p) { upb_json_printer *upb_json_printer_create(upb_arena *a, const upb_handlers *h, upb_bytessink output) { -#ifndef NDEBUG - size_t size_before = upb_arena_bytesallocated(a); -#endif - upb_json_printer *p = upb_arena_malloc(a, sizeof(upb_json_printer)); if (!p) return NULL; @@ -13260,9 +13795,6 @@ upb_json_printer *upb_json_printer_create(upb_arena *a, const upb_handlers *h, p->seconds = 0; p->nanos = 0; - /* If this fails, increase the value in printer.h. */ - UPB_ASSERT_DEBUGVAR(upb_arena_bytesallocated(a) - size_before <= - UPB_JSON_PRINTER_SIZE); return p; } @@ -13281,17 +13813,23 @@ upb_handlercache *upb_json_printer_newcache(bool preserve_proto_fieldnames) { } /* See port_def.inc. This should #undef all macros #defined there. */ +#undef UPB_MAPTYPE_STRING #undef UPB_SIZE -#undef UPB_FIELD_AT +#undef UPB_PTR_AT #undef UPB_READ_ONEOF #undef UPB_WRITE_ONEOF #undef UPB_INLINE +#undef UPB_ALIGN_UP +#undef UPB_ALIGN_DOWN +#undef UPB_ALIGN_MALLOC +#undef UPB_ALIGN_OF #undef UPB_FORCEINLINE #undef UPB_NOINLINE #undef UPB_NORETURN #undef UPB_MAX #undef UPB_MIN #undef UPB_UNUSED +#undef UPB_ASSUME #undef UPB_ASSERT #undef UPB_ASSERT_DEBUGVAR #undef UPB_UNREACHABLE diff --git a/php/ext/google/protobuf/upb.h b/php/ext/google/protobuf/upb.h index 6746476c2969..179e49877742 100644 --- a/php/ext/google/protobuf/upb.h +++ b/php/ext/google/protobuf/upb.h @@ -28,9 +28,8 @@ * * This file is private and must not be included by users! */ -#ifndef UINTPTR_MAX -#error must include stdint.h first -#endif +#include +#include #if UINTPTR_MAX == 0xffffffff #define UPB_SIZE(size32, size64) size32 @@ -38,17 +37,21 @@ #define UPB_SIZE(size32, size64) size64 #endif -#define UPB_FIELD_AT(msg, fieldtype, offset) \ - *(fieldtype*)((const char*)(msg) + offset) +/* If we always read/write as a consistent type to each address, this shouldn't + * violate aliasing. + */ +#define UPB_PTR_AT(msg, ofs, type) ((type*)((char*)(msg) + (ofs))) #define UPB_READ_ONEOF(msg, fieldtype, offset, case_offset, case_val, default) \ - UPB_FIELD_AT(msg, int, case_offset) == case_val \ - ? UPB_FIELD_AT(msg, fieldtype, offset) \ + *UPB_PTR_AT(msg, case_offset, int) == case_val \ + ? *UPB_PTR_AT(msg, offset, fieldtype) \ : default #define UPB_WRITE_ONEOF(msg, fieldtype, offset, value, case_offset, case_val) \ - UPB_FIELD_AT(msg, int, case_offset) = case_val; \ - UPB_FIELD_AT(msg, fieldtype, offset) = value; + *UPB_PTR_AT(msg, case_offset, int) = case_val; \ + *UPB_PTR_AT(msg, offset, fieldtype) = value; + +#define UPB_MAPTYPE_STRING 0 /* UPB_INLINE: inline if possible, emit standalone code if required. */ #ifdef __cplusplus @@ -59,6 +62,11 @@ #define UPB_INLINE static #endif +#define UPB_ALIGN_UP(size, align) (((size) + (align) - 1) / (align) * (align)) +#define UPB_ALIGN_DOWN(size, align) ((size) / (align) * (align)) +#define UPB_ALIGN_MALLOC(size) UPB_ALIGN_UP(size, 16) +#define UPB_ALIGN_OF(type) offsetof (struct { char c; type member; }, member) + /* Hints to the compiler about likely/unlikely branches. */ #if defined (__GNUC__) || defined(__clang__) #define UPB_LIKELY(x) __builtin_expect((x),1) @@ -133,6 +141,18 @@ int msvc_vsnprintf(char* s, size_t n, const char* format, va_list arg); #define UPB_UNUSED(var) (void)var +/* UPB_ASSUME(): in release mode, we tell the compiler to assume this is true. + */ +#ifdef NDEBUG +#ifdef __GNUC__ +#define UPB_ASSUME(expr) if (!(expr)) __builtin_unreachable() +#else +#define UPB_ASSUME(expr) do {} if (false && (expr)) +#endif +#else +#define UPB_ASSUME(expr) assert(expr) +#endif + /* UPB_ASSERT(): in release mode, we use the expression without letting it be * evaluated. This prevents "unused variable" warnings. */ #ifdef NDEBUG @@ -159,10 +179,51 @@ int msvc_vsnprintf(char* s, size_t n, const char* format, va_list arg); #define UPB_INFINITY (1.0 / 0.0) #endif /* -** This file contains shared definitions that are widely used across upb. +** upb_decode: parsing into a upb_msg using a upb_msglayout. +*/ + +#ifndef UPB_DECODE_H_ +#define UPB_DECODE_H_ + +/* +** Our memory representation for parsing tables and messages themselves. +** Functions in this file are used by generated code and possibly reflection. ** -** This is a mixed C/C++ interface that offers a full API to both languages. -** See the top-level README for more information. +** The definitions in this file are internal to upb. +**/ + +#ifndef UPB_MSG_H_ +#define UPB_MSG_H_ + +#include +#include + +/* +** 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 +#include +/* +** This file contains shared definitions that are widely used across upb. */ #ifndef UPB_H_ @@ -175,23 +236,13 @@ int msvc_vsnprintf(char* s, size_t n, const char* format, va_list arg); #include #include + #ifdef __cplusplus -#include -namespace upb { -class Arena; -class Status; -template class InlinedArena; -} +extern "C" { #endif - /* upb_status *****************************************************************/ -/* upb_status represents a success or failure status and error message. - * It owns no resources and allocates no memory, so it should work - * even in OOM situations. */ - -/* The maximum length of an error message before it will get truncated. */ #define UPB_STATUS_MAX_MESSAGE 127 typedef struct { @@ -199,59 +250,15 @@ typedef struct { char msg[UPB_STATUS_MAX_MESSAGE]; /* Error message; NULL-terminated. */ } upb_status; -#ifdef __cplusplus -extern "C" { -#endif - const char *upb_status_errmsg(const upb_status *status); bool upb_ok(const upb_status *status); -/* Any of the functions that write to a status object allow status to be NULL, - * to support use cases where the function's caller does not care about the - * status message. */ +/* These are no-op if |status| is NULL. */ void upb_status_clear(upb_status *status); void upb_status_seterrmsg(upb_status *status, const char *msg); void upb_status_seterrf(upb_status *status, const char *fmt, ...); void upb_status_vseterrf(upb_status *status, const char *fmt, va_list args); -UPB_INLINE void upb_status_setoom(upb_status *status) { - upb_status_seterrmsg(status, "out of memory"); -} - -#ifdef __cplusplus -} /* extern "C" */ - -class upb::Status { - public: - Status() { upb_status_clear(&status_); } - - upb_status* ptr() { return &status_; } - - /* Returns true if there is no error. */ - bool ok() const { return upb_ok(&status_); } - - /* Guaranteed to be NULL-terminated. */ - const char *error_message() const { return upb_status_errmsg(&status_); } - - /* The error message will be truncated if it is longer than - * UPB_STATUS_MAX_MESSAGE-4. */ - void SetErrorMessage(const char *msg) { upb_status_seterrmsg(&status_, msg); } - void SetFormattedErrorMessage(const char *fmt, ...) { - va_list args; - va_start(args, fmt); - upb_status_vseterrf(&status_, fmt, args); - va_end(args); - } - - /* Resets the status to a successful state with no message. */ - void Clear() { upb_status_clear(&status_); } - - private: - upb_status status_; -}; - -#endif /* __cplusplus */ - /** upb_strview ************************************************************/ typedef struct { @@ -318,16 +325,8 @@ UPB_INLINE void upb_free(upb_alloc *alloc, void *ptr) { /* The global allocator used by upb. Uses the standard malloc()/free(). */ -#ifdef __cplusplus -extern "C" { -#endif - extern upb_alloc upb_alloc_global; -#ifdef __cplusplus -} /* extern "C" */ -#endif - /* Functions that hard-code the global malloc. * * We still get benefit because we can put custom logic into our global @@ -364,9 +363,14 @@ typedef void upb_cleanup_func(void *ud); struct upb_arena; typedef struct upb_arena upb_arena; -#ifdef __cplusplus -extern "C" { -#endif +typedef struct { + /* We implement the allocator interface. + * This must be the first member of upb_arena! + * TODO(haberman): remove once handlers are gone. */ + upb_alloc alloc; + + char *ptr, *end; +} _upb_arena_head; /* Creates an arena from the given initial block (if any -- n may be 0). * Additional blocks will be allocated from |alloc|. If |alloc| is NULL, this @@ -374,83 +378,40 @@ extern "C" { upb_arena *upb_arena_init(void *mem, size_t n, upb_alloc *alloc); void upb_arena_free(upb_arena *a); bool upb_arena_addcleanup(upb_arena *a, void *ud, upb_cleanup_func *func); -size_t upb_arena_bytesallocated(const upb_arena *a); +void upb_arena_fuse(upb_arena *a, upb_arena *b); +void *_upb_arena_slowmalloc(upb_arena *a, size_t size); UPB_INLINE upb_alloc *upb_arena_alloc(upb_arena *a) { return (upb_alloc*)a; } -/* Convenience wrappers around upb_alloc functions. */ - UPB_INLINE void *upb_arena_malloc(upb_arena *a, size_t size) { - return upb_malloc(upb_arena_alloc(a), size); + _upb_arena_head *h = (_upb_arena_head*)a; + void* ret; + size = UPB_ALIGN_MALLOC(size); + + if (UPB_UNLIKELY((size_t)(h->end - h->ptr) < size)) { + return _upb_arena_slowmalloc(a, size); + } + + ret = h->ptr; + h->ptr += size; + return ret; } UPB_INLINE void *upb_arena_realloc(upb_arena *a, void *ptr, size_t oldsize, size_t size) { - return upb_realloc(upb_arena_alloc(a), ptr, oldsize, size); + void *ret = upb_arena_malloc(a, size); + + if (ret && oldsize > 0) { + memcpy(ret, ptr, oldsize); + } + + return ret; } UPB_INLINE upb_arena *upb_arena_new(void) { return upb_arena_init(NULL, 0, &upb_alloc_global); } -#ifdef __cplusplus -} /* extern "C" */ - -class upb::Arena { - public: - /* A simple arena with no initial memory block and the default allocator. */ - Arena() : ptr_(upb_arena_new(), upb_arena_free) {} - - upb_arena* ptr() { return ptr_.get(); } - - /* Allows this arena to be used as a generic allocator. - * - * The arena does not need free() calls so when using Arena as an allocator - * it is safe to skip them. However they are no-ops so there is no harm in - * calling free() either. */ - upb_alloc *allocator() { return upb_arena_alloc(ptr_.get()); } - - /* Add a cleanup function to run when the arena is destroyed. - * Returns false on out-of-memory. */ - bool AddCleanup(void *ud, upb_cleanup_func* func) { - return upb_arena_addcleanup(ptr_.get(), ud, func); - } - - /* Total number of bytes that have been allocated. It is undefined what - * Realloc() does to &arena_ counter. */ - size_t BytesAllocated() const { return upb_arena_bytesallocated(ptr_.get()); } - - private: - std::unique_ptr ptr_; -}; - -#endif - -/* upb::InlinedArena **********************************************************/ - -/* upb::InlinedArena seeds the arenas with a predefined amount of memory. No - * heap memory will be allocated until the initial block is exceeded. - * - * These types only exist in C++ */ - -#ifdef __cplusplus - -template class upb::InlinedArena : public upb::Arena { - public: - InlinedArena() : ptr_(upb_arena_new(&initial_block_, N, &upb_alloc_global)) {} - - upb_arena* ptr() { return ptr_.get(); } - - private: - InlinedArena(const InlinedArena*) = delete; - InlinedArena& operator=(const InlinedArena*) = delete; - - std::unique_ptr ptr_; - char initial_block_[N]; -}; - -#endif /* __cplusplus */ - /* Constants ******************************************************************/ /* Generic function type. */ @@ -470,21 +431,17 @@ typedef enum { * types defined in descriptor.proto, which gives INT32 and SINT32 separate * types (we distinguish the two with the "integer encoding" enum below). */ typedef enum { - /* Types stored in 1 byte. */ UPB_TYPE_BOOL = 1, - /* Types stored in 4 bytes. */ UPB_TYPE_FLOAT = 2, UPB_TYPE_INT32 = 3, UPB_TYPE_UINT32 = 4, UPB_TYPE_ENUM = 5, /* Enum values are int32. */ - /* Types stored as pointers (probably 4 or 8 bytes). */ - UPB_TYPE_STRING = 6, - UPB_TYPE_BYTES = 7, - UPB_TYPE_MESSAGE = 8, - /* Types stored as 8 bytes. */ - UPB_TYPE_DOUBLE = 9, - UPB_TYPE_INT64 = 10, - UPB_TYPE_UINT64 = 11 + UPB_TYPE_MESSAGE = 6, + UPB_TYPE_DOUBLE = 7, + UPB_TYPE_INT64 = 8, + UPB_TYPE_UINT64 = 9, + UPB_TYPE_STRING = 10, + UPB_TYPE_BYTES = 11 } upb_fieldtype_t; /* The repeated-ness of each field; this matches descriptor.proto. */ @@ -496,6 +453,7 @@ typedef enum { /* Descriptor types, as defined in descriptor.proto. */ typedef enum { + /* Old (long) names. TODO(haberman): remove */ UPB_DESCRIPTOR_TYPE_DOUBLE = 1, UPB_DESCRIPTOR_TYPE_FLOAT = 2, UPB_DESCRIPTOR_TYPE_INT64 = 3, @@ -513,251 +471,125 @@ typedef enum { UPB_DESCRIPTOR_TYPE_SFIXED32 = 15, UPB_DESCRIPTOR_TYPE_SFIXED64 = 16, UPB_DESCRIPTOR_TYPE_SINT32 = 17, - UPB_DESCRIPTOR_TYPE_SINT64 = 18 + UPB_DESCRIPTOR_TYPE_SINT64 = 18, + + UPB_DTYPE_DOUBLE = 1, + UPB_DTYPE_FLOAT = 2, + UPB_DTYPE_INT64 = 3, + UPB_DTYPE_UINT64 = 4, + UPB_DTYPE_INT32 = 5, + UPB_DTYPE_FIXED64 = 6, + UPB_DTYPE_FIXED32 = 7, + UPB_DTYPE_BOOL = 8, + UPB_DTYPE_STRING = 9, + UPB_DTYPE_GROUP = 10, + UPB_DTYPE_MESSAGE = 11, + UPB_DTYPE_BYTES = 12, + UPB_DTYPE_UINT32 = 13, + UPB_DTYPE_ENUM = 14, + UPB_DTYPE_SFIXED32 = 15, + UPB_DTYPE_SFIXED64 = 16, + UPB_DTYPE_SINT32 = 17, + UPB_DTYPE_SINT64 = 18 } upb_descriptortype_t; -extern const uint8_t upb_desctype_to_fieldtype[]; - - -#endif /* UPB_H_ */ -/* -** upb_decode: parsing into a upb_msg using a upb_msglayout. -*/ +#define UPB_MAP_BEGIN -1 -#ifndef UPB_DECODE_H_ -#define UPB_DECODE_H_ -/* -** Data structures for message tables, used for parsing and serialization. -** This are much lighter-weight than full reflection, but they are do not -** have enough information to convert to text format, JSON, etc. -** -** The definitions in this file are internal to upb. -**/ +#ifdef __cplusplus +} /* extern "C" */ +#endif -#ifndef UPB_MSG_H_ -#define UPB_MSG_H_ +#endif /* UPB_H_ */ -#include -#include #ifdef __cplusplus extern "C" { #endif -typedef void upb_msg; -/** upb_msglayout *************************************************************/ +/* upb_value ******************************************************************/ -/* upb_msglayout represents the memory layout of a given upb_msgdef. The - * members are public so generated code can initialize them, but users MUST NOT - * read or write any of its members. */ +/* A tagged union (stored untagged inside the table) so that we can check that + * clients calling table accessors are correctly typed without having to have + * an explosion of accessors. */ +typedef enum { + UPB_CTYPE_INT32 = 1, + UPB_CTYPE_INT64 = 2, + UPB_CTYPE_UINT32 = 3, + UPB_CTYPE_UINT64 = 4, + UPB_CTYPE_BOOL = 5, + UPB_CTYPE_CSTR = 6, + UPB_CTYPE_PTR = 7, + UPB_CTYPE_CONSTPTR = 8, + UPB_CTYPE_FPTR = 9, + UPB_CTYPE_FLOAT = 10, + UPB_CTYPE_DOUBLE = 11 +} upb_ctype_t; typedef struct { - uint32_t number; - uint16_t offset; - int16_t presence; /* If >0, hasbit_index+1. If <0, oneof_index+1. */ - uint16_t submsg_index; /* undefined if descriptortype != MESSAGE or GROUP. */ - uint8_t descriptortype; - uint8_t label; -} upb_msglayout_field; + uint64_t val; +} upb_value; -typedef struct upb_msglayout { - const struct upb_msglayout *const* submsgs; - const upb_msglayout_field *fields; - /* Must be aligned to sizeof(void*). Doesn't include internal members like - * unknown fields, extension dict, pointer to msglayout, etc. */ - uint16_t size; - uint16_t field_count; - bool extendable; -} upb_msglayout; +/* Like strdup(), which isn't always available since it's not ANSI C. */ +char *upb_strdup(const char *s, upb_alloc *a); +/* Variant that works with a length-delimited rather than NULL-delimited string, + * as supported by strtable. */ +char *upb_strdup2(const char *s, size_t len, upb_alloc *a); -/** Message internal representation *******************************************/ +UPB_INLINE char *upb_gstrdup(const char *s) { + return upb_strdup(s, &upb_alloc_global); +} -/* Our internal representation for repeated fields. */ -typedef struct { - void *data; /* Each element is element_size. */ - size_t len; /* Measured in elements. */ - size_t size; /* Measured in elements. */ -} upb_array; +UPB_INLINE void _upb_value_setval(upb_value *v, uint64_t val) { + v->val = val; +} -upb_msg *upb_msg_new(const upb_msglayout *l, upb_arena *a); -upb_msg *upb_msg_new(const upb_msglayout *l, upb_arena *a); +UPB_INLINE upb_value _upb_value_val(uint64_t val) { + upb_value ret; + _upb_value_setval(&ret, val); + return ret; +} -void upb_msg_addunknown(upb_msg *msg, const char *data, size_t len, - upb_arena *arena); -const char *upb_msg_getunknown(const upb_msg *msg, size_t *len); +/* For each value ctype, define the following set of functions: + * + * // Get/set an int32 from a upb_value. + * int32_t upb_value_getint32(upb_value val); + * void upb_value_setint32(upb_value *val, int32_t cval); + * + * // Construct a new upb_value from an int32. + * upb_value upb_value_int32(int32_t val); */ +#define FUNCS(name, membername, type_t, converter, proto_type) \ + UPB_INLINE void upb_value_set ## name(upb_value *val, type_t cval) { \ + val->val = (converter)cval; \ + } \ + UPB_INLINE upb_value upb_value_ ## name(type_t val) { \ + upb_value ret; \ + upb_value_set ## name(&ret, val); \ + return ret; \ + } \ + UPB_INLINE type_t upb_value_get ## name(upb_value val) { \ + return (type_t)(converter)val.val; \ + } -upb_array *upb_array_new(upb_arena *a); +FUNCS(int32, int32, int32_t, int32_t, UPB_CTYPE_INT32) +FUNCS(int64, int64, int64_t, int64_t, UPB_CTYPE_INT64) +FUNCS(uint32, uint32, uint32_t, uint32_t, UPB_CTYPE_UINT32) +FUNCS(uint64, uint64, uint64_t, uint64_t, UPB_CTYPE_UINT64) +FUNCS(bool, _bool, bool, bool, UPB_CTYPE_BOOL) +FUNCS(cstr, cstr, char*, uintptr_t, UPB_CTYPE_CSTR) +FUNCS(ptr, ptr, void*, uintptr_t, UPB_CTYPE_PTR) +FUNCS(constptr, constptr, const void*, uintptr_t, UPB_CTYPE_CONSTPTR) +FUNCS(fptr, fptr, upb_func*, uintptr_t, UPB_CTYPE_FPTR) -#ifdef __cplusplus -} /* extern "C" */ -#endif +#undef FUNCS -#endif /* UPB_MSG_H_ */ - -#ifdef __cplusplus -extern "C" { -#endif - -bool upb_decode(const char *buf, size_t size, upb_msg *msg, - const upb_msglayout *l, upb_arena *arena); - -#ifdef __cplusplus -} /* extern "C" */ -#endif - -#endif /* UPB_DECODE_H_ */ -/* -** upb_encode: parsing into a upb_msg using a upb_msglayout. -*/ - -#ifndef UPB_ENCODE_H_ -#define UPB_ENCODE_H_ - - -#ifdef __cplusplus -extern "C" { -#endif - -char *upb_encode(const void *msg, const upb_msglayout *l, upb_arena *arena, - size_t *size); - -#ifdef __cplusplus -} /* extern "C" */ -#endif - -#endif /* UPB_ENCODE_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 -#include - - -#ifdef __cplusplus -extern "C" { -#endif - - -/* upb_value ******************************************************************/ - -/* A tagged union (stored untagged inside the table) so that we can check that - * clients calling table accessors are correctly typed without having to have - * an explosion of accessors. */ -typedef enum { - UPB_CTYPE_INT32 = 1, - UPB_CTYPE_INT64 = 2, - UPB_CTYPE_UINT32 = 3, - UPB_CTYPE_UINT64 = 4, - UPB_CTYPE_BOOL = 5, - UPB_CTYPE_CSTR = 6, - UPB_CTYPE_PTR = 7, - UPB_CTYPE_CONSTPTR = 8, - UPB_CTYPE_FPTR = 9, - UPB_CTYPE_FLOAT = 10, - UPB_CTYPE_DOUBLE = 11 -} upb_ctype_t; - -typedef struct { - uint64_t val; -#ifndef NDEBUG - /* In debug mode we carry the value type around also so we can check accesses - * to be sure the right member is being read. */ - upb_ctype_t ctype; -#endif -} upb_value; - -#ifdef NDEBUG -#define SET_TYPE(dest, val) UPB_UNUSED(val) -#else -#define SET_TYPE(dest, val) dest = val -#endif - -/* Like strdup(), which isn't always available since it's not ANSI C. */ -char *upb_strdup(const char *s, upb_alloc *a); -/* Variant that works with a length-delimited rather than NULL-delimited string, - * as supported by strtable. */ -char *upb_strdup2(const char *s, size_t len, upb_alloc *a); - -UPB_INLINE char *upb_gstrdup(const char *s) { - return upb_strdup(s, &upb_alloc_global); -} - -UPB_INLINE void _upb_value_setval(upb_value *v, uint64_t val, - upb_ctype_t ctype) { - v->val = val; - SET_TYPE(v->ctype, ctype); -} - -UPB_INLINE upb_value _upb_value_val(uint64_t val, upb_ctype_t ctype) { - upb_value ret; - _upb_value_setval(&ret, val, ctype); - return ret; -} - -/* For each value ctype, define the following set of functions: - * - * // Get/set an int32 from a upb_value. - * int32_t upb_value_getint32(upb_value val); - * void upb_value_setint32(upb_value *val, int32_t cval); - * - * // Construct a new upb_value from an int32. - * upb_value upb_value_int32(int32_t val); */ -#define FUNCS(name, membername, type_t, converter, proto_type) \ - UPB_INLINE void upb_value_set ## name(upb_value *val, type_t cval) { \ - val->val = (converter)cval; \ - SET_TYPE(val->ctype, proto_type); \ - } \ - UPB_INLINE upb_value upb_value_ ## name(type_t val) { \ - upb_value ret; \ - upb_value_set ## name(&ret, val); \ - return ret; \ - } \ - UPB_INLINE type_t upb_value_get ## name(upb_value val) { \ - UPB_ASSERT_DEBUGVAR(val.ctype == proto_type); \ - return (type_t)(converter)val.val; \ - } - -FUNCS(int32, int32, int32_t, int32_t, UPB_CTYPE_INT32) -FUNCS(int64, int64, int64_t, int64_t, UPB_CTYPE_INT64) -FUNCS(uint32, uint32, uint32_t, uint32_t, UPB_CTYPE_UINT32) -FUNCS(uint64, uint64, uint64_t, uint64_t, UPB_CTYPE_UINT64) -FUNCS(bool, _bool, bool, bool, UPB_CTYPE_BOOL) -FUNCS(cstr, cstr, char*, uintptr_t, UPB_CTYPE_CSTR) -FUNCS(ptr, ptr, void*, uintptr_t, UPB_CTYPE_PTR) -FUNCS(constptr, constptr, const void*, uintptr_t, UPB_CTYPE_CONSTPTR) -FUNCS(fptr, fptr, upb_func*, uintptr_t, UPB_CTYPE_FPTR) - -#undef FUNCS - -UPB_INLINE void upb_value_setfloat(upb_value *val, float cval) { - memcpy(&val->val, &cval, sizeof(cval)); - SET_TYPE(val->ctype, UPB_CTYPE_FLOAT); -} +UPB_INLINE void upb_value_setfloat(upb_value *val, float cval) { + memcpy(&val->val, &cval, sizeof(cval)); +} UPB_INLINE void upb_value_setdouble(upb_value *val, double cval) { memcpy(&val->val, &cval, sizeof(cval)); - SET_TYPE(val->ctype, UPB_CTYPE_DOUBLE); } UPB_INLINE upb_value upb_value_float(float cval) { @@ -801,7 +633,6 @@ typedef struct { #define UPB_TABVALUE_EMPTY_INIT {-1} - /* upb_table ******************************************************************/ typedef struct _upb_tabent { @@ -818,7 +649,6 @@ typedef struct _upb_tabent { typedef struct { size_t count; /* Number of entries in the hash part. */ size_t mask; /* Mask to turn hash value -> bucket. */ - upb_ctype_t ctype; /* Type of all values. */ uint8_t size_lg2; /* Size of the hashtable part is 2^size_lg2 entries. */ /* Hash table entries. @@ -828,17 +658,6 @@ typedef struct { * initialize const hash tables. Then we cast away const when we have to. */ const upb_tabent *entries; - -#ifndef NDEBUG - /* This table's allocator. We make the user pass it in to every relevant - * function and only use this to check it in debug mode. We do this solely - * to keep upb_table as small as possible. This might seem slightly paranoid - * but the plan is to use upb_table for all map fields and extension sets in - * a forthcoming message representation, so there could be a lot of these. - * If this turns out to be too annoying later, we can change it (since this - * is an internal-only header file). */ - upb_alloc *alloc; -#endif } upb_table; typedef struct { @@ -852,12 +671,6 @@ typedef struct { size_t array_count; /* Array part number of elements. */ } upb_inttable; -#define UPB_INTTABLE_INIT(count, mask, ctype, size_lg2, ent, a, asize, acount) \ - {UPB_TABLE_INIT(count, mask, ctype, size_lg2, ent), a, asize, acount} - -#define UPB_EMPTY_INTTABLE_INIT(ctype) \ - UPB_INTTABLE_INIT(0, 0, ctype, 0, NULL, NULL, 0, 0) - #define UPB_ARRAY_EMPTYENT -1 UPB_INLINE size_t upb_table_size(const upb_table *t) { @@ -926,6 +739,7 @@ upb_inttable *upb_inttable_pack(const upb_inttable *t, void *p, size_t *ofs, size_t size); upb_strtable *upb_strtable_pack(const upb_strtable *t, void *p, size_t *ofs, size_t size); +void upb_strtable_clear(upb_strtable *t); /* Inserts the given key into the hashtable with the given value. The key must * not already exist in the hash table. For string tables, the key must be @@ -1027,7 +841,7 @@ UPB_INLINE bool upb_inttable_lookup32(const upb_inttable *t, uint32_t key, if (key < t->array_size) { upb_tabval arrval = t->array[key]; if (upb_arrhas(arrval)) { - _upb_value_setval(v, arrval.val, t->t.ctype); + _upb_value_setval(v, arrval.val); return true; } else { return false; @@ -1037,7 +851,7 @@ UPB_INLINE bool upb_inttable_lookup32(const upb_inttable *t, uint32_t key, if (t->t.entries == NULL) return false; for (e = upb_getentry(&t->t, upb_inthash(key)); true; e = e->next) { if ((uint32_t)e->key == key) { - _upb_value_setval(v, e->val.val, t->t.ctype); + _upb_value_setval(v, e->val.val); return true; } if (e->next == NULL) return false; @@ -1091,8 +905,7 @@ typedef struct { void upb_strtable_begin(upb_strtable_iter *i, const upb_strtable *t); void upb_strtable_next(upb_strtable_iter *i); bool upb_strtable_done(const upb_strtable_iter *i); -const char *upb_strtable_iter_key(const upb_strtable_iter *i); -size_t upb_strtable_iter_keylength(const upb_strtable_iter *i); +upb_strview upb_strtable_iter_key(const upb_strtable_iter *i); upb_value upb_strtable_iter_value(const upb_strtable_iter *i); void upb_strtable_iter_setdone(upb_strtable_iter *i); bool upb_strtable_iter_isequal(const upb_strtable_iter *i1, @@ -1116,6 +929,10 @@ typedef struct { bool array_part; } upb_inttable_iter; +UPB_INLINE const upb_tabent *str_tabent(const upb_strtable_iter *i) { + return &i->t->t.entries[i->index]; +} + void upb_inttable_begin(upb_inttable_iter *i, const upb_inttable *t); void upb_inttable_next(upb_inttable_iter *i); bool upb_inttable_done(const upb_inttable_iter *i); @@ -1132,36 +949,140 @@ bool upb_inttable_iter_isequal(const upb_inttable_iter *i1, #endif /* UPB_TABLE_H_ */ -/* This file was generated by upbc (the upb compiler) from the input - * file: - * - * google/protobuf/descriptor.proto - * - * Do not edit -- your changes will be discarded when the file is - * regenerated. */ -#ifndef GOOGLE_PROTOBUF_DESCRIPTOR_PROTO_UPB_H_ -#define GOOGLE_PROTOBUF_DESCRIPTOR_PROTO_UPB_H_ -/* -** Functions for use by generated code. These are not public and users must -** not call them directly. -*/ +#ifdef __cplusplus +extern "C" { +#endif -#ifndef UPB_GENERATED_UTIL_H_ -#define UPB_GENERATED_UTIL_H_ +#define PTR_AT(msg, ofs, type) (type*)((const char*)msg + ofs) -#include +typedef void upb_msg; +/** upb_msglayout *************************************************************/ -#define PTR_AT(msg, ofs, type) (type*)((const char*)msg + ofs) +/* upb_msglayout represents the memory layout of a given upb_msgdef. The + * members are public so generated code can initialize them, but users MUST NOT + * read or write any of its members. */ + +/* These aren't real labels according to descriptor.proto, but in the table we + * use these for map/packed fields instead of UPB_LABEL_REPEATED. */ +enum { + _UPB_LABEL_MAP = 4, + _UPB_LABEL_PACKED = 7 /* Low 3 bits are common with UPB_LABEL_REPEATED. */ +}; + +typedef struct { + uint32_t number; + uint16_t offset; + int16_t presence; /* If >0, hasbit_index. If <0, -oneof_index. */ + uint16_t submsg_index; /* undefined if descriptortype != MESSAGE or GROUP. */ + uint8_t descriptortype; + uint8_t label; +} upb_msglayout_field; + +typedef struct upb_msglayout { + const struct upb_msglayout *const* submsgs; + const upb_msglayout_field *fields; + /* Must be aligned to sizeof(void*). Doesn't include internal members like + * unknown fields, extension dict, pointer to msglayout, etc. */ + uint16_t size; + uint16_t field_count; + bool extendable; +} upb_msglayout; + +/** upb_msg *******************************************************************/ + +/* 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. */ + +/* Used when a message is not extendable. */ +typedef struct { + char *unknown; + size_t unknown_len; + size_t unknown_size; +} upb_msg_internal; + +/* Used when a message is extendable. */ +typedef struct { + upb_inttable *extdict; + upb_msg_internal base; +} upb_msg_internal_withext; + +/* Maps upb_fieldtype_t -> memory size. */ +extern char _upb_fieldtype_to_size[12]; + +/* Creates a new messages with the given layout on the given arena. */ +upb_msg *_upb_msg_new(const upb_msglayout *l, upb_arena *a); + +/* Adds unknown data (serialized protobuf data) to the given message. The data + * is copied into the message instance. */ +bool _upb_msg_addunknown(upb_msg *msg, const char *data, size_t len, + upb_arena *arena); + +/* Returns a reference to the message's unknown data. */ +const char *upb_msg_getunknown(const upb_msg *msg, size_t *len); + +UPB_INLINE bool _upb_has_field(const void *msg, size_t idx) { + return (*PTR_AT(msg, idx / 8, const char) & (1 << (idx % 8))) != 0; +} + +UPB_INLINE bool _upb_sethas(const void *msg, size_t idx) { + return (*PTR_AT(msg, idx / 8, char)) |= (char)(1 << (idx % 8)); +} + +UPB_INLINE bool _upb_clearhas(const void *msg, size_t idx) { + return (*PTR_AT(msg, idx / 8, char)) &= (char)(~(1 << (idx % 8))); +} + +UPB_INLINE bool _upb_has_oneof_field(const void *msg, size_t case_ofs, int32_t num) { + return *PTR_AT(msg, case_ofs, int32_t) == num; +} + +UPB_INLINE bool _upb_has_submsg_nohasbit(const void *msg, size_t ofs) { + return *PTR_AT(msg, ofs, const void*) != NULL; +} + +UPB_INLINE bool _upb_isrepeated(const upb_msglayout_field *field) { + return (field->label & 3) == UPB_LABEL_REPEATED; +} + +/** upb_array *****************************************************************/ + +/* Our internal representation for repeated fields. */ +typedef struct { + uintptr_t data; /* Tagged ptr: low 3 bits of ptr are lg2(elem size). */ + size_t len; /* Measured in elements. */ + size_t size; /* Measured in elements. */ +} upb_array; + +UPB_INLINE const void *_upb_array_constptr(const upb_array *arr) { + return (void*)(arr->data & ~(uintptr_t)7); +} + +UPB_INLINE void *_upb_array_ptr(upb_array *arr) { + return (void*)_upb_array_constptr(arr); +} + +/* Creates a new array on the given arena. */ +upb_array *_upb_array_new(upb_arena *a, upb_fieldtype_t type); + +/* Resizes the capacity of the array to be at least min_size. */ +bool _upb_array_realloc(upb_array *arr, size_t min_size, upb_arena *arena); + +/* Fallback functions for when the accessors require a resize. */ +void *_upb_array_resize_fallback(upb_array **arr_ptr, size_t size, + upb_fieldtype_t type, upb_arena *arena); +bool _upb_array_append_fallback(upb_array **arr_ptr, const void *value, + upb_fieldtype_t type, upb_arena *arena); UPB_INLINE const void *_upb_array_accessor(const void *msg, size_t ofs, size_t *size) { const upb_array *arr = *PTR_AT(msg, ofs, const upb_array*); if (arr) { if (size) *size = arr->len; - return arr->data; + return _upb_array_constptr(arr); } else { if (size) *size = 0; return NULL; @@ -1173,78 +1094,295 @@ UPB_INLINE void *_upb_array_mutable_accessor(void *msg, size_t ofs, upb_array *arr = *PTR_AT(msg, ofs, upb_array*); if (arr) { if (size) *size = arr->len; - return arr->data; + return _upb_array_ptr(arr); } else { if (size) *size = 0; return NULL; } } -/* TODO(haberman): this is a mess. It will improve when upb_array no longer - * carries reflective state (type, elem_size). */ UPB_INLINE void *_upb_array_resize_accessor(void *msg, size_t ofs, size_t size, - size_t elem_size, upb_fieldtype_t type, upb_arena *arena) { - upb_array *arr = *PTR_AT(msg, ofs, upb_array*); - - if (!arr) { - arr = upb_array_new(arena); - if (!arr) return NULL; - *PTR_AT(msg, ofs, upb_array*) = arr; + upb_array **arr_ptr = PTR_AT(msg, ofs, upb_array*); + upb_array *arr = *arr_ptr; + if (!arr || arr->size < size) { + return _upb_array_resize_fallback(arr_ptr, size, type, arena); } - - if (size > arr->size) { - size_t new_size = UPB_MAX(arr->size, 4); - size_t old_bytes = arr->size * elem_size; - size_t new_bytes; - while (new_size < size) new_size *= 2; - new_bytes = new_size * elem_size; - arr->data = upb_arena_realloc(arena, arr->data, old_bytes, new_bytes); - if (!arr->data) { - return NULL; - } - arr->size = new_size; - } - arr->len = size; - return arr->data; + return _upb_array_ptr(arr); } + UPB_INLINE bool _upb_array_append_accessor(void *msg, size_t ofs, size_t elem_size, upb_fieldtype_t type, const void *value, upb_arena *arena) { - upb_array *arr = *PTR_AT(msg, ofs, upb_array*); - size_t i = arr ? arr->len : 0; - void *data = - _upb_array_resize_accessor(msg, ofs, i + 1, elem_size, type, arena); - if (!data) return false; - memcpy(PTR_AT(data, i * elem_size, char), value, elem_size); + upb_array **arr_ptr = PTR_AT(msg, ofs, upb_array*); + upb_array *arr = *arr_ptr; + void* ptr; + if (!arr || arr->len == arr->size) { + return _upb_array_append_fallback(arr_ptr, value, type, arena); + } + ptr = _upb_array_ptr(arr); + memcpy(PTR_AT(ptr, arr->len * elem_size, char), value, elem_size); + arr->len++; return true; } -UPB_INLINE bool _upb_has_field(const void *msg, size_t idx) { - return (*PTR_AT(msg, idx / 8, const char) & (1 << (idx % 8))) != 0; -} +/** upb_map *******************************************************************/ -UPB_INLINE bool _upb_sethas(const void *msg, size_t idx) { - return (*PTR_AT(msg, idx / 8, char)) |= (char)(1 << (idx % 8)); -} +/* Right now we use strmaps for everything. We'll likely want to use + * integer-specific maps for integer-keyed maps.*/ +typedef struct { + /* Size of key and val, based on the map type. Strings are represented as '0' + * because they must be handled specially. */ + char key_size; + char val_size; -UPB_INLINE bool _upb_clearhas(const void *msg, size_t idx) { - return (*PTR_AT(msg, idx / 8, char)) &= (char)(~(1 << (idx % 8))); -} + upb_strtable table; +} upb_map; -UPB_INLINE bool _upb_has_oneof_field(const void *msg, size_t case_ofs, int32_t num) { - return *PTR_AT(msg, case_ofs, int32_t) == num; +/* Map entries aren't actually stored, they are only used during parsing. For + * parsing, it helps a lot if all map entry messages have the same layout. + * The compiler and def.c must ensure that all map entries have this layout. */ +typedef struct { + upb_msg_internal internal; + union { + upb_strview str; /* For str/bytes. */ + upb_value val; /* For all other types. */ + } k; + union { + upb_strview str; /* For str/bytes. */ + upb_value val; /* For all other types. */ + } v; +} upb_map_entry; + +/* Creates a new map on the given arena with this key/value type. */ +upb_map *_upb_map_new(upb_arena *a, size_t key_size, size_t value_size); + +/* Converting between internal table representation and user values. + * + * _upb_map_tokey() and _upb_map_fromkey() are inverses. + * _upb_map_tovalue() and _upb_map_fromvalue() are inverses. + * + * These functions account for the fact that strings are treated differently + * from other types when stored in a map. + */ + +UPB_INLINE upb_strview _upb_map_tokey(const void *key, size_t size) { + if (size == UPB_MAPTYPE_STRING) { + return *(upb_strview*)key; + } else { + return upb_strview_make((const char*)key, size); + } +} + +UPB_INLINE void _upb_map_fromkey(upb_strview key, void* out, size_t size) { + if (size == UPB_MAPTYPE_STRING) { + memcpy(out, &key, sizeof(key)); + } else { + memcpy(out, key.data, size); + } +} + +UPB_INLINE upb_value _upb_map_tovalue(const void *val, size_t size, + upb_arena *a) { + upb_value ret = {0}; + if (size == UPB_MAPTYPE_STRING) { + upb_strview *strp = (upb_strview*)upb_arena_malloc(a, sizeof(*strp)); + *strp = *(upb_strview*)val; + memcpy(&ret, &strp, sizeof(strp)); + } else { + memcpy(&ret, val, size); + } + return ret; +} + +UPB_INLINE void _upb_map_fromvalue(upb_value val, void* out, size_t size) { + if (size == UPB_MAPTYPE_STRING) { + const upb_strview *strp = (const upb_strview*)upb_value_getptr(val); + memcpy(out, strp, sizeof(upb_strview)); + } else { + memcpy(out, &val, size); + } +} + +/* Map operations, shared by reflection and generated code. */ + +UPB_INLINE size_t _upb_map_size(const upb_map *map) { + return map->table.t.count; +} + +UPB_INLINE bool _upb_map_get(const upb_map *map, const void *key, + size_t key_size, void *val, size_t val_size) { + upb_value tabval; + upb_strview k = _upb_map_tokey(key, key_size); + bool ret = upb_strtable_lookup2(&map->table, k.data, k.size, &tabval); + if (ret) { + _upb_map_fromvalue(tabval, val, val_size); + } + return ret; +} + +UPB_INLINE void* _upb_map_next(const upb_map *map, size_t *iter) { + upb_strtable_iter it; + it.t = &map->table; + it.index = *iter; + upb_strtable_next(&it); + if (upb_strtable_done(&it)) return NULL; + *iter = it.index; + return (void*)str_tabent(&it); +} + +UPB_INLINE bool _upb_map_set(upb_map *map, const void *key, size_t key_size, + void *val, size_t val_size, upb_arena *arena) { + upb_strview strkey = _upb_map_tokey(key, key_size); + upb_value tabval = _upb_map_tovalue(val, val_size, arena); + upb_alloc *a = upb_arena_alloc(arena); + + /* TODO(haberman): add overwrite operation to minimize number of lookups. */ + upb_strtable_remove3(&map->table, strkey.data, strkey.size, NULL, a); + return upb_strtable_insert3(&map->table, strkey.data, strkey.size, tabval, a); +} + +UPB_INLINE bool _upb_map_delete(upb_map *map, const void *key, size_t key_size) { + upb_strview k = _upb_map_tokey(key, key_size); + return upb_strtable_remove3(&map->table, k.data, k.size, NULL, NULL); +} + +UPB_INLINE void _upb_map_clear(upb_map *map) { + upb_strtable_clear(&map->table); +} + +/* Message map operations, these get the map from the message first. */ + +UPB_INLINE size_t _upb_msg_map_size(const upb_msg *msg, size_t ofs) { + upb_map *map = *UPB_PTR_AT(msg, ofs, upb_map *); + return map ? _upb_map_size(map) : 0; +} + +UPB_INLINE bool _upb_msg_map_get(const upb_msg *msg, size_t ofs, + const void *key, size_t key_size, void *val, + size_t val_size) { + upb_map *map = *UPB_PTR_AT(msg, ofs, upb_map *); + if (!map) return false; + return _upb_map_get(map, key, key_size, val, val_size); +} + +UPB_INLINE void *_upb_msg_map_next(const upb_msg *msg, size_t ofs, + size_t *iter) { + upb_map *map = *UPB_PTR_AT(msg, ofs, upb_map *); + if (!map) return NULL; + return _upb_map_next(map, iter); +} + +UPB_INLINE bool _upb_msg_map_set(upb_msg *msg, size_t ofs, const void *key, + size_t key_size, void *val, size_t val_size, + upb_arena *arena) { + upb_map **map = PTR_AT(msg, ofs, upb_map *); + if (!*map) { + *map = _upb_map_new(arena, key_size, val_size); + } + return _upb_map_set(*map, key, key_size, val, val_size, arena); +} + +UPB_INLINE bool _upb_msg_map_delete(upb_msg *msg, size_t ofs, const void *key, + size_t key_size) { + upb_map *map = *UPB_PTR_AT(msg, ofs, upb_map *); + if (!map) return false; + return _upb_map_delete(map, key, key_size); +} + +UPB_INLINE void _upb_msg_map_clear(upb_msg *msg, size_t ofs) { + upb_map *map = *UPB_PTR_AT(msg, ofs, upb_map *); + if (!map) return; + _upb_map_clear(map); +} + +/* Accessing map key/value from a pointer, used by generated code only. */ + +UPB_INLINE void _upb_msg_map_key(const void* msg, void* key, size_t size) { + const upb_tabent *ent = (const upb_tabent*)msg; + uint32_t u32len; + upb_strview k; + k.data = upb_tabstr(ent->key, &u32len); + k.size = u32len; + _upb_map_fromkey(k, key, size); +} + +UPB_INLINE void _upb_msg_map_value(const void* msg, void* val, size_t size) { + const upb_tabent *ent = (const upb_tabent*)msg; + upb_value v; + _upb_value_setval(&v, ent->val.val); + _upb_map_fromvalue(v, val, size); +} + +UPB_INLINE void _upb_msg_map_set_value(void* msg, const void* val, size_t size) { + upb_tabent *ent = (upb_tabent*)msg; + /* This is like _upb_map_tovalue() except the entry already exists so we can + * reuse the allocated upb_strview for string fields. */ + if (size == UPB_MAPTYPE_STRING) { + upb_strview *strp = (upb_strview*)ent->val.val; + memcpy(strp, val, sizeof(*strp)); + } else { + memcpy(&ent->val.val, val, size); + } } #undef PTR_AT +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_MSG_H_ */ + +#ifdef __cplusplus +extern "C" { +#endif + +bool upb_decode(const char *buf, size_t size, upb_msg *msg, + const upb_msglayout *l, upb_arena *arena); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* UPB_DECODE_H_ */ +/* +** upb_encode: parsing into a upb_msg using a upb_msglayout. +*/ + +#ifndef UPB_ENCODE_H_ +#define UPB_ENCODE_H_ + + +#ifdef __cplusplus +extern "C" { +#endif + +char *upb_encode(const void *msg, const upb_msglayout *l, upb_arena *arena, + size_t *size); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* UPB_ENCODE_H_ */ +/* This file was generated by upbc (the upb compiler) from the input + * file: + * + * google/protobuf/descriptor.proto + * + * Do not edit -- your changes will be discarded when the file is + * regenerated. */ + +#ifndef GOOGLE_PROTOBUF_DESCRIPTOR_PROTO_UPB_H_ +#define GOOGLE_PROTOBUF_DESCRIPTOR_PROTO_UPB_H_ -#endif /* UPB_GENERATED_UTIL_H_ */ #ifdef __cplusplus @@ -1388,7 +1526,7 @@ typedef enum { /* google.protobuf.FileDescriptorSet */ UPB_INLINE google_protobuf_FileDescriptorSet *google_protobuf_FileDescriptorSet_new(upb_arena *arena) { - return (google_protobuf_FileDescriptorSet *)upb_msg_new(&google_protobuf_FileDescriptorSet_msginit, arena); + return (google_protobuf_FileDescriptorSet *)_upb_msg_new(&google_protobuf_FileDescriptorSet_msginit, arena); } UPB_INLINE google_protobuf_FileDescriptorSet *google_protobuf_FileDescriptorSet_parse(const char *buf, size_t size, upb_arena *arena) { @@ -1399,16 +1537,17 @@ UPB_INLINE char *google_protobuf_FileDescriptorSet_serialize(const google_protob return upb_encode(msg, &google_protobuf_FileDescriptorSet_msginit, arena, len); } +UPB_INLINE bool google_protobuf_FileDescriptorSet_has_file(const google_protobuf_FileDescriptorSet *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(0, 0)); } UPB_INLINE const google_protobuf_FileDescriptorProto* const* google_protobuf_FileDescriptorSet_file(const google_protobuf_FileDescriptorSet *msg, size_t *len) { return (const google_protobuf_FileDescriptorProto* const*)_upb_array_accessor(msg, UPB_SIZE(0, 0), len); } UPB_INLINE google_protobuf_FileDescriptorProto** google_protobuf_FileDescriptorSet_mutable_file(google_protobuf_FileDescriptorSet *msg, size_t *len) { return (google_protobuf_FileDescriptorProto**)_upb_array_mutable_accessor(msg, UPB_SIZE(0, 0), len); } UPB_INLINE google_protobuf_FileDescriptorProto** google_protobuf_FileDescriptorSet_resize_file(google_protobuf_FileDescriptorSet *msg, size_t len, upb_arena *arena) { - return (google_protobuf_FileDescriptorProto**)_upb_array_resize_accessor(msg, UPB_SIZE(0, 0), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena); + return (google_protobuf_FileDescriptorProto**)_upb_array_resize_accessor(msg, UPB_SIZE(0, 0), len, UPB_TYPE_MESSAGE, arena); } UPB_INLINE struct google_protobuf_FileDescriptorProto* google_protobuf_FileDescriptorSet_add_file(google_protobuf_FileDescriptorSet *msg, upb_arena *arena) { - struct google_protobuf_FileDescriptorProto* sub = (struct google_protobuf_FileDescriptorProto*)upb_msg_new(&google_protobuf_FileDescriptorProto_msginit, arena); + struct google_protobuf_FileDescriptorProto* sub = (struct google_protobuf_FileDescriptorProto*)_upb_msg_new(&google_protobuf_FileDescriptorProto_msginit, arena); bool ok = _upb_array_append_accessor( msg, UPB_SIZE(0, 0), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); if (!ok) return NULL; @@ -1418,7 +1557,7 @@ UPB_INLINE struct google_protobuf_FileDescriptorProto* google_protobuf_FileDescr /* google.protobuf.FileDescriptorProto */ UPB_INLINE google_protobuf_FileDescriptorProto *google_protobuf_FileDescriptorProto_new(upb_arena *arena) { - return (google_protobuf_FileDescriptorProto *)upb_msg_new(&google_protobuf_FileDescriptorProto_msginit, arena); + return (google_protobuf_FileDescriptorProto *)_upb_msg_new(&google_protobuf_FileDescriptorProto_msginit, arena); } UPB_INLINE google_protobuf_FileDescriptorProto *google_protobuf_FileDescriptorProto_parse(const char *buf, size_t size, upb_arena *arena) { @@ -1430,49 +1569,53 @@ UPB_INLINE char *google_protobuf_FileDescriptorProto_serialize(const google_prot } UPB_INLINE bool google_protobuf_FileDescriptorProto_has_name(const google_protobuf_FileDescriptorProto *msg) { return _upb_has_field(msg, 1); } -UPB_INLINE upb_strview google_protobuf_FileDescriptorProto_name(const google_protobuf_FileDescriptorProto *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(4, 8)); } +UPB_INLINE upb_strview google_protobuf_FileDescriptorProto_name(const google_protobuf_FileDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview); } UPB_INLINE bool google_protobuf_FileDescriptorProto_has_package(const google_protobuf_FileDescriptorProto *msg) { return _upb_has_field(msg, 2); } -UPB_INLINE upb_strview google_protobuf_FileDescriptorProto_package(const google_protobuf_FileDescriptorProto *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(12, 24)); } +UPB_INLINE upb_strview google_protobuf_FileDescriptorProto_package(const google_protobuf_FileDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(12, 24), upb_strview); } UPB_INLINE upb_strview const* google_protobuf_FileDescriptorProto_dependency(const google_protobuf_FileDescriptorProto *msg, size_t *len) { return (upb_strview const*)_upb_array_accessor(msg, UPB_SIZE(36, 72), len); } +UPB_INLINE bool google_protobuf_FileDescriptorProto_has_message_type(const google_protobuf_FileDescriptorProto *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(40, 80)); } UPB_INLINE const google_protobuf_DescriptorProto* const* google_protobuf_FileDescriptorProto_message_type(const google_protobuf_FileDescriptorProto *msg, size_t *len) { return (const google_protobuf_DescriptorProto* const*)_upb_array_accessor(msg, UPB_SIZE(40, 80), len); } +UPB_INLINE bool google_protobuf_FileDescriptorProto_has_enum_type(const google_protobuf_FileDescriptorProto *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(44, 88)); } UPB_INLINE const google_protobuf_EnumDescriptorProto* const* google_protobuf_FileDescriptorProto_enum_type(const google_protobuf_FileDescriptorProto *msg, size_t *len) { return (const google_protobuf_EnumDescriptorProto* const*)_upb_array_accessor(msg, UPB_SIZE(44, 88), len); } +UPB_INLINE bool google_protobuf_FileDescriptorProto_has_service(const google_protobuf_FileDescriptorProto *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(48, 96)); } UPB_INLINE const google_protobuf_ServiceDescriptorProto* const* google_protobuf_FileDescriptorProto_service(const google_protobuf_FileDescriptorProto *msg, size_t *len) { return (const google_protobuf_ServiceDescriptorProto* const*)_upb_array_accessor(msg, UPB_SIZE(48, 96), len); } +UPB_INLINE bool google_protobuf_FileDescriptorProto_has_extension(const google_protobuf_FileDescriptorProto *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(52, 104)); } UPB_INLINE const google_protobuf_FieldDescriptorProto* const* google_protobuf_FileDescriptorProto_extension(const google_protobuf_FileDescriptorProto *msg, size_t *len) { return (const google_protobuf_FieldDescriptorProto* const*)_upb_array_accessor(msg, UPB_SIZE(52, 104), len); } UPB_INLINE bool google_protobuf_FileDescriptorProto_has_options(const google_protobuf_FileDescriptorProto *msg) { return _upb_has_field(msg, 4); } -UPB_INLINE const google_protobuf_FileOptions* google_protobuf_FileDescriptorProto_options(const google_protobuf_FileDescriptorProto *msg) { return UPB_FIELD_AT(msg, const google_protobuf_FileOptions*, UPB_SIZE(28, 56)); } +UPB_INLINE const google_protobuf_FileOptions* google_protobuf_FileDescriptorProto_options(const google_protobuf_FileDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(28, 56), const google_protobuf_FileOptions*); } UPB_INLINE bool google_protobuf_FileDescriptorProto_has_source_code_info(const google_protobuf_FileDescriptorProto *msg) { return _upb_has_field(msg, 5); } -UPB_INLINE const google_protobuf_SourceCodeInfo* google_protobuf_FileDescriptorProto_source_code_info(const google_protobuf_FileDescriptorProto *msg) { return UPB_FIELD_AT(msg, const google_protobuf_SourceCodeInfo*, UPB_SIZE(32, 64)); } +UPB_INLINE const google_protobuf_SourceCodeInfo* google_protobuf_FileDescriptorProto_source_code_info(const google_protobuf_FileDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(32, 64), const google_protobuf_SourceCodeInfo*); } UPB_INLINE int32_t const* google_protobuf_FileDescriptorProto_public_dependency(const google_protobuf_FileDescriptorProto *msg, size_t *len) { return (int32_t const*)_upb_array_accessor(msg, UPB_SIZE(56, 112), len); } UPB_INLINE int32_t const* google_protobuf_FileDescriptorProto_weak_dependency(const google_protobuf_FileDescriptorProto *msg, size_t *len) { return (int32_t const*)_upb_array_accessor(msg, UPB_SIZE(60, 120), len); } UPB_INLINE bool google_protobuf_FileDescriptorProto_has_syntax(const google_protobuf_FileDescriptorProto *msg) { return _upb_has_field(msg, 3); } -UPB_INLINE upb_strview google_protobuf_FileDescriptorProto_syntax(const google_protobuf_FileDescriptorProto *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(20, 40)); } +UPB_INLINE upb_strview google_protobuf_FileDescriptorProto_syntax(const google_protobuf_FileDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(20, 40), upb_strview); } UPB_INLINE void google_protobuf_FileDescriptorProto_set_name(google_protobuf_FileDescriptorProto *msg, upb_strview value) { _upb_sethas(msg, 1); - UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(4, 8)) = value; + *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview) = value; } UPB_INLINE void google_protobuf_FileDescriptorProto_set_package(google_protobuf_FileDescriptorProto *msg, upb_strview value) { _upb_sethas(msg, 2); - UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(12, 24)) = value; + *UPB_PTR_AT(msg, UPB_SIZE(12, 24), upb_strview) = value; } UPB_INLINE upb_strview* google_protobuf_FileDescriptorProto_mutable_dependency(google_protobuf_FileDescriptorProto *msg, size_t *len) { return (upb_strview*)_upb_array_mutable_accessor(msg, UPB_SIZE(36, 72), len); } UPB_INLINE upb_strview* google_protobuf_FileDescriptorProto_resize_dependency(google_protobuf_FileDescriptorProto *msg, size_t len, upb_arena *arena) { - return (upb_strview*)_upb_array_resize_accessor(msg, UPB_SIZE(36, 72), len, UPB_SIZE(8, 16), UPB_TYPE_STRING, arena); + return (upb_strview*)_upb_array_resize_accessor(msg, UPB_SIZE(36, 72), len, UPB_TYPE_STRING, arena); } UPB_INLINE bool google_protobuf_FileDescriptorProto_add_dependency(google_protobuf_FileDescriptorProto *msg, upb_strview val, upb_arena *arena) { - return _upb_array_append_accessor( - msg, UPB_SIZE(36, 72), UPB_SIZE(8, 16), UPB_TYPE_STRING, &val, arena); + return _upb_array_append_accessor(msg, UPB_SIZE(36, 72), UPB_SIZE(8, 16), UPB_TYPE_STRING, &val, + arena); } UPB_INLINE google_protobuf_DescriptorProto** google_protobuf_FileDescriptorProto_mutable_message_type(google_protobuf_FileDescriptorProto *msg, size_t *len) { return (google_protobuf_DescriptorProto**)_upb_array_mutable_accessor(msg, UPB_SIZE(40, 80), len); } UPB_INLINE google_protobuf_DescriptorProto** google_protobuf_FileDescriptorProto_resize_message_type(google_protobuf_FileDescriptorProto *msg, size_t len, upb_arena *arena) { - return (google_protobuf_DescriptorProto**)_upb_array_resize_accessor(msg, UPB_SIZE(40, 80), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena); + return (google_protobuf_DescriptorProto**)_upb_array_resize_accessor(msg, UPB_SIZE(40, 80), len, UPB_TYPE_MESSAGE, arena); } UPB_INLINE struct google_protobuf_DescriptorProto* google_protobuf_FileDescriptorProto_add_message_type(google_protobuf_FileDescriptorProto *msg, upb_arena *arena) { - struct google_protobuf_DescriptorProto* sub = (struct google_protobuf_DescriptorProto*)upb_msg_new(&google_protobuf_DescriptorProto_msginit, arena); + struct google_protobuf_DescriptorProto* sub = (struct google_protobuf_DescriptorProto*)_upb_msg_new(&google_protobuf_DescriptorProto_msginit, arena); bool ok = _upb_array_append_accessor( msg, UPB_SIZE(40, 80), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); if (!ok) return NULL; @@ -1482,10 +1625,10 @@ UPB_INLINE google_protobuf_EnumDescriptorProto** google_protobuf_FileDescriptorP return (google_protobuf_EnumDescriptorProto**)_upb_array_mutable_accessor(msg, UPB_SIZE(44, 88), len); } UPB_INLINE google_protobuf_EnumDescriptorProto** google_protobuf_FileDescriptorProto_resize_enum_type(google_protobuf_FileDescriptorProto *msg, size_t len, upb_arena *arena) { - return (google_protobuf_EnumDescriptorProto**)_upb_array_resize_accessor(msg, UPB_SIZE(44, 88), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena); + return (google_protobuf_EnumDescriptorProto**)_upb_array_resize_accessor(msg, UPB_SIZE(44, 88), len, UPB_TYPE_MESSAGE, arena); } UPB_INLINE struct google_protobuf_EnumDescriptorProto* google_protobuf_FileDescriptorProto_add_enum_type(google_protobuf_FileDescriptorProto *msg, upb_arena *arena) { - struct google_protobuf_EnumDescriptorProto* sub = (struct google_protobuf_EnumDescriptorProto*)upb_msg_new(&google_protobuf_EnumDescriptorProto_msginit, arena); + struct google_protobuf_EnumDescriptorProto* sub = (struct google_protobuf_EnumDescriptorProto*)_upb_msg_new(&google_protobuf_EnumDescriptorProto_msginit, arena); bool ok = _upb_array_append_accessor( msg, UPB_SIZE(44, 88), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); if (!ok) return NULL; @@ -1495,10 +1638,10 @@ UPB_INLINE google_protobuf_ServiceDescriptorProto** google_protobuf_FileDescript return (google_protobuf_ServiceDescriptorProto**)_upb_array_mutable_accessor(msg, UPB_SIZE(48, 96), len); } UPB_INLINE google_protobuf_ServiceDescriptorProto** google_protobuf_FileDescriptorProto_resize_service(google_protobuf_FileDescriptorProto *msg, size_t len, upb_arena *arena) { - return (google_protobuf_ServiceDescriptorProto**)_upb_array_resize_accessor(msg, UPB_SIZE(48, 96), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena); + return (google_protobuf_ServiceDescriptorProto**)_upb_array_resize_accessor(msg, UPB_SIZE(48, 96), len, UPB_TYPE_MESSAGE, arena); } UPB_INLINE struct google_protobuf_ServiceDescriptorProto* google_protobuf_FileDescriptorProto_add_service(google_protobuf_FileDescriptorProto *msg, upb_arena *arena) { - struct google_protobuf_ServiceDescriptorProto* sub = (struct google_protobuf_ServiceDescriptorProto*)upb_msg_new(&google_protobuf_ServiceDescriptorProto_msginit, arena); + struct google_protobuf_ServiceDescriptorProto* sub = (struct google_protobuf_ServiceDescriptorProto*)_upb_msg_new(&google_protobuf_ServiceDescriptorProto_msginit, arena); bool ok = _upb_array_append_accessor( msg, UPB_SIZE(48, 96), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); if (!ok) return NULL; @@ -1508,10 +1651,10 @@ UPB_INLINE google_protobuf_FieldDescriptorProto** google_protobuf_FileDescriptor return (google_protobuf_FieldDescriptorProto**)_upb_array_mutable_accessor(msg, UPB_SIZE(52, 104), len); } UPB_INLINE google_protobuf_FieldDescriptorProto** google_protobuf_FileDescriptorProto_resize_extension(google_protobuf_FileDescriptorProto *msg, size_t len, upb_arena *arena) { - return (google_protobuf_FieldDescriptorProto**)_upb_array_resize_accessor(msg, UPB_SIZE(52, 104), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena); + return (google_protobuf_FieldDescriptorProto**)_upb_array_resize_accessor(msg, UPB_SIZE(52, 104), len, UPB_TYPE_MESSAGE, arena); } UPB_INLINE struct google_protobuf_FieldDescriptorProto* google_protobuf_FileDescriptorProto_add_extension(google_protobuf_FileDescriptorProto *msg, upb_arena *arena) { - struct google_protobuf_FieldDescriptorProto* sub = (struct google_protobuf_FieldDescriptorProto*)upb_msg_new(&google_protobuf_FieldDescriptorProto_msginit, arena); + struct google_protobuf_FieldDescriptorProto* sub = (struct google_protobuf_FieldDescriptorProto*)_upb_msg_new(&google_protobuf_FieldDescriptorProto_msginit, arena); bool ok = _upb_array_append_accessor( msg, UPB_SIZE(52, 104), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); if (!ok) return NULL; @@ -1519,12 +1662,12 @@ UPB_INLINE struct google_protobuf_FieldDescriptorProto* google_protobuf_FileDesc } UPB_INLINE void google_protobuf_FileDescriptorProto_set_options(google_protobuf_FileDescriptorProto *msg, google_protobuf_FileOptions* value) { _upb_sethas(msg, 4); - UPB_FIELD_AT(msg, google_protobuf_FileOptions*, UPB_SIZE(28, 56)) = value; + *UPB_PTR_AT(msg, UPB_SIZE(28, 56), google_protobuf_FileOptions*) = value; } UPB_INLINE struct google_protobuf_FileOptions* google_protobuf_FileDescriptorProto_mutable_options(google_protobuf_FileDescriptorProto *msg, upb_arena *arena) { struct google_protobuf_FileOptions* sub = (struct google_protobuf_FileOptions*)google_protobuf_FileDescriptorProto_options(msg); if (sub == NULL) { - sub = (struct google_protobuf_FileOptions*)upb_msg_new(&google_protobuf_FileOptions_msginit, arena); + sub = (struct google_protobuf_FileOptions*)_upb_msg_new(&google_protobuf_FileOptions_msginit, arena); if (!sub) return NULL; google_protobuf_FileDescriptorProto_set_options(msg, sub); } @@ -1532,12 +1675,12 @@ UPB_INLINE struct google_protobuf_FileOptions* google_protobuf_FileDescriptorPro } UPB_INLINE void google_protobuf_FileDescriptorProto_set_source_code_info(google_protobuf_FileDescriptorProto *msg, google_protobuf_SourceCodeInfo* value) { _upb_sethas(msg, 5); - UPB_FIELD_AT(msg, google_protobuf_SourceCodeInfo*, UPB_SIZE(32, 64)) = value; + *UPB_PTR_AT(msg, UPB_SIZE(32, 64), google_protobuf_SourceCodeInfo*) = value; } UPB_INLINE struct google_protobuf_SourceCodeInfo* google_protobuf_FileDescriptorProto_mutable_source_code_info(google_protobuf_FileDescriptorProto *msg, upb_arena *arena) { struct google_protobuf_SourceCodeInfo* sub = (struct google_protobuf_SourceCodeInfo*)google_protobuf_FileDescriptorProto_source_code_info(msg); if (sub == NULL) { - sub = (struct google_protobuf_SourceCodeInfo*)upb_msg_new(&google_protobuf_SourceCodeInfo_msginit, arena); + sub = (struct google_protobuf_SourceCodeInfo*)_upb_msg_new(&google_protobuf_SourceCodeInfo_msginit, arena); if (!sub) return NULL; google_protobuf_FileDescriptorProto_set_source_code_info(msg, sub); } @@ -1547,31 +1690,31 @@ UPB_INLINE int32_t* google_protobuf_FileDescriptorProto_mutable_public_dependenc return (int32_t*)_upb_array_mutable_accessor(msg, UPB_SIZE(56, 112), len); } UPB_INLINE int32_t* google_protobuf_FileDescriptorProto_resize_public_dependency(google_protobuf_FileDescriptorProto *msg, size_t len, upb_arena *arena) { - return (int32_t*)_upb_array_resize_accessor(msg, UPB_SIZE(56, 112), len, UPB_SIZE(4, 4), UPB_TYPE_INT32, arena); + return (int32_t*)_upb_array_resize_accessor(msg, UPB_SIZE(56, 112), len, UPB_TYPE_INT32, arena); } UPB_INLINE bool google_protobuf_FileDescriptorProto_add_public_dependency(google_protobuf_FileDescriptorProto *msg, int32_t val, upb_arena *arena) { - return _upb_array_append_accessor( - msg, UPB_SIZE(56, 112), UPB_SIZE(4, 4), UPB_TYPE_INT32, &val, arena); + return _upb_array_append_accessor(msg, UPB_SIZE(56, 112), UPB_SIZE(4, 4), UPB_TYPE_INT32, &val, + arena); } UPB_INLINE int32_t* google_protobuf_FileDescriptorProto_mutable_weak_dependency(google_protobuf_FileDescriptorProto *msg, size_t *len) { return (int32_t*)_upb_array_mutable_accessor(msg, UPB_SIZE(60, 120), len); } UPB_INLINE int32_t* google_protobuf_FileDescriptorProto_resize_weak_dependency(google_protobuf_FileDescriptorProto *msg, size_t len, upb_arena *arena) { - return (int32_t*)_upb_array_resize_accessor(msg, UPB_SIZE(60, 120), len, UPB_SIZE(4, 4), UPB_TYPE_INT32, arena); + return (int32_t*)_upb_array_resize_accessor(msg, UPB_SIZE(60, 120), len, UPB_TYPE_INT32, arena); } UPB_INLINE bool google_protobuf_FileDescriptorProto_add_weak_dependency(google_protobuf_FileDescriptorProto *msg, int32_t val, upb_arena *arena) { - return _upb_array_append_accessor( - msg, UPB_SIZE(60, 120), UPB_SIZE(4, 4), UPB_TYPE_INT32, &val, arena); + return _upb_array_append_accessor(msg, UPB_SIZE(60, 120), UPB_SIZE(4, 4), UPB_TYPE_INT32, &val, + arena); } UPB_INLINE void google_protobuf_FileDescriptorProto_set_syntax(google_protobuf_FileDescriptorProto *msg, upb_strview value) { _upb_sethas(msg, 3); - UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(20, 40)) = value; + *UPB_PTR_AT(msg, UPB_SIZE(20, 40), upb_strview) = value; } /* google.protobuf.DescriptorProto */ UPB_INLINE google_protobuf_DescriptorProto *google_protobuf_DescriptorProto_new(upb_arena *arena) { - return (google_protobuf_DescriptorProto *)upb_msg_new(&google_protobuf_DescriptorProto_msginit, arena); + return (google_protobuf_DescriptorProto *)_upb_msg_new(&google_protobuf_DescriptorProto_msginit, arena); } UPB_INLINE google_protobuf_DescriptorProto *google_protobuf_DescriptorProto_parse(const char *buf, size_t size, upb_arena *arena) { @@ -1583,30 +1726,37 @@ UPB_INLINE char *google_protobuf_DescriptorProto_serialize(const google_protobuf } UPB_INLINE bool google_protobuf_DescriptorProto_has_name(const google_protobuf_DescriptorProto *msg) { return _upb_has_field(msg, 1); } -UPB_INLINE upb_strview google_protobuf_DescriptorProto_name(const google_protobuf_DescriptorProto *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(4, 8)); } +UPB_INLINE upb_strview google_protobuf_DescriptorProto_name(const google_protobuf_DescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview); } +UPB_INLINE bool google_protobuf_DescriptorProto_has_field(const google_protobuf_DescriptorProto *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(16, 32)); } UPB_INLINE const google_protobuf_FieldDescriptorProto* const* google_protobuf_DescriptorProto_field(const google_protobuf_DescriptorProto *msg, size_t *len) { return (const google_protobuf_FieldDescriptorProto* const*)_upb_array_accessor(msg, UPB_SIZE(16, 32), len); } +UPB_INLINE bool google_protobuf_DescriptorProto_has_nested_type(const google_protobuf_DescriptorProto *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(20, 40)); } UPB_INLINE const google_protobuf_DescriptorProto* const* google_protobuf_DescriptorProto_nested_type(const google_protobuf_DescriptorProto *msg, size_t *len) { return (const google_protobuf_DescriptorProto* const*)_upb_array_accessor(msg, UPB_SIZE(20, 40), len); } +UPB_INLINE bool google_protobuf_DescriptorProto_has_enum_type(const google_protobuf_DescriptorProto *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(24, 48)); } UPB_INLINE const google_protobuf_EnumDescriptorProto* const* google_protobuf_DescriptorProto_enum_type(const google_protobuf_DescriptorProto *msg, size_t *len) { return (const google_protobuf_EnumDescriptorProto* const*)_upb_array_accessor(msg, UPB_SIZE(24, 48), len); } +UPB_INLINE bool google_protobuf_DescriptorProto_has_extension_range(const google_protobuf_DescriptorProto *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(28, 56)); } UPB_INLINE const google_protobuf_DescriptorProto_ExtensionRange* const* google_protobuf_DescriptorProto_extension_range(const google_protobuf_DescriptorProto *msg, size_t *len) { return (const google_protobuf_DescriptorProto_ExtensionRange* const*)_upb_array_accessor(msg, UPB_SIZE(28, 56), len); } +UPB_INLINE bool google_protobuf_DescriptorProto_has_extension(const google_protobuf_DescriptorProto *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(32, 64)); } UPB_INLINE const google_protobuf_FieldDescriptorProto* const* google_protobuf_DescriptorProto_extension(const google_protobuf_DescriptorProto *msg, size_t *len) { return (const google_protobuf_FieldDescriptorProto* const*)_upb_array_accessor(msg, UPB_SIZE(32, 64), len); } UPB_INLINE bool google_protobuf_DescriptorProto_has_options(const google_protobuf_DescriptorProto *msg) { return _upb_has_field(msg, 2); } -UPB_INLINE const google_protobuf_MessageOptions* google_protobuf_DescriptorProto_options(const google_protobuf_DescriptorProto *msg) { return UPB_FIELD_AT(msg, const google_protobuf_MessageOptions*, UPB_SIZE(12, 24)); } +UPB_INLINE const google_protobuf_MessageOptions* google_protobuf_DescriptorProto_options(const google_protobuf_DescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(12, 24), const google_protobuf_MessageOptions*); } +UPB_INLINE bool google_protobuf_DescriptorProto_has_oneof_decl(const google_protobuf_DescriptorProto *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(36, 72)); } UPB_INLINE const google_protobuf_OneofDescriptorProto* const* google_protobuf_DescriptorProto_oneof_decl(const google_protobuf_DescriptorProto *msg, size_t *len) { return (const google_protobuf_OneofDescriptorProto* const*)_upb_array_accessor(msg, UPB_SIZE(36, 72), len); } +UPB_INLINE bool google_protobuf_DescriptorProto_has_reserved_range(const google_protobuf_DescriptorProto *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(40, 80)); } UPB_INLINE const google_protobuf_DescriptorProto_ReservedRange* const* google_protobuf_DescriptorProto_reserved_range(const google_protobuf_DescriptorProto *msg, size_t *len) { return (const google_protobuf_DescriptorProto_ReservedRange* const*)_upb_array_accessor(msg, UPB_SIZE(40, 80), len); } UPB_INLINE upb_strview const* google_protobuf_DescriptorProto_reserved_name(const google_protobuf_DescriptorProto *msg, size_t *len) { return (upb_strview const*)_upb_array_accessor(msg, UPB_SIZE(44, 88), len); } UPB_INLINE void google_protobuf_DescriptorProto_set_name(google_protobuf_DescriptorProto *msg, upb_strview value) { _upb_sethas(msg, 1); - UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(4, 8)) = value; + *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview) = value; } UPB_INLINE google_protobuf_FieldDescriptorProto** google_protobuf_DescriptorProto_mutable_field(google_protobuf_DescriptorProto *msg, size_t *len) { return (google_protobuf_FieldDescriptorProto**)_upb_array_mutable_accessor(msg, UPB_SIZE(16, 32), len); } UPB_INLINE google_protobuf_FieldDescriptorProto** google_protobuf_DescriptorProto_resize_field(google_protobuf_DescriptorProto *msg, size_t len, upb_arena *arena) { - return (google_protobuf_FieldDescriptorProto**)_upb_array_resize_accessor(msg, UPB_SIZE(16, 32), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena); + return (google_protobuf_FieldDescriptorProto**)_upb_array_resize_accessor(msg, UPB_SIZE(16, 32), len, UPB_TYPE_MESSAGE, arena); } UPB_INLINE struct google_protobuf_FieldDescriptorProto* google_protobuf_DescriptorProto_add_field(google_protobuf_DescriptorProto *msg, upb_arena *arena) { - struct google_protobuf_FieldDescriptorProto* sub = (struct google_protobuf_FieldDescriptorProto*)upb_msg_new(&google_protobuf_FieldDescriptorProto_msginit, arena); + struct google_protobuf_FieldDescriptorProto* sub = (struct google_protobuf_FieldDescriptorProto*)_upb_msg_new(&google_protobuf_FieldDescriptorProto_msginit, arena); bool ok = _upb_array_append_accessor( msg, UPB_SIZE(16, 32), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); if (!ok) return NULL; @@ -1616,10 +1766,10 @@ UPB_INLINE google_protobuf_DescriptorProto** google_protobuf_DescriptorProto_mut return (google_protobuf_DescriptorProto**)_upb_array_mutable_accessor(msg, UPB_SIZE(20, 40), len); } UPB_INLINE google_protobuf_DescriptorProto** google_protobuf_DescriptorProto_resize_nested_type(google_protobuf_DescriptorProto *msg, size_t len, upb_arena *arena) { - return (google_protobuf_DescriptorProto**)_upb_array_resize_accessor(msg, UPB_SIZE(20, 40), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena); + return (google_protobuf_DescriptorProto**)_upb_array_resize_accessor(msg, UPB_SIZE(20, 40), len, UPB_TYPE_MESSAGE, arena); } UPB_INLINE struct google_protobuf_DescriptorProto* google_protobuf_DescriptorProto_add_nested_type(google_protobuf_DescriptorProto *msg, upb_arena *arena) { - struct google_protobuf_DescriptorProto* sub = (struct google_protobuf_DescriptorProto*)upb_msg_new(&google_protobuf_DescriptorProto_msginit, arena); + struct google_protobuf_DescriptorProto* sub = (struct google_protobuf_DescriptorProto*)_upb_msg_new(&google_protobuf_DescriptorProto_msginit, arena); bool ok = _upb_array_append_accessor( msg, UPB_SIZE(20, 40), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); if (!ok) return NULL; @@ -1629,10 +1779,10 @@ UPB_INLINE google_protobuf_EnumDescriptorProto** google_protobuf_DescriptorProto return (google_protobuf_EnumDescriptorProto**)_upb_array_mutable_accessor(msg, UPB_SIZE(24, 48), len); } UPB_INLINE google_protobuf_EnumDescriptorProto** google_protobuf_DescriptorProto_resize_enum_type(google_protobuf_DescriptorProto *msg, size_t len, upb_arena *arena) { - return (google_protobuf_EnumDescriptorProto**)_upb_array_resize_accessor(msg, UPB_SIZE(24, 48), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena); + return (google_protobuf_EnumDescriptorProto**)_upb_array_resize_accessor(msg, UPB_SIZE(24, 48), len, UPB_TYPE_MESSAGE, arena); } UPB_INLINE struct google_protobuf_EnumDescriptorProto* google_protobuf_DescriptorProto_add_enum_type(google_protobuf_DescriptorProto *msg, upb_arena *arena) { - struct google_protobuf_EnumDescriptorProto* sub = (struct google_protobuf_EnumDescriptorProto*)upb_msg_new(&google_protobuf_EnumDescriptorProto_msginit, arena); + struct google_protobuf_EnumDescriptorProto* sub = (struct google_protobuf_EnumDescriptorProto*)_upb_msg_new(&google_protobuf_EnumDescriptorProto_msginit, arena); bool ok = _upb_array_append_accessor( msg, UPB_SIZE(24, 48), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); if (!ok) return NULL; @@ -1642,10 +1792,10 @@ UPB_INLINE google_protobuf_DescriptorProto_ExtensionRange** google_protobuf_Desc return (google_protobuf_DescriptorProto_ExtensionRange**)_upb_array_mutable_accessor(msg, UPB_SIZE(28, 56), len); } UPB_INLINE google_protobuf_DescriptorProto_ExtensionRange** google_protobuf_DescriptorProto_resize_extension_range(google_protobuf_DescriptorProto *msg, size_t len, upb_arena *arena) { - return (google_protobuf_DescriptorProto_ExtensionRange**)_upb_array_resize_accessor(msg, UPB_SIZE(28, 56), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena); + return (google_protobuf_DescriptorProto_ExtensionRange**)_upb_array_resize_accessor(msg, UPB_SIZE(28, 56), len, UPB_TYPE_MESSAGE, arena); } UPB_INLINE struct google_protobuf_DescriptorProto_ExtensionRange* google_protobuf_DescriptorProto_add_extension_range(google_protobuf_DescriptorProto *msg, upb_arena *arena) { - struct google_protobuf_DescriptorProto_ExtensionRange* sub = (struct google_protobuf_DescriptorProto_ExtensionRange*)upb_msg_new(&google_protobuf_DescriptorProto_ExtensionRange_msginit, arena); + struct google_protobuf_DescriptorProto_ExtensionRange* sub = (struct google_protobuf_DescriptorProto_ExtensionRange*)_upb_msg_new(&google_protobuf_DescriptorProto_ExtensionRange_msginit, arena); bool ok = _upb_array_append_accessor( msg, UPB_SIZE(28, 56), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); if (!ok) return NULL; @@ -1655,10 +1805,10 @@ UPB_INLINE google_protobuf_FieldDescriptorProto** google_protobuf_DescriptorProt return (google_protobuf_FieldDescriptorProto**)_upb_array_mutable_accessor(msg, UPB_SIZE(32, 64), len); } UPB_INLINE google_protobuf_FieldDescriptorProto** google_protobuf_DescriptorProto_resize_extension(google_protobuf_DescriptorProto *msg, size_t len, upb_arena *arena) { - return (google_protobuf_FieldDescriptorProto**)_upb_array_resize_accessor(msg, UPB_SIZE(32, 64), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena); + return (google_protobuf_FieldDescriptorProto**)_upb_array_resize_accessor(msg, UPB_SIZE(32, 64), len, UPB_TYPE_MESSAGE, arena); } UPB_INLINE struct google_protobuf_FieldDescriptorProto* google_protobuf_DescriptorProto_add_extension(google_protobuf_DescriptorProto *msg, upb_arena *arena) { - struct google_protobuf_FieldDescriptorProto* sub = (struct google_protobuf_FieldDescriptorProto*)upb_msg_new(&google_protobuf_FieldDescriptorProto_msginit, arena); + struct google_protobuf_FieldDescriptorProto* sub = (struct google_protobuf_FieldDescriptorProto*)_upb_msg_new(&google_protobuf_FieldDescriptorProto_msginit, arena); bool ok = _upb_array_append_accessor( msg, UPB_SIZE(32, 64), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); if (!ok) return NULL; @@ -1666,12 +1816,12 @@ UPB_INLINE struct google_protobuf_FieldDescriptorProto* google_protobuf_Descript } UPB_INLINE void google_protobuf_DescriptorProto_set_options(google_protobuf_DescriptorProto *msg, google_protobuf_MessageOptions* value) { _upb_sethas(msg, 2); - UPB_FIELD_AT(msg, google_protobuf_MessageOptions*, UPB_SIZE(12, 24)) = value; + *UPB_PTR_AT(msg, UPB_SIZE(12, 24), google_protobuf_MessageOptions*) = value; } UPB_INLINE struct google_protobuf_MessageOptions* google_protobuf_DescriptorProto_mutable_options(google_protobuf_DescriptorProto *msg, upb_arena *arena) { struct google_protobuf_MessageOptions* sub = (struct google_protobuf_MessageOptions*)google_protobuf_DescriptorProto_options(msg); if (sub == NULL) { - sub = (struct google_protobuf_MessageOptions*)upb_msg_new(&google_protobuf_MessageOptions_msginit, arena); + sub = (struct google_protobuf_MessageOptions*)_upb_msg_new(&google_protobuf_MessageOptions_msginit, arena); if (!sub) return NULL; google_protobuf_DescriptorProto_set_options(msg, sub); } @@ -1681,10 +1831,10 @@ UPB_INLINE google_protobuf_OneofDescriptorProto** google_protobuf_DescriptorProt return (google_protobuf_OneofDescriptorProto**)_upb_array_mutable_accessor(msg, UPB_SIZE(36, 72), len); } UPB_INLINE google_protobuf_OneofDescriptorProto** google_protobuf_DescriptorProto_resize_oneof_decl(google_protobuf_DescriptorProto *msg, size_t len, upb_arena *arena) { - return (google_protobuf_OneofDescriptorProto**)_upb_array_resize_accessor(msg, UPB_SIZE(36, 72), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena); + return (google_protobuf_OneofDescriptorProto**)_upb_array_resize_accessor(msg, UPB_SIZE(36, 72), len, UPB_TYPE_MESSAGE, arena); } UPB_INLINE struct google_protobuf_OneofDescriptorProto* google_protobuf_DescriptorProto_add_oneof_decl(google_protobuf_DescriptorProto *msg, upb_arena *arena) { - struct google_protobuf_OneofDescriptorProto* sub = (struct google_protobuf_OneofDescriptorProto*)upb_msg_new(&google_protobuf_OneofDescriptorProto_msginit, arena); + struct google_protobuf_OneofDescriptorProto* sub = (struct google_protobuf_OneofDescriptorProto*)_upb_msg_new(&google_protobuf_OneofDescriptorProto_msginit, arena); bool ok = _upb_array_append_accessor( msg, UPB_SIZE(36, 72), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); if (!ok) return NULL; @@ -1694,10 +1844,10 @@ UPB_INLINE google_protobuf_DescriptorProto_ReservedRange** google_protobuf_Descr return (google_protobuf_DescriptorProto_ReservedRange**)_upb_array_mutable_accessor(msg, UPB_SIZE(40, 80), len); } UPB_INLINE google_protobuf_DescriptorProto_ReservedRange** google_protobuf_DescriptorProto_resize_reserved_range(google_protobuf_DescriptorProto *msg, size_t len, upb_arena *arena) { - return (google_protobuf_DescriptorProto_ReservedRange**)_upb_array_resize_accessor(msg, UPB_SIZE(40, 80), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena); + return (google_protobuf_DescriptorProto_ReservedRange**)_upb_array_resize_accessor(msg, UPB_SIZE(40, 80), len, UPB_TYPE_MESSAGE, arena); } UPB_INLINE struct google_protobuf_DescriptorProto_ReservedRange* google_protobuf_DescriptorProto_add_reserved_range(google_protobuf_DescriptorProto *msg, upb_arena *arena) { - struct google_protobuf_DescriptorProto_ReservedRange* sub = (struct google_protobuf_DescriptorProto_ReservedRange*)upb_msg_new(&google_protobuf_DescriptorProto_ReservedRange_msginit, arena); + struct google_protobuf_DescriptorProto_ReservedRange* sub = (struct google_protobuf_DescriptorProto_ReservedRange*)_upb_msg_new(&google_protobuf_DescriptorProto_ReservedRange_msginit, arena); bool ok = _upb_array_append_accessor( msg, UPB_SIZE(40, 80), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); if (!ok) return NULL; @@ -1707,17 +1857,17 @@ UPB_INLINE upb_strview* google_protobuf_DescriptorProto_mutable_reserved_name(go return (upb_strview*)_upb_array_mutable_accessor(msg, UPB_SIZE(44, 88), len); } UPB_INLINE upb_strview* google_protobuf_DescriptorProto_resize_reserved_name(google_protobuf_DescriptorProto *msg, size_t len, upb_arena *arena) { - return (upb_strview*)_upb_array_resize_accessor(msg, UPB_SIZE(44, 88), len, UPB_SIZE(8, 16), UPB_TYPE_STRING, arena); + return (upb_strview*)_upb_array_resize_accessor(msg, UPB_SIZE(44, 88), len, UPB_TYPE_STRING, arena); } UPB_INLINE bool google_protobuf_DescriptorProto_add_reserved_name(google_protobuf_DescriptorProto *msg, upb_strview val, upb_arena *arena) { - return _upb_array_append_accessor( - msg, UPB_SIZE(44, 88), UPB_SIZE(8, 16), UPB_TYPE_STRING, &val, arena); + return _upb_array_append_accessor(msg, UPB_SIZE(44, 88), UPB_SIZE(8, 16), UPB_TYPE_STRING, &val, + arena); } /* google.protobuf.DescriptorProto.ExtensionRange */ UPB_INLINE google_protobuf_DescriptorProto_ExtensionRange *google_protobuf_DescriptorProto_ExtensionRange_new(upb_arena *arena) { - return (google_protobuf_DescriptorProto_ExtensionRange *)upb_msg_new(&google_protobuf_DescriptorProto_ExtensionRange_msginit, arena); + return (google_protobuf_DescriptorProto_ExtensionRange *)_upb_msg_new(&google_protobuf_DescriptorProto_ExtensionRange_msginit, arena); } UPB_INLINE google_protobuf_DescriptorProto_ExtensionRange *google_protobuf_DescriptorProto_ExtensionRange_parse(const char *buf, size_t size, upb_arena *arena) { @@ -1729,28 +1879,28 @@ UPB_INLINE char *google_protobuf_DescriptorProto_ExtensionRange_serialize(const } UPB_INLINE bool google_protobuf_DescriptorProto_ExtensionRange_has_start(const google_protobuf_DescriptorProto_ExtensionRange *msg) { return _upb_has_field(msg, 1); } -UPB_INLINE int32_t google_protobuf_DescriptorProto_ExtensionRange_start(const google_protobuf_DescriptorProto_ExtensionRange *msg) { return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(4, 4)); } +UPB_INLINE int32_t google_protobuf_DescriptorProto_ExtensionRange_start(const google_protobuf_DescriptorProto_ExtensionRange *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 4), int32_t); } UPB_INLINE bool google_protobuf_DescriptorProto_ExtensionRange_has_end(const google_protobuf_DescriptorProto_ExtensionRange *msg) { return _upb_has_field(msg, 2); } -UPB_INLINE int32_t google_protobuf_DescriptorProto_ExtensionRange_end(const google_protobuf_DescriptorProto_ExtensionRange *msg) { return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(8, 8)); } +UPB_INLINE int32_t google_protobuf_DescriptorProto_ExtensionRange_end(const google_protobuf_DescriptorProto_ExtensionRange *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 8), int32_t); } UPB_INLINE bool google_protobuf_DescriptorProto_ExtensionRange_has_options(const google_protobuf_DescriptorProto_ExtensionRange *msg) { return _upb_has_field(msg, 3); } -UPB_INLINE const google_protobuf_ExtensionRangeOptions* google_protobuf_DescriptorProto_ExtensionRange_options(const google_protobuf_DescriptorProto_ExtensionRange *msg) { return UPB_FIELD_AT(msg, const google_protobuf_ExtensionRangeOptions*, UPB_SIZE(12, 16)); } +UPB_INLINE const google_protobuf_ExtensionRangeOptions* google_protobuf_DescriptorProto_ExtensionRange_options(const google_protobuf_DescriptorProto_ExtensionRange *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(12, 16), const google_protobuf_ExtensionRangeOptions*); } UPB_INLINE void google_protobuf_DescriptorProto_ExtensionRange_set_start(google_protobuf_DescriptorProto_ExtensionRange *msg, int32_t value) { _upb_sethas(msg, 1); - UPB_FIELD_AT(msg, int32_t, UPB_SIZE(4, 4)) = value; + *UPB_PTR_AT(msg, UPB_SIZE(4, 4), int32_t) = value; } UPB_INLINE void google_protobuf_DescriptorProto_ExtensionRange_set_end(google_protobuf_DescriptorProto_ExtensionRange *msg, int32_t value) { _upb_sethas(msg, 2); - UPB_FIELD_AT(msg, int32_t, UPB_SIZE(8, 8)) = value; + *UPB_PTR_AT(msg, UPB_SIZE(8, 8), int32_t) = value; } UPB_INLINE void google_protobuf_DescriptorProto_ExtensionRange_set_options(google_protobuf_DescriptorProto_ExtensionRange *msg, google_protobuf_ExtensionRangeOptions* value) { _upb_sethas(msg, 3); - UPB_FIELD_AT(msg, google_protobuf_ExtensionRangeOptions*, UPB_SIZE(12, 16)) = value; + *UPB_PTR_AT(msg, UPB_SIZE(12, 16), google_protobuf_ExtensionRangeOptions*) = value; } UPB_INLINE struct google_protobuf_ExtensionRangeOptions* google_protobuf_DescriptorProto_ExtensionRange_mutable_options(google_protobuf_DescriptorProto_ExtensionRange *msg, upb_arena *arena) { struct google_protobuf_ExtensionRangeOptions* sub = (struct google_protobuf_ExtensionRangeOptions*)google_protobuf_DescriptorProto_ExtensionRange_options(msg); if (sub == NULL) { - sub = (struct google_protobuf_ExtensionRangeOptions*)upb_msg_new(&google_protobuf_ExtensionRangeOptions_msginit, arena); + sub = (struct google_protobuf_ExtensionRangeOptions*)_upb_msg_new(&google_protobuf_ExtensionRangeOptions_msginit, arena); if (!sub) return NULL; google_protobuf_DescriptorProto_ExtensionRange_set_options(msg, sub); } @@ -1760,7 +1910,7 @@ UPB_INLINE struct google_protobuf_ExtensionRangeOptions* google_protobuf_Descrip /* google.protobuf.DescriptorProto.ReservedRange */ UPB_INLINE google_protobuf_DescriptorProto_ReservedRange *google_protobuf_DescriptorProto_ReservedRange_new(upb_arena *arena) { - return (google_protobuf_DescriptorProto_ReservedRange *)upb_msg_new(&google_protobuf_DescriptorProto_ReservedRange_msginit, arena); + return (google_protobuf_DescriptorProto_ReservedRange *)_upb_msg_new(&google_protobuf_DescriptorProto_ReservedRange_msginit, arena); } UPB_INLINE google_protobuf_DescriptorProto_ReservedRange *google_protobuf_DescriptorProto_ReservedRange_parse(const char *buf, size_t size, upb_arena *arena) { @@ -1772,23 +1922,23 @@ UPB_INLINE char *google_protobuf_DescriptorProto_ReservedRange_serialize(const g } UPB_INLINE bool google_protobuf_DescriptorProto_ReservedRange_has_start(const google_protobuf_DescriptorProto_ReservedRange *msg) { return _upb_has_field(msg, 1); } -UPB_INLINE int32_t google_protobuf_DescriptorProto_ReservedRange_start(const google_protobuf_DescriptorProto_ReservedRange *msg) { return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(4, 4)); } +UPB_INLINE int32_t google_protobuf_DescriptorProto_ReservedRange_start(const google_protobuf_DescriptorProto_ReservedRange *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 4), int32_t); } UPB_INLINE bool google_protobuf_DescriptorProto_ReservedRange_has_end(const google_protobuf_DescriptorProto_ReservedRange *msg) { return _upb_has_field(msg, 2); } -UPB_INLINE int32_t google_protobuf_DescriptorProto_ReservedRange_end(const google_protobuf_DescriptorProto_ReservedRange *msg) { return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(8, 8)); } +UPB_INLINE int32_t google_protobuf_DescriptorProto_ReservedRange_end(const google_protobuf_DescriptorProto_ReservedRange *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 8), int32_t); } UPB_INLINE void google_protobuf_DescriptorProto_ReservedRange_set_start(google_protobuf_DescriptorProto_ReservedRange *msg, int32_t value) { _upb_sethas(msg, 1); - UPB_FIELD_AT(msg, int32_t, UPB_SIZE(4, 4)) = value; + *UPB_PTR_AT(msg, UPB_SIZE(4, 4), int32_t) = value; } UPB_INLINE void google_protobuf_DescriptorProto_ReservedRange_set_end(google_protobuf_DescriptorProto_ReservedRange *msg, int32_t value) { _upb_sethas(msg, 2); - UPB_FIELD_AT(msg, int32_t, UPB_SIZE(8, 8)) = value; + *UPB_PTR_AT(msg, UPB_SIZE(8, 8), int32_t) = value; } /* google.protobuf.ExtensionRangeOptions */ UPB_INLINE google_protobuf_ExtensionRangeOptions *google_protobuf_ExtensionRangeOptions_new(upb_arena *arena) { - return (google_protobuf_ExtensionRangeOptions *)upb_msg_new(&google_protobuf_ExtensionRangeOptions_msginit, arena); + return (google_protobuf_ExtensionRangeOptions *)_upb_msg_new(&google_protobuf_ExtensionRangeOptions_msginit, arena); } UPB_INLINE google_protobuf_ExtensionRangeOptions *google_protobuf_ExtensionRangeOptions_parse(const char *buf, size_t size, upb_arena *arena) { @@ -1799,16 +1949,17 @@ UPB_INLINE char *google_protobuf_ExtensionRangeOptions_serialize(const google_pr return upb_encode(msg, &google_protobuf_ExtensionRangeOptions_msginit, arena, len); } +UPB_INLINE bool google_protobuf_ExtensionRangeOptions_has_uninterpreted_option(const google_protobuf_ExtensionRangeOptions *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(0, 0)); } UPB_INLINE const google_protobuf_UninterpretedOption* const* google_protobuf_ExtensionRangeOptions_uninterpreted_option(const google_protobuf_ExtensionRangeOptions *msg, size_t *len) { return (const google_protobuf_UninterpretedOption* const*)_upb_array_accessor(msg, UPB_SIZE(0, 0), len); } UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_ExtensionRangeOptions_mutable_uninterpreted_option(google_protobuf_ExtensionRangeOptions *msg, size_t *len) { return (google_protobuf_UninterpretedOption**)_upb_array_mutable_accessor(msg, UPB_SIZE(0, 0), len); } UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_ExtensionRangeOptions_resize_uninterpreted_option(google_protobuf_ExtensionRangeOptions *msg, size_t len, upb_arena *arena) { - return (google_protobuf_UninterpretedOption**)_upb_array_resize_accessor(msg, UPB_SIZE(0, 0), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena); + return (google_protobuf_UninterpretedOption**)_upb_array_resize_accessor(msg, UPB_SIZE(0, 0), len, UPB_TYPE_MESSAGE, arena); } UPB_INLINE struct google_protobuf_UninterpretedOption* google_protobuf_ExtensionRangeOptions_add_uninterpreted_option(google_protobuf_ExtensionRangeOptions *msg, upb_arena *arena) { - struct google_protobuf_UninterpretedOption* sub = (struct google_protobuf_UninterpretedOption*)upb_msg_new(&google_protobuf_UninterpretedOption_msginit, arena); + struct google_protobuf_UninterpretedOption* sub = (struct google_protobuf_UninterpretedOption*)_upb_msg_new(&google_protobuf_UninterpretedOption_msginit, arena); bool ok = _upb_array_append_accessor( msg, UPB_SIZE(0, 0), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); if (!ok) return NULL; @@ -1818,7 +1969,7 @@ UPB_INLINE struct google_protobuf_UninterpretedOption* google_protobuf_Extension /* google.protobuf.FieldDescriptorProto */ UPB_INLINE google_protobuf_FieldDescriptorProto *google_protobuf_FieldDescriptorProto_new(upb_arena *arena) { - return (google_protobuf_FieldDescriptorProto *)upb_msg_new(&google_protobuf_FieldDescriptorProto_msginit, arena); + return (google_protobuf_FieldDescriptorProto *)_upb_msg_new(&google_protobuf_FieldDescriptorProto_msginit, arena); } UPB_INLINE google_protobuf_FieldDescriptorProto *google_protobuf_FieldDescriptorProto_parse(const char *buf, size_t size, upb_arena *arena) { @@ -1829,63 +1980,65 @@ UPB_INLINE char *google_protobuf_FieldDescriptorProto_serialize(const google_pro return upb_encode(msg, &google_protobuf_FieldDescriptorProto_msginit, arena, len); } -UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_name(const google_protobuf_FieldDescriptorProto *msg) { return _upb_has_field(msg, 5); } -UPB_INLINE upb_strview google_protobuf_FieldDescriptorProto_name(const google_protobuf_FieldDescriptorProto *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(32, 32)); } -UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_extendee(const google_protobuf_FieldDescriptorProto *msg) { return _upb_has_field(msg, 6); } -UPB_INLINE upb_strview google_protobuf_FieldDescriptorProto_extendee(const google_protobuf_FieldDescriptorProto *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(40, 48)); } +UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_name(const google_protobuf_FieldDescriptorProto *msg) { return _upb_has_field(msg, 6); } +UPB_INLINE upb_strview google_protobuf_FieldDescriptorProto_name(const google_protobuf_FieldDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(36, 40), upb_strview); } +UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_extendee(const google_protobuf_FieldDescriptorProto *msg) { return _upb_has_field(msg, 7); } +UPB_INLINE upb_strview google_protobuf_FieldDescriptorProto_extendee(const google_protobuf_FieldDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(44, 56), upb_strview); } UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_number(const google_protobuf_FieldDescriptorProto *msg) { return _upb_has_field(msg, 3); } -UPB_INLINE int32_t google_protobuf_FieldDescriptorProto_number(const google_protobuf_FieldDescriptorProto *msg) { return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(24, 24)); } +UPB_INLINE int32_t google_protobuf_FieldDescriptorProto_number(const google_protobuf_FieldDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(24, 24), int32_t); } UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_label(const google_protobuf_FieldDescriptorProto *msg) { return _upb_has_field(msg, 1); } -UPB_INLINE int32_t google_protobuf_FieldDescriptorProto_label(const google_protobuf_FieldDescriptorProto *msg) { return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(8, 8)); } +UPB_INLINE int32_t google_protobuf_FieldDescriptorProto_label(const google_protobuf_FieldDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 8), int32_t); } UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_type(const google_protobuf_FieldDescriptorProto *msg) { return _upb_has_field(msg, 2); } -UPB_INLINE int32_t google_protobuf_FieldDescriptorProto_type(const google_protobuf_FieldDescriptorProto *msg) { return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(16, 16)); } -UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_type_name(const google_protobuf_FieldDescriptorProto *msg) { return _upb_has_field(msg, 7); } -UPB_INLINE upb_strview google_protobuf_FieldDescriptorProto_type_name(const google_protobuf_FieldDescriptorProto *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(48, 64)); } -UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_default_value(const google_protobuf_FieldDescriptorProto *msg) { return _upb_has_field(msg, 8); } -UPB_INLINE upb_strview google_protobuf_FieldDescriptorProto_default_value(const google_protobuf_FieldDescriptorProto *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(56, 80)); } -UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_options(const google_protobuf_FieldDescriptorProto *msg) { return _upb_has_field(msg, 10); } -UPB_INLINE const google_protobuf_FieldOptions* google_protobuf_FieldDescriptorProto_options(const google_protobuf_FieldDescriptorProto *msg) { return UPB_FIELD_AT(msg, const google_protobuf_FieldOptions*, UPB_SIZE(72, 112)); } +UPB_INLINE int32_t google_protobuf_FieldDescriptorProto_type(const google_protobuf_FieldDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(16, 16), int32_t); } +UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_type_name(const google_protobuf_FieldDescriptorProto *msg) { return _upb_has_field(msg, 8); } +UPB_INLINE upb_strview google_protobuf_FieldDescriptorProto_type_name(const google_protobuf_FieldDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(52, 72), upb_strview); } +UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_default_value(const google_protobuf_FieldDescriptorProto *msg) { return _upb_has_field(msg, 9); } +UPB_INLINE upb_strview google_protobuf_FieldDescriptorProto_default_value(const google_protobuf_FieldDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(60, 88), upb_strview); } +UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_options(const google_protobuf_FieldDescriptorProto *msg) { return _upb_has_field(msg, 11); } +UPB_INLINE const google_protobuf_FieldOptions* google_protobuf_FieldDescriptorProto_options(const google_protobuf_FieldDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(76, 120), const google_protobuf_FieldOptions*); } UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_oneof_index(const google_protobuf_FieldDescriptorProto *msg) { return _upb_has_field(msg, 4); } -UPB_INLINE int32_t google_protobuf_FieldDescriptorProto_oneof_index(const google_protobuf_FieldDescriptorProto *msg) { return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(28, 28)); } -UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_json_name(const google_protobuf_FieldDescriptorProto *msg) { return _upb_has_field(msg, 9); } -UPB_INLINE upb_strview google_protobuf_FieldDescriptorProto_json_name(const google_protobuf_FieldDescriptorProto *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(64, 96)); } +UPB_INLINE int32_t google_protobuf_FieldDescriptorProto_oneof_index(const google_protobuf_FieldDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(28, 28), int32_t); } +UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_json_name(const google_protobuf_FieldDescriptorProto *msg) { return _upb_has_field(msg, 10); } +UPB_INLINE upb_strview google_protobuf_FieldDescriptorProto_json_name(const google_protobuf_FieldDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(68, 104), upb_strview); } +UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_proto3_optional(const google_protobuf_FieldDescriptorProto *msg) { return _upb_has_field(msg, 5); } +UPB_INLINE bool google_protobuf_FieldDescriptorProto_proto3_optional(const google_protobuf_FieldDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(32, 32), bool); } UPB_INLINE void google_protobuf_FieldDescriptorProto_set_name(google_protobuf_FieldDescriptorProto *msg, upb_strview value) { - _upb_sethas(msg, 5); - UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(32, 32)) = value; + _upb_sethas(msg, 6); + *UPB_PTR_AT(msg, UPB_SIZE(36, 40), upb_strview) = value; } UPB_INLINE void google_protobuf_FieldDescriptorProto_set_extendee(google_protobuf_FieldDescriptorProto *msg, upb_strview value) { - _upb_sethas(msg, 6); - UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(40, 48)) = value; + _upb_sethas(msg, 7); + *UPB_PTR_AT(msg, UPB_SIZE(44, 56), upb_strview) = value; } UPB_INLINE void google_protobuf_FieldDescriptorProto_set_number(google_protobuf_FieldDescriptorProto *msg, int32_t value) { _upb_sethas(msg, 3); - UPB_FIELD_AT(msg, int32_t, UPB_SIZE(24, 24)) = value; + *UPB_PTR_AT(msg, UPB_SIZE(24, 24), int32_t) = value; } UPB_INLINE void google_protobuf_FieldDescriptorProto_set_label(google_protobuf_FieldDescriptorProto *msg, int32_t value) { _upb_sethas(msg, 1); - UPB_FIELD_AT(msg, int32_t, UPB_SIZE(8, 8)) = value; + *UPB_PTR_AT(msg, UPB_SIZE(8, 8), int32_t) = value; } UPB_INLINE void google_protobuf_FieldDescriptorProto_set_type(google_protobuf_FieldDescriptorProto *msg, int32_t value) { _upb_sethas(msg, 2); - UPB_FIELD_AT(msg, int32_t, UPB_SIZE(16, 16)) = value; + *UPB_PTR_AT(msg, UPB_SIZE(16, 16), int32_t) = value; } UPB_INLINE void google_protobuf_FieldDescriptorProto_set_type_name(google_protobuf_FieldDescriptorProto *msg, upb_strview value) { - _upb_sethas(msg, 7); - UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(48, 64)) = value; + _upb_sethas(msg, 8); + *UPB_PTR_AT(msg, UPB_SIZE(52, 72), upb_strview) = value; } UPB_INLINE void google_protobuf_FieldDescriptorProto_set_default_value(google_protobuf_FieldDescriptorProto *msg, upb_strview value) { - _upb_sethas(msg, 8); - UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(56, 80)) = value; + _upb_sethas(msg, 9); + *UPB_PTR_AT(msg, UPB_SIZE(60, 88), upb_strview) = value; } UPB_INLINE void google_protobuf_FieldDescriptorProto_set_options(google_protobuf_FieldDescriptorProto *msg, google_protobuf_FieldOptions* value) { - _upb_sethas(msg, 10); - UPB_FIELD_AT(msg, google_protobuf_FieldOptions*, UPB_SIZE(72, 112)) = value; + _upb_sethas(msg, 11); + *UPB_PTR_AT(msg, UPB_SIZE(76, 120), google_protobuf_FieldOptions*) = value; } UPB_INLINE struct google_protobuf_FieldOptions* google_protobuf_FieldDescriptorProto_mutable_options(google_protobuf_FieldDescriptorProto *msg, upb_arena *arena) { struct google_protobuf_FieldOptions* sub = (struct google_protobuf_FieldOptions*)google_protobuf_FieldDescriptorProto_options(msg); if (sub == NULL) { - sub = (struct google_protobuf_FieldOptions*)upb_msg_new(&google_protobuf_FieldOptions_msginit, arena); + sub = (struct google_protobuf_FieldOptions*)_upb_msg_new(&google_protobuf_FieldOptions_msginit, arena); if (!sub) return NULL; google_protobuf_FieldDescriptorProto_set_options(msg, sub); } @@ -1893,17 +2046,21 @@ UPB_INLINE struct google_protobuf_FieldOptions* google_protobuf_FieldDescriptorP } UPB_INLINE void google_protobuf_FieldDescriptorProto_set_oneof_index(google_protobuf_FieldDescriptorProto *msg, int32_t value) { _upb_sethas(msg, 4); - UPB_FIELD_AT(msg, int32_t, UPB_SIZE(28, 28)) = value; + *UPB_PTR_AT(msg, UPB_SIZE(28, 28), int32_t) = value; } UPB_INLINE void google_protobuf_FieldDescriptorProto_set_json_name(google_protobuf_FieldDescriptorProto *msg, upb_strview value) { - _upb_sethas(msg, 9); - UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(64, 96)) = value; + _upb_sethas(msg, 10); + *UPB_PTR_AT(msg, UPB_SIZE(68, 104), upb_strview) = value; +} +UPB_INLINE void google_protobuf_FieldDescriptorProto_set_proto3_optional(google_protobuf_FieldDescriptorProto *msg, bool value) { + _upb_sethas(msg, 5); + *UPB_PTR_AT(msg, UPB_SIZE(32, 32), bool) = value; } /* google.protobuf.OneofDescriptorProto */ UPB_INLINE google_protobuf_OneofDescriptorProto *google_protobuf_OneofDescriptorProto_new(upb_arena *arena) { - return (google_protobuf_OneofDescriptorProto *)upb_msg_new(&google_protobuf_OneofDescriptorProto_msginit, arena); + return (google_protobuf_OneofDescriptorProto *)_upb_msg_new(&google_protobuf_OneofDescriptorProto_msginit, arena); } UPB_INLINE google_protobuf_OneofDescriptorProto *google_protobuf_OneofDescriptorProto_parse(const char *buf, size_t size, upb_arena *arena) { @@ -1915,22 +2072,22 @@ UPB_INLINE char *google_protobuf_OneofDescriptorProto_serialize(const google_pro } UPB_INLINE bool google_protobuf_OneofDescriptorProto_has_name(const google_protobuf_OneofDescriptorProto *msg) { return _upb_has_field(msg, 1); } -UPB_INLINE upb_strview google_protobuf_OneofDescriptorProto_name(const google_protobuf_OneofDescriptorProto *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(4, 8)); } +UPB_INLINE upb_strview google_protobuf_OneofDescriptorProto_name(const google_protobuf_OneofDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview); } UPB_INLINE bool google_protobuf_OneofDescriptorProto_has_options(const google_protobuf_OneofDescriptorProto *msg) { return _upb_has_field(msg, 2); } -UPB_INLINE const google_protobuf_OneofOptions* google_protobuf_OneofDescriptorProto_options(const google_protobuf_OneofDescriptorProto *msg) { return UPB_FIELD_AT(msg, const google_protobuf_OneofOptions*, UPB_SIZE(12, 24)); } +UPB_INLINE const google_protobuf_OneofOptions* google_protobuf_OneofDescriptorProto_options(const google_protobuf_OneofDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(12, 24), const google_protobuf_OneofOptions*); } UPB_INLINE void google_protobuf_OneofDescriptorProto_set_name(google_protobuf_OneofDescriptorProto *msg, upb_strview value) { _upb_sethas(msg, 1); - UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(4, 8)) = value; + *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview) = value; } UPB_INLINE void google_protobuf_OneofDescriptorProto_set_options(google_protobuf_OneofDescriptorProto *msg, google_protobuf_OneofOptions* value) { _upb_sethas(msg, 2); - UPB_FIELD_AT(msg, google_protobuf_OneofOptions*, UPB_SIZE(12, 24)) = value; + *UPB_PTR_AT(msg, UPB_SIZE(12, 24), google_protobuf_OneofOptions*) = value; } UPB_INLINE struct google_protobuf_OneofOptions* google_protobuf_OneofDescriptorProto_mutable_options(google_protobuf_OneofDescriptorProto *msg, upb_arena *arena) { struct google_protobuf_OneofOptions* sub = (struct google_protobuf_OneofOptions*)google_protobuf_OneofDescriptorProto_options(msg); if (sub == NULL) { - sub = (struct google_protobuf_OneofOptions*)upb_msg_new(&google_protobuf_OneofOptions_msginit, arena); + sub = (struct google_protobuf_OneofOptions*)_upb_msg_new(&google_protobuf_OneofOptions_msginit, arena); if (!sub) return NULL; google_protobuf_OneofDescriptorProto_set_options(msg, sub); } @@ -1940,7 +2097,7 @@ UPB_INLINE struct google_protobuf_OneofOptions* google_protobuf_OneofDescriptorP /* google.protobuf.EnumDescriptorProto */ UPB_INLINE google_protobuf_EnumDescriptorProto *google_protobuf_EnumDescriptorProto_new(upb_arena *arena) { - return (google_protobuf_EnumDescriptorProto *)upb_msg_new(&google_protobuf_EnumDescriptorProto_msginit, arena); + return (google_protobuf_EnumDescriptorProto *)_upb_msg_new(&google_protobuf_EnumDescriptorProto_msginit, arena); } UPB_INLINE google_protobuf_EnumDescriptorProto *google_protobuf_EnumDescriptorProto_parse(const char *buf, size_t size, upb_arena *arena) { @@ -1952,25 +2109,27 @@ UPB_INLINE char *google_protobuf_EnumDescriptorProto_serialize(const google_prot } UPB_INLINE bool google_protobuf_EnumDescriptorProto_has_name(const google_protobuf_EnumDescriptorProto *msg) { return _upb_has_field(msg, 1); } -UPB_INLINE upb_strview google_protobuf_EnumDescriptorProto_name(const google_protobuf_EnumDescriptorProto *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(4, 8)); } +UPB_INLINE upb_strview google_protobuf_EnumDescriptorProto_name(const google_protobuf_EnumDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview); } +UPB_INLINE bool google_protobuf_EnumDescriptorProto_has_value(const google_protobuf_EnumDescriptorProto *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(16, 32)); } UPB_INLINE const google_protobuf_EnumValueDescriptorProto* const* google_protobuf_EnumDescriptorProto_value(const google_protobuf_EnumDescriptorProto *msg, size_t *len) { return (const google_protobuf_EnumValueDescriptorProto* const*)_upb_array_accessor(msg, UPB_SIZE(16, 32), len); } UPB_INLINE bool google_protobuf_EnumDescriptorProto_has_options(const google_protobuf_EnumDescriptorProto *msg) { return _upb_has_field(msg, 2); } -UPB_INLINE const google_protobuf_EnumOptions* google_protobuf_EnumDescriptorProto_options(const google_protobuf_EnumDescriptorProto *msg) { return UPB_FIELD_AT(msg, const google_protobuf_EnumOptions*, UPB_SIZE(12, 24)); } +UPB_INLINE const google_protobuf_EnumOptions* google_protobuf_EnumDescriptorProto_options(const google_protobuf_EnumDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(12, 24), const google_protobuf_EnumOptions*); } +UPB_INLINE bool google_protobuf_EnumDescriptorProto_has_reserved_range(const google_protobuf_EnumDescriptorProto *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(20, 40)); } UPB_INLINE const google_protobuf_EnumDescriptorProto_EnumReservedRange* const* google_protobuf_EnumDescriptorProto_reserved_range(const google_protobuf_EnumDescriptorProto *msg, size_t *len) { return (const google_protobuf_EnumDescriptorProto_EnumReservedRange* const*)_upb_array_accessor(msg, UPB_SIZE(20, 40), len); } UPB_INLINE upb_strview const* google_protobuf_EnumDescriptorProto_reserved_name(const google_protobuf_EnumDescriptorProto *msg, size_t *len) { return (upb_strview const*)_upb_array_accessor(msg, UPB_SIZE(24, 48), len); } UPB_INLINE void google_protobuf_EnumDescriptorProto_set_name(google_protobuf_EnumDescriptorProto *msg, upb_strview value) { _upb_sethas(msg, 1); - UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(4, 8)) = value; + *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview) = value; } UPB_INLINE google_protobuf_EnumValueDescriptorProto** google_protobuf_EnumDescriptorProto_mutable_value(google_protobuf_EnumDescriptorProto *msg, size_t *len) { return (google_protobuf_EnumValueDescriptorProto**)_upb_array_mutable_accessor(msg, UPB_SIZE(16, 32), len); } UPB_INLINE google_protobuf_EnumValueDescriptorProto** google_protobuf_EnumDescriptorProto_resize_value(google_protobuf_EnumDescriptorProto *msg, size_t len, upb_arena *arena) { - return (google_protobuf_EnumValueDescriptorProto**)_upb_array_resize_accessor(msg, UPB_SIZE(16, 32), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena); + return (google_protobuf_EnumValueDescriptorProto**)_upb_array_resize_accessor(msg, UPB_SIZE(16, 32), len, UPB_TYPE_MESSAGE, arena); } UPB_INLINE struct google_protobuf_EnumValueDescriptorProto* google_protobuf_EnumDescriptorProto_add_value(google_protobuf_EnumDescriptorProto *msg, upb_arena *arena) { - struct google_protobuf_EnumValueDescriptorProto* sub = (struct google_protobuf_EnumValueDescriptorProto*)upb_msg_new(&google_protobuf_EnumValueDescriptorProto_msginit, arena); + struct google_protobuf_EnumValueDescriptorProto* sub = (struct google_protobuf_EnumValueDescriptorProto*)_upb_msg_new(&google_protobuf_EnumValueDescriptorProto_msginit, arena); bool ok = _upb_array_append_accessor( msg, UPB_SIZE(16, 32), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); if (!ok) return NULL; @@ -1978,12 +2137,12 @@ UPB_INLINE struct google_protobuf_EnumValueDescriptorProto* google_protobuf_Enum } UPB_INLINE void google_protobuf_EnumDescriptorProto_set_options(google_protobuf_EnumDescriptorProto *msg, google_protobuf_EnumOptions* value) { _upb_sethas(msg, 2); - UPB_FIELD_AT(msg, google_protobuf_EnumOptions*, UPB_SIZE(12, 24)) = value; + *UPB_PTR_AT(msg, UPB_SIZE(12, 24), google_protobuf_EnumOptions*) = value; } UPB_INLINE struct google_protobuf_EnumOptions* google_protobuf_EnumDescriptorProto_mutable_options(google_protobuf_EnumDescriptorProto *msg, upb_arena *arena) { struct google_protobuf_EnumOptions* sub = (struct google_protobuf_EnumOptions*)google_protobuf_EnumDescriptorProto_options(msg); if (sub == NULL) { - sub = (struct google_protobuf_EnumOptions*)upb_msg_new(&google_protobuf_EnumOptions_msginit, arena); + sub = (struct google_protobuf_EnumOptions*)_upb_msg_new(&google_protobuf_EnumOptions_msginit, arena); if (!sub) return NULL; google_protobuf_EnumDescriptorProto_set_options(msg, sub); } @@ -1993,10 +2152,10 @@ UPB_INLINE google_protobuf_EnumDescriptorProto_EnumReservedRange** google_protob return (google_protobuf_EnumDescriptorProto_EnumReservedRange**)_upb_array_mutable_accessor(msg, UPB_SIZE(20, 40), len); } UPB_INLINE google_protobuf_EnumDescriptorProto_EnumReservedRange** google_protobuf_EnumDescriptorProto_resize_reserved_range(google_protobuf_EnumDescriptorProto *msg, size_t len, upb_arena *arena) { - return (google_protobuf_EnumDescriptorProto_EnumReservedRange**)_upb_array_resize_accessor(msg, UPB_SIZE(20, 40), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena); + return (google_protobuf_EnumDescriptorProto_EnumReservedRange**)_upb_array_resize_accessor(msg, UPB_SIZE(20, 40), len, UPB_TYPE_MESSAGE, arena); } UPB_INLINE struct google_protobuf_EnumDescriptorProto_EnumReservedRange* google_protobuf_EnumDescriptorProto_add_reserved_range(google_protobuf_EnumDescriptorProto *msg, upb_arena *arena) { - struct google_protobuf_EnumDescriptorProto_EnumReservedRange* sub = (struct google_protobuf_EnumDescriptorProto_EnumReservedRange*)upb_msg_new(&google_protobuf_EnumDescriptorProto_EnumReservedRange_msginit, arena); + struct google_protobuf_EnumDescriptorProto_EnumReservedRange* sub = (struct google_protobuf_EnumDescriptorProto_EnumReservedRange*)_upb_msg_new(&google_protobuf_EnumDescriptorProto_EnumReservedRange_msginit, arena); bool ok = _upb_array_append_accessor( msg, UPB_SIZE(20, 40), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); if (!ok) return NULL; @@ -2006,17 +2165,17 @@ UPB_INLINE upb_strview* google_protobuf_EnumDescriptorProto_mutable_reserved_nam return (upb_strview*)_upb_array_mutable_accessor(msg, UPB_SIZE(24, 48), len); } UPB_INLINE upb_strview* google_protobuf_EnumDescriptorProto_resize_reserved_name(google_protobuf_EnumDescriptorProto *msg, size_t len, upb_arena *arena) { - return (upb_strview*)_upb_array_resize_accessor(msg, UPB_SIZE(24, 48), len, UPB_SIZE(8, 16), UPB_TYPE_STRING, arena); + return (upb_strview*)_upb_array_resize_accessor(msg, UPB_SIZE(24, 48), len, UPB_TYPE_STRING, arena); } UPB_INLINE bool google_protobuf_EnumDescriptorProto_add_reserved_name(google_protobuf_EnumDescriptorProto *msg, upb_strview val, upb_arena *arena) { - return _upb_array_append_accessor( - msg, UPB_SIZE(24, 48), UPB_SIZE(8, 16), UPB_TYPE_STRING, &val, arena); + return _upb_array_append_accessor(msg, UPB_SIZE(24, 48), UPB_SIZE(8, 16), UPB_TYPE_STRING, &val, + arena); } /* google.protobuf.EnumDescriptorProto.EnumReservedRange */ UPB_INLINE google_protobuf_EnumDescriptorProto_EnumReservedRange *google_protobuf_EnumDescriptorProto_EnumReservedRange_new(upb_arena *arena) { - return (google_protobuf_EnumDescriptorProto_EnumReservedRange *)upb_msg_new(&google_protobuf_EnumDescriptorProto_EnumReservedRange_msginit, arena); + return (google_protobuf_EnumDescriptorProto_EnumReservedRange *)_upb_msg_new(&google_protobuf_EnumDescriptorProto_EnumReservedRange_msginit, arena); } UPB_INLINE google_protobuf_EnumDescriptorProto_EnumReservedRange *google_protobuf_EnumDescriptorProto_EnumReservedRange_parse(const char *buf, size_t size, upb_arena *arena) { @@ -2028,23 +2187,23 @@ UPB_INLINE char *google_protobuf_EnumDescriptorProto_EnumReservedRange_serialize } UPB_INLINE bool google_protobuf_EnumDescriptorProto_EnumReservedRange_has_start(const google_protobuf_EnumDescriptorProto_EnumReservedRange *msg) { return _upb_has_field(msg, 1); } -UPB_INLINE int32_t google_protobuf_EnumDescriptorProto_EnumReservedRange_start(const google_protobuf_EnumDescriptorProto_EnumReservedRange *msg) { return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(4, 4)); } +UPB_INLINE int32_t google_protobuf_EnumDescriptorProto_EnumReservedRange_start(const google_protobuf_EnumDescriptorProto_EnumReservedRange *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 4), int32_t); } UPB_INLINE bool google_protobuf_EnumDescriptorProto_EnumReservedRange_has_end(const google_protobuf_EnumDescriptorProto_EnumReservedRange *msg) { return _upb_has_field(msg, 2); } -UPB_INLINE int32_t google_protobuf_EnumDescriptorProto_EnumReservedRange_end(const google_protobuf_EnumDescriptorProto_EnumReservedRange *msg) { return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(8, 8)); } +UPB_INLINE int32_t google_protobuf_EnumDescriptorProto_EnumReservedRange_end(const google_protobuf_EnumDescriptorProto_EnumReservedRange *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 8), int32_t); } UPB_INLINE void google_protobuf_EnumDescriptorProto_EnumReservedRange_set_start(google_protobuf_EnumDescriptorProto_EnumReservedRange *msg, int32_t value) { _upb_sethas(msg, 1); - UPB_FIELD_AT(msg, int32_t, UPB_SIZE(4, 4)) = value; + *UPB_PTR_AT(msg, UPB_SIZE(4, 4), int32_t) = value; } UPB_INLINE void google_protobuf_EnumDescriptorProto_EnumReservedRange_set_end(google_protobuf_EnumDescriptorProto_EnumReservedRange *msg, int32_t value) { _upb_sethas(msg, 2); - UPB_FIELD_AT(msg, int32_t, UPB_SIZE(8, 8)) = value; + *UPB_PTR_AT(msg, UPB_SIZE(8, 8), int32_t) = value; } /* google.protobuf.EnumValueDescriptorProto */ UPB_INLINE google_protobuf_EnumValueDescriptorProto *google_protobuf_EnumValueDescriptorProto_new(upb_arena *arena) { - return (google_protobuf_EnumValueDescriptorProto *)upb_msg_new(&google_protobuf_EnumValueDescriptorProto_msginit, arena); + return (google_protobuf_EnumValueDescriptorProto *)_upb_msg_new(&google_protobuf_EnumValueDescriptorProto_msginit, arena); } UPB_INLINE google_protobuf_EnumValueDescriptorProto *google_protobuf_EnumValueDescriptorProto_parse(const char *buf, size_t size, upb_arena *arena) { @@ -2056,28 +2215,28 @@ UPB_INLINE char *google_protobuf_EnumValueDescriptorProto_serialize(const google } UPB_INLINE bool google_protobuf_EnumValueDescriptorProto_has_name(const google_protobuf_EnumValueDescriptorProto *msg) { return _upb_has_field(msg, 2); } -UPB_INLINE upb_strview google_protobuf_EnumValueDescriptorProto_name(const google_protobuf_EnumValueDescriptorProto *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(8, 8)); } +UPB_INLINE upb_strview google_protobuf_EnumValueDescriptorProto_name(const google_protobuf_EnumValueDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 8), upb_strview); } UPB_INLINE bool google_protobuf_EnumValueDescriptorProto_has_number(const google_protobuf_EnumValueDescriptorProto *msg) { return _upb_has_field(msg, 1); } -UPB_INLINE int32_t google_protobuf_EnumValueDescriptorProto_number(const google_protobuf_EnumValueDescriptorProto *msg) { return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(4, 4)); } +UPB_INLINE int32_t google_protobuf_EnumValueDescriptorProto_number(const google_protobuf_EnumValueDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 4), int32_t); } UPB_INLINE bool google_protobuf_EnumValueDescriptorProto_has_options(const google_protobuf_EnumValueDescriptorProto *msg) { return _upb_has_field(msg, 3); } -UPB_INLINE const google_protobuf_EnumValueOptions* google_protobuf_EnumValueDescriptorProto_options(const google_protobuf_EnumValueDescriptorProto *msg) { return UPB_FIELD_AT(msg, const google_protobuf_EnumValueOptions*, UPB_SIZE(16, 24)); } +UPB_INLINE const google_protobuf_EnumValueOptions* google_protobuf_EnumValueDescriptorProto_options(const google_protobuf_EnumValueDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(16, 24), const google_protobuf_EnumValueOptions*); } UPB_INLINE void google_protobuf_EnumValueDescriptorProto_set_name(google_protobuf_EnumValueDescriptorProto *msg, upb_strview value) { _upb_sethas(msg, 2); - UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(8, 8)) = value; + *UPB_PTR_AT(msg, UPB_SIZE(8, 8), upb_strview) = value; } UPB_INLINE void google_protobuf_EnumValueDescriptorProto_set_number(google_protobuf_EnumValueDescriptorProto *msg, int32_t value) { _upb_sethas(msg, 1); - UPB_FIELD_AT(msg, int32_t, UPB_SIZE(4, 4)) = value; + *UPB_PTR_AT(msg, UPB_SIZE(4, 4), int32_t) = value; } UPB_INLINE void google_protobuf_EnumValueDescriptorProto_set_options(google_protobuf_EnumValueDescriptorProto *msg, google_protobuf_EnumValueOptions* value) { _upb_sethas(msg, 3); - UPB_FIELD_AT(msg, google_protobuf_EnumValueOptions*, UPB_SIZE(16, 24)) = value; + *UPB_PTR_AT(msg, UPB_SIZE(16, 24), google_protobuf_EnumValueOptions*) = value; } UPB_INLINE struct google_protobuf_EnumValueOptions* google_protobuf_EnumValueDescriptorProto_mutable_options(google_protobuf_EnumValueDescriptorProto *msg, upb_arena *arena) { struct google_protobuf_EnumValueOptions* sub = (struct google_protobuf_EnumValueOptions*)google_protobuf_EnumValueDescriptorProto_options(msg); if (sub == NULL) { - sub = (struct google_protobuf_EnumValueOptions*)upb_msg_new(&google_protobuf_EnumValueOptions_msginit, arena); + sub = (struct google_protobuf_EnumValueOptions*)_upb_msg_new(&google_protobuf_EnumValueOptions_msginit, arena); if (!sub) return NULL; google_protobuf_EnumValueDescriptorProto_set_options(msg, sub); } @@ -2087,7 +2246,7 @@ UPB_INLINE struct google_protobuf_EnumValueOptions* google_protobuf_EnumValueDes /* google.protobuf.ServiceDescriptorProto */ UPB_INLINE google_protobuf_ServiceDescriptorProto *google_protobuf_ServiceDescriptorProto_new(upb_arena *arena) { - return (google_protobuf_ServiceDescriptorProto *)upb_msg_new(&google_protobuf_ServiceDescriptorProto_msginit, arena); + return (google_protobuf_ServiceDescriptorProto *)_upb_msg_new(&google_protobuf_ServiceDescriptorProto_msginit, arena); } UPB_INLINE google_protobuf_ServiceDescriptorProto *google_protobuf_ServiceDescriptorProto_parse(const char *buf, size_t size, upb_arena *arena) { @@ -2099,23 +2258,24 @@ UPB_INLINE char *google_protobuf_ServiceDescriptorProto_serialize(const google_p } UPB_INLINE bool google_protobuf_ServiceDescriptorProto_has_name(const google_protobuf_ServiceDescriptorProto *msg) { return _upb_has_field(msg, 1); } -UPB_INLINE upb_strview google_protobuf_ServiceDescriptorProto_name(const google_protobuf_ServiceDescriptorProto *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(4, 8)); } +UPB_INLINE upb_strview google_protobuf_ServiceDescriptorProto_name(const google_protobuf_ServiceDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview); } +UPB_INLINE bool google_protobuf_ServiceDescriptorProto_has_method(const google_protobuf_ServiceDescriptorProto *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(16, 32)); } UPB_INLINE const google_protobuf_MethodDescriptorProto* const* google_protobuf_ServiceDescriptorProto_method(const google_protobuf_ServiceDescriptorProto *msg, size_t *len) { return (const google_protobuf_MethodDescriptorProto* const*)_upb_array_accessor(msg, UPB_SIZE(16, 32), len); } UPB_INLINE bool google_protobuf_ServiceDescriptorProto_has_options(const google_protobuf_ServiceDescriptorProto *msg) { return _upb_has_field(msg, 2); } -UPB_INLINE const google_protobuf_ServiceOptions* google_protobuf_ServiceDescriptorProto_options(const google_protobuf_ServiceDescriptorProto *msg) { return UPB_FIELD_AT(msg, const google_protobuf_ServiceOptions*, UPB_SIZE(12, 24)); } +UPB_INLINE const google_protobuf_ServiceOptions* google_protobuf_ServiceDescriptorProto_options(const google_protobuf_ServiceDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(12, 24), const google_protobuf_ServiceOptions*); } UPB_INLINE void google_protobuf_ServiceDescriptorProto_set_name(google_protobuf_ServiceDescriptorProto *msg, upb_strview value) { _upb_sethas(msg, 1); - UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(4, 8)) = value; + *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview) = value; } UPB_INLINE google_protobuf_MethodDescriptorProto** google_protobuf_ServiceDescriptorProto_mutable_method(google_protobuf_ServiceDescriptorProto *msg, size_t *len) { return (google_protobuf_MethodDescriptorProto**)_upb_array_mutable_accessor(msg, UPB_SIZE(16, 32), len); } UPB_INLINE google_protobuf_MethodDescriptorProto** google_protobuf_ServiceDescriptorProto_resize_method(google_protobuf_ServiceDescriptorProto *msg, size_t len, upb_arena *arena) { - return (google_protobuf_MethodDescriptorProto**)_upb_array_resize_accessor(msg, UPB_SIZE(16, 32), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena); + return (google_protobuf_MethodDescriptorProto**)_upb_array_resize_accessor(msg, UPB_SIZE(16, 32), len, UPB_TYPE_MESSAGE, arena); } UPB_INLINE struct google_protobuf_MethodDescriptorProto* google_protobuf_ServiceDescriptorProto_add_method(google_protobuf_ServiceDescriptorProto *msg, upb_arena *arena) { - struct google_protobuf_MethodDescriptorProto* sub = (struct google_protobuf_MethodDescriptorProto*)upb_msg_new(&google_protobuf_MethodDescriptorProto_msginit, arena); + struct google_protobuf_MethodDescriptorProto* sub = (struct google_protobuf_MethodDescriptorProto*)_upb_msg_new(&google_protobuf_MethodDescriptorProto_msginit, arena); bool ok = _upb_array_append_accessor( msg, UPB_SIZE(16, 32), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); if (!ok) return NULL; @@ -2123,12 +2283,12 @@ UPB_INLINE struct google_protobuf_MethodDescriptorProto* google_protobuf_Service } UPB_INLINE void google_protobuf_ServiceDescriptorProto_set_options(google_protobuf_ServiceDescriptorProto *msg, google_protobuf_ServiceOptions* value) { _upb_sethas(msg, 2); - UPB_FIELD_AT(msg, google_protobuf_ServiceOptions*, UPB_SIZE(12, 24)) = value; + *UPB_PTR_AT(msg, UPB_SIZE(12, 24), google_protobuf_ServiceOptions*) = value; } UPB_INLINE struct google_protobuf_ServiceOptions* google_protobuf_ServiceDescriptorProto_mutable_options(google_protobuf_ServiceDescriptorProto *msg, upb_arena *arena) { struct google_protobuf_ServiceOptions* sub = (struct google_protobuf_ServiceOptions*)google_protobuf_ServiceDescriptorProto_options(msg); if (sub == NULL) { - sub = (struct google_protobuf_ServiceOptions*)upb_msg_new(&google_protobuf_ServiceOptions_msginit, arena); + sub = (struct google_protobuf_ServiceOptions*)_upb_msg_new(&google_protobuf_ServiceOptions_msginit, arena); if (!sub) return NULL; google_protobuf_ServiceDescriptorProto_set_options(msg, sub); } @@ -2138,7 +2298,7 @@ UPB_INLINE struct google_protobuf_ServiceOptions* google_protobuf_ServiceDescrip /* google.protobuf.MethodDescriptorProto */ UPB_INLINE google_protobuf_MethodDescriptorProto *google_protobuf_MethodDescriptorProto_new(upb_arena *arena) { - return (google_protobuf_MethodDescriptorProto *)upb_msg_new(&google_protobuf_MethodDescriptorProto_msginit, arena); + return (google_protobuf_MethodDescriptorProto *)_upb_msg_new(&google_protobuf_MethodDescriptorProto_msginit, arena); } UPB_INLINE google_protobuf_MethodDescriptorProto *google_protobuf_MethodDescriptorProto_parse(const char *buf, size_t size, upb_arena *arena) { @@ -2150,38 +2310,38 @@ UPB_INLINE char *google_protobuf_MethodDescriptorProto_serialize(const google_pr } UPB_INLINE bool google_protobuf_MethodDescriptorProto_has_name(const google_protobuf_MethodDescriptorProto *msg) { return _upb_has_field(msg, 3); } -UPB_INLINE upb_strview google_protobuf_MethodDescriptorProto_name(const google_protobuf_MethodDescriptorProto *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(4, 8)); } +UPB_INLINE upb_strview google_protobuf_MethodDescriptorProto_name(const google_protobuf_MethodDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview); } UPB_INLINE bool google_protobuf_MethodDescriptorProto_has_input_type(const google_protobuf_MethodDescriptorProto *msg) { return _upb_has_field(msg, 4); } -UPB_INLINE upb_strview google_protobuf_MethodDescriptorProto_input_type(const google_protobuf_MethodDescriptorProto *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(12, 24)); } +UPB_INLINE upb_strview google_protobuf_MethodDescriptorProto_input_type(const google_protobuf_MethodDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(12, 24), upb_strview); } UPB_INLINE bool google_protobuf_MethodDescriptorProto_has_output_type(const google_protobuf_MethodDescriptorProto *msg) { return _upb_has_field(msg, 5); } -UPB_INLINE upb_strview google_protobuf_MethodDescriptorProto_output_type(const google_protobuf_MethodDescriptorProto *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(20, 40)); } +UPB_INLINE upb_strview google_protobuf_MethodDescriptorProto_output_type(const google_protobuf_MethodDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(20, 40), upb_strview); } UPB_INLINE bool google_protobuf_MethodDescriptorProto_has_options(const google_protobuf_MethodDescriptorProto *msg) { return _upb_has_field(msg, 6); } -UPB_INLINE const google_protobuf_MethodOptions* google_protobuf_MethodDescriptorProto_options(const google_protobuf_MethodDescriptorProto *msg) { return UPB_FIELD_AT(msg, const google_protobuf_MethodOptions*, UPB_SIZE(28, 56)); } +UPB_INLINE const google_protobuf_MethodOptions* google_protobuf_MethodDescriptorProto_options(const google_protobuf_MethodDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(28, 56), const google_protobuf_MethodOptions*); } UPB_INLINE bool google_protobuf_MethodDescriptorProto_has_client_streaming(const google_protobuf_MethodDescriptorProto *msg) { return _upb_has_field(msg, 1); } -UPB_INLINE bool google_protobuf_MethodDescriptorProto_client_streaming(const google_protobuf_MethodDescriptorProto *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(1, 1)); } +UPB_INLINE bool google_protobuf_MethodDescriptorProto_client_streaming(const google_protobuf_MethodDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(1, 1), bool); } UPB_INLINE bool google_protobuf_MethodDescriptorProto_has_server_streaming(const google_protobuf_MethodDescriptorProto *msg) { return _upb_has_field(msg, 2); } -UPB_INLINE bool google_protobuf_MethodDescriptorProto_server_streaming(const google_protobuf_MethodDescriptorProto *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(2, 2)); } +UPB_INLINE bool google_protobuf_MethodDescriptorProto_server_streaming(const google_protobuf_MethodDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(2, 2), bool); } UPB_INLINE void google_protobuf_MethodDescriptorProto_set_name(google_protobuf_MethodDescriptorProto *msg, upb_strview value) { _upb_sethas(msg, 3); - UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(4, 8)) = value; + *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview) = value; } UPB_INLINE void google_protobuf_MethodDescriptorProto_set_input_type(google_protobuf_MethodDescriptorProto *msg, upb_strview value) { _upb_sethas(msg, 4); - UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(12, 24)) = value; + *UPB_PTR_AT(msg, UPB_SIZE(12, 24), upb_strview) = value; } UPB_INLINE void google_protobuf_MethodDescriptorProto_set_output_type(google_protobuf_MethodDescriptorProto *msg, upb_strview value) { _upb_sethas(msg, 5); - UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(20, 40)) = value; + *UPB_PTR_AT(msg, UPB_SIZE(20, 40), upb_strview) = value; } UPB_INLINE void google_protobuf_MethodDescriptorProto_set_options(google_protobuf_MethodDescriptorProto *msg, google_protobuf_MethodOptions* value) { _upb_sethas(msg, 6); - UPB_FIELD_AT(msg, google_protobuf_MethodOptions*, UPB_SIZE(28, 56)) = value; + *UPB_PTR_AT(msg, UPB_SIZE(28, 56), google_protobuf_MethodOptions*) = value; } UPB_INLINE struct google_protobuf_MethodOptions* google_protobuf_MethodDescriptorProto_mutable_options(google_protobuf_MethodDescriptorProto *msg, upb_arena *arena) { struct google_protobuf_MethodOptions* sub = (struct google_protobuf_MethodOptions*)google_protobuf_MethodDescriptorProto_options(msg); if (sub == NULL) { - sub = (struct google_protobuf_MethodOptions*)upb_msg_new(&google_protobuf_MethodOptions_msginit, arena); + sub = (struct google_protobuf_MethodOptions*)_upb_msg_new(&google_protobuf_MethodOptions_msginit, arena); if (!sub) return NULL; google_protobuf_MethodDescriptorProto_set_options(msg, sub); } @@ -2189,17 +2349,17 @@ UPB_INLINE struct google_protobuf_MethodOptions* google_protobuf_MethodDescripto } UPB_INLINE void google_protobuf_MethodDescriptorProto_set_client_streaming(google_protobuf_MethodDescriptorProto *msg, bool value) { _upb_sethas(msg, 1); - UPB_FIELD_AT(msg, bool, UPB_SIZE(1, 1)) = value; + *UPB_PTR_AT(msg, UPB_SIZE(1, 1), bool) = value; } UPB_INLINE void google_protobuf_MethodDescriptorProto_set_server_streaming(google_protobuf_MethodDescriptorProto *msg, bool value) { _upb_sethas(msg, 2); - UPB_FIELD_AT(msg, bool, UPB_SIZE(2, 2)) = value; + *UPB_PTR_AT(msg, UPB_SIZE(2, 2), bool) = value; } /* google.protobuf.FileOptions */ UPB_INLINE google_protobuf_FileOptions *google_protobuf_FileOptions_new(upb_arena *arena) { - return (google_protobuf_FileOptions *)upb_msg_new(&google_protobuf_FileOptions_msginit, arena); + return (google_protobuf_FileOptions *)_upb_msg_new(&google_protobuf_FileOptions_msginit, arena); } UPB_INLINE google_protobuf_FileOptions *google_protobuf_FileOptions_parse(const char *buf, size_t size, upb_arena *arena) { @@ -2211,135 +2371,136 @@ UPB_INLINE char *google_protobuf_FileOptions_serialize(const google_protobuf_Fil } UPB_INLINE bool google_protobuf_FileOptions_has_java_package(const google_protobuf_FileOptions *msg) { return _upb_has_field(msg, 11); } -UPB_INLINE upb_strview google_protobuf_FileOptions_java_package(const google_protobuf_FileOptions *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(28, 32)); } +UPB_INLINE upb_strview google_protobuf_FileOptions_java_package(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(28, 32), upb_strview); } UPB_INLINE bool google_protobuf_FileOptions_has_java_outer_classname(const google_protobuf_FileOptions *msg) { return _upb_has_field(msg, 12); } -UPB_INLINE upb_strview google_protobuf_FileOptions_java_outer_classname(const google_protobuf_FileOptions *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(36, 48)); } +UPB_INLINE upb_strview google_protobuf_FileOptions_java_outer_classname(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(36, 48), upb_strview); } UPB_INLINE bool google_protobuf_FileOptions_has_optimize_for(const google_protobuf_FileOptions *msg) { return _upb_has_field(msg, 1); } -UPB_INLINE int32_t google_protobuf_FileOptions_optimize_for(const google_protobuf_FileOptions *msg) { return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(8, 8)); } +UPB_INLINE int32_t google_protobuf_FileOptions_optimize_for(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 8), int32_t); } UPB_INLINE bool google_protobuf_FileOptions_has_java_multiple_files(const google_protobuf_FileOptions *msg) { return _upb_has_field(msg, 2); } -UPB_INLINE bool google_protobuf_FileOptions_java_multiple_files(const google_protobuf_FileOptions *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(16, 16)); } +UPB_INLINE bool google_protobuf_FileOptions_java_multiple_files(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(16, 16), bool); } UPB_INLINE bool google_protobuf_FileOptions_has_go_package(const google_protobuf_FileOptions *msg) { return _upb_has_field(msg, 13); } -UPB_INLINE upb_strview google_protobuf_FileOptions_go_package(const google_protobuf_FileOptions *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(44, 64)); } +UPB_INLINE upb_strview google_protobuf_FileOptions_go_package(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(44, 64), upb_strview); } UPB_INLINE bool google_protobuf_FileOptions_has_cc_generic_services(const google_protobuf_FileOptions *msg) { return _upb_has_field(msg, 3); } -UPB_INLINE bool google_protobuf_FileOptions_cc_generic_services(const google_protobuf_FileOptions *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(17, 17)); } +UPB_INLINE bool google_protobuf_FileOptions_cc_generic_services(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(17, 17), bool); } UPB_INLINE bool google_protobuf_FileOptions_has_java_generic_services(const google_protobuf_FileOptions *msg) { return _upb_has_field(msg, 4); } -UPB_INLINE bool google_protobuf_FileOptions_java_generic_services(const google_protobuf_FileOptions *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(18, 18)); } +UPB_INLINE bool google_protobuf_FileOptions_java_generic_services(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(18, 18), bool); } UPB_INLINE bool google_protobuf_FileOptions_has_py_generic_services(const google_protobuf_FileOptions *msg) { return _upb_has_field(msg, 5); } -UPB_INLINE bool google_protobuf_FileOptions_py_generic_services(const google_protobuf_FileOptions *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(19, 19)); } +UPB_INLINE bool google_protobuf_FileOptions_py_generic_services(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(19, 19), bool); } UPB_INLINE bool google_protobuf_FileOptions_has_java_generate_equals_and_hash(const google_protobuf_FileOptions *msg) { return _upb_has_field(msg, 6); } -UPB_INLINE bool google_protobuf_FileOptions_java_generate_equals_and_hash(const google_protobuf_FileOptions *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(20, 20)); } +UPB_INLINE bool google_protobuf_FileOptions_java_generate_equals_and_hash(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(20, 20), bool); } UPB_INLINE bool google_protobuf_FileOptions_has_deprecated(const google_protobuf_FileOptions *msg) { return _upb_has_field(msg, 7); } -UPB_INLINE bool google_protobuf_FileOptions_deprecated(const google_protobuf_FileOptions *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(21, 21)); } +UPB_INLINE bool google_protobuf_FileOptions_deprecated(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(21, 21), bool); } UPB_INLINE bool google_protobuf_FileOptions_has_java_string_check_utf8(const google_protobuf_FileOptions *msg) { return _upb_has_field(msg, 8); } -UPB_INLINE bool google_protobuf_FileOptions_java_string_check_utf8(const google_protobuf_FileOptions *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(22, 22)); } +UPB_INLINE bool google_protobuf_FileOptions_java_string_check_utf8(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(22, 22), bool); } UPB_INLINE bool google_protobuf_FileOptions_has_cc_enable_arenas(const google_protobuf_FileOptions *msg) { return _upb_has_field(msg, 9); } -UPB_INLINE bool google_protobuf_FileOptions_cc_enable_arenas(const google_protobuf_FileOptions *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(23, 23)); } +UPB_INLINE bool google_protobuf_FileOptions_cc_enable_arenas(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(23, 23), bool); } UPB_INLINE bool google_protobuf_FileOptions_has_objc_class_prefix(const google_protobuf_FileOptions *msg) { return _upb_has_field(msg, 14); } -UPB_INLINE upb_strview google_protobuf_FileOptions_objc_class_prefix(const google_protobuf_FileOptions *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(52, 80)); } +UPB_INLINE upb_strview google_protobuf_FileOptions_objc_class_prefix(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(52, 80), upb_strview); } UPB_INLINE bool google_protobuf_FileOptions_has_csharp_namespace(const google_protobuf_FileOptions *msg) { return _upb_has_field(msg, 15); } -UPB_INLINE upb_strview google_protobuf_FileOptions_csharp_namespace(const google_protobuf_FileOptions *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(60, 96)); } +UPB_INLINE upb_strview google_protobuf_FileOptions_csharp_namespace(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(60, 96), upb_strview); } UPB_INLINE bool google_protobuf_FileOptions_has_swift_prefix(const google_protobuf_FileOptions *msg) { return _upb_has_field(msg, 16); } -UPB_INLINE upb_strview google_protobuf_FileOptions_swift_prefix(const google_protobuf_FileOptions *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(68, 112)); } +UPB_INLINE upb_strview google_protobuf_FileOptions_swift_prefix(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(68, 112), upb_strview); } UPB_INLINE bool google_protobuf_FileOptions_has_php_class_prefix(const google_protobuf_FileOptions *msg) { return _upb_has_field(msg, 17); } -UPB_INLINE upb_strview google_protobuf_FileOptions_php_class_prefix(const google_protobuf_FileOptions *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(76, 128)); } +UPB_INLINE upb_strview google_protobuf_FileOptions_php_class_prefix(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(76, 128), upb_strview); } UPB_INLINE bool google_protobuf_FileOptions_has_php_namespace(const google_protobuf_FileOptions *msg) { return _upb_has_field(msg, 18); } -UPB_INLINE upb_strview google_protobuf_FileOptions_php_namespace(const google_protobuf_FileOptions *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(84, 144)); } +UPB_INLINE upb_strview google_protobuf_FileOptions_php_namespace(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(84, 144), upb_strview); } UPB_INLINE bool google_protobuf_FileOptions_has_php_generic_services(const google_protobuf_FileOptions *msg) { return _upb_has_field(msg, 10); } -UPB_INLINE bool google_protobuf_FileOptions_php_generic_services(const google_protobuf_FileOptions *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(24, 24)); } +UPB_INLINE bool google_protobuf_FileOptions_php_generic_services(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(24, 24), bool); } UPB_INLINE bool google_protobuf_FileOptions_has_php_metadata_namespace(const google_protobuf_FileOptions *msg) { return _upb_has_field(msg, 19); } -UPB_INLINE upb_strview google_protobuf_FileOptions_php_metadata_namespace(const google_protobuf_FileOptions *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(92, 160)); } +UPB_INLINE upb_strview google_protobuf_FileOptions_php_metadata_namespace(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(92, 160), upb_strview); } UPB_INLINE bool google_protobuf_FileOptions_has_ruby_package(const google_protobuf_FileOptions *msg) { return _upb_has_field(msg, 20); } -UPB_INLINE upb_strview google_protobuf_FileOptions_ruby_package(const google_protobuf_FileOptions *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(100, 176)); } +UPB_INLINE upb_strview google_protobuf_FileOptions_ruby_package(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(100, 176), upb_strview); } +UPB_INLINE bool google_protobuf_FileOptions_has_uninterpreted_option(const google_protobuf_FileOptions *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(108, 192)); } UPB_INLINE const google_protobuf_UninterpretedOption* const* google_protobuf_FileOptions_uninterpreted_option(const google_protobuf_FileOptions *msg, size_t *len) { return (const google_protobuf_UninterpretedOption* const*)_upb_array_accessor(msg, UPB_SIZE(108, 192), len); } UPB_INLINE void google_protobuf_FileOptions_set_java_package(google_protobuf_FileOptions *msg, upb_strview value) { _upb_sethas(msg, 11); - UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(28, 32)) = value; + *UPB_PTR_AT(msg, UPB_SIZE(28, 32), upb_strview) = value; } UPB_INLINE void google_protobuf_FileOptions_set_java_outer_classname(google_protobuf_FileOptions *msg, upb_strview value) { _upb_sethas(msg, 12); - UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(36, 48)) = value; + *UPB_PTR_AT(msg, UPB_SIZE(36, 48), upb_strview) = value; } UPB_INLINE void google_protobuf_FileOptions_set_optimize_for(google_protobuf_FileOptions *msg, int32_t value) { _upb_sethas(msg, 1); - UPB_FIELD_AT(msg, int32_t, UPB_SIZE(8, 8)) = value; + *UPB_PTR_AT(msg, UPB_SIZE(8, 8), int32_t) = value; } UPB_INLINE void google_protobuf_FileOptions_set_java_multiple_files(google_protobuf_FileOptions *msg, bool value) { _upb_sethas(msg, 2); - UPB_FIELD_AT(msg, bool, UPB_SIZE(16, 16)) = value; + *UPB_PTR_AT(msg, UPB_SIZE(16, 16), bool) = value; } UPB_INLINE void google_protobuf_FileOptions_set_go_package(google_protobuf_FileOptions *msg, upb_strview value) { _upb_sethas(msg, 13); - UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(44, 64)) = value; + *UPB_PTR_AT(msg, UPB_SIZE(44, 64), upb_strview) = value; } UPB_INLINE void google_protobuf_FileOptions_set_cc_generic_services(google_protobuf_FileOptions *msg, bool value) { _upb_sethas(msg, 3); - UPB_FIELD_AT(msg, bool, UPB_SIZE(17, 17)) = value; + *UPB_PTR_AT(msg, UPB_SIZE(17, 17), bool) = value; } UPB_INLINE void google_protobuf_FileOptions_set_java_generic_services(google_protobuf_FileOptions *msg, bool value) { _upb_sethas(msg, 4); - UPB_FIELD_AT(msg, bool, UPB_SIZE(18, 18)) = value; + *UPB_PTR_AT(msg, UPB_SIZE(18, 18), bool) = value; } UPB_INLINE void google_protobuf_FileOptions_set_py_generic_services(google_protobuf_FileOptions *msg, bool value) { _upb_sethas(msg, 5); - UPB_FIELD_AT(msg, bool, UPB_SIZE(19, 19)) = value; + *UPB_PTR_AT(msg, UPB_SIZE(19, 19), bool) = value; } UPB_INLINE void google_protobuf_FileOptions_set_java_generate_equals_and_hash(google_protobuf_FileOptions *msg, bool value) { _upb_sethas(msg, 6); - UPB_FIELD_AT(msg, bool, UPB_SIZE(20, 20)) = value; + *UPB_PTR_AT(msg, UPB_SIZE(20, 20), bool) = value; } UPB_INLINE void google_protobuf_FileOptions_set_deprecated(google_protobuf_FileOptions *msg, bool value) { _upb_sethas(msg, 7); - UPB_FIELD_AT(msg, bool, UPB_SIZE(21, 21)) = value; + *UPB_PTR_AT(msg, UPB_SIZE(21, 21), bool) = value; } UPB_INLINE void google_protobuf_FileOptions_set_java_string_check_utf8(google_protobuf_FileOptions *msg, bool value) { _upb_sethas(msg, 8); - UPB_FIELD_AT(msg, bool, UPB_SIZE(22, 22)) = value; + *UPB_PTR_AT(msg, UPB_SIZE(22, 22), bool) = value; } UPB_INLINE void google_protobuf_FileOptions_set_cc_enable_arenas(google_protobuf_FileOptions *msg, bool value) { _upb_sethas(msg, 9); - UPB_FIELD_AT(msg, bool, UPB_SIZE(23, 23)) = value; + *UPB_PTR_AT(msg, UPB_SIZE(23, 23), bool) = value; } UPB_INLINE void google_protobuf_FileOptions_set_objc_class_prefix(google_protobuf_FileOptions *msg, upb_strview value) { _upb_sethas(msg, 14); - UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(52, 80)) = value; + *UPB_PTR_AT(msg, UPB_SIZE(52, 80), upb_strview) = value; } UPB_INLINE void google_protobuf_FileOptions_set_csharp_namespace(google_protobuf_FileOptions *msg, upb_strview value) { _upb_sethas(msg, 15); - UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(60, 96)) = value; + *UPB_PTR_AT(msg, UPB_SIZE(60, 96), upb_strview) = value; } UPB_INLINE void google_protobuf_FileOptions_set_swift_prefix(google_protobuf_FileOptions *msg, upb_strview value) { _upb_sethas(msg, 16); - UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(68, 112)) = value; + *UPB_PTR_AT(msg, UPB_SIZE(68, 112), upb_strview) = value; } UPB_INLINE void google_protobuf_FileOptions_set_php_class_prefix(google_protobuf_FileOptions *msg, upb_strview value) { _upb_sethas(msg, 17); - UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(76, 128)) = value; + *UPB_PTR_AT(msg, UPB_SIZE(76, 128), upb_strview) = value; } UPB_INLINE void google_protobuf_FileOptions_set_php_namespace(google_protobuf_FileOptions *msg, upb_strview value) { _upb_sethas(msg, 18); - UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(84, 144)) = value; + *UPB_PTR_AT(msg, UPB_SIZE(84, 144), upb_strview) = value; } UPB_INLINE void google_protobuf_FileOptions_set_php_generic_services(google_protobuf_FileOptions *msg, bool value) { _upb_sethas(msg, 10); - UPB_FIELD_AT(msg, bool, UPB_SIZE(24, 24)) = value; + *UPB_PTR_AT(msg, UPB_SIZE(24, 24), bool) = value; } UPB_INLINE void google_protobuf_FileOptions_set_php_metadata_namespace(google_protobuf_FileOptions *msg, upb_strview value) { _upb_sethas(msg, 19); - UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(92, 160)) = value; + *UPB_PTR_AT(msg, UPB_SIZE(92, 160), upb_strview) = value; } UPB_INLINE void google_protobuf_FileOptions_set_ruby_package(google_protobuf_FileOptions *msg, upb_strview value) { _upb_sethas(msg, 20); - UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(100, 176)) = value; + *UPB_PTR_AT(msg, UPB_SIZE(100, 176), upb_strview) = value; } UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_FileOptions_mutable_uninterpreted_option(google_protobuf_FileOptions *msg, size_t *len) { return (google_protobuf_UninterpretedOption**)_upb_array_mutable_accessor(msg, UPB_SIZE(108, 192), len); } UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_FileOptions_resize_uninterpreted_option(google_protobuf_FileOptions *msg, size_t len, upb_arena *arena) { - return (google_protobuf_UninterpretedOption**)_upb_array_resize_accessor(msg, UPB_SIZE(108, 192), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena); + return (google_protobuf_UninterpretedOption**)_upb_array_resize_accessor(msg, UPB_SIZE(108, 192), len, UPB_TYPE_MESSAGE, arena); } UPB_INLINE struct google_protobuf_UninterpretedOption* google_protobuf_FileOptions_add_uninterpreted_option(google_protobuf_FileOptions *msg, upb_arena *arena) { - struct google_protobuf_UninterpretedOption* sub = (struct google_protobuf_UninterpretedOption*)upb_msg_new(&google_protobuf_UninterpretedOption_msginit, arena); + struct google_protobuf_UninterpretedOption* sub = (struct google_protobuf_UninterpretedOption*)_upb_msg_new(&google_protobuf_UninterpretedOption_msginit, arena); bool ok = _upb_array_append_accessor( msg, UPB_SIZE(108, 192), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); if (!ok) return NULL; @@ -2349,7 +2510,7 @@ UPB_INLINE struct google_protobuf_UninterpretedOption* google_protobuf_FileOptio /* google.protobuf.MessageOptions */ UPB_INLINE google_protobuf_MessageOptions *google_protobuf_MessageOptions_new(upb_arena *arena) { - return (google_protobuf_MessageOptions *)upb_msg_new(&google_protobuf_MessageOptions_msginit, arena); + return (google_protobuf_MessageOptions *)_upb_msg_new(&google_protobuf_MessageOptions_msginit, arena); } UPB_INLINE google_protobuf_MessageOptions *google_protobuf_MessageOptions_parse(const char *buf, size_t size, upb_arena *arena) { @@ -2361,39 +2522,40 @@ UPB_INLINE char *google_protobuf_MessageOptions_serialize(const google_protobuf_ } UPB_INLINE bool google_protobuf_MessageOptions_has_message_set_wire_format(const google_protobuf_MessageOptions *msg) { return _upb_has_field(msg, 1); } -UPB_INLINE bool google_protobuf_MessageOptions_message_set_wire_format(const google_protobuf_MessageOptions *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(1, 1)); } +UPB_INLINE bool google_protobuf_MessageOptions_message_set_wire_format(const google_protobuf_MessageOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(1, 1), bool); } UPB_INLINE bool google_protobuf_MessageOptions_has_no_standard_descriptor_accessor(const google_protobuf_MessageOptions *msg) { return _upb_has_field(msg, 2); } -UPB_INLINE bool google_protobuf_MessageOptions_no_standard_descriptor_accessor(const google_protobuf_MessageOptions *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(2, 2)); } +UPB_INLINE bool google_protobuf_MessageOptions_no_standard_descriptor_accessor(const google_protobuf_MessageOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(2, 2), bool); } UPB_INLINE bool google_protobuf_MessageOptions_has_deprecated(const google_protobuf_MessageOptions *msg) { return _upb_has_field(msg, 3); } -UPB_INLINE bool google_protobuf_MessageOptions_deprecated(const google_protobuf_MessageOptions *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(3, 3)); } +UPB_INLINE bool google_protobuf_MessageOptions_deprecated(const google_protobuf_MessageOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(3, 3), bool); } UPB_INLINE bool google_protobuf_MessageOptions_has_map_entry(const google_protobuf_MessageOptions *msg) { return _upb_has_field(msg, 4); } -UPB_INLINE bool google_protobuf_MessageOptions_map_entry(const google_protobuf_MessageOptions *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(4, 4)); } +UPB_INLINE bool google_protobuf_MessageOptions_map_entry(const google_protobuf_MessageOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 4), bool); } +UPB_INLINE bool google_protobuf_MessageOptions_has_uninterpreted_option(const google_protobuf_MessageOptions *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(8, 8)); } UPB_INLINE const google_protobuf_UninterpretedOption* const* google_protobuf_MessageOptions_uninterpreted_option(const google_protobuf_MessageOptions *msg, size_t *len) { return (const google_protobuf_UninterpretedOption* const*)_upb_array_accessor(msg, UPB_SIZE(8, 8), len); } UPB_INLINE void google_protobuf_MessageOptions_set_message_set_wire_format(google_protobuf_MessageOptions *msg, bool value) { _upb_sethas(msg, 1); - UPB_FIELD_AT(msg, bool, UPB_SIZE(1, 1)) = value; + *UPB_PTR_AT(msg, UPB_SIZE(1, 1), bool) = value; } UPB_INLINE void google_protobuf_MessageOptions_set_no_standard_descriptor_accessor(google_protobuf_MessageOptions *msg, bool value) { _upb_sethas(msg, 2); - UPB_FIELD_AT(msg, bool, UPB_SIZE(2, 2)) = value; + *UPB_PTR_AT(msg, UPB_SIZE(2, 2), bool) = value; } UPB_INLINE void google_protobuf_MessageOptions_set_deprecated(google_protobuf_MessageOptions *msg, bool value) { _upb_sethas(msg, 3); - UPB_FIELD_AT(msg, bool, UPB_SIZE(3, 3)) = value; + *UPB_PTR_AT(msg, UPB_SIZE(3, 3), bool) = value; } UPB_INLINE void google_protobuf_MessageOptions_set_map_entry(google_protobuf_MessageOptions *msg, bool value) { _upb_sethas(msg, 4); - UPB_FIELD_AT(msg, bool, UPB_SIZE(4, 4)) = value; + *UPB_PTR_AT(msg, UPB_SIZE(4, 4), bool) = value; } UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_MessageOptions_mutable_uninterpreted_option(google_protobuf_MessageOptions *msg, size_t *len) { return (google_protobuf_UninterpretedOption**)_upb_array_mutable_accessor(msg, UPB_SIZE(8, 8), len); } UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_MessageOptions_resize_uninterpreted_option(google_protobuf_MessageOptions *msg, size_t len, upb_arena *arena) { - return (google_protobuf_UninterpretedOption**)_upb_array_resize_accessor(msg, UPB_SIZE(8, 8), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena); + return (google_protobuf_UninterpretedOption**)_upb_array_resize_accessor(msg, UPB_SIZE(8, 8), len, UPB_TYPE_MESSAGE, arena); } UPB_INLINE struct google_protobuf_UninterpretedOption* google_protobuf_MessageOptions_add_uninterpreted_option(google_protobuf_MessageOptions *msg, upb_arena *arena) { - struct google_protobuf_UninterpretedOption* sub = (struct google_protobuf_UninterpretedOption*)upb_msg_new(&google_protobuf_UninterpretedOption_msginit, arena); + struct google_protobuf_UninterpretedOption* sub = (struct google_protobuf_UninterpretedOption*)_upb_msg_new(&google_protobuf_UninterpretedOption_msginit, arena); bool ok = _upb_array_append_accessor( msg, UPB_SIZE(8, 8), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); if (!ok) return NULL; @@ -2403,7 +2565,7 @@ UPB_INLINE struct google_protobuf_UninterpretedOption* google_protobuf_MessageOp /* google.protobuf.FieldOptions */ UPB_INLINE google_protobuf_FieldOptions *google_protobuf_FieldOptions_new(upb_arena *arena) { - return (google_protobuf_FieldOptions *)upb_msg_new(&google_protobuf_FieldOptions_msginit, arena); + return (google_protobuf_FieldOptions *)_upb_msg_new(&google_protobuf_FieldOptions_msginit, arena); } UPB_INLINE google_protobuf_FieldOptions *google_protobuf_FieldOptions_parse(const char *buf, size_t size, upb_arena *arena) { @@ -2415,51 +2577,52 @@ UPB_INLINE char *google_protobuf_FieldOptions_serialize(const google_protobuf_Fi } UPB_INLINE bool google_protobuf_FieldOptions_has_ctype(const google_protobuf_FieldOptions *msg) { return _upb_has_field(msg, 1); } -UPB_INLINE int32_t google_protobuf_FieldOptions_ctype(const google_protobuf_FieldOptions *msg) { return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(8, 8)); } +UPB_INLINE int32_t google_protobuf_FieldOptions_ctype(const google_protobuf_FieldOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 8), int32_t); } UPB_INLINE bool google_protobuf_FieldOptions_has_packed(const google_protobuf_FieldOptions *msg) { return _upb_has_field(msg, 3); } -UPB_INLINE bool google_protobuf_FieldOptions_packed(const google_protobuf_FieldOptions *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(24, 24)); } +UPB_INLINE bool google_protobuf_FieldOptions_packed(const google_protobuf_FieldOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(24, 24), bool); } UPB_INLINE bool google_protobuf_FieldOptions_has_deprecated(const google_protobuf_FieldOptions *msg) { return _upb_has_field(msg, 4); } -UPB_INLINE bool google_protobuf_FieldOptions_deprecated(const google_protobuf_FieldOptions *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(25, 25)); } +UPB_INLINE bool google_protobuf_FieldOptions_deprecated(const google_protobuf_FieldOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(25, 25), bool); } UPB_INLINE bool google_protobuf_FieldOptions_has_lazy(const google_protobuf_FieldOptions *msg) { return _upb_has_field(msg, 5); } -UPB_INLINE bool google_protobuf_FieldOptions_lazy(const google_protobuf_FieldOptions *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(26, 26)); } +UPB_INLINE bool google_protobuf_FieldOptions_lazy(const google_protobuf_FieldOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(26, 26), bool); } UPB_INLINE bool google_protobuf_FieldOptions_has_jstype(const google_protobuf_FieldOptions *msg) { return _upb_has_field(msg, 2); } -UPB_INLINE int32_t google_protobuf_FieldOptions_jstype(const google_protobuf_FieldOptions *msg) { return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(16, 16)); } +UPB_INLINE int32_t google_protobuf_FieldOptions_jstype(const google_protobuf_FieldOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(16, 16), int32_t); } UPB_INLINE bool google_protobuf_FieldOptions_has_weak(const google_protobuf_FieldOptions *msg) { return _upb_has_field(msg, 6); } -UPB_INLINE bool google_protobuf_FieldOptions_weak(const google_protobuf_FieldOptions *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(27, 27)); } +UPB_INLINE bool google_protobuf_FieldOptions_weak(const google_protobuf_FieldOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(27, 27), bool); } +UPB_INLINE bool google_protobuf_FieldOptions_has_uninterpreted_option(const google_protobuf_FieldOptions *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(28, 32)); } UPB_INLINE const google_protobuf_UninterpretedOption* const* google_protobuf_FieldOptions_uninterpreted_option(const google_protobuf_FieldOptions *msg, size_t *len) { return (const google_protobuf_UninterpretedOption* const*)_upb_array_accessor(msg, UPB_SIZE(28, 32), len); } UPB_INLINE void google_protobuf_FieldOptions_set_ctype(google_protobuf_FieldOptions *msg, int32_t value) { _upb_sethas(msg, 1); - UPB_FIELD_AT(msg, int32_t, UPB_SIZE(8, 8)) = value; + *UPB_PTR_AT(msg, UPB_SIZE(8, 8), int32_t) = value; } UPB_INLINE void google_protobuf_FieldOptions_set_packed(google_protobuf_FieldOptions *msg, bool value) { _upb_sethas(msg, 3); - UPB_FIELD_AT(msg, bool, UPB_SIZE(24, 24)) = value; + *UPB_PTR_AT(msg, UPB_SIZE(24, 24), bool) = value; } UPB_INLINE void google_protobuf_FieldOptions_set_deprecated(google_protobuf_FieldOptions *msg, bool value) { _upb_sethas(msg, 4); - UPB_FIELD_AT(msg, bool, UPB_SIZE(25, 25)) = value; + *UPB_PTR_AT(msg, UPB_SIZE(25, 25), bool) = value; } UPB_INLINE void google_protobuf_FieldOptions_set_lazy(google_protobuf_FieldOptions *msg, bool value) { _upb_sethas(msg, 5); - UPB_FIELD_AT(msg, bool, UPB_SIZE(26, 26)) = value; + *UPB_PTR_AT(msg, UPB_SIZE(26, 26), bool) = value; } UPB_INLINE void google_protobuf_FieldOptions_set_jstype(google_protobuf_FieldOptions *msg, int32_t value) { _upb_sethas(msg, 2); - UPB_FIELD_AT(msg, int32_t, UPB_SIZE(16, 16)) = value; + *UPB_PTR_AT(msg, UPB_SIZE(16, 16), int32_t) = value; } UPB_INLINE void google_protobuf_FieldOptions_set_weak(google_protobuf_FieldOptions *msg, bool value) { _upb_sethas(msg, 6); - UPB_FIELD_AT(msg, bool, UPB_SIZE(27, 27)) = value; + *UPB_PTR_AT(msg, UPB_SIZE(27, 27), bool) = value; } UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_FieldOptions_mutable_uninterpreted_option(google_protobuf_FieldOptions *msg, size_t *len) { return (google_protobuf_UninterpretedOption**)_upb_array_mutable_accessor(msg, UPB_SIZE(28, 32), len); } UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_FieldOptions_resize_uninterpreted_option(google_protobuf_FieldOptions *msg, size_t len, upb_arena *arena) { - return (google_protobuf_UninterpretedOption**)_upb_array_resize_accessor(msg, UPB_SIZE(28, 32), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena); + return (google_protobuf_UninterpretedOption**)_upb_array_resize_accessor(msg, UPB_SIZE(28, 32), len, UPB_TYPE_MESSAGE, arena); } UPB_INLINE struct google_protobuf_UninterpretedOption* google_protobuf_FieldOptions_add_uninterpreted_option(google_protobuf_FieldOptions *msg, upb_arena *arena) { - struct google_protobuf_UninterpretedOption* sub = (struct google_protobuf_UninterpretedOption*)upb_msg_new(&google_protobuf_UninterpretedOption_msginit, arena); + struct google_protobuf_UninterpretedOption* sub = (struct google_protobuf_UninterpretedOption*)_upb_msg_new(&google_protobuf_UninterpretedOption_msginit, arena); bool ok = _upb_array_append_accessor( msg, UPB_SIZE(28, 32), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); if (!ok) return NULL; @@ -2469,7 +2632,7 @@ UPB_INLINE struct google_protobuf_UninterpretedOption* google_protobuf_FieldOpti /* google.protobuf.OneofOptions */ UPB_INLINE google_protobuf_OneofOptions *google_protobuf_OneofOptions_new(upb_arena *arena) { - return (google_protobuf_OneofOptions *)upb_msg_new(&google_protobuf_OneofOptions_msginit, arena); + return (google_protobuf_OneofOptions *)_upb_msg_new(&google_protobuf_OneofOptions_msginit, arena); } UPB_INLINE google_protobuf_OneofOptions *google_protobuf_OneofOptions_parse(const char *buf, size_t size, upb_arena *arena) { @@ -2480,16 +2643,17 @@ UPB_INLINE char *google_protobuf_OneofOptions_serialize(const google_protobuf_On return upb_encode(msg, &google_protobuf_OneofOptions_msginit, arena, len); } +UPB_INLINE bool google_protobuf_OneofOptions_has_uninterpreted_option(const google_protobuf_OneofOptions *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(0, 0)); } UPB_INLINE const google_protobuf_UninterpretedOption* const* google_protobuf_OneofOptions_uninterpreted_option(const google_protobuf_OneofOptions *msg, size_t *len) { return (const google_protobuf_UninterpretedOption* const*)_upb_array_accessor(msg, UPB_SIZE(0, 0), len); } UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_OneofOptions_mutable_uninterpreted_option(google_protobuf_OneofOptions *msg, size_t *len) { return (google_protobuf_UninterpretedOption**)_upb_array_mutable_accessor(msg, UPB_SIZE(0, 0), len); } UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_OneofOptions_resize_uninterpreted_option(google_protobuf_OneofOptions *msg, size_t len, upb_arena *arena) { - return (google_protobuf_UninterpretedOption**)_upb_array_resize_accessor(msg, UPB_SIZE(0, 0), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena); + return (google_protobuf_UninterpretedOption**)_upb_array_resize_accessor(msg, UPB_SIZE(0, 0), len, UPB_TYPE_MESSAGE, arena); } UPB_INLINE struct google_protobuf_UninterpretedOption* google_protobuf_OneofOptions_add_uninterpreted_option(google_protobuf_OneofOptions *msg, upb_arena *arena) { - struct google_protobuf_UninterpretedOption* sub = (struct google_protobuf_UninterpretedOption*)upb_msg_new(&google_protobuf_UninterpretedOption_msginit, arena); + struct google_protobuf_UninterpretedOption* sub = (struct google_protobuf_UninterpretedOption*)_upb_msg_new(&google_protobuf_UninterpretedOption_msginit, arena); bool ok = _upb_array_append_accessor( msg, UPB_SIZE(0, 0), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); if (!ok) return NULL; @@ -2499,7 +2663,7 @@ UPB_INLINE struct google_protobuf_UninterpretedOption* google_protobuf_OneofOpti /* google.protobuf.EnumOptions */ UPB_INLINE google_protobuf_EnumOptions *google_protobuf_EnumOptions_new(upb_arena *arena) { - return (google_protobuf_EnumOptions *)upb_msg_new(&google_protobuf_EnumOptions_msginit, arena); + return (google_protobuf_EnumOptions *)_upb_msg_new(&google_protobuf_EnumOptions_msginit, arena); } UPB_INLINE google_protobuf_EnumOptions *google_protobuf_EnumOptions_parse(const char *buf, size_t size, upb_arena *arena) { @@ -2511,27 +2675,28 @@ UPB_INLINE char *google_protobuf_EnumOptions_serialize(const google_protobuf_Enu } UPB_INLINE bool google_protobuf_EnumOptions_has_allow_alias(const google_protobuf_EnumOptions *msg) { return _upb_has_field(msg, 1); } -UPB_INLINE bool google_protobuf_EnumOptions_allow_alias(const google_protobuf_EnumOptions *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(1, 1)); } +UPB_INLINE bool google_protobuf_EnumOptions_allow_alias(const google_protobuf_EnumOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(1, 1), bool); } UPB_INLINE bool google_protobuf_EnumOptions_has_deprecated(const google_protobuf_EnumOptions *msg) { return _upb_has_field(msg, 2); } -UPB_INLINE bool google_protobuf_EnumOptions_deprecated(const google_protobuf_EnumOptions *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(2, 2)); } +UPB_INLINE bool google_protobuf_EnumOptions_deprecated(const google_protobuf_EnumOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(2, 2), bool); } +UPB_INLINE bool google_protobuf_EnumOptions_has_uninterpreted_option(const google_protobuf_EnumOptions *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(4, 8)); } UPB_INLINE const google_protobuf_UninterpretedOption* const* google_protobuf_EnumOptions_uninterpreted_option(const google_protobuf_EnumOptions *msg, size_t *len) { return (const google_protobuf_UninterpretedOption* const*)_upb_array_accessor(msg, UPB_SIZE(4, 8), len); } UPB_INLINE void google_protobuf_EnumOptions_set_allow_alias(google_protobuf_EnumOptions *msg, bool value) { _upb_sethas(msg, 1); - UPB_FIELD_AT(msg, bool, UPB_SIZE(1, 1)) = value; + *UPB_PTR_AT(msg, UPB_SIZE(1, 1), bool) = value; } UPB_INLINE void google_protobuf_EnumOptions_set_deprecated(google_protobuf_EnumOptions *msg, bool value) { _upb_sethas(msg, 2); - UPB_FIELD_AT(msg, bool, UPB_SIZE(2, 2)) = value; + *UPB_PTR_AT(msg, UPB_SIZE(2, 2), bool) = value; } UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_EnumOptions_mutable_uninterpreted_option(google_protobuf_EnumOptions *msg, size_t *len) { return (google_protobuf_UninterpretedOption**)_upb_array_mutable_accessor(msg, UPB_SIZE(4, 8), len); } UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_EnumOptions_resize_uninterpreted_option(google_protobuf_EnumOptions *msg, size_t len, upb_arena *arena) { - return (google_protobuf_UninterpretedOption**)_upb_array_resize_accessor(msg, UPB_SIZE(4, 8), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena); + return (google_protobuf_UninterpretedOption**)_upb_array_resize_accessor(msg, UPB_SIZE(4, 8), len, UPB_TYPE_MESSAGE, arena); } UPB_INLINE struct google_protobuf_UninterpretedOption* google_protobuf_EnumOptions_add_uninterpreted_option(google_protobuf_EnumOptions *msg, upb_arena *arena) { - struct google_protobuf_UninterpretedOption* sub = (struct google_protobuf_UninterpretedOption*)upb_msg_new(&google_protobuf_UninterpretedOption_msginit, arena); + struct google_protobuf_UninterpretedOption* sub = (struct google_protobuf_UninterpretedOption*)_upb_msg_new(&google_protobuf_UninterpretedOption_msginit, arena); bool ok = _upb_array_append_accessor( msg, UPB_SIZE(4, 8), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); if (!ok) return NULL; @@ -2541,7 +2706,7 @@ UPB_INLINE struct google_protobuf_UninterpretedOption* google_protobuf_EnumOptio /* google.protobuf.EnumValueOptions */ UPB_INLINE google_protobuf_EnumValueOptions *google_protobuf_EnumValueOptions_new(upb_arena *arena) { - return (google_protobuf_EnumValueOptions *)upb_msg_new(&google_protobuf_EnumValueOptions_msginit, arena); + return (google_protobuf_EnumValueOptions *)_upb_msg_new(&google_protobuf_EnumValueOptions_msginit, arena); } UPB_INLINE google_protobuf_EnumValueOptions *google_protobuf_EnumValueOptions_parse(const char *buf, size_t size, upb_arena *arena) { @@ -2553,21 +2718,22 @@ UPB_INLINE char *google_protobuf_EnumValueOptions_serialize(const google_protobu } UPB_INLINE bool google_protobuf_EnumValueOptions_has_deprecated(const google_protobuf_EnumValueOptions *msg) { return _upb_has_field(msg, 1); } -UPB_INLINE bool google_protobuf_EnumValueOptions_deprecated(const google_protobuf_EnumValueOptions *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(1, 1)); } +UPB_INLINE bool google_protobuf_EnumValueOptions_deprecated(const google_protobuf_EnumValueOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(1, 1), bool); } +UPB_INLINE bool google_protobuf_EnumValueOptions_has_uninterpreted_option(const google_protobuf_EnumValueOptions *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(4, 8)); } UPB_INLINE const google_protobuf_UninterpretedOption* const* google_protobuf_EnumValueOptions_uninterpreted_option(const google_protobuf_EnumValueOptions *msg, size_t *len) { return (const google_protobuf_UninterpretedOption* const*)_upb_array_accessor(msg, UPB_SIZE(4, 8), len); } UPB_INLINE void google_protobuf_EnumValueOptions_set_deprecated(google_protobuf_EnumValueOptions *msg, bool value) { _upb_sethas(msg, 1); - UPB_FIELD_AT(msg, bool, UPB_SIZE(1, 1)) = value; + *UPB_PTR_AT(msg, UPB_SIZE(1, 1), bool) = value; } UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_EnumValueOptions_mutable_uninterpreted_option(google_protobuf_EnumValueOptions *msg, size_t *len) { return (google_protobuf_UninterpretedOption**)_upb_array_mutable_accessor(msg, UPB_SIZE(4, 8), len); } UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_EnumValueOptions_resize_uninterpreted_option(google_protobuf_EnumValueOptions *msg, size_t len, upb_arena *arena) { - return (google_protobuf_UninterpretedOption**)_upb_array_resize_accessor(msg, UPB_SIZE(4, 8), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena); + return (google_protobuf_UninterpretedOption**)_upb_array_resize_accessor(msg, UPB_SIZE(4, 8), len, UPB_TYPE_MESSAGE, arena); } UPB_INLINE struct google_protobuf_UninterpretedOption* google_protobuf_EnumValueOptions_add_uninterpreted_option(google_protobuf_EnumValueOptions *msg, upb_arena *arena) { - struct google_protobuf_UninterpretedOption* sub = (struct google_protobuf_UninterpretedOption*)upb_msg_new(&google_protobuf_UninterpretedOption_msginit, arena); + struct google_protobuf_UninterpretedOption* sub = (struct google_protobuf_UninterpretedOption*)_upb_msg_new(&google_protobuf_UninterpretedOption_msginit, arena); bool ok = _upb_array_append_accessor( msg, UPB_SIZE(4, 8), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); if (!ok) return NULL; @@ -2577,7 +2743,7 @@ UPB_INLINE struct google_protobuf_UninterpretedOption* google_protobuf_EnumValue /* google.protobuf.ServiceOptions */ UPB_INLINE google_protobuf_ServiceOptions *google_protobuf_ServiceOptions_new(upb_arena *arena) { - return (google_protobuf_ServiceOptions *)upb_msg_new(&google_protobuf_ServiceOptions_msginit, arena); + return (google_protobuf_ServiceOptions *)_upb_msg_new(&google_protobuf_ServiceOptions_msginit, arena); } UPB_INLINE google_protobuf_ServiceOptions *google_protobuf_ServiceOptions_parse(const char *buf, size_t size, upb_arena *arena) { @@ -2589,21 +2755,22 @@ UPB_INLINE char *google_protobuf_ServiceOptions_serialize(const google_protobuf_ } UPB_INLINE bool google_protobuf_ServiceOptions_has_deprecated(const google_protobuf_ServiceOptions *msg) { return _upb_has_field(msg, 1); } -UPB_INLINE bool google_protobuf_ServiceOptions_deprecated(const google_protobuf_ServiceOptions *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(1, 1)); } +UPB_INLINE bool google_protobuf_ServiceOptions_deprecated(const google_protobuf_ServiceOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(1, 1), bool); } +UPB_INLINE bool google_protobuf_ServiceOptions_has_uninterpreted_option(const google_protobuf_ServiceOptions *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(4, 8)); } UPB_INLINE const google_protobuf_UninterpretedOption* const* google_protobuf_ServiceOptions_uninterpreted_option(const google_protobuf_ServiceOptions *msg, size_t *len) { return (const google_protobuf_UninterpretedOption* const*)_upb_array_accessor(msg, UPB_SIZE(4, 8), len); } UPB_INLINE void google_protobuf_ServiceOptions_set_deprecated(google_protobuf_ServiceOptions *msg, bool value) { _upb_sethas(msg, 1); - UPB_FIELD_AT(msg, bool, UPB_SIZE(1, 1)) = value; + *UPB_PTR_AT(msg, UPB_SIZE(1, 1), bool) = value; } UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_ServiceOptions_mutable_uninterpreted_option(google_protobuf_ServiceOptions *msg, size_t *len) { return (google_protobuf_UninterpretedOption**)_upb_array_mutable_accessor(msg, UPB_SIZE(4, 8), len); } UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_ServiceOptions_resize_uninterpreted_option(google_protobuf_ServiceOptions *msg, size_t len, upb_arena *arena) { - return (google_protobuf_UninterpretedOption**)_upb_array_resize_accessor(msg, UPB_SIZE(4, 8), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena); + return (google_protobuf_UninterpretedOption**)_upb_array_resize_accessor(msg, UPB_SIZE(4, 8), len, UPB_TYPE_MESSAGE, arena); } UPB_INLINE struct google_protobuf_UninterpretedOption* google_protobuf_ServiceOptions_add_uninterpreted_option(google_protobuf_ServiceOptions *msg, upb_arena *arena) { - struct google_protobuf_UninterpretedOption* sub = (struct google_protobuf_UninterpretedOption*)upb_msg_new(&google_protobuf_UninterpretedOption_msginit, arena); + struct google_protobuf_UninterpretedOption* sub = (struct google_protobuf_UninterpretedOption*)_upb_msg_new(&google_protobuf_UninterpretedOption_msginit, arena); bool ok = _upb_array_append_accessor( msg, UPB_SIZE(4, 8), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); if (!ok) return NULL; @@ -2613,7 +2780,7 @@ UPB_INLINE struct google_protobuf_UninterpretedOption* google_protobuf_ServiceOp /* google.protobuf.MethodOptions */ UPB_INLINE google_protobuf_MethodOptions *google_protobuf_MethodOptions_new(upb_arena *arena) { - return (google_protobuf_MethodOptions *)upb_msg_new(&google_protobuf_MethodOptions_msginit, arena); + return (google_protobuf_MethodOptions *)_upb_msg_new(&google_protobuf_MethodOptions_msginit, arena); } UPB_INLINE google_protobuf_MethodOptions *google_protobuf_MethodOptions_parse(const char *buf, size_t size, upb_arena *arena) { @@ -2625,27 +2792,28 @@ UPB_INLINE char *google_protobuf_MethodOptions_serialize(const google_protobuf_M } UPB_INLINE bool google_protobuf_MethodOptions_has_deprecated(const google_protobuf_MethodOptions *msg) { return _upb_has_field(msg, 2); } -UPB_INLINE bool google_protobuf_MethodOptions_deprecated(const google_protobuf_MethodOptions *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(16, 16)); } +UPB_INLINE bool google_protobuf_MethodOptions_deprecated(const google_protobuf_MethodOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(16, 16), bool); } UPB_INLINE bool google_protobuf_MethodOptions_has_idempotency_level(const google_protobuf_MethodOptions *msg) { return _upb_has_field(msg, 1); } -UPB_INLINE int32_t google_protobuf_MethodOptions_idempotency_level(const google_protobuf_MethodOptions *msg) { return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(8, 8)); } +UPB_INLINE int32_t google_protobuf_MethodOptions_idempotency_level(const google_protobuf_MethodOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 8), int32_t); } +UPB_INLINE bool google_protobuf_MethodOptions_has_uninterpreted_option(const google_protobuf_MethodOptions *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(20, 24)); } UPB_INLINE const google_protobuf_UninterpretedOption* const* google_protobuf_MethodOptions_uninterpreted_option(const google_protobuf_MethodOptions *msg, size_t *len) { return (const google_protobuf_UninterpretedOption* const*)_upb_array_accessor(msg, UPB_SIZE(20, 24), len); } UPB_INLINE void google_protobuf_MethodOptions_set_deprecated(google_protobuf_MethodOptions *msg, bool value) { _upb_sethas(msg, 2); - UPB_FIELD_AT(msg, bool, UPB_SIZE(16, 16)) = value; + *UPB_PTR_AT(msg, UPB_SIZE(16, 16), bool) = value; } UPB_INLINE void google_protobuf_MethodOptions_set_idempotency_level(google_protobuf_MethodOptions *msg, int32_t value) { _upb_sethas(msg, 1); - UPB_FIELD_AT(msg, int32_t, UPB_SIZE(8, 8)) = value; + *UPB_PTR_AT(msg, UPB_SIZE(8, 8), int32_t) = value; } UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_MethodOptions_mutable_uninterpreted_option(google_protobuf_MethodOptions *msg, size_t *len) { return (google_protobuf_UninterpretedOption**)_upb_array_mutable_accessor(msg, UPB_SIZE(20, 24), len); } UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_MethodOptions_resize_uninterpreted_option(google_protobuf_MethodOptions *msg, size_t len, upb_arena *arena) { - return (google_protobuf_UninterpretedOption**)_upb_array_resize_accessor(msg, UPB_SIZE(20, 24), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena); + return (google_protobuf_UninterpretedOption**)_upb_array_resize_accessor(msg, UPB_SIZE(20, 24), len, UPB_TYPE_MESSAGE, arena); } UPB_INLINE struct google_protobuf_UninterpretedOption* google_protobuf_MethodOptions_add_uninterpreted_option(google_protobuf_MethodOptions *msg, upb_arena *arena) { - struct google_protobuf_UninterpretedOption* sub = (struct google_protobuf_UninterpretedOption*)upb_msg_new(&google_protobuf_UninterpretedOption_msginit, arena); + struct google_protobuf_UninterpretedOption* sub = (struct google_protobuf_UninterpretedOption*)_upb_msg_new(&google_protobuf_UninterpretedOption_msginit, arena); bool ok = _upb_array_append_accessor( msg, UPB_SIZE(20, 24), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); if (!ok) return NULL; @@ -2655,7 +2823,7 @@ UPB_INLINE struct google_protobuf_UninterpretedOption* google_protobuf_MethodOpt /* google.protobuf.UninterpretedOption */ UPB_INLINE google_protobuf_UninterpretedOption *google_protobuf_UninterpretedOption_new(upb_arena *arena) { - return (google_protobuf_UninterpretedOption *)upb_msg_new(&google_protobuf_UninterpretedOption_msginit, arena); + return (google_protobuf_UninterpretedOption *)_upb_msg_new(&google_protobuf_UninterpretedOption_msginit, arena); } UPB_INLINE google_protobuf_UninterpretedOption *google_protobuf_UninterpretedOption_parse(const char *buf, size_t size, upb_arena *arena) { @@ -2666,28 +2834,29 @@ UPB_INLINE char *google_protobuf_UninterpretedOption_serialize(const google_prot return upb_encode(msg, &google_protobuf_UninterpretedOption_msginit, arena, len); } +UPB_INLINE bool google_protobuf_UninterpretedOption_has_name(const google_protobuf_UninterpretedOption *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(56, 80)); } UPB_INLINE const google_protobuf_UninterpretedOption_NamePart* const* google_protobuf_UninterpretedOption_name(const google_protobuf_UninterpretedOption *msg, size_t *len) { return (const google_protobuf_UninterpretedOption_NamePart* const*)_upb_array_accessor(msg, UPB_SIZE(56, 80), len); } UPB_INLINE bool google_protobuf_UninterpretedOption_has_identifier_value(const google_protobuf_UninterpretedOption *msg) { return _upb_has_field(msg, 4); } -UPB_INLINE upb_strview google_protobuf_UninterpretedOption_identifier_value(const google_protobuf_UninterpretedOption *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(32, 32)); } +UPB_INLINE upb_strview google_protobuf_UninterpretedOption_identifier_value(const google_protobuf_UninterpretedOption *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(32, 32), upb_strview); } UPB_INLINE bool google_protobuf_UninterpretedOption_has_positive_int_value(const google_protobuf_UninterpretedOption *msg) { return _upb_has_field(msg, 1); } -UPB_INLINE uint64_t google_protobuf_UninterpretedOption_positive_int_value(const google_protobuf_UninterpretedOption *msg) { return UPB_FIELD_AT(msg, uint64_t, UPB_SIZE(8, 8)); } +UPB_INLINE uint64_t google_protobuf_UninterpretedOption_positive_int_value(const google_protobuf_UninterpretedOption *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 8), uint64_t); } UPB_INLINE bool google_protobuf_UninterpretedOption_has_negative_int_value(const google_protobuf_UninterpretedOption *msg) { return _upb_has_field(msg, 2); } -UPB_INLINE int64_t google_protobuf_UninterpretedOption_negative_int_value(const google_protobuf_UninterpretedOption *msg) { return UPB_FIELD_AT(msg, int64_t, UPB_SIZE(16, 16)); } +UPB_INLINE int64_t google_protobuf_UninterpretedOption_negative_int_value(const google_protobuf_UninterpretedOption *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(16, 16), int64_t); } UPB_INLINE bool google_protobuf_UninterpretedOption_has_double_value(const google_protobuf_UninterpretedOption *msg) { return _upb_has_field(msg, 3); } -UPB_INLINE double google_protobuf_UninterpretedOption_double_value(const google_protobuf_UninterpretedOption *msg) { return UPB_FIELD_AT(msg, double, UPB_SIZE(24, 24)); } +UPB_INLINE double google_protobuf_UninterpretedOption_double_value(const google_protobuf_UninterpretedOption *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(24, 24), double); } UPB_INLINE bool google_protobuf_UninterpretedOption_has_string_value(const google_protobuf_UninterpretedOption *msg) { return _upb_has_field(msg, 5); } -UPB_INLINE upb_strview google_protobuf_UninterpretedOption_string_value(const google_protobuf_UninterpretedOption *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(40, 48)); } +UPB_INLINE upb_strview google_protobuf_UninterpretedOption_string_value(const google_protobuf_UninterpretedOption *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(40, 48), upb_strview); } UPB_INLINE bool google_protobuf_UninterpretedOption_has_aggregate_value(const google_protobuf_UninterpretedOption *msg) { return _upb_has_field(msg, 6); } -UPB_INLINE upb_strview google_protobuf_UninterpretedOption_aggregate_value(const google_protobuf_UninterpretedOption *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(48, 64)); } +UPB_INLINE upb_strview google_protobuf_UninterpretedOption_aggregate_value(const google_protobuf_UninterpretedOption *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(48, 64), upb_strview); } UPB_INLINE google_protobuf_UninterpretedOption_NamePart** google_protobuf_UninterpretedOption_mutable_name(google_protobuf_UninterpretedOption *msg, size_t *len) { return (google_protobuf_UninterpretedOption_NamePart**)_upb_array_mutable_accessor(msg, UPB_SIZE(56, 80), len); } UPB_INLINE google_protobuf_UninterpretedOption_NamePart** google_protobuf_UninterpretedOption_resize_name(google_protobuf_UninterpretedOption *msg, size_t len, upb_arena *arena) { - return (google_protobuf_UninterpretedOption_NamePart**)_upb_array_resize_accessor(msg, UPB_SIZE(56, 80), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena); + return (google_protobuf_UninterpretedOption_NamePart**)_upb_array_resize_accessor(msg, UPB_SIZE(56, 80), len, UPB_TYPE_MESSAGE, arena); } UPB_INLINE struct google_protobuf_UninterpretedOption_NamePart* google_protobuf_UninterpretedOption_add_name(google_protobuf_UninterpretedOption *msg, upb_arena *arena) { - struct google_protobuf_UninterpretedOption_NamePart* sub = (struct google_protobuf_UninterpretedOption_NamePart*)upb_msg_new(&google_protobuf_UninterpretedOption_NamePart_msginit, arena); + struct google_protobuf_UninterpretedOption_NamePart* sub = (struct google_protobuf_UninterpretedOption_NamePart*)_upb_msg_new(&google_protobuf_UninterpretedOption_NamePart_msginit, arena); bool ok = _upb_array_append_accessor( msg, UPB_SIZE(56, 80), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); if (!ok) return NULL; @@ -2695,33 +2864,33 @@ UPB_INLINE struct google_protobuf_UninterpretedOption_NamePart* google_protobuf_ } UPB_INLINE void google_protobuf_UninterpretedOption_set_identifier_value(google_protobuf_UninterpretedOption *msg, upb_strview value) { _upb_sethas(msg, 4); - UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(32, 32)) = value; + *UPB_PTR_AT(msg, UPB_SIZE(32, 32), upb_strview) = value; } UPB_INLINE void google_protobuf_UninterpretedOption_set_positive_int_value(google_protobuf_UninterpretedOption *msg, uint64_t value) { _upb_sethas(msg, 1); - UPB_FIELD_AT(msg, uint64_t, UPB_SIZE(8, 8)) = value; + *UPB_PTR_AT(msg, UPB_SIZE(8, 8), uint64_t) = value; } UPB_INLINE void google_protobuf_UninterpretedOption_set_negative_int_value(google_protobuf_UninterpretedOption *msg, int64_t value) { _upb_sethas(msg, 2); - UPB_FIELD_AT(msg, int64_t, UPB_SIZE(16, 16)) = value; + *UPB_PTR_AT(msg, UPB_SIZE(16, 16), int64_t) = value; } UPB_INLINE void google_protobuf_UninterpretedOption_set_double_value(google_protobuf_UninterpretedOption *msg, double value) { _upb_sethas(msg, 3); - UPB_FIELD_AT(msg, double, UPB_SIZE(24, 24)) = value; + *UPB_PTR_AT(msg, UPB_SIZE(24, 24), double) = value; } UPB_INLINE void google_protobuf_UninterpretedOption_set_string_value(google_protobuf_UninterpretedOption *msg, upb_strview value) { _upb_sethas(msg, 5); - UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(40, 48)) = value; + *UPB_PTR_AT(msg, UPB_SIZE(40, 48), upb_strview) = value; } UPB_INLINE void google_protobuf_UninterpretedOption_set_aggregate_value(google_protobuf_UninterpretedOption *msg, upb_strview value) { _upb_sethas(msg, 6); - UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(48, 64)) = value; + *UPB_PTR_AT(msg, UPB_SIZE(48, 64), upb_strview) = value; } /* google.protobuf.UninterpretedOption.NamePart */ UPB_INLINE google_protobuf_UninterpretedOption_NamePart *google_protobuf_UninterpretedOption_NamePart_new(upb_arena *arena) { - return (google_protobuf_UninterpretedOption_NamePart *)upb_msg_new(&google_protobuf_UninterpretedOption_NamePart_msginit, arena); + return (google_protobuf_UninterpretedOption_NamePart *)_upb_msg_new(&google_protobuf_UninterpretedOption_NamePart_msginit, arena); } UPB_INLINE google_protobuf_UninterpretedOption_NamePart *google_protobuf_UninterpretedOption_NamePart_parse(const char *buf, size_t size, upb_arena *arena) { @@ -2733,23 +2902,23 @@ UPB_INLINE char *google_protobuf_UninterpretedOption_NamePart_serialize(const go } UPB_INLINE bool google_protobuf_UninterpretedOption_NamePart_has_name_part(const google_protobuf_UninterpretedOption_NamePart *msg) { return _upb_has_field(msg, 2); } -UPB_INLINE upb_strview google_protobuf_UninterpretedOption_NamePart_name_part(const google_protobuf_UninterpretedOption_NamePart *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(4, 8)); } +UPB_INLINE upb_strview google_protobuf_UninterpretedOption_NamePart_name_part(const google_protobuf_UninterpretedOption_NamePart *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview); } UPB_INLINE bool google_protobuf_UninterpretedOption_NamePart_has_is_extension(const google_protobuf_UninterpretedOption_NamePart *msg) { return _upb_has_field(msg, 1); } -UPB_INLINE bool google_protobuf_UninterpretedOption_NamePart_is_extension(const google_protobuf_UninterpretedOption_NamePart *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(1, 1)); } +UPB_INLINE bool google_protobuf_UninterpretedOption_NamePart_is_extension(const google_protobuf_UninterpretedOption_NamePart *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(1, 1), bool); } UPB_INLINE void google_protobuf_UninterpretedOption_NamePart_set_name_part(google_protobuf_UninterpretedOption_NamePart *msg, upb_strview value) { _upb_sethas(msg, 2); - UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(4, 8)) = value; + *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview) = value; } UPB_INLINE void google_protobuf_UninterpretedOption_NamePart_set_is_extension(google_protobuf_UninterpretedOption_NamePart *msg, bool value) { _upb_sethas(msg, 1); - UPB_FIELD_AT(msg, bool, UPB_SIZE(1, 1)) = value; + *UPB_PTR_AT(msg, UPB_SIZE(1, 1), bool) = value; } /* google.protobuf.SourceCodeInfo */ UPB_INLINE google_protobuf_SourceCodeInfo *google_protobuf_SourceCodeInfo_new(upb_arena *arena) { - return (google_protobuf_SourceCodeInfo *)upb_msg_new(&google_protobuf_SourceCodeInfo_msginit, arena); + return (google_protobuf_SourceCodeInfo *)_upb_msg_new(&google_protobuf_SourceCodeInfo_msginit, arena); } UPB_INLINE google_protobuf_SourceCodeInfo *google_protobuf_SourceCodeInfo_parse(const char *buf, size_t size, upb_arena *arena) { @@ -2760,16 +2929,17 @@ UPB_INLINE char *google_protobuf_SourceCodeInfo_serialize(const google_protobuf_ return upb_encode(msg, &google_protobuf_SourceCodeInfo_msginit, arena, len); } +UPB_INLINE bool google_protobuf_SourceCodeInfo_has_location(const google_protobuf_SourceCodeInfo *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(0, 0)); } UPB_INLINE const google_protobuf_SourceCodeInfo_Location* const* google_protobuf_SourceCodeInfo_location(const google_protobuf_SourceCodeInfo *msg, size_t *len) { return (const google_protobuf_SourceCodeInfo_Location* const*)_upb_array_accessor(msg, UPB_SIZE(0, 0), len); } UPB_INLINE google_protobuf_SourceCodeInfo_Location** google_protobuf_SourceCodeInfo_mutable_location(google_protobuf_SourceCodeInfo *msg, size_t *len) { return (google_protobuf_SourceCodeInfo_Location**)_upb_array_mutable_accessor(msg, UPB_SIZE(0, 0), len); } UPB_INLINE google_protobuf_SourceCodeInfo_Location** google_protobuf_SourceCodeInfo_resize_location(google_protobuf_SourceCodeInfo *msg, size_t len, upb_arena *arena) { - return (google_protobuf_SourceCodeInfo_Location**)_upb_array_resize_accessor(msg, UPB_SIZE(0, 0), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena); + return (google_protobuf_SourceCodeInfo_Location**)_upb_array_resize_accessor(msg, UPB_SIZE(0, 0), len, UPB_TYPE_MESSAGE, arena); } UPB_INLINE struct google_protobuf_SourceCodeInfo_Location* google_protobuf_SourceCodeInfo_add_location(google_protobuf_SourceCodeInfo *msg, upb_arena *arena) { - struct google_protobuf_SourceCodeInfo_Location* sub = (struct google_protobuf_SourceCodeInfo_Location*)upb_msg_new(&google_protobuf_SourceCodeInfo_Location_msginit, arena); + struct google_protobuf_SourceCodeInfo_Location* sub = (struct google_protobuf_SourceCodeInfo_Location*)_upb_msg_new(&google_protobuf_SourceCodeInfo_Location_msginit, arena); bool ok = _upb_array_append_accessor( msg, UPB_SIZE(0, 0), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); if (!ok) return NULL; @@ -2779,7 +2949,7 @@ UPB_INLINE struct google_protobuf_SourceCodeInfo_Location* google_protobuf_Sourc /* google.protobuf.SourceCodeInfo.Location */ UPB_INLINE google_protobuf_SourceCodeInfo_Location *google_protobuf_SourceCodeInfo_Location_new(upb_arena *arena) { - return (google_protobuf_SourceCodeInfo_Location *)upb_msg_new(&google_protobuf_SourceCodeInfo_Location_msginit, arena); + return (google_protobuf_SourceCodeInfo_Location *)_upb_msg_new(&google_protobuf_SourceCodeInfo_Location_msginit, arena); } UPB_INLINE google_protobuf_SourceCodeInfo_Location *google_protobuf_SourceCodeInfo_Location_parse(const char *buf, size_t size, upb_arena *arena) { @@ -2793,54 +2963,54 @@ UPB_INLINE char *google_protobuf_SourceCodeInfo_Location_serialize(const google_ UPB_INLINE int32_t const* google_protobuf_SourceCodeInfo_Location_path(const google_protobuf_SourceCodeInfo_Location *msg, size_t *len) { return (int32_t const*)_upb_array_accessor(msg, UPB_SIZE(20, 40), len); } UPB_INLINE int32_t const* google_protobuf_SourceCodeInfo_Location_span(const google_protobuf_SourceCodeInfo_Location *msg, size_t *len) { return (int32_t const*)_upb_array_accessor(msg, UPB_SIZE(24, 48), len); } UPB_INLINE bool google_protobuf_SourceCodeInfo_Location_has_leading_comments(const google_protobuf_SourceCodeInfo_Location *msg) { return _upb_has_field(msg, 1); } -UPB_INLINE upb_strview google_protobuf_SourceCodeInfo_Location_leading_comments(const google_protobuf_SourceCodeInfo_Location *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(4, 8)); } +UPB_INLINE upb_strview google_protobuf_SourceCodeInfo_Location_leading_comments(const google_protobuf_SourceCodeInfo_Location *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview); } UPB_INLINE bool google_protobuf_SourceCodeInfo_Location_has_trailing_comments(const google_protobuf_SourceCodeInfo_Location *msg) { return _upb_has_field(msg, 2); } -UPB_INLINE upb_strview google_protobuf_SourceCodeInfo_Location_trailing_comments(const google_protobuf_SourceCodeInfo_Location *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(12, 24)); } +UPB_INLINE upb_strview google_protobuf_SourceCodeInfo_Location_trailing_comments(const google_protobuf_SourceCodeInfo_Location *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(12, 24), upb_strview); } UPB_INLINE upb_strview const* google_protobuf_SourceCodeInfo_Location_leading_detached_comments(const google_protobuf_SourceCodeInfo_Location *msg, size_t *len) { return (upb_strview const*)_upb_array_accessor(msg, UPB_SIZE(28, 56), len); } UPB_INLINE int32_t* google_protobuf_SourceCodeInfo_Location_mutable_path(google_protobuf_SourceCodeInfo_Location *msg, size_t *len) { return (int32_t*)_upb_array_mutable_accessor(msg, UPB_SIZE(20, 40), len); } UPB_INLINE int32_t* google_protobuf_SourceCodeInfo_Location_resize_path(google_protobuf_SourceCodeInfo_Location *msg, size_t len, upb_arena *arena) { - return (int32_t*)_upb_array_resize_accessor(msg, UPB_SIZE(20, 40), len, UPB_SIZE(4, 4), UPB_TYPE_INT32, arena); + return (int32_t*)_upb_array_resize_accessor(msg, UPB_SIZE(20, 40), len, UPB_TYPE_INT32, arena); } UPB_INLINE bool google_protobuf_SourceCodeInfo_Location_add_path(google_protobuf_SourceCodeInfo_Location *msg, int32_t val, upb_arena *arena) { - return _upb_array_append_accessor( - msg, UPB_SIZE(20, 40), UPB_SIZE(4, 4), UPB_TYPE_INT32, &val, arena); + return _upb_array_append_accessor(msg, UPB_SIZE(20, 40), UPB_SIZE(4, 4), UPB_TYPE_INT32, &val, + arena); } UPB_INLINE int32_t* google_protobuf_SourceCodeInfo_Location_mutable_span(google_protobuf_SourceCodeInfo_Location *msg, size_t *len) { return (int32_t*)_upb_array_mutable_accessor(msg, UPB_SIZE(24, 48), len); } UPB_INLINE int32_t* google_protobuf_SourceCodeInfo_Location_resize_span(google_protobuf_SourceCodeInfo_Location *msg, size_t len, upb_arena *arena) { - return (int32_t*)_upb_array_resize_accessor(msg, UPB_SIZE(24, 48), len, UPB_SIZE(4, 4), UPB_TYPE_INT32, arena); + return (int32_t*)_upb_array_resize_accessor(msg, UPB_SIZE(24, 48), len, UPB_TYPE_INT32, arena); } UPB_INLINE bool google_protobuf_SourceCodeInfo_Location_add_span(google_protobuf_SourceCodeInfo_Location *msg, int32_t val, upb_arena *arena) { - return _upb_array_append_accessor( - msg, UPB_SIZE(24, 48), UPB_SIZE(4, 4), UPB_TYPE_INT32, &val, arena); + return _upb_array_append_accessor(msg, UPB_SIZE(24, 48), UPB_SIZE(4, 4), UPB_TYPE_INT32, &val, + arena); } UPB_INLINE void google_protobuf_SourceCodeInfo_Location_set_leading_comments(google_protobuf_SourceCodeInfo_Location *msg, upb_strview value) { _upb_sethas(msg, 1); - UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(4, 8)) = value; + *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview) = value; } UPB_INLINE void google_protobuf_SourceCodeInfo_Location_set_trailing_comments(google_protobuf_SourceCodeInfo_Location *msg, upb_strview value) { _upb_sethas(msg, 2); - UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(12, 24)) = value; + *UPB_PTR_AT(msg, UPB_SIZE(12, 24), upb_strview) = value; } UPB_INLINE upb_strview* google_protobuf_SourceCodeInfo_Location_mutable_leading_detached_comments(google_protobuf_SourceCodeInfo_Location *msg, size_t *len) { return (upb_strview*)_upb_array_mutable_accessor(msg, UPB_SIZE(28, 56), len); } UPB_INLINE upb_strview* google_protobuf_SourceCodeInfo_Location_resize_leading_detached_comments(google_protobuf_SourceCodeInfo_Location *msg, size_t len, upb_arena *arena) { - return (upb_strview*)_upb_array_resize_accessor(msg, UPB_SIZE(28, 56), len, UPB_SIZE(8, 16), UPB_TYPE_STRING, arena); + return (upb_strview*)_upb_array_resize_accessor(msg, UPB_SIZE(28, 56), len, UPB_TYPE_STRING, arena); } UPB_INLINE bool google_protobuf_SourceCodeInfo_Location_add_leading_detached_comments(google_protobuf_SourceCodeInfo_Location *msg, upb_strview val, upb_arena *arena) { - return _upb_array_append_accessor( - msg, UPB_SIZE(28, 56), UPB_SIZE(8, 16), UPB_TYPE_STRING, &val, arena); + return _upb_array_append_accessor(msg, UPB_SIZE(28, 56), UPB_SIZE(8, 16), UPB_TYPE_STRING, &val, + arena); } /* google.protobuf.GeneratedCodeInfo */ UPB_INLINE google_protobuf_GeneratedCodeInfo *google_protobuf_GeneratedCodeInfo_new(upb_arena *arena) { - return (google_protobuf_GeneratedCodeInfo *)upb_msg_new(&google_protobuf_GeneratedCodeInfo_msginit, arena); + return (google_protobuf_GeneratedCodeInfo *)_upb_msg_new(&google_protobuf_GeneratedCodeInfo_msginit, arena); } UPB_INLINE google_protobuf_GeneratedCodeInfo *google_protobuf_GeneratedCodeInfo_parse(const char *buf, size_t size, upb_arena *arena) { @@ -2851,16 +3021,17 @@ UPB_INLINE char *google_protobuf_GeneratedCodeInfo_serialize(const google_protob return upb_encode(msg, &google_protobuf_GeneratedCodeInfo_msginit, arena, len); } +UPB_INLINE bool google_protobuf_GeneratedCodeInfo_has_annotation(const google_protobuf_GeneratedCodeInfo *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(0, 0)); } UPB_INLINE const google_protobuf_GeneratedCodeInfo_Annotation* const* google_protobuf_GeneratedCodeInfo_annotation(const google_protobuf_GeneratedCodeInfo *msg, size_t *len) { return (const google_protobuf_GeneratedCodeInfo_Annotation* const*)_upb_array_accessor(msg, UPB_SIZE(0, 0), len); } UPB_INLINE google_protobuf_GeneratedCodeInfo_Annotation** google_protobuf_GeneratedCodeInfo_mutable_annotation(google_protobuf_GeneratedCodeInfo *msg, size_t *len) { return (google_protobuf_GeneratedCodeInfo_Annotation**)_upb_array_mutable_accessor(msg, UPB_SIZE(0, 0), len); } UPB_INLINE google_protobuf_GeneratedCodeInfo_Annotation** google_protobuf_GeneratedCodeInfo_resize_annotation(google_protobuf_GeneratedCodeInfo *msg, size_t len, upb_arena *arena) { - return (google_protobuf_GeneratedCodeInfo_Annotation**)_upb_array_resize_accessor(msg, UPB_SIZE(0, 0), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena); + return (google_protobuf_GeneratedCodeInfo_Annotation**)_upb_array_resize_accessor(msg, UPB_SIZE(0, 0), len, UPB_TYPE_MESSAGE, arena); } UPB_INLINE struct google_protobuf_GeneratedCodeInfo_Annotation* google_protobuf_GeneratedCodeInfo_add_annotation(google_protobuf_GeneratedCodeInfo *msg, upb_arena *arena) { - struct google_protobuf_GeneratedCodeInfo_Annotation* sub = (struct google_protobuf_GeneratedCodeInfo_Annotation*)upb_msg_new(&google_protobuf_GeneratedCodeInfo_Annotation_msginit, arena); + struct google_protobuf_GeneratedCodeInfo_Annotation* sub = (struct google_protobuf_GeneratedCodeInfo_Annotation*)_upb_msg_new(&google_protobuf_GeneratedCodeInfo_Annotation_msginit, arena); bool ok = _upb_array_append_accessor( msg, UPB_SIZE(0, 0), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); if (!ok) return NULL; @@ -2870,7 +3041,7 @@ UPB_INLINE struct google_protobuf_GeneratedCodeInfo_Annotation* google_protobuf_ /* google.protobuf.GeneratedCodeInfo.Annotation */ UPB_INLINE google_protobuf_GeneratedCodeInfo_Annotation *google_protobuf_GeneratedCodeInfo_Annotation_new(upb_arena *arena) { - return (google_protobuf_GeneratedCodeInfo_Annotation *)upb_msg_new(&google_protobuf_GeneratedCodeInfo_Annotation_msginit, arena); + return (google_protobuf_GeneratedCodeInfo_Annotation *)_upb_msg_new(&google_protobuf_GeneratedCodeInfo_Annotation_msginit, arena); } UPB_INLINE google_protobuf_GeneratedCodeInfo_Annotation *google_protobuf_GeneratedCodeInfo_Annotation_parse(const char *buf, size_t size, upb_arena *arena) { @@ -2883,33 +3054,33 @@ UPB_INLINE char *google_protobuf_GeneratedCodeInfo_Annotation_serialize(const go UPB_INLINE int32_t const* google_protobuf_GeneratedCodeInfo_Annotation_path(const google_protobuf_GeneratedCodeInfo_Annotation *msg, size_t *len) { return (int32_t const*)_upb_array_accessor(msg, UPB_SIZE(20, 32), len); } UPB_INLINE bool google_protobuf_GeneratedCodeInfo_Annotation_has_source_file(const google_protobuf_GeneratedCodeInfo_Annotation *msg) { return _upb_has_field(msg, 3); } -UPB_INLINE upb_strview google_protobuf_GeneratedCodeInfo_Annotation_source_file(const google_protobuf_GeneratedCodeInfo_Annotation *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(12, 16)); } +UPB_INLINE upb_strview google_protobuf_GeneratedCodeInfo_Annotation_source_file(const google_protobuf_GeneratedCodeInfo_Annotation *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(12, 16), upb_strview); } UPB_INLINE bool google_protobuf_GeneratedCodeInfo_Annotation_has_begin(const google_protobuf_GeneratedCodeInfo_Annotation *msg) { return _upb_has_field(msg, 1); } -UPB_INLINE int32_t google_protobuf_GeneratedCodeInfo_Annotation_begin(const google_protobuf_GeneratedCodeInfo_Annotation *msg) { return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(4, 4)); } +UPB_INLINE int32_t google_protobuf_GeneratedCodeInfo_Annotation_begin(const google_protobuf_GeneratedCodeInfo_Annotation *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 4), int32_t); } UPB_INLINE bool google_protobuf_GeneratedCodeInfo_Annotation_has_end(const google_protobuf_GeneratedCodeInfo_Annotation *msg) { return _upb_has_field(msg, 2); } -UPB_INLINE int32_t google_protobuf_GeneratedCodeInfo_Annotation_end(const google_protobuf_GeneratedCodeInfo_Annotation *msg) { return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(8, 8)); } +UPB_INLINE int32_t google_protobuf_GeneratedCodeInfo_Annotation_end(const google_protobuf_GeneratedCodeInfo_Annotation *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 8), int32_t); } UPB_INLINE int32_t* google_protobuf_GeneratedCodeInfo_Annotation_mutable_path(google_protobuf_GeneratedCodeInfo_Annotation *msg, size_t *len) { return (int32_t*)_upb_array_mutable_accessor(msg, UPB_SIZE(20, 32), len); } UPB_INLINE int32_t* google_protobuf_GeneratedCodeInfo_Annotation_resize_path(google_protobuf_GeneratedCodeInfo_Annotation *msg, size_t len, upb_arena *arena) { - return (int32_t*)_upb_array_resize_accessor(msg, UPB_SIZE(20, 32), len, UPB_SIZE(4, 4), UPB_TYPE_INT32, arena); + return (int32_t*)_upb_array_resize_accessor(msg, UPB_SIZE(20, 32), len, UPB_TYPE_INT32, arena); } UPB_INLINE bool google_protobuf_GeneratedCodeInfo_Annotation_add_path(google_protobuf_GeneratedCodeInfo_Annotation *msg, int32_t val, upb_arena *arena) { - return _upb_array_append_accessor( - msg, UPB_SIZE(20, 32), UPB_SIZE(4, 4), UPB_TYPE_INT32, &val, arena); + return _upb_array_append_accessor(msg, UPB_SIZE(20, 32), UPB_SIZE(4, 4), UPB_TYPE_INT32, &val, + arena); } UPB_INLINE void google_protobuf_GeneratedCodeInfo_Annotation_set_source_file(google_protobuf_GeneratedCodeInfo_Annotation *msg, upb_strview value) { _upb_sethas(msg, 3); - UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(12, 16)) = value; + *UPB_PTR_AT(msg, UPB_SIZE(12, 16), upb_strview) = value; } UPB_INLINE void google_protobuf_GeneratedCodeInfo_Annotation_set_begin(google_protobuf_GeneratedCodeInfo_Annotation *msg, int32_t value) { _upb_sethas(msg, 1); - UPB_FIELD_AT(msg, int32_t, UPB_SIZE(4, 4)) = value; + *UPB_PTR_AT(msg, UPB_SIZE(4, 4), int32_t) = value; } UPB_INLINE void google_protobuf_GeneratedCodeInfo_Annotation_set_end(google_protobuf_GeneratedCodeInfo_Annotation *msg, int32_t value) { _upb_sethas(msg, 2); - UPB_FIELD_AT(msg, int32_t, UPB_SIZE(8, 8)) = value; + *UPB_PTR_AT(msg, UPB_SIZE(8, 8), int32_t) = value; } #ifdef __cplusplus @@ -2922,38 +3093,23 @@ UPB_INLINE void google_protobuf_GeneratedCodeInfo_Annotation_set_end(google_prot ** Defs are upb's internal representation of the constructs that can appear ** in a .proto file: ** -** - upb::MessageDefPtr (upb_msgdef): describes a "message" construct. -** - upb::FieldDefPtr (upb_fielddef): describes a message field. -** - upb::FileDefPtr (upb_filedef): describes a .proto file and its defs. -** - upb::EnumDefPtr (upb_enumdef): describes an enum. -** - upb::OneofDefPtr (upb_oneofdef): describes a oneof. +** - upb_msgdef: describes a "message" construct. +** - upb_fielddef: describes a message field. +** - upb_filedef: describes a .proto file and its defs. +** - upb_enumdef: describes an enum. +** - upb_oneofdef: describes a oneof. ** ** TODO: definitions of services. -** -** 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_ -#ifdef __cplusplus -#include -#include -#include -#include - -namespace upb { -class EnumDefPtr; -class FieldDefPtr; -class FileDefPtr; -class MessageDefPtr; -class OneofDefPtr; -class SymbolTable; -} -#endif +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ struct upb_enumdef; typedef struct upb_enumdef upb_enumdef; @@ -3005,22 +3161,20 @@ typedef enum { * protobuf wire format. */ #define UPB_MAX_FIELDNUMBER ((1 << 29) - 1) -#ifdef __cplusplus -extern "C" { -#endif - const char *upb_fielddef_fullname(const upb_fielddef *f); upb_fieldtype_t upb_fielddef_type(const upb_fielddef *f); upb_descriptortype_t upb_fielddef_descriptortype(const upb_fielddef *f); upb_label_t upb_fielddef_label(const upb_fielddef *f); uint32_t upb_fielddef_number(const upb_fielddef *f); const char *upb_fielddef_name(const upb_fielddef *f); +const char *upb_fielddef_jsonname(const upb_fielddef *f); bool upb_fielddef_isextension(const upb_fielddef *f); bool upb_fielddef_lazy(const upb_fielddef *f); bool upb_fielddef_packed(const upb_fielddef *f); -size_t upb_fielddef_getjsonname(const upb_fielddef *f, char *buf, size_t len); +const upb_filedef *upb_fielddef_file(const upb_fielddef *f); const upb_msgdef *upb_fielddef_containingtype(const upb_fielddef *f); const upb_oneofdef *upb_fielddef_containingoneof(const upb_fielddef *f); +const upb_oneofdef *upb_fielddef_realcontainingoneof(const upb_fielddef *f); uint32_t upb_fielddef_index(const upb_fielddef *f); bool upb_fielddef_issubmsg(const upb_fielddef *f); bool upb_fielddef_isstring(const upb_fielddef *f); @@ -3039,155 +3193,20 @@ bool upb_fielddef_hassubdef(const upb_fielddef *f); bool upb_fielddef_haspresence(const upb_fielddef *f); const upb_msgdef *upb_fielddef_msgsubdef(const upb_fielddef *f); const upb_enumdef *upb_fielddef_enumsubdef(const upb_fielddef *f); +const upb_msglayout_field *upb_fielddef_layout(const upb_fielddef *f); /* Internal only. */ uint32_t upb_fielddef_selectorbase(const upb_fielddef *f); -#ifdef __cplusplus -} /* extern "C" */ - -/* A upb_fielddef describes a single field in a message. It is most often - * found as a part of a upb_msgdef, but can also stand alone to represent - * an extension. */ -class upb::FieldDefPtr { - public: - FieldDefPtr() : ptr_(nullptr) {} - explicit FieldDefPtr(const upb_fielddef *ptr) : ptr_(ptr) {} - - const upb_fielddef* ptr() const { return ptr_; } - explicit operator bool() const { return ptr_ != nullptr; } - - typedef upb_fieldtype_t Type; - typedef upb_label_t Label; - typedef upb_descriptortype_t DescriptorType; - - const char* full_name() const { return upb_fielddef_fullname(ptr_); } - - Type type() const { return upb_fielddef_type(ptr_); } - Label label() const { return upb_fielddef_label(ptr_); } - const char* name() const { return upb_fielddef_name(ptr_); } - uint32_t number() const { return upb_fielddef_number(ptr_); } - bool is_extension() const { return upb_fielddef_isextension(ptr_); } - - /* Copies the JSON name for this field into the given buffer. Returns the - * actual size of the JSON name, including the NULL terminator. If the - * return value is 0, the JSON name is unset. If the return value is - * greater than len, the JSON name was truncated. The buffer is always - * NULL-terminated if len > 0. - * - * The JSON name always defaults to a camelCased version of the regular - * name. However if the regular name is unset, the JSON name will be unset - * also. - */ - size_t GetJsonName(char *buf, size_t len) const { - return upb_fielddef_getjsonname(ptr_, buf, len); - } - - /* Convenience version of the above function which copies the JSON name - * into the given string, returning false if the name is not set. */ - template - bool GetJsonName(T* str) { - str->resize(GetJsonName(NULL, 0)); - GetJsonName(&(*str)[0], str->size()); - return str->size() > 0; - } - - /* For UPB_TYPE_MESSAGE fields only where is_tag_delimited() == false, - * indicates whether this field should have lazy parsing handlers that yield - * the unparsed string for the submessage. - * - * TODO(haberman): I think we want to move this into a FieldOptions container - * when we add support for custom options (the FieldOptions struct will - * contain both regular FieldOptions like "lazy" *and* custom options). */ - bool lazy() const { return upb_fielddef_lazy(ptr_); } - - /* For non-string, non-submessage fields, this indicates whether binary - * protobufs are encoded in packed or non-packed format. - * - * TODO(haberman): see note above about putting options like this into a - * FieldOptions container. */ - bool packed() const { return upb_fielddef_packed(ptr_); } - - /* An integer that can be used as an index into an array of fields for - * whatever message this field belongs to. Guaranteed to be less than - * f->containing_type()->field_count(). May only be accessed once the def has - * been finalized. */ - uint32_t index() const { return upb_fielddef_index(ptr_); } - - /* The MessageDef to which this field belongs. - * - * If this field has been added to a MessageDef, that message can be retrieved - * directly (this is always the case for frozen FieldDefs). - * - * If the field has not yet been added to a MessageDef, you can set the name - * of the containing type symbolically instead. This is mostly useful for - * extensions, where the extension is declared separately from the message. */ - MessageDefPtr containing_type() const; - - /* The OneofDef to which this field belongs, or NULL if this field is not part - * of a oneof. */ - OneofDefPtr containing_oneof() const; - - /* The field's type according to the enum in descriptor.proto. This is not - * the same as UPB_TYPE_*, because it distinguishes between (for example) - * INT32 and SINT32, whereas our "type" enum does not. This return of - * descriptor_type() is a function of type(), integer_format(), and - * is_tag_delimited(). */ - DescriptorType descriptor_type() const { - return upb_fielddef_descriptortype(ptr_); - } - - /* Convenient field type tests. */ - bool IsSubMessage() const { return upb_fielddef_issubmsg(ptr_); } - bool IsString() const { return upb_fielddef_isstring(ptr_); } - bool IsSequence() const { return upb_fielddef_isseq(ptr_); } - bool IsPrimitive() const { return upb_fielddef_isprimitive(ptr_); } - bool IsMap() const { return upb_fielddef_ismap(ptr_); } - - /* Returns the non-string default value for this fielddef, which may either - * be something the client set explicitly or the "default default" (0 for - * numbers, empty for strings). The field's type indicates the type of the - * returned value, except for enum fields that are still mutable. - * - * Requires that the given function matches the field's current type. */ - int64_t default_int64() const { return upb_fielddef_defaultint64(ptr_); } - int32_t default_int32() const { return upb_fielddef_defaultint32(ptr_); } - uint64_t default_uint64() const { return upb_fielddef_defaultuint64(ptr_); } - uint32_t default_uint32() const { return upb_fielddef_defaultuint32(ptr_); } - bool default_bool() const { return upb_fielddef_defaultbool(ptr_); } - float default_float() const { return upb_fielddef_defaultfloat(ptr_); } - double default_double() const { return upb_fielddef_defaultdouble(ptr_); } - - /* The resulting string is always NULL-terminated. If non-NULL, the length - * will be stored in *len. */ - const char *default_string(size_t * len) const { - return upb_fielddef_defaultstr(ptr_, len); - } - - /* Returns the enum or submessage def for this field, if any. The field's - * type must match (ie. you may only call enum_subdef() for fields where - * type() == UPB_TYPE_ENUM). */ - EnumDefPtr enum_subdef() const; - MessageDefPtr message_subdef() const; - - private: - const upb_fielddef *ptr_; -}; - -#endif /* __cplusplus */ - /* upb_oneofdef ***************************************************************/ -#ifdef __cplusplus -extern "C" { -#endif - typedef upb_inttable_iter upb_oneof_iter; const char *upb_oneofdef_name(const upb_oneofdef *o); const upb_msgdef *upb_oneofdef_containingtype(const upb_oneofdef *o); int upb_oneofdef_numfields(const upb_oneofdef *o); uint32_t upb_oneofdef_index(const upb_oneofdef *o); +bool upb_oneofdef_issynthetic(const upb_oneofdef *o); /* Oneof lookups: * - ntof: look up a field by name. @@ -3214,92 +3233,6 @@ void upb_oneof_iter_setdone(upb_oneof_iter *iter); bool upb_oneof_iter_isequal(const upb_oneof_iter *iter1, const upb_oneof_iter *iter2); -#ifdef __cplusplus -} /* extern "C" */ - -/* Class that represents a oneof. */ -class upb::OneofDefPtr { - public: - OneofDefPtr() : ptr_(nullptr) {} - explicit OneofDefPtr(const upb_oneofdef *ptr) : ptr_(ptr) {} - - const upb_oneofdef* ptr() const { return ptr_; } - explicit operator bool() { return ptr_ != nullptr; } - - /* Returns the MessageDef that owns this OneofDef. */ - MessageDefPtr containing_type() const; - - /* Returns the name of this oneof. This is the name used to look up the oneof - * by name once added to a message def. */ - const char* name() const { return upb_oneofdef_name(ptr_); } - - /* Returns the number of fields currently defined in the oneof. */ - int field_count() const { return upb_oneofdef_numfields(ptr_); } - - /* Looks up by name. */ - FieldDefPtr FindFieldByName(const char *name, size_t len) const { - return FieldDefPtr(upb_oneofdef_ntof(ptr_, name, len)); - } - FieldDefPtr FindFieldByName(const char* name) const { - return FieldDefPtr(upb_oneofdef_ntofz(ptr_, name)); - } - - template - FieldDefPtr FindFieldByName(const T& str) const { - return FindFieldByName(str.c_str(), str.size()); - } - - /* Looks up by tag number. */ - FieldDefPtr FindFieldByNumber(uint32_t num) const { - return FieldDefPtr(upb_oneofdef_itof(ptr_, num)); - } - - class const_iterator - : public std::iterator { - public: - void operator++() { upb_oneof_next(&iter_); } - - FieldDefPtr operator*() const { - return FieldDefPtr(upb_oneof_iter_field(&iter_)); - } - - bool operator!=(const const_iterator& other) const { - return !upb_oneof_iter_isequal(&iter_, &other.iter_); - } - - bool operator==(const const_iterator& other) const { - return upb_oneof_iter_isequal(&iter_, &other.iter_); - } - - private: - friend class OneofDefPtr; - - const_iterator() {} - explicit const_iterator(OneofDefPtr o) { - upb_oneof_begin(&iter_, o.ptr()); - } - static const_iterator end() { - const_iterator iter; - upb_oneof_iter_setdone(&iter.iter_); - return iter; - } - - upb_oneof_iter iter_; - }; - - const_iterator begin() const { return const_iterator(*this); } - const_iterator end() const { return const_iterator::end(); } - - private: - const upb_oneofdef *ptr_; -}; - -inline upb::OneofDefPtr upb::FieldDefPtr::containing_oneof() const { - return OneofDefPtr(upb_fielddef_containingoneof(ptr_)); -} - -#endif /* __cplusplus */ - /* upb_msgdef *****************************************************************/ typedef upb_inttable_iter upb_msg_field_iter; @@ -3321,26 +3254,23 @@ typedef upb_strtable_iter upb_msg_oneof_iter; #define UPB_TIMESTAMP_SECONDS 1 #define UPB_TIMESTAMP_NANOS 2 -#ifdef __cplusplus -extern "C" { -#endif - const char *upb_msgdef_fullname(const upb_msgdef *m); const upb_filedef *upb_msgdef_file(const upb_msgdef *m); const char *upb_msgdef_name(const upb_msgdef *m); +int upb_msgdef_numfields(const upb_msgdef *m); int upb_msgdef_numoneofs(const upb_msgdef *m); +int upb_msgdef_numrealoneofs(const upb_msgdef *m); upb_syntax_t upb_msgdef_syntax(const upb_msgdef *m); bool upb_msgdef_mapentry(const upb_msgdef *m); upb_wellknowntype_t upb_msgdef_wellknowntype(const upb_msgdef *m); bool upb_msgdef_isnumberwrapper(const upb_msgdef *m); -bool upb_msgdef_setsyntax(upb_msgdef *m, upb_syntax_t syntax); const upb_fielddef *upb_msgdef_itof(const upb_msgdef *m, uint32_t i); const upb_fielddef *upb_msgdef_ntof(const upb_msgdef *m, const char *name, size_t len); const upb_oneofdef *upb_msgdef_ntoo(const upb_msgdef *m, const char *name, size_t len); -int upb_msgdef_numfields(const upb_msgdef *m); -int upb_msgdef_numoneofs(const upb_msgdef *m); +const upb_msglayout *upb_msgdef_layout(const upb_msgdef *m); +const upb_fielddef *_upb_msgdef_field(const upb_msgdef *m, int i); UPB_INLINE const upb_oneofdef *upb_msgdef_ntooz(const upb_msgdef *m, const char *name) { @@ -3368,6 +3298,10 @@ UPB_INLINE bool upb_msgdef_lookupnamez(const upb_msgdef *m, const char *name, return upb_msgdef_lookupname(m, name, strlen(name), f, o); } +/* Returns a field by either JSON name or regular proto name. */ +const upb_fielddef *upb_msgdef_lookupjsonname(const upb_msgdef *m, + const char *name, size_t len); + /* Iteration over fields and oneofs. For example: * * upb_msg_field_iter i; @@ -3399,194 +3333,6 @@ void upb_msg_oneof_iter_setdone(upb_msg_oneof_iter * iter); bool upb_msg_oneof_iter_isequal(const upb_msg_oneof_iter *iter1, const upb_msg_oneof_iter *iter2); -#ifdef __cplusplus -} /* extern "C" */ - -/* Structure that describes a single .proto message type. */ -class upb::MessageDefPtr { - public: - MessageDefPtr() : ptr_(nullptr) {} - explicit MessageDefPtr(const upb_msgdef *ptr) : ptr_(ptr) {} - - const upb_msgdef *ptr() const { return ptr_; } - explicit operator bool() const { return ptr_ != nullptr; } - - const char* full_name() const { return upb_msgdef_fullname(ptr_); } - const char* name() const { return upb_msgdef_name(ptr_); } - - /* The number of fields that belong to the MessageDef. */ - int field_count() const { return upb_msgdef_numfields(ptr_); } - - /* The number of oneofs that belong to the MessageDef. */ - int oneof_count() const { return upb_msgdef_numoneofs(ptr_); } - - upb_syntax_t syntax() const { return upb_msgdef_syntax(ptr_); } - - /* These return null pointers if the field is not found. */ - FieldDefPtr FindFieldByNumber(uint32_t number) const { - return FieldDefPtr(upb_msgdef_itof(ptr_, number)); - } - FieldDefPtr FindFieldByName(const char* name, size_t len) const { - return FieldDefPtr(upb_msgdef_ntof(ptr_, name, len)); - } - FieldDefPtr FindFieldByName(const char *name) const { - return FieldDefPtr(upb_msgdef_ntofz(ptr_, name)); - } - - template - FieldDefPtr FindFieldByName(const T& str) const { - return FindFieldByName(str.c_str(), str.size()); - } - - OneofDefPtr FindOneofByName(const char* name, size_t len) const { - return OneofDefPtr(upb_msgdef_ntoo(ptr_, name, len)); - } - - OneofDefPtr FindOneofByName(const char *name) const { - return OneofDefPtr(upb_msgdef_ntooz(ptr_, name)); - } - - template - OneofDefPtr FindOneofByName(const T &str) const { - return FindOneofByName(str.c_str(), str.size()); - } - - /* Is this message a map entry? */ - bool mapentry() const { return upb_msgdef_mapentry(ptr_); } - - /* Return the type of well known type message. UPB_WELLKNOWN_UNSPECIFIED for - * non-well-known message. */ - upb_wellknowntype_t wellknowntype() const { - return upb_msgdef_wellknowntype(ptr_); - } - - /* Whether is a number wrapper. */ - bool isnumberwrapper() const { return upb_msgdef_isnumberwrapper(ptr_); } - - /* Iteration over fields. The order is undefined. */ - class const_field_iterator - : public std::iterator { - public: - void operator++() { upb_msg_field_next(&iter_); } - - FieldDefPtr operator*() const { - return FieldDefPtr(upb_msg_iter_field(&iter_)); - } - - bool operator!=(const const_field_iterator &other) const { - return !upb_msg_field_iter_isequal(&iter_, &other.iter_); - } - - bool operator==(const const_field_iterator &other) const { - return upb_msg_field_iter_isequal(&iter_, &other.iter_); - } - - private: - friend class MessageDefPtr; - - explicit const_field_iterator() {} - - explicit const_field_iterator(MessageDefPtr msg) { - upb_msg_field_begin(&iter_, msg.ptr()); - } - - static const_field_iterator end() { - const_field_iterator iter; - upb_msg_field_iter_setdone(&iter.iter_); - return iter; - } - - upb_msg_field_iter iter_; - }; - - /* Iteration over oneofs. The order is undefined. */ - class const_oneof_iterator - : public std::iterator { - public: - - void operator++() { upb_msg_oneof_next(&iter_); } - - OneofDefPtr operator*() const { - return OneofDefPtr(upb_msg_iter_oneof(&iter_)); - } - - bool operator!=(const const_oneof_iterator& other) const { - return !upb_msg_oneof_iter_isequal(&iter_, &other.iter_); - } - - bool operator==(const const_oneof_iterator &other) const { - return upb_msg_oneof_iter_isequal(&iter_, &other.iter_); - } - - private: - friend class MessageDefPtr; - - const_oneof_iterator() {} - - explicit const_oneof_iterator(MessageDefPtr msg) { - upb_msg_oneof_begin(&iter_, msg.ptr()); - } - - static const_oneof_iterator end() { - const_oneof_iterator iter; - upb_msg_oneof_iter_setdone(&iter.iter_); - return iter; - } - - upb_msg_oneof_iter iter_; - }; - - class ConstFieldAccessor { - public: - explicit ConstFieldAccessor(const upb_msgdef* md) : md_(md) {} - const_field_iterator begin() { return MessageDefPtr(md_).field_begin(); } - const_field_iterator end() { return MessageDefPtr(md_).field_end(); } - private: - const upb_msgdef* md_; - }; - - class ConstOneofAccessor { - public: - explicit ConstOneofAccessor(const upb_msgdef* md) : md_(md) {} - const_oneof_iterator begin() { return MessageDefPtr(md_).oneof_begin(); } - const_oneof_iterator end() { return MessageDefPtr(md_).oneof_end(); } - private: - const upb_msgdef* md_; - }; - - const_field_iterator field_begin() const { - return const_field_iterator(*this); - } - - const_field_iterator field_end() const { return const_field_iterator::end(); } - - const_oneof_iterator oneof_begin() const { - return const_oneof_iterator(*this); - } - - const_oneof_iterator oneof_end() const { return const_oneof_iterator::end(); } - - ConstFieldAccessor fields() const { return ConstFieldAccessor(ptr()); } - ConstOneofAccessor oneofs() const { return ConstOneofAccessor(ptr()); } - - private: - const upb_msgdef* ptr_; -}; - -inline upb::MessageDefPtr upb::FieldDefPtr::message_subdef() const { - return MessageDefPtr(upb_fielddef_msgsubdef(ptr_)); -} - -inline upb::MessageDefPtr upb::FieldDefPtr::containing_type() const { - return MessageDefPtr(upb_fielddef_containingtype(ptr_)); -} - -inline upb::MessageDefPtr upb::OneofDefPtr::containing_type() const { - return MessageDefPtr(upb_oneofdef_containingtype(ptr_)); -} - -#endif /* __cplusplus */ - /* upb_enumdef ****************************************************************/ typedef upb_strtable_iter upb_enum_iter; @@ -3621,75 +3367,8 @@ bool upb_enum_done(upb_enum_iter *iter); const char *upb_enum_iter_name(upb_enum_iter *iter); int32_t upb_enum_iter_number(upb_enum_iter *iter); -#ifdef __cplusplus - -class upb::EnumDefPtr { - public: - EnumDefPtr() : ptr_(nullptr) {} - explicit EnumDefPtr(const upb_enumdef* ptr) : ptr_(ptr) {} - - const upb_enumdef* ptr() const { return ptr_; } - explicit operator bool() const { return ptr_ != nullptr; } - - const char* full_name() const { return upb_enumdef_fullname(ptr_); } - const char* name() const { return upb_enumdef_name(ptr_); } - - /* The value that is used as the default when no field default is specified. - * If not set explicitly, the first value that was added will be used. - * The default value must be a member of the enum. - * Requires that value_count() > 0. */ - int32_t default_value() const { return upb_enumdef_default(ptr_); } - - /* Returns the number of values currently defined in the enum. Note that - * multiple names can refer to the same number, so this may be greater than - * the total number of unique numbers. */ - int value_count() const { return upb_enumdef_numvals(ptr_); } - - /* Lookups from name to integer, returning true if found. */ - bool FindValueByName(const char *name, int32_t *num) const { - return upb_enumdef_ntoiz(ptr_, name, num); - } - - /* Finds the name corresponding to the given number, or NULL if none was - * found. If more than one name corresponds to this number, returns the - * first one that was added. */ - const char *FindValueByNumber(int32_t num) const { - return upb_enumdef_iton(ptr_, num); - } - - /* Iteration over name/value pairs. The order is undefined. - * Adding an enum val invalidates any iterators. - * - * TODO: make compatible with range-for, with elements as pairs? */ - class Iterator { - public: - explicit Iterator(EnumDefPtr e) { upb_enum_begin(&iter_, e.ptr()); } - - int32_t number() { return upb_enum_iter_number(&iter_); } - const char *name() { return upb_enum_iter_name(&iter_); } - bool Done() { return upb_enum_done(&iter_); } - void Next() { return upb_enum_next(&iter_); } - - private: - upb_enum_iter iter_; - }; - - private: - const upb_enumdef *ptr_; -}; - -inline upb::EnumDefPtr upb::FieldDefPtr::enum_subdef() const { - return EnumDefPtr(upb_fielddef_enumsubdef(ptr_)); -} - -#endif /* __cplusplus */ - /* upb_filedef ****************************************************************/ -#ifdef __cplusplus -extern "C" { -#endif - const char *upb_filedef_name(const upb_filedef *f); const char *upb_filedef_package(const upb_filedef *f); const char *upb_filedef_phpprefix(const upb_filedef *f); @@ -3702,57 +3381,8 @@ const upb_filedef *upb_filedef_dep(const upb_filedef *f, int i); const upb_msgdef *upb_filedef_msg(const upb_filedef *f, int i); const upb_enumdef *upb_filedef_enum(const upb_filedef *f, int i); -#ifdef __cplusplus -} /* extern "C" */ - -/* Class that represents a .proto file with some things defined in it. - * - * Many users won't care about FileDefs, but they are necessary if you want to - * read the values of file-level options. */ -class upb::FileDefPtr { - public: - explicit FileDefPtr(const upb_filedef *ptr) : ptr_(ptr) {} - - const upb_filedef* ptr() const { return ptr_; } - explicit operator bool() const { return ptr_ != nullptr; } - - /* Get/set name of the file (eg. "foo/bar.proto"). */ - const char* name() const { return upb_filedef_name(ptr_); } - - /* Package name for definitions inside the file (eg. "foo.bar"). */ - const char* package() const { return upb_filedef_package(ptr_); } - - /* Sets the php class prefix which is prepended to all php generated classes - * from this .proto. Default is empty. */ - const char* phpprefix() const { return upb_filedef_phpprefix(ptr_); } - - /* Use this option to change the namespace of php generated classes. Default - * is empty. When this option is empty, the package name will be used for - * determining the namespace. */ - const char* phpnamespace() const { return upb_filedef_phpnamespace(ptr_); } - - /* Syntax for the file. Defaults to proto2. */ - upb_syntax_t syntax() const { return upb_filedef_syntax(ptr_); } - - /* Get the list of dependencies from the file. These are returned in the - * order that they were added to the FileDefPtr. */ - int dependency_count() const { return upb_filedef_depcount(ptr_); } - const FileDefPtr dependency(int index) const { - return FileDefPtr(upb_filedef_dep(ptr_, index)); - } - - private: - const upb_filedef* ptr_; -}; - -#endif /* __cplusplus */ - /* upb_symtab *****************************************************************/ -#ifdef __cplusplus -extern "C" { -#endif - upb_symtab *upb_symtab_new(void); void upb_symtab_free(upb_symtab* s); const upb_msgdef *upb_symtab_lookupmsg(const upb_symtab *s, const char *sym); @@ -3769,107 +3399,171 @@ const upb_filedef *upb_symtab_addfile( /* For generated code only: loads a generated descriptor. */ typedef struct upb_def_init { - struct upb_def_init **deps; + struct upb_def_init **deps; /* Dependencies of this file. */ + const upb_msglayout **layouts; /* Pre-order layouts of all messages. */ const char *filename; - upb_strview descriptor; + upb_strview descriptor; /* Serialized descriptor. */ } upb_def_init; bool _upb_symtab_loaddefinit(upb_symtab *s, const upb_def_init *init); + #ifdef __cplusplus } /* extern "C" */ +#endif /* __cplusplus */ -/* Non-const methods in upb::SymbolTable are NOT thread-safe. */ -class upb::SymbolTable { - public: - SymbolTable() : ptr_(upb_symtab_new(), upb_symtab_free) {} - explicit SymbolTable(upb_symtab* s) : ptr_(s, upb_symtab_free) {} +#endif /* UPB_DEF_H_ */ - const upb_symtab* ptr() const { return ptr_.get(); } - upb_symtab* ptr() { return ptr_.get(); } +#ifndef UPB_REFLECTION_H_ +#define UPB_REFLECTION_H_ - /* Finds an entry in the symbol table with this exact name. If not found, - * returns NULL. */ - MessageDefPtr LookupMessage(const char *sym) const { - return MessageDefPtr(upb_symtab_lookupmsg(ptr_.get(), sym)); - } - EnumDefPtr LookupEnum(const char *sym) const { - return EnumDefPtr(upb_symtab_lookupenum(ptr_.get(), sym)); - } - FileDefPtr LookupFile(const char *name) const { - return FileDefPtr(upb_symtab_lookupfile(ptr_.get(), name)); - } +typedef union { + bool bool_val; + float float_val; + double double_val; + int32_t int32_val; + int64_t int64_val; + uint32_t uint32_val; + uint64_t uint64_val; + const upb_map* map_val; + const upb_msg* msg_val; + const upb_array* array_val; + upb_strview str_val; +} upb_msgval; - /* TODO: iteration? */ +typedef union { + upb_map* map; + upb_msg* msg; + upb_array* array; +} upb_mutmsgval; - /* Adds the given serialized FileDescriptorProto to the pool. */ - FileDefPtr AddFile(const google_protobuf_FileDescriptorProto *file_proto, - Status *status) { - return FileDefPtr( - upb_symtab_addfile(ptr_.get(), file_proto, status->ptr())); - } +/** upb_msg *******************************************************************/ - private: - std::unique_ptr ptr_; -}; +/* Creates a new message of the given type in the given arena. */ +upb_msg *upb_msg_new(const upb_msgdef *m, upb_arena *a); -UPB_INLINE const char* upb_safecstr(const std::string& str) { - UPB_ASSERT(str.size() == std::strlen(str.c_str())); - return str.c_str(); -} +/* Returns the value associated with this field. */ +upb_msgval upb_msg_get(const upb_msg *msg, const upb_fielddef *f); -#endif /* __cplusplus */ +/* Returns a mutable pointer to a map, array, or submessage value. If the given + * arena is non-NULL this will construct a new object if it was not previously + * present. May not be called for primitive fields. */ +upb_mutmsgval upb_msg_mutable(upb_msg *msg, const upb_fielddef *f, upb_arena *a); +/* May only be called for fields where upb_fielddef_haspresence(f) == true. */ +bool upb_msg_has(const upb_msg *msg, const upb_fielddef *f); -#endif /* UPB_DEF_H_ */ +/* Returns whether any field is set in the oneof. */ +bool upb_msg_hasoneof(const upb_msg *msg, const upb_oneofdef *o); +/* Sets the given field to the given value. For a msg/array/map/string, the + * value must be in the same arena. */ +void upb_msg_set(upb_msg *msg, const upb_fielddef *f, upb_msgval val, + upb_arena *a); -#ifndef UPB_MSGFACTORY_H_ -#define UPB_MSGFACTORY_H_ +/* Clears any field presence and sets the value back to its default. */ +void upb_msg_clearfield(upb_msg *msg, const upb_fielddef *f); -/** upb_msgfactory ************************************************************/ +/* Iterate over present fields. + * + * size_t iter = UPB_MSG_BEGIN; + * const upb_fielddef *f; + * upb_msgval val; + * while (upb_msg_next(msg, m, ext_pool, &f, &val, &iter)) { + * process_field(f, val); + * } + * + * If ext_pool is NULL, no extensions will be returned. If the given symtab + * returns extensions that don't match what is in this message, those extensions + * will be skipped. + */ -struct upb_msgfactory; -typedef struct upb_msgfactory upb_msgfactory; +#define UPB_MSG_BEGIN -1 +bool upb_msg_next(const upb_msg *msg, const upb_msgdef *m, + const upb_symtab *ext_pool, const upb_fielddef **f, + upb_msgval *val, size_t *iter); -#ifdef __cplusplus -extern "C" { -#endif +/* Adds unknown data (serialized protobuf data) to the given message. The data + * is copied into the message instance. */ +void upb_msg_addunknown(upb_msg *msg, const char *data, size_t len, + upb_arena *arena); -/* A upb_msgfactory contains a cache of upb_msglayout, upb_handlers, and - * upb_visitorplan objects. These are the objects necessary to represent, - * populate, and and visit upb_msg objects. - * - * These caches are all populated by upb_msgdef, and lazily created on demand. - */ +/* Returns a reference to the message's unknown data. */ +const char *upb_msg_getunknown(const upb_msg *msg, size_t *len); -/* Creates and destroys a msgfactory, respectively. The messages for this - * msgfactory must come from |symtab| (which should outlive the msgfactory). */ -upb_msgfactory *upb_msgfactory_new(const upb_symtab *symtab); -void upb_msgfactory_free(upb_msgfactory *f); +/** upb_array *****************************************************************/ -const upb_symtab *upb_msgfactory_symtab(const upb_msgfactory *f); +/* Creates a new array on the given arena that holds elements of this type. */ +upb_array *upb_array_new(upb_arena *a, upb_fieldtype_t type); -/* The functions to get cached objects, lazily creating them on demand. These - * all require: - * - * - m is in upb_msgfactory_symtab(f) - * - upb_msgdef_mapentry(m) == false (since map messages can't have layouts). +/* Returns the size of the array. */ +size_t upb_array_size(const upb_array *arr); + +/* Returns the given element, which must be within the array's current size. */ +upb_msgval upb_array_get(const upb_array *arr, size_t i); + +/* Sets the given element, which must be within the array's current size. */ +void upb_array_set(upb_array *arr, size_t i, upb_msgval val); + +/* Appends an element to the array. Returns false on allocation failure. */ +bool upb_array_append(upb_array *array, upb_msgval val, upb_arena *arena); + +/* Changes the size of a vector. New elements are initialized to empty/0. + * Returns false on allocation failure. */ +bool upb_array_resize(upb_array *array, size_t size, upb_arena *arena); + +/** upb_map *******************************************************************/ + +/* Creates a new map on the given arena with the given key/value size. */ +upb_map *upb_map_new(upb_arena *a, upb_fieldtype_t key_type, + upb_fieldtype_t value_type); + +/* Returns the number of entries in the map. */ +size_t upb_map_size(const upb_map *map); + +/* Stores a value for the given key into |*val| (or the zero value if the key is + * not present). Returns whether the key was present. The |val| pointer may be + * NULL, in which case the function tests whether the given key is present. */ +bool upb_map_get(const upb_map *map, upb_msgval key, upb_msgval *val); + +/* Removes all entries in the map. */ +void upb_map_clear(upb_map *map); + +/* Sets the given key to the given value. Returns true if this was a new key in + * the map, or false if an existing key was replaced. */ +bool upb_map_set(upb_map *map, upb_msgval key, upb_msgval val, + upb_arena *arena); + +/* Deletes this key from the table. Returns true if the key was present. */ +bool upb_map_delete(upb_map *map, upb_msgval key); + +/* Map iteration: * - * The returned objects will live for as long as the msgfactory does. + * size_t iter = UPB_MAP_BEGIN; + * while (upb_mapiter_next(map, &iter)) { + * upb_msgval key = upb_mapiter_key(map, iter); + * upb_msgval val = upb_mapiter_value(map, iter); * - * TODO(haberman): consider making this thread-safe and take a const - * upb_msgfactory. */ -const upb_msglayout *upb_msgfactory_getlayout(upb_msgfactory *f, - const upb_msgdef *m); + * // If mutating is desired. + * upb_mapiter_setvalue(map, iter, value2); + * } + */ + +/* Advances to the next entry. Returns false if no more entries are present. */ +bool upb_mapiter_next(const upb_map *map, size_t *iter); + +/* Returns the key and value for this entry of the map. */ +upb_msgval upb_mapiter_key(const upb_map *map, size_t iter); +upb_msgval upb_mapiter_value(const upb_map *map, size_t iter); + +/* Sets the value for this entry. The iterator must not be done, and the + * iterator must not have been initialized const. */ +void upb_mapiter_setvalue(upb_map *map, size_t iter, upb_msgval value); -#ifdef __cplusplus -} /* extern "C" */ -#endif -#endif /* UPB_MSGFACTORY_H_ */ +#endif /* UPB_REFLECTION_H_ */ /* ** upb::Handlers (upb_handlers) ** @@ -6378,7 +6072,7 @@ typedef struct { typedef struct { /* Space optimization note: we store two pointers here that the JIT * doesn't need at all; the upb_handlers* inside the sink and - * the dispatch table pointer. We can optimize so that the JIT uses + * the dispatch table pointer. We can optimze so that the JIT uses * smaller stack frames than the interpreter. The only thing we need * to guarantee is that the fallback routines can find end_ofs. */ upb_sink sink; @@ -6455,7 +6149,7 @@ struct upb_pbdecoder { char residual[UPB_DECODER_MAX_RESIDUAL_BYTES]; char *residual_end; - /* Bytes of data that should be discarded from the input before we start + /* Bytes of data that should be discarded from the input beore we start * parsing again. We set this when we internally determine that we can * safely skip the next N bytes, but this region extends past the current * user buffer. */ @@ -6577,21 +6271,22 @@ extern "C" { * descriptor type (upb_descriptortype_t). */ extern const uint8_t upb_pb_native_wire_types[]; -UPB_INLINE uint64_t byteswap64(uint64_t val) -{ - return ((((val) & 0xff00000000000000ull) >> 56) - | (((val) & 0x00ff000000000000ull) >> 40) - | (((val) & 0x0000ff0000000000ull) >> 24) - | (((val) & 0x000000ff00000000ull) >> 8) - | (((val) & 0x00000000ff000000ull) << 8) - | (((val) & 0x0000000000ff0000ull) << 24) - | (((val) & 0x000000000000ff00ull) << 40) - | (((val) & 0x00000000000000ffull) << 56)); +UPB_INLINE uint64_t byteswap64(uint64_t val) { + uint64_t byte = 0xff; + return (val & (byte << 56) >> 56) + | (val & (byte << 48) >> 40) + | (val & (byte << 40) >> 24) + | (val & (byte << 32) >> 8) + | (val & (byte << 24) << 8) + | (val & (byte << 16) << 24) + | (val & (byte << 8) << 40) + | (val & (byte << 0) << 56); } /* Zig-zag encoding/decoding **************************************************/ -UPB_INLINE int32_t upb_zzdec_32(uint32_t n) { +UPB_INLINE int32_t upb_zzdec_32(uint64_t _n) { + uint32_t n = (uint32_t)_n; return (n >> 1) ^ -(int32_t)(n & 1); } UPB_INLINE int64_t upb_zzdec_64(uint64_t n) { @@ -7074,17 +6769,23 @@ class upb::json::PrinterPtr { #endif /* UPB_JSON_TYPED_PRINTER_H_ */ /* See port_def.inc. This should #undef all macros #defined there. */ +#undef UPB_MAPTYPE_STRING #undef UPB_SIZE -#undef UPB_FIELD_AT +#undef UPB_PTR_AT #undef UPB_READ_ONEOF #undef UPB_WRITE_ONEOF #undef UPB_INLINE +#undef UPB_ALIGN_UP +#undef UPB_ALIGN_DOWN +#undef UPB_ALIGN_MALLOC +#undef UPB_ALIGN_OF #undef UPB_FORCEINLINE #undef UPB_NOINLINE #undef UPB_NORETURN #undef UPB_MAX #undef UPB_MIN #undef UPB_UNUSED +#undef UPB_ASSUME #undef UPB_ASSERT #undef UPB_ASSERT_DEBUGVAR #undef UPB_UNREACHABLE diff --git a/php/src/Google/Protobuf/Internal/Message.php b/php/src/Google/Protobuf/Internal/Message.php index e292026f377e..77614bc0e977 100644 --- a/php/src/Google/Protobuf/Internal/Message.php +++ b/php/src/Google/Protobuf/Internal/Message.php @@ -773,10 +773,10 @@ public function mergeFromString($data) * @return null. * @throws \Exception Invalid data. */ - public function mergeFromJsonString($data) + public function mergeFromJsonString($data, $ignore_unknown = false) { $input = new RawInputStream($data); - $this->parseFromJsonStream($input); + $this->parseFromJsonStream($input, $ignore_unknown); } /** @@ -801,6 +801,7 @@ public function parseFromStream($input) private function convertJsonValueToProtoValue( $value, $field, + $ignore_unknown, $is_map_key = false) { switch ($field->getType()) { @@ -849,7 +850,7 @@ private function convertJsonValueToProtoValue( } elseif (!is_object($value) && !is_array($value)) { throw new GPBDecodeException("Expect message."); } - $submsg->mergeFromJsonArray($value); + $submsg->mergeFromJsonArray($value, $ignore_unknown); } return $submsg; case GPBType::ENUM: @@ -862,9 +863,12 @@ private function convertJsonValueToProtoValue( $enum_value = $field->getEnumType()->getValueByName($value); if (!is_null($enum_value)) { return $enum_value->getNumber(); + } else if ($ignore_unknown) { + return $this->defaultValue($field); + } else { + throw new GPBDecodeException( + "Enum field only accepts integer or enum value name"); } - throw new GPBDecodeException( - "Enum field only accepts integer or enum value name"); case GPBType::STRING: if (is_null($value)) { return $this->defaultValue($field); @@ -1125,17 +1129,17 @@ private static function normalizeToMessageType(&$value, $class) } } - protected function mergeFromJsonArray($array) + protected function mergeFromJsonArray($array, $ignore_unknown) { if (is_a($this, "Google\Protobuf\Any")) { $this->clear(); $this->setTypeUrl($array["@type"]); $msg = $this->unpack(); if (GPBUtil::hasSpecialJsonMapping($msg)) { - $msg->mergeFromJsonArray($array["value"]); + $msg->mergeFromJsonArray($array["value"], $ignore_unknown); } else { unset($array["@type"]); - $msg->mergeFromJsonArray($array); + $msg->mergeFromJsonArray($array, $ignore_unknown); } $this->setValue($msg->serializeToString()); return; @@ -1171,7 +1175,7 @@ protected function mergeFromJsonArray($array) $fields = $this->getFields(); foreach($array as $key => $value) { $v = new Value(); - $v->mergeFromJsonArray($value); + $v->mergeFromJsonArray($value, $ignore_unknown); $fields[$key] = $v; } } @@ -1194,7 +1198,7 @@ protected function mergeFromJsonArray($array) } foreach ($array as $key => $v) { $value = new Value(); - $value->mergeFromJsonArray($v); + $value->mergeFromJsonArray($v, $ignore_unknown); $values = $struct_value->getFields(); $values[$key]= $value; } @@ -1207,7 +1211,7 @@ protected function mergeFromJsonArray($array) } foreach ($array as $v) { $value = new Value(); - $value->mergeFromJsonArray($v); + $value->mergeFromJsonArray($v, $ignore_unknown); $values = $list_value->getValues(); $values[]= $value; } @@ -1217,10 +1221,10 @@ protected function mergeFromJsonArray($array) } return; } - $this->mergeFromArrayJsonImpl($array); + $this->mergeFromArrayJsonImpl($array, $ignore_unknown); } - private function mergeFromArrayJsonImpl($array) + private function mergeFromArrayJsonImpl($array, $ignore_unknown) { foreach ($array as $key => $value) { $field = $this->desc->getFieldByJsonName($key); @@ -1244,10 +1248,12 @@ private function mergeFromArrayJsonImpl($array) $proto_key = $this->convertJsonValueToProtoValue( $tmp_key, $key_field, + $ignore_unknown, true); $proto_value = $this->convertJsonValueToProtoValue( $tmp_value, - $value_field); + $value_field, + $ignore_unknown); self::kvUpdateHelper($field, $proto_key, $proto_value); } } else if ($field->isRepeated()) { @@ -1261,14 +1267,16 @@ private function mergeFromArrayJsonImpl($array) } $proto_value = $this->convertJsonValueToProtoValue( $tmp, - $field); + $field, + $ignore_unknown); self::appendHelper($field, $proto_value); } } else { $setter = $field->getSetter(); $proto_value = $this->convertJsonValueToProtoValue( $value, - $field); + $field, + $ignore_unknown); if ($field->getType() === GPBType::MESSAGE) { if (is_null($proto_value)) { continue; @@ -1288,7 +1296,7 @@ private function mergeFromArrayJsonImpl($array) /** * @ignore */ - public function parseFromJsonStream($input) + public function parseFromJsonStream($input, $ignore_unknown) { $array = json_decode($input->getData(), true, 512, JSON_BIGINT_AS_STRING); if ($this instanceof \Google\Protobuf\ListValue) { @@ -1304,7 +1312,7 @@ public function parseFromJsonStream($input) } } try { - $this->mergeFromJsonArray($array); + $this->mergeFromJsonArray($array, $ignore_unknown); } catch (\Exception $e) { throw new GPBDecodeException($e->getMessage()); } diff --git a/php/tests/encode_decode_test.php b/php/tests/encode_decode_test.php index 319e3321d2a1..5442f504d576 100644 --- a/php/tests/encode_decode_test.php +++ b/php/tests/encode_decode_test.php @@ -884,6 +884,11 @@ public function testJsonUnknown() $m->mergeFromJsonString("{\"unknown\":{\"a\":1, \"b\":1}, \"optionalInt32\":1}", true); $this->assertSame(1, $m->getOptionalInt32()); + + // Test unknown enum value + $m = new TestMessage(); + $m->mergeFromJsonString("{\"optionalEnum\":\"UNKNOWN\"}", true); + $this->assertSame(0, $m->getOptionalEnum()); } public function testJsonEncode()