Fixed PHP to support field numbers >=2**28. (#8235)
diff --git a/php/ext/google/protobuf/php-upb.c b/php/ext/google/protobuf/php-upb.c
index 7383868..4c6a56a 100644
--- a/php/ext/google/protobuf/php-upb.c
+++ b/php/ext/google/protobuf/php-upb.c
@@ -23,12 +23,10 @@
* This file is private and must not be included by users!
*/
-#if !(__STDC_VERSION__ >= 199901L || __cplusplus >= 201103L)
-#error upb requires C99 or C++11
-#endif
-
-#if (defined(_MSC_VER) && _MSC_VER < 1900)
-#error upb requires MSVC >= 2015.
+#if !((defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || \
+ (defined(__cplusplus) && __cplusplus >= 201103L) || \
+ (defined(_MSC_VER) && _MSC_VER >= 1900))
+#error upb requires C99 or C++11 or MSVC >= 2015.
#endif
#include <stdint.h>
@@ -84,14 +82,17 @@
#define UPB_FORCEINLINE __inline__ __attribute__((always_inline))
#define UPB_NOINLINE __attribute__((noinline))
#define UPB_NORETURN __attribute__((__noreturn__))
+#define UPB_PRINTF(str, first_vararg) __attribute__((format (printf, str, first_vararg)))
#elif defined(_MSC_VER)
#define UPB_NOINLINE
#define UPB_FORCEINLINE
#define UPB_NORETURN __declspec(noreturn)
+#define UPB_PRINTF(str, first_vararg)
#else /* !defined(__GNUC__) */
#define UPB_FORCEINLINE
#define UPB_NOINLINE
#define UPB_NORETURN
+#define UPB_PRINTF(str, first_vararg)
#endif
#define UPB_MAX(x, y) ((x) > (y) ? (x) : (y))
@@ -127,6 +128,52 @@
#define UPB_UNREACHABLE() do { assert(0); } while(0)
#endif
+/* UPB_SETJMP() / UPB_LONGJMP(): avoid setting/restoring signal mask. */
+#ifdef __APPLE__
+#define UPB_SETJMP(buf) _setjmp(buf)
+#define UPB_LONGJMP(buf, val) _longjmp(buf, val)
+#else
+#define UPB_SETJMP(buf) setjmp(buf)
+#define UPB_LONGJMP(buf, val) longjmp(buf, val)
+#endif
+
+/* Configure whether fasttable is switched on or not. *************************/
+
+#if defined(__x86_64__) && defined(__GNUC__)
+#define UPB_FASTTABLE_SUPPORTED 1
+#else
+#define UPB_FASTTABLE_SUPPORTED 0
+#endif
+
+/* define UPB_ENABLE_FASTTABLE to force fast table support.
+ * This is useful when we want to ensure we are really getting fasttable,
+ * for example for testing or benchmarking. */
+#if defined(UPB_ENABLE_FASTTABLE)
+#if !UPB_FASTTABLE_SUPPORTED
+#error fasttable is x86-64 + Clang/GCC only
+#endif
+#define UPB_FASTTABLE 1
+/* Define UPB_TRY_ENABLE_FASTTABLE to use fasttable if possible.
+ * This is useful for releasing code that might be used on multiple platforms,
+ * for example the PHP or Ruby C extensions. */
+#elif defined(UPB_TRY_ENABLE_FASTTABLE)
+#define UPB_FASTTABLE UPB_FASTTABLE_SUPPORTED
+#else
+#define UPB_FASTTABLE 0
+#endif
+
+/* UPB_FASTTABLE_INIT() allows protos compiled for fasttable to gracefully
+ * degrade to non-fasttable if we are using UPB_TRY_ENABLE_FASTTABLE. */
+#if !UPB_FASTTABLE && defined(UPB_TRY_ENABLE_FASTTABLE)
+#define UPB_FASTTABLE_INIT(...)
+#else
+#define UPB_FASTTABLE_INIT(...) __VA_ARGS__
+#endif
+
+#undef UPB_FASTTABLE_SUPPORTED
+
+/* ASAN poisoning (for arena) *************************************************/
+
#if defined(__SANITIZE_ADDRESS__)
#define UPB_ASAN 1
#ifdef __cplusplus
@@ -283,19 +330,6 @@
OP_VARPCK_LG2(3), /* REPEATED SINT64 */
};
-/* Data pertaining to the parse. */
-typedef struct {
- const char *end; /* Can read up to 16 bytes slop beyond this. */
- const char *limit_ptr; /* = end + UPB_MIN(limit, 0) */
- int limit; /* Submessage limit relative to end. */
- int depth;
- uint32_t end_group; /* Set to field number of END_GROUP tag, if any. */
- bool alias;
- char patch[32];
- upb_arena arena;
- jmp_buf err;
-} upb_decstate;
-
typedef union {
bool bool_val;
uint32_t uint32_val;
@@ -306,40 +340,41 @@
static const char *decode_msg(upb_decstate *d, const char *ptr, upb_msg *msg,
const upb_msglayout *layout);
-UPB_NORETURN static void decode_err(upb_decstate *d) { longjmp(d->err, 1); }
+UPB_NORETURN static void decode_err(upb_decstate *d) { UPB_LONGJMP(d->err, 1); }
-void decode_verifyutf8(upb_decstate *d, const char *buf, int len) {
- static const uint8_t utf8_offset[] = {
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
- 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0,
- };
+// We don't want to mark this NORETURN, see comment in .h.
+// Unfortunately this code to suppress the warning doesn't appear to be working.
+#ifdef __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wunknown-warning-option"
+#pragma clang diagnostic ignored "-Wsuggest-attribute"
+#endif
- int i, j;
- uint8_t offset;
+const char *fastdecode_err(upb_decstate *d) {
+ longjmp(d->err, 1);
+ return NULL;
+}
- i = 0;
- while (i < len) {
- offset = utf8_offset[(uint8_t)buf[i]];
- if (offset == 0 || i + offset > len) {
- decode_err(d);
- }
- for (j = i + 1; j < i + offset; j++) {
- if ((buf[j] & 0xc0) != 0x80) {
- decode_err(d);
- }
- }
- i += offset;
- }
- if (i != len) decode_err(d);
+#ifdef __clang__
+#pragma clang diagnostic pop
+#endif
+
+const uint8_t upb_utf8_offsets[] = {
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static void decode_verifyutf8(upb_decstate *d, const char *buf, int len) {
+ if (!decode_verifyutf8_inl(buf, len)) decode_err(d);
}
static bool decode_reserve(upb_decstate *d, upb_array *arr, size_t elem) {
@@ -388,13 +423,20 @@
}
UPB_FORCEINLINE
-static const char *decode_varint32(upb_decstate *d, const char *ptr,
+static const char *decode_tag(upb_decstate *d, const char *ptr,
uint32_t *val) {
- uint64_t u64;
- ptr = decode_varint64(d, ptr, &u64);
- if (u64 > UINT32_MAX) decode_err(d);
- *val = (uint32_t)u64;
- return ptr;
+ uint64_t byte = (uint8_t)*ptr;
+ if (UPB_LIKELY((byte & 0x80) == 0)) {
+ *val = byte;
+ return ptr + 1;
+ } else {
+ const char *start = ptr;
+ decode_vret res = decode_longvarint64(ptr, byte);
+ ptr = res.ptr;
+ *val = res.val;
+ if (!ptr || *val > UINT32_MAX || ptr - start > 5) decode_err(d);
+ return ptr;
+ }
}
static void decode_munge(int type, wireval *val) {
@@ -444,55 +486,14 @@
return _upb_msg_new_inl(subl, &d->arena);
}
-static int decode_pushlimit(upb_decstate *d, const char *ptr, int size) {
- int limit = size + (int)(ptr - d->end);
- int delta = d->limit - limit;
- d->limit = limit;
- d->limit_ptr = d->end + UPB_MIN(0, limit);
- return delta;
-}
-
-static void decode_poplimit(upb_decstate *d, int saved_delta) {
- d->limit += saved_delta;
- d->limit_ptr = d->end + UPB_MIN(0, d->limit);
-}
-
-typedef struct {
- bool ok;
- const char *ptr;
-} decode_doneret;
-
UPB_NOINLINE
-static const char *decode_isdonefallback(upb_decstate *d, const char *ptr,
- int overrun) {
- if (overrun < d->limit) {
- /* Need to copy remaining data into patch buffer. */
- UPB_ASSERT(overrun < 16);
- memset(d->patch + 16, 0, 16);
- memcpy(d->patch, d->end, 16);
- ptr = &d->patch[0] + overrun;
- d->end = &d->patch[16];
- d->limit -= 16;
- d->limit_ptr = d->end + d->limit;
- d->alias = false;
- UPB_ASSERT(ptr < d->limit_ptr);
- return ptr;
- } else {
+const char *decode_isdonefallback(upb_decstate *d, const char *ptr,
+ int overrun) {
+ ptr = decode_isdonefallback_inl(d, ptr, overrun);
+ if (ptr == NULL) {
decode_err(d);
}
-}
-
-UPB_FORCEINLINE
-static bool decode_isdone(upb_decstate *d, const char **ptr) {
- int overrun = *ptr - d->end;
- if (UPB_LIKELY(*ptr < d->limit_ptr)) {
- return false;
- } else if (UPB_LIKELY(overrun == d->limit)) {
- return true;
- } else {
- *ptr = decode_isdonefallback(d, *ptr, overrun);
- return false;
- }
+ return ptr;
}
static const char *decode_readstr(upb_decstate *d, const char *ptr, int size,
@@ -509,30 +510,38 @@
return ptr + size;
}
+UPB_FORCEINLINE
static const char *decode_tosubmsg(upb_decstate *d, const char *ptr,
upb_msg *submsg, const upb_msglayout *layout,
const upb_msglayout_field *field, int size) {
const upb_msglayout *subl = layout->submsgs[field->submsg_index];
int saved_delta = decode_pushlimit(d, ptr, size);
if (--d->depth < 0) decode_err(d);
- ptr = decode_msg(d, ptr, submsg, subl);
- decode_poplimit(d, saved_delta);
- if (d->end_group != 0) decode_err(d);
+ if (!decode_isdone(d, &ptr)) {
+ ptr = decode_msg(d, ptr, submsg, subl);
+ }
+ if (d->end_group != DECODE_NOGROUP) decode_err(d);
+ decode_poplimit(d, ptr, saved_delta);
d->depth++;
return ptr;
}
+UPB_FORCEINLINE
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);
+ if (decode_isdone(d, &ptr)) {
+ decode_err(d);
+ }
ptr = decode_msg(d, ptr, submsg, subl);
if (d->end_group != number) decode_err(d);
- d->end_group = 0;
+ d->end_group = DECODE_NOGROUP;
d->depth++;
return ptr;
}
+UPB_FORCEINLINE
static const char *decode_togroup(upb_decstate *d, const char *ptr,
upb_msg *submsg, const upb_msglayout *layout,
const upb_msglayout_field *field) {
@@ -621,7 +630,7 @@
memcpy(out, &elem, scale);
out += scale;
}
- decode_poplimit(d, saved_limit);
+ decode_poplimit(d, ptr, saved_limit);
return ptr;
}
default:
@@ -720,9 +729,24 @@
return ptr;
}
+UPB_FORCEINLINE
+static bool decode_tryfastdispatch(upb_decstate *d, const char **ptr,
+ upb_msg *msg, const upb_msglayout *layout) {
+#if UPB_FASTTABLE
+ if (layout && layout->table_mask != (unsigned char)-1) {
+ uint16_t tag = fastdecode_loadtag(*ptr);
+ intptr_t table = decode_totable(layout);
+ *ptr = fastdecode_tagdispatch(d, *ptr, msg, table, 0, tag);
+ return true;
+ }
+#endif
+ return false;
+}
+
+UPB_NOINLINE
static const char *decode_msg(upb_decstate *d, const char *ptr, upb_msg *msg,
const upb_msglayout *layout) {
- while (!decode_isdone(d, &ptr)) {
+ while (true) {
uint32_t tag;
const upb_msglayout_field *field;
int field_number;
@@ -731,7 +755,8 @@
wireval val;
int op;
- ptr = decode_varint32(d, ptr, &tag);
+ UPB_ASSERT(ptr < d->limit_ptr);
+ ptr = decode_tag(d, ptr, &tag);
field_number = tag >> 3;
wire_type = tag & 7;
@@ -759,13 +784,15 @@
break;
case UPB_WIRE_TYPE_DELIMITED: {
int ndx = field->descriptortype;
+ uint64_t size;
if (_upb_isrepeated(field)) ndx += 18;
- ptr = decode_varint32(d, ptr, &val.size);
- if (val.size >= INT32_MAX ||
- ptr - d->end + (int32_t)val.size > d->limit) {
+ ptr = decode_varint64(d, ptr, &size);
+ if (size >= INT32_MAX ||
+ ptr - d->end + (int32_t)size > d->limit) {
decode_err(d); /* Length overflow. */
}
op = delim_ops[ndx];
+ val.size = size;
break;
}
case UPB_WIRE_TYPE_START_GROUP:
@@ -798,30 +825,54 @@
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 (wire_type == UPB_WIRE_TYPE_DELIMITED) ptr += val.size;
if (msg) {
- if (wire_type == UPB_WIRE_TYPE_DELIMITED) ptr += val.size;
+ if (wire_type == UPB_WIRE_TYPE_START_GROUP) {
+ d->unknown = field_start;
+ d->unknown_msg = msg;
+ ptr = decode_group(d, ptr, NULL, NULL, field_number);
+ d->unknown_msg = NULL;
+ field_start = d->unknown;
+ }
if (!_upb_msg_addunknown(msg, field_start, ptr - field_start,
&d->arena)) {
decode_err(d);
}
+ } else if (wire_type == UPB_WIRE_TYPE_START_GROUP) {
+ ptr = decode_group(d, ptr, NULL, NULL, field_number);
}
}
- }
- return ptr;
+ if (decode_isdone(d, &ptr)) return ptr;
+ if (decode_tryfastdispatch(d, &ptr, msg, layout)) return ptr;
+ }
}
-bool upb_decode(const char *buf, size_t size, void *msg, const upb_msglayout *l,
- upb_arena *arena) {
+const char *fastdecode_generic(struct upb_decstate *d, const char *ptr,
+ upb_msg *msg, intptr_t table, uint64_t hasbits,
+ uint64_t data) {
+ (void)data;
+ *(uint32_t*)msg |= hasbits;
+ return decode_msg(d, ptr, msg, decode_totablep(table));
+}
+
+static bool decode_top(struct upb_decstate *d, const char *buf, void *msg,
+ const upb_msglayout *l) {
+ if (!decode_tryfastdispatch(d, &buf, msg, l)) {
+ decode_msg(d, buf, msg, l);
+ }
+ return d->end_group == DECODE_NOGROUP;
+}
+
+bool _upb_decode(const char *buf, size_t size, void *msg,
+ const upb_msglayout *l, upb_arena *arena, int options) {
bool ok;
upb_decstate state;
+ unsigned depth = (unsigned)options >> 16;
if (size == 0) {
return true;
- } else if (size < 16) {
+ } else if (size <= 16) {
memset(&state.patch, 0, 32);
memcpy(&state.patch, buf, size);
buf = state.patch;
@@ -831,25 +882,27 @@
} else {
state.end = buf + size - 16;
state.limit = 16;
- state.alias = true;
+ state.alias = options & UPB_DECODE_ALIAS;
}
state.limit_ptr = state.end;
- state.depth = 64;
- state.end_group = 0;
+ state.unknown_msg = NULL;
+ state.depth = depth ? depth : 64;
+ state.end_group = DECODE_NOGROUP;
state.arena.head = arena->head;
state.arena.last_size = arena->last_size;
+ state.arena.cleanups = arena->cleanups;
state.arena.parent = arena;
- if (UPB_UNLIKELY(setjmp(state.err))) {
+ if (UPB_UNLIKELY(UPB_SETJMP(state.err))) {
ok = false;
} else {
- decode_msg(&state, buf, msg, l);
- ok = state.end_group == 0;
+ ok = decode_top(&state, buf, msg, l);
}
arena->head.ptr = state.arena.head.ptr;
arena->head.end = state.arena.head.end;
+ arena->cleanups = state.arena.cleanups;
return ok;
}
@@ -865,6 +918,7 @@
#include <string.h>
+/* Must be last. */
#define UPB_PB_VARINT_MAX_LEN 10
@@ -887,6 +941,9 @@
jmp_buf err;
upb_alloc *alloc;
char *buf, *ptr, *limit;
+ int options;
+ int depth;
+ _upb_mapsorter sorter;
} upb_encstate;
static size_t upb_roundup_pow2(size_t bytes) {
@@ -897,7 +954,9 @@
return ret;
}
-UPB_NORETURN static void encode_err(upb_encstate *e) { longjmp(e->err, 1); }
+UPB_NORETURN static void encode_err(upb_encstate *e) {
+ UPB_LONGJMP(e->err, 1);
+}
UPB_NOINLINE
static void encode_growbuffer(upb_encstate *e, size_t bytes) {
@@ -984,7 +1043,8 @@
encode_fixed32(e, u32);
}
-static void encode_tag(upb_encstate *e, int field_number, int wire_type) {
+static void encode_tag(upb_encstate *e, uint32_t field_number,
+ uint8_t wire_type) {
encode_varint(e, (field_number << 3) | wire_type);
}
@@ -1068,9 +1128,11 @@
if (submsg == NULL) {
return;
}
+ if (--e->depth == 0) encode_err(e);
encode_tag(e, f->number, UPB_WIRE_TYPE_END_GROUP);
encode_message(e, submsg, subm, &size);
wire_type = UPB_WIRE_TYPE_START_GROUP;
+ e->depth++;
break;
}
case UPB_DESCRIPTOR_TYPE_MESSAGE: {
@@ -1080,9 +1142,11 @@
if (submsg == NULL) {
return;
}
+ if (--e->depth == 0) encode_err(e);
encode_message(e, submsg, subm, &size);
encode_varint(e, size);
wire_type = UPB_WIRE_TYPE_DELIMITED;
+ e->depth++;
break;
}
default:
@@ -1163,6 +1227,7 @@
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 (--e->depth == 0) encode_err(e);
do {
size_t size;
ptr--;
@@ -1170,12 +1235,14 @@
encode_message(e, *ptr, subm, &size);
encode_tag(e, f->number, UPB_WIRE_TYPE_START_GROUP);
} while (ptr != start);
+ e->depth++;
return;
}
case UPB_DESCRIPTOR_TYPE_MESSAGE: {
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 (--e->depth == 0) encode_err(e);
do {
size_t size;
ptr--;
@@ -1183,6 +1250,7 @@
encode_varint(e, size);
encode_tag(e, f->number, UPB_WIRE_TYPE_DELIMITED);
} while (ptr != start);
+ e->depth++;
return;
}
}
@@ -1194,31 +1262,48 @@
}
}
+static void encode_mapentry(upb_encstate *e, uint32_t number,
+ const upb_msglayout *layout,
+ const upb_map_entry *ent) {
+ const upb_msglayout_field *key_field = &layout->fields[0];
+ const upb_msglayout_field *val_field = &layout->fields[1];
+ size_t pre_len = e->limit - e->ptr;
+ size_t size;
+ encode_scalar(e, &ent->v, layout, val_field, false);
+ encode_scalar(e, &ent->k, layout, key_field, false);
+ size = (e->limit - e->ptr) - pre_len;
+ encode_varint(e, size);
+ encode_tag(e, number, UPB_WIRE_TYPE_DELIMITED);
+}
+
static void 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;
- }
+ const upb_msglayout *layout = m->submsgs[f->submsg_index];
+ UPB_ASSERT(layout->field_count == 2);
- 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);
+ if (map == NULL) return;
+
+ if (e->options & UPB_ENCODE_DETERMINISTIC) {
+ _upb_sortedmap sorted;
+ _upb_mapsorter_pushmap(&e->sorter, layout->fields[0].descriptortype, map,
+ &sorted);
upb_map_entry ent;
- _upb_map_fromkey(key, &ent.k, map->key_size);
- _upb_map_fromvalue(val, &ent.v, map->val_size);
- encode_scalar(e, &ent.v, entry, val_field, false);
- encode_scalar(e, &ent.k, entry, key_field, false);
- size = (e->limit - e->ptr) - pre_len;
- encode_varint(e, size);
- encode_tag(e, f->number, UPB_WIRE_TYPE_DELIMITED);
+ while (_upb_sortedmap_next(&e->sorter, map, &sorted, &ent)) {
+ encode_mapentry(e, f->number, layout, &ent);
+ }
+ _upb_mapsorter_popmap(&e->sorter, &sorted);
+ } else {
+ upb_strtable_iter i;
+ upb_strtable_begin(&i, &map->table);
+ for(; !upb_strtable_done(&i); upb_strtable_next(&i)) {
+ upb_strview key = upb_strtable_iter_key(&i);
+ const upb_value val = upb_strtable_iter_value(&i);
+ upb_map_entry ent;
+ _upb_map_fromkey(key, &ent.k, map->key_size);
+ _upb_map_fromvalue(val, &ent.v, map->val_size);
+ encode_mapentry(e, f->number, layout, &ent);
+ }
}
}
@@ -1242,15 +1327,16 @@
static void encode_message(upb_encstate *e, const char *msg,
const upb_msglayout *m, size_t *size) {
size_t pre_len = e->limit - e->ptr;
- const char *unknown;
- size_t unknown_size;
const upb_msglayout_field *f = &m->fields[m->field_count];
const upb_msglayout_field *first = &m->fields[0];
- unknown = upb_msg_getunknown(msg, &unknown_size);
+ if ((e->options & UPB_ENCODE_SKIPUNKNOWN) == 0) {
+ size_t unknown_size;
+ const char *unknown = upb_msg_getunknown(msg, &unknown_size);
- if (unknown) {
- encode_bytes(e, unknown, unknown_size);
+ if (unknown) {
+ encode_bytes(e, unknown, unknown_size);
+ }
}
while (f != first) {
@@ -1267,30 +1353,37 @@
*size = (e->limit - e->ptr) - pre_len;
}
-char *upb_encode(const void *msg, const upb_msglayout *m, upb_arena *arena,
- size_t *size) {
+char *upb_encode_ex(const void *msg, const upb_msglayout *l, int options,
+ upb_arena *arena, size_t *size) {
upb_encstate e;
+ unsigned depth = (unsigned)options >> 16;
+
e.alloc = upb_arena_alloc(arena);
e.buf = NULL;
e.limit = NULL;
e.ptr = NULL;
+ e.depth = depth ? depth : 64;
+ e.options = options;
+ _upb_mapsorter_init(&e.sorter);
+ char *ret = NULL;
- if (setjmp(e.err)) {
+ if (UPB_SETJMP(e.err)) {
*size = 0;
- return NULL;
- }
-
- encode_message(&e, msg, m, size);
-
- *size = e.limit - e.ptr;
-
- if (*size == 0) {
- static char ch;
- return &ch;
+ ret = NULL;
} else {
- UPB_ASSERT(e.ptr);
- return e.ptr;
+ encode_message(&e, msg, l, size);
+ *size = e.limit - e.ptr;
+ if (*size == 0) {
+ static char ch;
+ ret = &ch;
+ } else {
+ UPB_ASSERT(e.ptr);
+ ret = e.ptr;
+ }
}
+
+ _upb_mapsorter_destroy(&e.sorter);
+ return ret;
}
@@ -1430,6 +1523,121 @@
return map;
}
+
+static void _upb_mapsorter_getkeys(const void *_a, const void *_b, void *a_key,
+ void *b_key, size_t size) {
+ const upb_tabent *const*a = _a;
+ const upb_tabent *const*b = _b;
+ upb_strview a_tabkey = upb_tabstrview((*a)->key);
+ upb_strview b_tabkey = upb_tabstrview((*b)->key);
+ _upb_map_fromkey(a_tabkey, a_key, size);
+ _upb_map_fromkey(b_tabkey, b_key, size);
+}
+
+static int _upb_mapsorter_cmpi64(const void *_a, const void *_b) {
+ int64_t a, b;
+ _upb_mapsorter_getkeys(_a, _b, &a, &b, 8);
+ return a - b;
+}
+
+static int _upb_mapsorter_cmpu64(const void *_a, const void *_b) {
+ uint64_t a, b;
+ _upb_mapsorter_getkeys(_a, _b, &a, &b, 8);
+ return a - b;
+}
+
+static int _upb_mapsorter_cmpi32(const void *_a, const void *_b) {
+ int32_t a, b;
+ _upb_mapsorter_getkeys(_a, _b, &a, &b, 4);
+ return a - b;
+}
+
+static int _upb_mapsorter_cmpu32(const void *_a, const void *_b) {
+ uint32_t a, b;
+ _upb_mapsorter_getkeys(_a, _b, &a, &b, 4);
+ return a - b;
+}
+
+static int _upb_mapsorter_cmpbool(const void *_a, const void *_b) {
+ bool a, b;
+ _upb_mapsorter_getkeys(_a, _b, &a, &b, 1);
+ return a - b;
+}
+
+static int _upb_mapsorter_cmpstr(const void *_a, const void *_b) {
+ upb_strview a, b;
+ _upb_mapsorter_getkeys(_a, _b, &a, &b, UPB_MAPTYPE_STRING);
+ size_t common_size = UPB_MIN(a.size, b.size);
+ int cmp = memcmp(a.data, b.data, common_size);
+ if (cmp) return cmp;
+ return a.size - b.size;
+}
+
+bool _upb_mapsorter_pushmap(_upb_mapsorter *s, upb_descriptortype_t key_type,
+ const upb_map *map, _upb_sortedmap *sorted) {
+ int map_size = _upb_map_size(map);
+ sorted->start = s->size;
+ sorted->pos = sorted->start;
+ sorted->end = sorted->start + map_size;
+
+ /* Grow s->entries if necessary. */
+ if (sorted->end > s->cap) {
+ s->cap = _upb_lg2ceilsize(sorted->end);
+ s->entries = realloc(s->entries, s->cap * sizeof(*s->entries));
+ if (!s->entries) return false;
+ }
+
+ s->size = sorted->end;
+
+ /* Copy non-empty entries from the table to s->entries. */
+ upb_tabent const**dst = &s->entries[sorted->start];
+ const upb_tabent *src = map->table.t.entries;
+ const upb_tabent *end = src + upb_table_size(&map->table.t);
+ for (; src < end; src++) {
+ if (!upb_tabent_isempty(src)) {
+ *dst = src;
+ dst++;
+ }
+ }
+ UPB_ASSERT(dst == &s->entries[sorted->end]);
+
+ /* Sort entries according to the key type. */
+
+ int (*compar)(const void *, const void *);
+
+ switch (key_type) {
+ case UPB_DESCRIPTOR_TYPE_INT64:
+ case UPB_DESCRIPTOR_TYPE_SFIXED64:
+ case UPB_DESCRIPTOR_TYPE_SINT64:
+ compar = _upb_mapsorter_cmpi64;
+ break;
+ case UPB_DESCRIPTOR_TYPE_UINT64:
+ case UPB_DESCRIPTOR_TYPE_FIXED64:
+ compar = _upb_mapsorter_cmpu64;
+ break;
+ case UPB_DESCRIPTOR_TYPE_INT32:
+ case UPB_DESCRIPTOR_TYPE_SINT32:
+ case UPB_DESCRIPTOR_TYPE_SFIXED32:
+ case UPB_DESCRIPTOR_TYPE_ENUM:
+ compar = _upb_mapsorter_cmpi32;
+ break;
+ case UPB_DESCRIPTOR_TYPE_UINT32:
+ case UPB_DESCRIPTOR_TYPE_FIXED32:
+ compar = _upb_mapsorter_cmpu32;
+ break;
+ case UPB_DESCRIPTOR_TYPE_BOOL:
+ compar = _upb_mapsorter_cmpbool;
+ break;
+ case UPB_DESCRIPTOR_TYPE_STRING:
+ compar = _upb_mapsorter_cmpstr;
+ break;
+ default:
+ UPB_UNREACHABLE();
+ }
+
+ qsort(&s->entries[sorted->start], map_size, sizeof(*s->entries), compar);
+ return true;
+}
/*
** upb_table Implementation
**
@@ -1614,7 +1822,7 @@
/* Head of collider's chain. */
upb_tabent *chain = getentry_mutable(t, hashfunc(mainpos_e->key));
if (chain == mainpos_e) {
- /* Existing ent is in its main posisiton (it has the same hash as us, and
+ /* Existing ent is in its main position (it has the same hash as us, and
* is the head of our chain). Insert to new ent and append to this chain. */
new_e->next = mainpos_e->next;
mainpos_e->next = new_e;
@@ -2274,7 +2482,7 @@
void *_upb_arena_slowmalloc(upb_arena *a, size_t size) {
if (!upb_arena_allocblock(a, size)) return NULL; /* Out of memory. */
- UPB_ASSERT(_upb_arenahas(a, size));
+ UPB_ASSERT(_upb_arenahas(a) >= size);
return upb_arena_malloc(a, size);
}
@@ -2323,15 +2531,14 @@
}
a = UPB_PTR_AT(mem, n - sizeof(*a), upb_arena);
- n -= sizeof(*a);
a->head.alloc.func = &upb_arena_doalloc;
a->block_alloc = alloc;
a->parent = a;
a->refcount = 1;
- a->last_size = 128;
+ a->last_size = UPB_MAX(128, n);
a->head.ptr = mem;
- a->head.end = UPB_PTR_AT(mem, n, char);
+ a->head.end = UPB_PTR_AT(mem, n - sizeof(*a), char);
a->freelist = NULL;
a->cleanups = NULL;
@@ -2369,9 +2576,9 @@
bool upb_arena_addcleanup(upb_arena *a, void *ud, upb_cleanup_func *func) {
cleanup_ent *ent;
- if (!a->cleanups || !_upb_arenahas(a, sizeof(cleanup_ent))) {
+ if (!a->cleanups || _upb_arenahas(a) < sizeof(cleanup_ent)) {
if (!upb_arena_allocblock(a, 128)) return false; /* Out of memory. */
- UPB_ASSERT(_upb_arenahas(a, sizeof(cleanup_ent)));
+ UPB_ASSERT(_upb_arenahas(a) >= sizeof(cleanup_ent));
}
a->head.end -= sizeof(cleanup_ent);
@@ -2408,6 +2615,1043 @@
}
r2->parent = r1;
}
+// Fast decoder: ~3x the speed of decode.c, but x86-64 specific.
+// Also the table size grows by 2x.
+//
+// Could potentially be ported to ARM64 or other 64-bit archs that pass at
+// least six arguments in registers.
+//
+// The overall design is to create specialized functions for every possible
+// field type (eg. oneof boolean field with a 1 byte tag) and then dispatch
+// to the specialized function as quickly as possible.
+
+
+
+/* Must be last. */
+
+#if UPB_FASTTABLE
+
+// The standard set of arguments passed to each parsing function.
+// Thanks to x86-64 calling conventions, these will stay in registers.
+#define UPB_PARSE_PARAMS \
+ upb_decstate *d, const char *ptr, upb_msg *msg, intptr_t table, \
+ uint64_t hasbits, uint64_t data
+
+#define UPB_PARSE_ARGS d, ptr, msg, table, hasbits, data
+
+#define RETURN_GENERIC(m) \
+ /* fprintf(stderr, m); */ \
+ return fastdecode_generic(d, ptr, msg, table, hasbits, 0);
+
+typedef enum {
+ CARD_s = 0, /* Singular (optional, non-repeated) */
+ CARD_o = 1, /* Oneof */
+ CARD_r = 2, /* Repeated */
+ CARD_p = 3 /* Packed Repeated */
+} upb_card;
+
+UPB_NOINLINE
+static const char *fastdecode_isdonefallback(upb_decstate *d, const char *ptr,
+ upb_msg *msg, intptr_t table,
+ uint64_t hasbits, int overrun) {
+ ptr = decode_isdonefallback_inl(d, ptr, overrun);
+ if (ptr == NULL) {
+ return fastdecode_err(d);
+ }
+ uint16_t tag = fastdecode_loadtag(ptr);
+ return fastdecode_tagdispatch(d, ptr, msg, table, hasbits, tag);
+}
+
+UPB_FORCEINLINE
+static const char *fastdecode_dispatch(upb_decstate *d, const char *ptr,
+ upb_msg *msg, intptr_t table,
+ uint64_t hasbits) {
+ if (UPB_UNLIKELY(ptr >= d->limit_ptr)) {
+ int overrun = ptr - d->end;
+ if (UPB_LIKELY(overrun == d->limit)) {
+ // Parse is finished.
+ *(uint32_t*)msg |= hasbits; // Sync hasbits.
+ return ptr;
+ } else {
+ return fastdecode_isdonefallback(d, ptr, msg, table, hasbits, overrun);
+ }
+ }
+
+ // Read two bytes of tag data (for a one-byte tag, the high byte is junk).
+ uint16_t tag = fastdecode_loadtag(ptr);
+ return fastdecode_tagdispatch(d, ptr, msg, table, hasbits, tag);
+}
+
+UPB_FORCEINLINE
+static bool fastdecode_checktag(uint64_t data, int tagbytes) {
+ if (tagbytes == 1) {
+ return (data & 0xff) == 0;
+ } else {
+ return (data & 0xffff) == 0;
+ }
+}
+
+UPB_FORCEINLINE
+static const char *fastdecode_longsize(const char *ptr, int *size) {
+ int i;
+ UPB_ASSERT(*size & 0x80);
+ *size &= 0xff;
+ for (i = 0; i < 3; i++) {
+ ptr++;
+ size_t byte = (uint8_t)ptr[-1];
+ *size += (byte - 1) << (7 + 7 * i);
+ if (UPB_LIKELY((byte & 0x80) == 0)) return ptr;
+ }
+ ptr++;
+ size_t byte = (uint8_t)ptr[-1];
+ // len is limited by 2gb not 4gb, hence 8 and not 16 as normally expected
+ // for a 32 bit varint.
+ if (UPB_UNLIKELY(byte >= 8)) return NULL;
+ *size += (byte - 1) << 28;
+ return ptr;
+}
+
+UPB_FORCEINLINE
+static bool fastdecode_boundscheck(const char *ptr, size_t len,
+ const char *end) {
+ uintptr_t uptr = (uintptr_t)ptr;
+ uintptr_t uend = (uintptr_t)end + 16;
+ uintptr_t res = uptr + len;
+ return res < uptr || res > uend;
+}
+
+UPB_FORCEINLINE
+static bool fastdecode_boundscheck2(const char *ptr, size_t len,
+ const char *end) {
+ // This is one extra branch compared to the more normal:
+ // return (size_t)(end - ptr) < size;
+ // However it is one less computation if we are just about to use "ptr + len":
+ // https://godbolt.org/z/35YGPz
+ // In microbenchmarks this shows an overall 4% improvement.
+ uintptr_t uptr = (uintptr_t)ptr;
+ uintptr_t uend = (uintptr_t)end;
+ uintptr_t res = uptr + len;
+ return res < uptr || res > uend;
+}
+
+typedef const char *fastdecode_delimfunc(upb_decstate *d, const char *ptr,
+ void *ctx);
+
+UPB_FORCEINLINE
+static const char *fastdecode_delimited(upb_decstate *d, const char *ptr,
+ fastdecode_delimfunc *func, void *ctx) {
+ ptr++;
+ int len = (int8_t)ptr[-1];
+ if (fastdecode_boundscheck2(ptr, len, d->limit_ptr)) {
+ // Slow case: Sub-message is >=128 bytes and/or exceeds the current buffer.
+ // If it exceeds the buffer limit, limit/limit_ptr will change during
+ // sub-message parsing, so we need to preserve delta, not limit.
+ if (UPB_UNLIKELY(len & 0x80)) {
+ // Size varint >1 byte (length >= 128).
+ ptr = fastdecode_longsize(ptr, &len);
+ if (!ptr) {
+ // Corrupt wire format: size exceeded INT_MAX.
+ return NULL;
+ }
+ }
+ if (ptr - d->end + (int)len > d->limit) {
+ // Corrupt wire format: invalid limit.
+ return NULL;
+ }
+ int delta = decode_pushlimit(d, ptr, len);
+ ptr = func(d, ptr, ctx);
+ decode_poplimit(d, ptr, delta);
+ } else {
+ // Fast case: Sub-message is <128 bytes and fits in the current buffer.
+ // This means we can preserve limit/limit_ptr verbatim.
+ const char *saved_limit_ptr = d->limit_ptr;
+ int saved_limit = d->limit;
+ d->limit_ptr = ptr + len;
+ d->limit = d->limit_ptr - d->end;
+ UPB_ASSERT(d->limit_ptr == d->end + UPB_MIN(0, d->limit));
+ ptr = func(d, ptr, ctx);
+ d->limit_ptr = saved_limit_ptr;
+ d->limit = saved_limit;
+ UPB_ASSERT(d->limit_ptr == d->end + UPB_MIN(0, d->limit));
+ }
+ return ptr;
+}
+
+/* singular, oneof, repeated field handling ***********************************/
+
+typedef struct {
+ upb_array *arr;
+ void *end;
+} fastdecode_arr;
+
+typedef enum {
+ FD_NEXT_ATLIMIT,
+ FD_NEXT_SAMEFIELD,
+ FD_NEXT_OTHERFIELD
+} fastdecode_next;
+
+typedef struct {
+ void *dst;
+ fastdecode_next next;
+ uint32_t tag;
+} fastdecode_nextret;
+
+UPB_FORCEINLINE
+static void *fastdecode_resizearr(upb_decstate *d, void *dst,
+ fastdecode_arr *farr, int valbytes) {
+ if (UPB_UNLIKELY(dst == farr->end)) {
+ size_t old_size = farr->arr->size;
+ size_t old_bytes = old_size * valbytes;
+ size_t new_size = old_size * 2;
+ size_t new_bytes = new_size * valbytes;
+ char *old_ptr = _upb_array_ptr(farr->arr);
+ char *new_ptr = upb_arena_realloc(&d->arena, old_ptr, old_bytes, new_bytes);
+ uint8_t elem_size_lg2 = __builtin_ctz(valbytes);
+ farr->arr->size = new_size;
+ farr->arr->data = _upb_array_tagptr(new_ptr, elem_size_lg2);
+ dst = (void*)(new_ptr + (old_size * valbytes));
+ farr->end = (void*)(new_ptr + (new_size * valbytes));
+ }
+ return dst;
+}
+
+UPB_FORCEINLINE
+static bool fastdecode_tagmatch(uint32_t tag, uint64_t data, int tagbytes) {
+ if (tagbytes == 1) {
+ return (uint8_t)tag == (uint8_t)data;
+ } else {
+ return (uint16_t)tag == (uint16_t)data;
+ }
+}
+
+UPB_FORCEINLINE
+static void fastdecode_commitarr(void *dst, fastdecode_arr *farr,
+ int valbytes) {
+ farr->arr->len =
+ (size_t)((char *)dst - (char *)_upb_array_ptr(farr->arr)) / valbytes;
+}
+
+UPB_FORCEINLINE
+static fastdecode_nextret fastdecode_nextrepeated(upb_decstate *d, void *dst,
+ const char **ptr,
+ fastdecode_arr *farr,
+ uint64_t data, int tagbytes,
+ int valbytes) {
+ fastdecode_nextret ret;
+ dst = (char *)dst + valbytes;
+
+ if (UPB_LIKELY(!decode_isdone(d, ptr))) {
+ ret.tag = fastdecode_loadtag(*ptr);
+ if (fastdecode_tagmatch(ret.tag, data, tagbytes)) {
+ ret.next = FD_NEXT_SAMEFIELD;
+ } else {
+ fastdecode_commitarr(dst, farr, valbytes);
+ ret.next = FD_NEXT_OTHERFIELD;
+ }
+ } else {
+ fastdecode_commitarr(dst, farr, valbytes);
+ ret.next = FD_NEXT_ATLIMIT;
+ }
+
+ ret.dst = dst;
+ return ret;
+}
+
+UPB_FORCEINLINE
+static void *fastdecode_fieldmem(upb_msg *msg, uint64_t data) {
+ size_t ofs = data >> 48;
+ return (char *)msg + ofs;
+}
+
+UPB_FORCEINLINE
+static void *fastdecode_getfield(upb_decstate *d, const char *ptr, upb_msg *msg,
+ uint64_t *data, uint64_t *hasbits,
+ fastdecode_arr *farr, int valbytes,
+ upb_card card) {
+ switch (card) {
+ case CARD_s: {
+ uint8_t hasbit_index = *data >> 24;
+ // Set hasbit and return pointer to scalar field.
+ *hasbits |= 1ull << hasbit_index;
+ return fastdecode_fieldmem(msg, *data);
+ }
+ case CARD_o: {
+ uint16_t case_ofs = *data >> 32;
+ uint32_t *oneof_case = UPB_PTR_AT(msg, case_ofs, uint32_t);
+ uint8_t field_number = *data >> 24;
+ *oneof_case = field_number;
+ return fastdecode_fieldmem(msg, *data);
+ }
+ case CARD_r: {
+ // Get pointer to upb_array and allocate/expand if necessary.
+ uint8_t elem_size_lg2 = __builtin_ctz(valbytes);
+ upb_array **arr_p = fastdecode_fieldmem(msg, *data);
+ char *begin;
+ *(uint32_t*)msg |= *hasbits;
+ *hasbits = 0;
+ if (UPB_LIKELY(!*arr_p)) {
+ farr->arr = _upb_array_new(&d->arena, 8, elem_size_lg2);
+ *arr_p = farr->arr;
+ } else {
+ farr->arr = *arr_p;
+ }
+ begin = _upb_array_ptr(farr->arr);
+ farr->end = begin + (farr->arr->size * valbytes);
+ *data = fastdecode_loadtag(ptr);
+ return begin + (farr->arr->len * valbytes);
+ }
+ default:
+ UPB_UNREACHABLE();
+ }
+}
+
+UPB_FORCEINLINE
+static bool fastdecode_flippacked(uint64_t *data, int tagbytes) {
+ *data ^= (0x2 ^ 0x0); // Patch data to match packed wiretype.
+ return fastdecode_checktag(*data, tagbytes);
+}
+
+/* varint fields **************************************************************/
+
+UPB_FORCEINLINE
+static uint64_t fastdecode_munge(uint64_t val, int valbytes, bool zigzag) {
+ if (valbytes == 1) {
+ return val != 0;
+ } else if (zigzag) {
+ if (valbytes == 4) {
+ uint32_t n = val;
+ return (n >> 1) ^ -(int32_t)(n & 1);
+ } else if (valbytes == 8) {
+ return (val >> 1) ^ -(int64_t)(val & 1);
+ }
+ UPB_UNREACHABLE();
+ }
+ return val;
+}
+
+UPB_FORCEINLINE
+static const char *fastdecode_varint64(const char *ptr, uint64_t *val) {
+ ptr++;
+ *val = (uint8_t)ptr[-1];
+ if (UPB_UNLIKELY(*val & 0x80)) {
+ int i;
+ for (i = 0; i < 8; i++) {
+ ptr++;
+ uint64_t byte = (uint8_t)ptr[-1];
+ *val += (byte - 1) << (7 + 7 * i);
+ if (UPB_LIKELY((byte & 0x80) == 0)) goto done;
+ }
+ ptr++;
+ uint64_t byte = (uint8_t)ptr[-1];
+ if (byte > 1) {
+ return NULL;
+ }
+ *val += (byte - 1) << 63;
+ }
+done:
+ UPB_ASSUME(ptr != NULL);
+ return ptr;
+}
+
+UPB_FORCEINLINE
+static const char *fastdecode_unpackedvarint(UPB_PARSE_PARAMS, int tagbytes,
+ int valbytes, upb_card card,
+ bool zigzag,
+ _upb_field_parser *packed) {
+ uint64_t val;
+ void *dst;
+ fastdecode_arr farr;
+
+ if (UPB_UNLIKELY(!fastdecode_checktag(data, tagbytes))) {
+ if (card == CARD_r && fastdecode_flippacked(&data, tagbytes)) {
+ return packed(UPB_PARSE_ARGS);
+ }
+ RETURN_GENERIC("varint field tag mismatch\n");
+ }
+
+ dst =
+ fastdecode_getfield(d, ptr, msg, &data, &hasbits, &farr, valbytes, card);
+ if (card == CARD_r) {
+ if (UPB_UNLIKELY(!dst)) {
+ RETURN_GENERIC("need array resize\n");
+ }
+ }
+
+again:
+ if (card == CARD_r) {
+ dst = fastdecode_resizearr(d, dst, &farr, valbytes);
+ }
+
+ ptr += tagbytes;
+ ptr = fastdecode_varint64(ptr, &val);
+ if (ptr == NULL) return fastdecode_err(d);
+ val = fastdecode_munge(val, valbytes, zigzag);
+ memcpy(dst, &val, valbytes);
+
+ if (card == CARD_r) {
+ fastdecode_nextret ret =
+ fastdecode_nextrepeated(d, dst, &ptr, &farr, data, tagbytes, valbytes);
+ switch (ret.next) {
+ case FD_NEXT_SAMEFIELD:
+ dst = ret.dst;
+ goto again;
+ case FD_NEXT_OTHERFIELD:
+ return fastdecode_tagdispatch(d, ptr, msg, table, hasbits, ret.tag);
+ case FD_NEXT_ATLIMIT:
+ return ptr;
+ }
+ }
+
+ return fastdecode_dispatch(d, ptr, msg, table, hasbits);
+}
+
+typedef struct {
+ uint8_t valbytes;
+ bool zigzag;
+ void *dst;
+ fastdecode_arr farr;
+} fastdecode_varintdata;
+
+UPB_FORCEINLINE
+static const char *fastdecode_topackedvarint(upb_decstate *d, const char *ptr,
+ void *ctx) {
+ fastdecode_varintdata *data = ctx;
+ void *dst = data->dst;
+ uint64_t val;
+
+ while (!decode_isdone(d, &ptr)) {
+ dst = fastdecode_resizearr(d, dst, &data->farr, data->valbytes);
+ ptr = fastdecode_varint64(ptr, &val);
+ if (ptr == NULL) return NULL;
+ val = fastdecode_munge(val, data->valbytes, data->zigzag);
+ memcpy(dst, &val, data->valbytes);
+ dst = (char *)dst + data->valbytes;
+ }
+
+ fastdecode_commitarr(dst, &data->farr, data->valbytes);
+ return ptr;
+}
+
+UPB_FORCEINLINE
+static const char *fastdecode_packedvarint(UPB_PARSE_PARAMS, int tagbytes,
+ int valbytes, bool zigzag,
+ _upb_field_parser *unpacked) {
+ fastdecode_varintdata ctx = {valbytes, zigzag};
+
+ if (UPB_UNLIKELY(!fastdecode_checktag(data, tagbytes))) {
+ if (fastdecode_flippacked(&data, tagbytes)) {
+ return unpacked(UPB_PARSE_ARGS);
+ } else {
+ RETURN_GENERIC("varint field tag mismatch\n");
+ }
+ }
+
+ ctx.dst = fastdecode_getfield(d, ptr, msg, &data, &hasbits, &ctx.farr,
+ valbytes, CARD_r);
+ if (UPB_UNLIKELY(!ctx.dst)) {
+ RETURN_GENERIC("need array resize\n");
+ }
+
+ ptr += tagbytes;
+ ptr = fastdecode_delimited(d, ptr, &fastdecode_topackedvarint, &ctx);
+
+ if (UPB_UNLIKELY(ptr == NULL)) {
+ return fastdecode_err(d);
+ }
+
+ return fastdecode_dispatch(d, ptr, msg, table, hasbits);
+}
+
+UPB_FORCEINLINE
+static const char *fastdecode_varint(UPB_PARSE_PARAMS, int tagbytes,
+ int valbytes, upb_card card, bool zigzag,
+ _upb_field_parser *unpacked,
+ _upb_field_parser *packed) {
+ if (card == CARD_p) {
+ return fastdecode_packedvarint(UPB_PARSE_ARGS, tagbytes, valbytes, zigzag,
+ unpacked);
+ } else {
+ return fastdecode_unpackedvarint(UPB_PARSE_ARGS, tagbytes, valbytes, card,
+ zigzag, packed);
+ }
+}
+
+#define z_ZZ true
+#define b_ZZ false
+#define v_ZZ false
+
+/* Generate all combinations:
+ * {s,o,r,p} x {b1,v4,z4,v8,z8} x {1bt,2bt} */
+
+#define F(card, type, valbytes, tagbytes) \
+ UPB_NOINLINE \
+ const char *upb_p##card##type##valbytes##_##tagbytes##bt(UPB_PARSE_PARAMS) { \
+ return fastdecode_varint(UPB_PARSE_ARGS, tagbytes, valbytes, CARD_##card, \
+ type##_ZZ, \
+ &upb_pr##type##valbytes##_##tagbytes##bt, \
+ &upb_pp##type##valbytes##_##tagbytes##bt); \
+ }
+
+#define TYPES(card, tagbytes) \
+ F(card, b, 1, tagbytes) \
+ F(card, v, 4, tagbytes) \
+ F(card, v, 8, tagbytes) \
+ F(card, z, 4, tagbytes) \
+ F(card, z, 8, tagbytes)
+
+#define TAGBYTES(card) \
+ TYPES(card, 1) \
+ TYPES(card, 2)
+
+TAGBYTES(s)
+TAGBYTES(o)
+TAGBYTES(r)
+TAGBYTES(p)
+
+#undef z_ZZ
+#undef b_ZZ
+#undef v_ZZ
+#undef o_ONEOF
+#undef s_ONEOF
+#undef r_ONEOF
+#undef F
+#undef TYPES
+#undef TAGBYTES
+
+
+/* fixed fields ***************************************************************/
+
+UPB_FORCEINLINE
+static const char *fastdecode_unpackedfixed(UPB_PARSE_PARAMS, int tagbytes,
+ int valbytes, upb_card card,
+ _upb_field_parser *packed) {
+ void *dst;
+ fastdecode_arr farr;
+
+ if (UPB_UNLIKELY(!fastdecode_checktag(data, tagbytes))) {
+ if (card == CARD_r && fastdecode_flippacked(&data, tagbytes)) {
+ return packed(UPB_PARSE_ARGS);
+ }
+ RETURN_GENERIC("fixed field tag mismatch\n");
+ }
+
+ dst =
+ fastdecode_getfield(d, ptr, msg, &data, &hasbits, &farr, valbytes, card);
+ if (card == CARD_r) {
+ if (UPB_UNLIKELY(!dst)) {
+ RETURN_GENERIC("couldn't allocate array in arena\n");
+ }
+ }
+
+
+again:
+ if (card == CARD_r) {
+ dst = fastdecode_resizearr(d, dst, &farr, valbytes);
+ }
+
+ ptr += tagbytes;
+ memcpy(dst, ptr, valbytes);
+ ptr += valbytes;
+
+ if (card == CARD_r) {
+ fastdecode_nextret ret =
+ fastdecode_nextrepeated(d, dst, &ptr, &farr, data, tagbytes, valbytes);
+ switch (ret.next) {
+ case FD_NEXT_SAMEFIELD:
+ dst = ret.dst;
+ goto again;
+ case FD_NEXT_OTHERFIELD:
+ return fastdecode_tagdispatch(d, ptr, msg, table, hasbits, ret.tag);
+ case FD_NEXT_ATLIMIT:
+ return ptr;
+ }
+ }
+
+ return fastdecode_dispatch(d, ptr, msg, table, hasbits);
+}
+
+UPB_FORCEINLINE
+static const char *fastdecode_packedfixed(UPB_PARSE_PARAMS, int tagbytes,
+ int valbytes,
+ _upb_field_parser *unpacked) {
+ if (UPB_UNLIKELY(!fastdecode_checktag(data, tagbytes))) {
+ if (fastdecode_flippacked(&data, tagbytes)) {
+ return unpacked(UPB_PARSE_ARGS);
+ } else {
+ RETURN_GENERIC("varint field tag mismatch\n");
+ }
+ }
+
+ ptr += tagbytes;
+ int size = (uint8_t)ptr[0];
+ ptr++;
+ if (size & 0x80) {
+ ptr = fastdecode_longsize(ptr, &size);
+ }
+
+ if (UPB_UNLIKELY(fastdecode_boundscheck(ptr, size, d->limit_ptr)) ||
+ (size % valbytes) != 0) {
+ return fastdecode_err(d);
+ }
+
+ upb_array **arr_p = fastdecode_fieldmem(msg, data);
+ upb_array *arr = *arr_p;
+ uint8_t elem_size_lg2 = __builtin_ctz(valbytes);
+ int elems = size / valbytes;
+
+ if (UPB_LIKELY(!arr)) {
+ *arr_p = arr = _upb_array_new(&d->arena, elems, elem_size_lg2);
+ if (!arr) {
+ return fastdecode_err(d);
+ }
+ } else {
+ _upb_array_resize(arr, elems, &d->arena);
+ }
+
+ char *dst = _upb_array_ptr(arr);
+ memcpy(dst, ptr, size);
+ arr->len = elems;
+
+ return fastdecode_dispatch(d, ptr + size, msg, table, hasbits);
+}
+
+UPB_FORCEINLINE
+static const char *fastdecode_fixed(UPB_PARSE_PARAMS, int tagbytes,
+ int valbytes, upb_card card,
+ _upb_field_parser *unpacked,
+ _upb_field_parser *packed) {
+ if (card == CARD_p) {
+ return fastdecode_packedfixed(UPB_PARSE_ARGS, tagbytes, valbytes, unpacked);
+ } else {
+ return fastdecode_unpackedfixed(UPB_PARSE_ARGS, tagbytes, valbytes, card,
+ packed);
+ }
+}
+
+/* Generate all combinations:
+ * {s,o,r,p} x {f4,f8} x {1bt,2bt} */
+
+#define F(card, valbytes, tagbytes) \
+ UPB_NOINLINE \
+ const char *upb_p##card##f##valbytes##_##tagbytes##bt(UPB_PARSE_PARAMS) { \
+ return fastdecode_fixed(UPB_PARSE_ARGS, tagbytes, valbytes, CARD_##card, \
+ &upb_ppf##valbytes##_##tagbytes##bt, \
+ &upb_prf##valbytes##_##tagbytes##bt); \
+ }
+
+#define TYPES(card, tagbytes) \
+ F(card, 4, tagbytes) \
+ F(card, 8, tagbytes)
+
+#define TAGBYTES(card) \
+ TYPES(card, 1) \
+ TYPES(card, 2)
+
+TAGBYTES(s)
+TAGBYTES(o)
+TAGBYTES(r)
+TAGBYTES(p)
+
+#undef F
+#undef TYPES
+#undef TAGBYTES
+
+/* string fields **************************************************************/
+
+typedef const char *fastdecode_copystr_func(struct upb_decstate *d,
+ const char *ptr, upb_msg *msg,
+ const upb_msglayout *table,
+ uint64_t hasbits, upb_strview *dst);
+
+UPB_NOINLINE
+static const char *fastdecode_verifyutf8(upb_decstate *d, const char *ptr,
+ upb_msg *msg, intptr_t table,
+ uint64_t hasbits, upb_strview *dst) {
+ if (!decode_verifyutf8_inl(dst->data, dst->size)) {
+ return fastdecode_err(d);
+ }
+ return fastdecode_dispatch(d, ptr, msg, table, hasbits);
+}
+
+UPB_FORCEINLINE
+static const char *fastdecode_longstring(struct upb_decstate *d,
+ const char *ptr, upb_msg *msg,
+ intptr_t table, uint64_t hasbits,
+ upb_strview *dst,
+ bool validate_utf8) {
+ int size = (uint8_t)ptr[0]; // Could plumb through hasbits.
+ ptr++;
+ if (size & 0x80) {
+ ptr = fastdecode_longsize(ptr, &size);
+ }
+
+ if (UPB_UNLIKELY(fastdecode_boundscheck(ptr, size, d->limit_ptr))) {
+ dst->size = 0;
+ return fastdecode_err(d);
+ }
+
+ if (d->alias) {
+ dst->data = ptr;
+ dst->size = size;
+ } else {
+ char *data = upb_arena_malloc(&d->arena, size);
+ if (!data) {
+ return fastdecode_err(d);
+ }
+ memcpy(data, ptr, size);
+ dst->data = data;
+ dst->size = size;
+ }
+
+ if (validate_utf8) {
+ return fastdecode_verifyutf8(d, ptr + size, msg, table, hasbits, dst);
+ } else {
+ return fastdecode_dispatch(d, ptr + size, msg, table, hasbits);
+ }
+}
+
+UPB_NOINLINE
+static const char *fastdecode_longstring_utf8(struct upb_decstate *d,
+ const char *ptr, upb_msg *msg,
+ intptr_t table, uint64_t hasbits,
+ upb_strview *dst) {
+ return fastdecode_longstring(d, ptr, msg, table, hasbits, dst, true);
+}
+
+UPB_NOINLINE
+static const char *fastdecode_longstring_noutf8(struct upb_decstate *d,
+ const char *ptr, upb_msg *msg,
+ intptr_t table,
+ uint64_t hasbits,
+ upb_strview *dst) {
+ return fastdecode_longstring(d, ptr, msg, table, hasbits, dst, false);
+}
+
+UPB_FORCEINLINE
+static void fastdecode_docopy(upb_decstate *d, const char *ptr, uint32_t size,
+ int copy, char *data, upb_strview *dst) {
+ d->arena.head.ptr += copy;
+ dst->data = data;
+ UPB_UNPOISON_MEMORY_REGION(data, copy);
+ memcpy(data, ptr, copy);
+ UPB_POISON_MEMORY_REGION(data + size, copy - size);
+}
+
+UPB_FORCEINLINE
+static const char *fastdecode_copystring(UPB_PARSE_PARAMS, int tagbytes,
+ upb_card card, bool validate_utf8) {
+ upb_strview *dst;
+ fastdecode_arr farr;
+ int64_t size;
+ size_t arena_has;
+ size_t common_has;
+ char *buf;
+
+ UPB_ASSERT(!d->alias);
+ UPB_ASSERT(fastdecode_checktag(data, tagbytes));
+
+ dst = fastdecode_getfield(d, ptr, msg, &data, &hasbits, &farr,
+ sizeof(upb_strview), card);
+
+again:
+ if (card == CARD_r) {
+ dst = fastdecode_resizearr(d, dst, &farr, sizeof(upb_strview));
+ }
+
+ size = (uint8_t)ptr[tagbytes];
+ ptr += tagbytes + 1;
+ dst->size = size;
+
+ buf = d->arena.head.ptr;
+ arena_has = _upb_arenahas(&d->arena);
+ common_has = UPB_MIN(arena_has, (d->end - ptr) + 16);
+
+ if (UPB_LIKELY(size <= 15 - tagbytes)) {
+ if (arena_has < 16) goto longstr;
+ d->arena.head.ptr += 16;
+ memcpy(buf, ptr - tagbytes - 1, 16);
+ dst->data = buf + tagbytes + 1;
+ } else if (UPB_LIKELY(size <= 32)) {
+ if (UPB_UNLIKELY(common_has < 32)) goto longstr;
+ fastdecode_docopy(d, ptr, size, 32, buf, dst);
+ } else if (UPB_LIKELY(size <= 64)) {
+ if (UPB_UNLIKELY(common_has < 64)) goto longstr;
+ fastdecode_docopy(d, ptr, size, 64, buf, dst);
+ } else if (UPB_LIKELY(size < 128)) {
+ if (UPB_UNLIKELY(common_has < 128)) goto longstr;
+ fastdecode_docopy(d, ptr, size, 128, buf, dst);
+ } else {
+ goto longstr;
+ }
+
+ ptr += size;
+
+ if (card == CARD_r) {
+ if (validate_utf8 && !decode_verifyutf8_inl(dst->data, dst->size)) {
+ return fastdecode_err(d);
+ }
+ fastdecode_nextret ret = fastdecode_nextrepeated(
+ d, dst, &ptr, &farr, data, tagbytes, sizeof(upb_strview));
+ switch (ret.next) {
+ case FD_NEXT_SAMEFIELD:
+ dst = ret.dst;
+ goto again;
+ case FD_NEXT_OTHERFIELD:
+ return fastdecode_tagdispatch(d, ptr, msg, table, hasbits, ret.tag);
+ case FD_NEXT_ATLIMIT:
+ return ptr;
+ }
+ }
+
+ if (card != CARD_r && validate_utf8) {
+ return fastdecode_verifyutf8(d, ptr, msg, table, hasbits, dst);
+ }
+
+ return fastdecode_dispatch(d, ptr, msg, table, hasbits);
+
+longstr:
+ ptr--;
+ if (validate_utf8) {
+ return fastdecode_longstring_utf8(d, ptr, msg, table, hasbits, dst);
+ } else {
+ return fastdecode_longstring_noutf8(d, ptr, msg, table, hasbits, dst);
+ }
+}
+
+UPB_FORCEINLINE
+static const char *fastdecode_string(UPB_PARSE_PARAMS, int tagbytes,
+ upb_card card, _upb_field_parser *copyfunc,
+ bool validate_utf8) {
+ upb_strview *dst;
+ fastdecode_arr farr;
+ int64_t size;
+
+ if (UPB_UNLIKELY(!fastdecode_checktag(data, tagbytes))) {
+ RETURN_GENERIC("string field tag mismatch\n");
+ }
+
+ if (UPB_UNLIKELY(!d->alias)) {
+ return copyfunc(UPB_PARSE_ARGS);
+ }
+
+ dst = fastdecode_getfield(d, ptr, msg, &data, &hasbits, &farr,
+ sizeof(upb_strview), card);
+
+again:
+ if (card == CARD_r) {
+ dst = fastdecode_resizearr(d, dst, &farr, sizeof(upb_strview));
+ }
+
+ size = (int8_t)ptr[tagbytes];
+ ptr += tagbytes + 1;
+ dst->data = ptr;
+ dst->size = size;
+
+ if (UPB_UNLIKELY(fastdecode_boundscheck(ptr, size, d->end))) {
+ ptr--;
+ if (validate_utf8) {
+ return fastdecode_longstring_utf8(d, ptr, msg, table, hasbits, dst);
+ } else {
+ return fastdecode_longstring_noutf8(d, ptr, msg, table, hasbits, dst);
+ }
+ }
+
+ ptr += size;
+
+ if (card == CARD_r) {
+ if (validate_utf8 && !decode_verifyutf8_inl(dst->data, dst->size)) {
+ return fastdecode_err(d);
+ }
+ fastdecode_nextret ret = fastdecode_nextrepeated(
+ d, dst, &ptr, &farr, data, tagbytes, sizeof(upb_strview));
+ switch (ret.next) {
+ case FD_NEXT_SAMEFIELD:
+ dst = ret.dst;
+ if (UPB_UNLIKELY(!d->alias)) {
+ // Buffer flipped and we can't alias any more. Bounce to copyfunc(),
+ // but via dispatch since we need to reload table data also.
+ fastdecode_commitarr(dst, &farr, sizeof(upb_strview));
+ return fastdecode_tagdispatch(d, ptr, msg, table, hasbits, ret.tag);
+ }
+ goto again;
+ case FD_NEXT_OTHERFIELD:
+ return fastdecode_tagdispatch(d, ptr, msg, table, hasbits, ret.tag);
+ case FD_NEXT_ATLIMIT:
+ return ptr;
+ }
+ }
+
+ if (card != CARD_r && validate_utf8) {
+ return fastdecode_verifyutf8(d, ptr, msg, table, hasbits, dst);
+ }
+
+ return fastdecode_dispatch(d, ptr, msg, table, hasbits);
+}
+
+/* Generate all combinations:
+ * {p,c} x {s,o,r} x {s, b} x {1bt,2bt} */
+
+#define s_VALIDATE true
+#define b_VALIDATE false
+
+#define F(card, tagbytes, type) \
+ UPB_NOINLINE \
+ const char *upb_c##card##type##_##tagbytes##bt(UPB_PARSE_PARAMS) { \
+ return fastdecode_copystring(UPB_PARSE_ARGS, tagbytes, CARD_##card, \
+ type##_VALIDATE); \
+ } \
+ const char *upb_p##card##type##_##tagbytes##bt(UPB_PARSE_PARAMS) { \
+ return fastdecode_string(UPB_PARSE_ARGS, tagbytes, CARD_##card, \
+ &upb_c##card##type##_##tagbytes##bt, \
+ type##_VALIDATE); \
+ }
+
+#define UTF8(card, tagbytes) \
+ F(card, tagbytes, s) \
+ F(card, tagbytes, b)
+
+#define TAGBYTES(card) \
+ UTF8(card, 1) \
+ UTF8(card, 2)
+
+TAGBYTES(s)
+TAGBYTES(o)
+TAGBYTES(r)
+
+#undef s_VALIDATE
+#undef b_VALIDATE
+#undef F
+#undef TAGBYTES
+
+/* message fields *************************************************************/
+
+UPB_INLINE
+upb_msg *decode_newmsg_ceil(upb_decstate *d, const upb_msglayout *l,
+ int msg_ceil_bytes) {
+ size_t size = l->size + sizeof(upb_msg_internal);
+ char *msg_data;
+ if (UPB_LIKELY(msg_ceil_bytes > 0 &&
+ _upb_arenahas(&d->arena) >= msg_ceil_bytes)) {
+ UPB_ASSERT(size <= (size_t)msg_ceil_bytes);
+ msg_data = d->arena.head.ptr;
+ d->arena.head.ptr += size;
+ UPB_UNPOISON_MEMORY_REGION(msg_data, msg_ceil_bytes);
+ memset(msg_data, 0, msg_ceil_bytes);
+ UPB_POISON_MEMORY_REGION(msg_data + size, msg_ceil_bytes - size);
+ } else {
+ msg_data = (char*)upb_arena_malloc(&d->arena, size);
+ memset(msg_data, 0, size);
+ }
+ return msg_data + sizeof(upb_msg_internal);
+}
+
+typedef struct {
+ intptr_t table;
+ upb_msg *msg;
+} fastdecode_submsgdata;
+
+UPB_FORCEINLINE
+static const char *fastdecode_tosubmsg(upb_decstate *d, const char *ptr,
+ void *ctx) {
+ fastdecode_submsgdata *submsg = ctx;
+ ptr = fastdecode_dispatch(d, ptr, submsg->msg, submsg->table, 0);
+ UPB_ASSUME(ptr != NULL);
+ return ptr;
+}
+
+UPB_FORCEINLINE
+static const char *fastdecode_submsg(UPB_PARSE_PARAMS, int tagbytes,
+ int msg_ceil_bytes, upb_card card) {
+
+ if (UPB_UNLIKELY(!fastdecode_checktag(data, tagbytes))) {
+ RETURN_GENERIC("submessage field tag mismatch\n");
+ }
+
+ if (--d->depth == 0) return fastdecode_err(d);
+
+ upb_msg **dst;
+ uint32_t submsg_idx = (data >> 16) & 0xff;
+ const upb_msglayout *tablep = decode_totablep(table);
+ const upb_msglayout *subtablep = tablep->submsgs[submsg_idx];
+ fastdecode_submsgdata submsg = {decode_totable(subtablep)};
+ fastdecode_arr farr;
+
+ if (subtablep->table_mask == (uint8_t)-1) {
+ RETURN_GENERIC("submessage doesn't have fast tables.");
+ }
+
+ dst = fastdecode_getfield(d, ptr, msg, &data, &hasbits, &farr,
+ sizeof(upb_msg *), card);
+
+ if (card == CARD_s) {
+ *(uint32_t*)msg |= hasbits;
+ hasbits = 0;
+ }
+
+again:
+ if (card == CARD_r) {
+ dst = fastdecode_resizearr(d, dst, &farr, sizeof(upb_msg*));
+ }
+
+ submsg.msg = *dst;
+
+ if (card == CARD_r || UPB_LIKELY(!submsg.msg)) {
+ *dst = submsg.msg = decode_newmsg_ceil(d, subtablep, msg_ceil_bytes);
+ }
+
+ ptr += tagbytes;
+ ptr = fastdecode_delimited(d, ptr, fastdecode_tosubmsg, &submsg);
+
+ if (UPB_UNLIKELY(ptr == NULL || d->end_group != DECODE_NOGROUP)) {
+ return fastdecode_err(d);
+ }
+
+ if (card == CARD_r) {
+ fastdecode_nextret ret = fastdecode_nextrepeated(
+ d, dst, &ptr, &farr, data, tagbytes, sizeof(upb_msg *));
+ switch (ret.next) {
+ case FD_NEXT_SAMEFIELD:
+ dst = ret.dst;
+ goto again;
+ case FD_NEXT_OTHERFIELD:
+ d->depth++;
+ return fastdecode_tagdispatch(d, ptr, msg, table, hasbits, ret.tag);
+ case FD_NEXT_ATLIMIT:
+ d->depth++;
+ return ptr;
+ }
+ }
+
+ d->depth++;
+ return fastdecode_dispatch(d, ptr, msg, table, hasbits);
+}
+
+#define F(card, tagbytes, size_ceil, ceil_arg) \
+ const char *upb_p##card##m_##tagbytes##bt_max##size_ceil##b( \
+ UPB_PARSE_PARAMS) { \
+ return fastdecode_submsg(UPB_PARSE_ARGS, tagbytes, ceil_arg, CARD_##card); \
+ }
+
+#define SIZES(card, tagbytes) \
+ F(card, tagbytes, 64, 64) \
+ F(card, tagbytes, 128, 128) \
+ F(card, tagbytes, 192, 192) \
+ F(card, tagbytes, 256, 256) \
+ F(card, tagbytes, max, -1)
+
+#define TAGBYTES(card) \
+ SIZES(card, 1) \
+ SIZES(card, 2)
+
+TAGBYTES(s)
+TAGBYTES(o)
+TAGBYTES(r)
+
+#undef TAGBYTES
+#undef SIZES
+#undef F
+
+#endif /* UPB_FASTTABLE */
/* This file was generated by upbc (the upb compiler) from the input
* file:
*
@@ -2430,7 +3674,7 @@
const upb_msglayout google_protobuf_FileDescriptorSet_msginit = {
&google_protobuf_FileDescriptorSet_submsgs[0],
&google_protobuf_FileDescriptorSet__fields[0],
- UPB_SIZE(4, 8), 1, false,
+ UPB_SIZE(8, 8), 1, false, 255,
};
static const upb_msglayout *const google_protobuf_FileDescriptorProto_submsgs[6] = {
@@ -2450,17 +3694,17 @@
{5, UPB_SIZE(44, 88), 0, 1, 11, 3},
{6, UPB_SIZE(48, 96), 0, 4, 11, 3},
{7, UPB_SIZE(52, 104), 0, 2, 11, 3},
- {8, UPB_SIZE(28, 56), 4, 3, 11, 1},
- {9, UPB_SIZE(32, 64), 5, 5, 11, 1},
+ {8, UPB_SIZE(28, 56), 3, 3, 11, 1},
+ {9, UPB_SIZE(32, 64), 4, 5, 11, 1},
{10, UPB_SIZE(56, 112), 0, 0, 5, 3},
{11, UPB_SIZE(60, 120), 0, 0, 5, 3},
- {12, UPB_SIZE(20, 40), 3, 0, 12, 1},
+ {12, UPB_SIZE(20, 40), 5, 0, 12, 1},
};
const upb_msglayout google_protobuf_FileDescriptorProto_msginit = {
&google_protobuf_FileDescriptorProto_submsgs[0],
&google_protobuf_FileDescriptorProto__fields[0],
- UPB_SIZE(64, 128), 12, false,
+ UPB_SIZE(64, 128), 12, false, 255,
};
static const upb_msglayout *const google_protobuf_DescriptorProto_submsgs[7] = {
@@ -2489,7 +3733,7 @@
const upb_msglayout google_protobuf_DescriptorProto_msginit = {
&google_protobuf_DescriptorProto_submsgs[0],
&google_protobuf_DescriptorProto__fields[0],
- UPB_SIZE(48, 96), 10, false,
+ UPB_SIZE(48, 96), 10, false, 255,
};
static const upb_msglayout *const google_protobuf_DescriptorProto_ExtensionRange_submsgs[1] = {
@@ -2505,7 +3749,7 @@
const upb_msglayout google_protobuf_DescriptorProto_ExtensionRange_msginit = {
&google_protobuf_DescriptorProto_ExtensionRange_submsgs[0],
&google_protobuf_DescriptorProto_ExtensionRange__fields[0],
- UPB_SIZE(16, 24), 3, false,
+ UPB_SIZE(16, 24), 3, false, 255,
};
static const upb_msglayout_field google_protobuf_DescriptorProto_ReservedRange__fields[2] = {
@@ -2516,7 +3760,7 @@
const upb_msglayout google_protobuf_DescriptorProto_ReservedRange_msginit = {
NULL,
&google_protobuf_DescriptorProto_ReservedRange__fields[0],
- UPB_SIZE(12, 12), 2, false,
+ UPB_SIZE(16, 16), 2, false, 255,
};
static const upb_msglayout *const google_protobuf_ExtensionRangeOptions_submsgs[1] = {
@@ -2530,7 +3774,7 @@
const upb_msglayout google_protobuf_ExtensionRangeOptions_msginit = {
&google_protobuf_ExtensionRangeOptions_submsgs[0],
&google_protobuf_ExtensionRangeOptions__fields[0],
- UPB_SIZE(4, 8), 1, false,
+ UPB_SIZE(8, 8), 1, false, 255,
};
static const upb_msglayout *const google_protobuf_FieldDescriptorProto_submsgs[1] = {
@@ -2538,23 +3782,23 @@
};
static const upb_msglayout_field google_protobuf_FieldDescriptorProto__fields[11] = {
- {1, UPB_SIZE(24, 24), 6, 0, 12, 1},
- {2, UPB_SIZE(32, 40), 7, 0, 12, 1},
+ {1, UPB_SIZE(24, 24), 1, 0, 12, 1},
+ {2, UPB_SIZE(32, 40), 2, 0, 12, 1},
{3, UPB_SIZE(12, 12), 3, 0, 5, 1},
- {4, UPB_SIZE(4, 4), 1, 0, 14, 1},
- {5, UPB_SIZE(8, 8), 2, 0, 14, 1},
- {6, UPB_SIZE(40, 56), 8, 0, 12, 1},
- {7, UPB_SIZE(48, 72), 9, 0, 12, 1},
- {8, UPB_SIZE(64, 104), 11, 0, 11, 1},
- {9, UPB_SIZE(16, 16), 4, 0, 5, 1},
+ {4, UPB_SIZE(4, 4), 4, 0, 14, 1},
+ {5, UPB_SIZE(8, 8), 5, 0, 14, 1},
+ {6, UPB_SIZE(40, 56), 6, 0, 12, 1},
+ {7, UPB_SIZE(48, 72), 7, 0, 12, 1},
+ {8, UPB_SIZE(64, 104), 8, 0, 11, 1},
+ {9, UPB_SIZE(16, 16), 9, 0, 5, 1},
{10, UPB_SIZE(56, 88), 10, 0, 12, 1},
- {17, UPB_SIZE(20, 20), 5, 0, 8, 1},
+ {17, UPB_SIZE(20, 20), 11, 0, 8, 1},
};
const upb_msglayout google_protobuf_FieldDescriptorProto_msginit = {
&google_protobuf_FieldDescriptorProto_submsgs[0],
&google_protobuf_FieldDescriptorProto__fields[0],
- UPB_SIZE(72, 112), 11, false,
+ UPB_SIZE(72, 112), 11, false, 255,
};
static const upb_msglayout *const google_protobuf_OneofDescriptorProto_submsgs[1] = {
@@ -2569,7 +3813,7 @@
const upb_msglayout google_protobuf_OneofDescriptorProto_msginit = {
&google_protobuf_OneofDescriptorProto_submsgs[0],
&google_protobuf_OneofDescriptorProto__fields[0],
- UPB_SIZE(16, 32), 2, false,
+ UPB_SIZE(16, 32), 2, false, 255,
};
static const upb_msglayout *const google_protobuf_EnumDescriptorProto_submsgs[3] = {
@@ -2589,7 +3833,7 @@
const upb_msglayout google_protobuf_EnumDescriptorProto_msginit = {
&google_protobuf_EnumDescriptorProto_submsgs[0],
&google_protobuf_EnumDescriptorProto__fields[0],
- UPB_SIZE(32, 64), 5, false,
+ UPB_SIZE(32, 64), 5, false, 255,
};
static const upb_msglayout_field google_protobuf_EnumDescriptorProto_EnumReservedRange__fields[2] = {
@@ -2600,7 +3844,7 @@
const upb_msglayout google_protobuf_EnumDescriptorProto_EnumReservedRange_msginit = {
NULL,
&google_protobuf_EnumDescriptorProto_EnumReservedRange__fields[0],
- UPB_SIZE(12, 12), 2, false,
+ UPB_SIZE(16, 16), 2, false, 255,
};
static const upb_msglayout *const google_protobuf_EnumValueDescriptorProto_submsgs[1] = {
@@ -2608,15 +3852,15 @@
};
static const upb_msglayout_field google_protobuf_EnumValueDescriptorProto__fields[3] = {
- {1, UPB_SIZE(8, 8), 2, 0, 12, 1},
- {2, UPB_SIZE(4, 4), 1, 0, 5, 1},
+ {1, UPB_SIZE(8, 8), 1, 0, 12, 1},
+ {2, UPB_SIZE(4, 4), 2, 0, 5, 1},
{3, UPB_SIZE(16, 24), 3, 0, 11, 1},
};
const upb_msglayout google_protobuf_EnumValueDescriptorProto_msginit = {
&google_protobuf_EnumValueDescriptorProto_submsgs[0],
&google_protobuf_EnumValueDescriptorProto__fields[0],
- UPB_SIZE(24, 32), 3, false,
+ UPB_SIZE(24, 32), 3, false, 255,
};
static const upb_msglayout *const google_protobuf_ServiceDescriptorProto_submsgs[2] = {
@@ -2633,7 +3877,7 @@
const upb_msglayout google_protobuf_ServiceDescriptorProto_msginit = {
&google_protobuf_ServiceDescriptorProto_submsgs[0],
&google_protobuf_ServiceDescriptorProto__fields[0],
- UPB_SIZE(24, 48), 3, false,
+ UPB_SIZE(24, 48), 3, false, 255,
};
static const upb_msglayout *const google_protobuf_MethodDescriptorProto_submsgs[1] = {
@@ -2641,18 +3885,18 @@
};
static const upb_msglayout_field google_protobuf_MethodDescriptorProto__fields[6] = {
- {1, UPB_SIZE(4, 8), 3, 0, 12, 1},
- {2, UPB_SIZE(12, 24), 4, 0, 12, 1},
- {3, UPB_SIZE(20, 40), 5, 0, 12, 1},
- {4, UPB_SIZE(28, 56), 6, 0, 11, 1},
- {5, UPB_SIZE(1, 1), 1, 0, 8, 1},
- {6, UPB_SIZE(2, 2), 2, 0, 8, 1},
+ {1, UPB_SIZE(4, 8), 1, 0, 12, 1},
+ {2, UPB_SIZE(12, 24), 2, 0, 12, 1},
+ {3, UPB_SIZE(20, 40), 3, 0, 12, 1},
+ {4, UPB_SIZE(28, 56), 4, 0, 11, 1},
+ {5, UPB_SIZE(1, 1), 5, 0, 8, 1},
+ {6, UPB_SIZE(2, 2), 6, 0, 8, 1},
};
const upb_msglayout google_protobuf_MethodDescriptorProto_msginit = {
&google_protobuf_MethodDescriptorProto_submsgs[0],
&google_protobuf_MethodDescriptorProto__fields[0],
- UPB_SIZE(32, 64), 6, false,
+ UPB_SIZE(32, 64), 6, false, 255,
};
static const upb_msglayout *const google_protobuf_FileOptions_submsgs[1] = {
@@ -2660,24 +3904,24 @@
};
static const upb_msglayout_field google_protobuf_FileOptions__fields[21] = {
- {1, UPB_SIZE(20, 24), 11, 0, 12, 1},
- {8, UPB_SIZE(28, 40), 12, 0, 12, 1},
- {9, UPB_SIZE(4, 4), 1, 0, 14, 1},
- {10, UPB_SIZE(8, 8), 2, 0, 8, 1},
- {11, UPB_SIZE(36, 56), 13, 0, 12, 1},
- {16, UPB_SIZE(9, 9), 3, 0, 8, 1},
- {17, UPB_SIZE(10, 10), 4, 0, 8, 1},
- {18, UPB_SIZE(11, 11), 5, 0, 8, 1},
- {20, UPB_SIZE(12, 12), 6, 0, 8, 1},
- {23, UPB_SIZE(13, 13), 7, 0, 8, 1},
- {27, UPB_SIZE(14, 14), 8, 0, 8, 1},
- {31, UPB_SIZE(15, 15), 9, 0, 8, 1},
- {36, UPB_SIZE(44, 72), 14, 0, 12, 1},
- {37, UPB_SIZE(52, 88), 15, 0, 12, 1},
- {39, UPB_SIZE(60, 104), 16, 0, 12, 1},
- {40, UPB_SIZE(68, 120), 17, 0, 12, 1},
- {41, UPB_SIZE(76, 136), 18, 0, 12, 1},
- {42, UPB_SIZE(16, 16), 10, 0, 8, 1},
+ {1, UPB_SIZE(20, 24), 1, 0, 12, 1},
+ {8, UPB_SIZE(28, 40), 2, 0, 12, 1},
+ {9, UPB_SIZE(4, 4), 3, 0, 14, 1},
+ {10, UPB_SIZE(8, 8), 4, 0, 8, 1},
+ {11, UPB_SIZE(36, 56), 5, 0, 12, 1},
+ {16, UPB_SIZE(9, 9), 6, 0, 8, 1},
+ {17, UPB_SIZE(10, 10), 7, 0, 8, 1},
+ {18, UPB_SIZE(11, 11), 8, 0, 8, 1},
+ {20, UPB_SIZE(12, 12), 9, 0, 8, 1},
+ {23, UPB_SIZE(13, 13), 10, 0, 8, 1},
+ {27, UPB_SIZE(14, 14), 11, 0, 8, 1},
+ {31, UPB_SIZE(15, 15), 12, 0, 8, 1},
+ {36, UPB_SIZE(44, 72), 13, 0, 12, 1},
+ {37, UPB_SIZE(52, 88), 14, 0, 12, 1},
+ {39, UPB_SIZE(60, 104), 15, 0, 12, 1},
+ {40, UPB_SIZE(68, 120), 16, 0, 12, 1},
+ {41, UPB_SIZE(76, 136), 17, 0, 12, 1},
+ {42, UPB_SIZE(16, 16), 18, 0, 8, 1},
{44, UPB_SIZE(84, 152), 19, 0, 12, 1},
{45, UPB_SIZE(92, 168), 20, 0, 12, 1},
{999, UPB_SIZE(100, 184), 0, 0, 11, 3},
@@ -2686,7 +3930,7 @@
const upb_msglayout google_protobuf_FileOptions_msginit = {
&google_protobuf_FileOptions_submsgs[0],
&google_protobuf_FileOptions__fields[0],
- UPB_SIZE(104, 192), 21, false,
+ UPB_SIZE(104, 192), 21, false, 255,
};
static const upb_msglayout *const google_protobuf_MessageOptions_submsgs[1] = {
@@ -2704,7 +3948,7 @@
const upb_msglayout google_protobuf_MessageOptions_msginit = {
&google_protobuf_MessageOptions_submsgs[0],
&google_protobuf_MessageOptions__fields[0],
- UPB_SIZE(12, 16), 5, false,
+ UPB_SIZE(16, 16), 5, false, 255,
};
static const upb_msglayout *const google_protobuf_FieldOptions_submsgs[1] = {
@@ -2713,10 +3957,10 @@
static const upb_msglayout_field google_protobuf_FieldOptions__fields[7] = {
{1, UPB_SIZE(4, 4), 1, 0, 14, 1},
- {2, UPB_SIZE(12, 12), 3, 0, 8, 1},
- {3, UPB_SIZE(13, 13), 4, 0, 8, 1},
- {5, UPB_SIZE(14, 14), 5, 0, 8, 1},
- {6, UPB_SIZE(8, 8), 2, 0, 14, 1},
+ {2, UPB_SIZE(12, 12), 2, 0, 8, 1},
+ {3, UPB_SIZE(13, 13), 3, 0, 8, 1},
+ {5, UPB_SIZE(14, 14), 4, 0, 8, 1},
+ {6, UPB_SIZE(8, 8), 5, 0, 14, 1},
{10, UPB_SIZE(15, 15), 6, 0, 8, 1},
{999, UPB_SIZE(16, 16), 0, 0, 11, 3},
};
@@ -2724,7 +3968,7 @@
const upb_msglayout google_protobuf_FieldOptions_msginit = {
&google_protobuf_FieldOptions_submsgs[0],
&google_protobuf_FieldOptions__fields[0],
- UPB_SIZE(20, 24), 7, false,
+ UPB_SIZE(24, 24), 7, false, 255,
};
static const upb_msglayout *const google_protobuf_OneofOptions_submsgs[1] = {
@@ -2738,7 +3982,7 @@
const upb_msglayout google_protobuf_OneofOptions_msginit = {
&google_protobuf_OneofOptions_submsgs[0],
&google_protobuf_OneofOptions__fields[0],
- UPB_SIZE(4, 8), 1, false,
+ UPB_SIZE(8, 8), 1, false, 255,
};
static const upb_msglayout *const google_protobuf_EnumOptions_submsgs[1] = {
@@ -2754,7 +3998,7 @@
const upb_msglayout google_protobuf_EnumOptions_msginit = {
&google_protobuf_EnumOptions_submsgs[0],
&google_protobuf_EnumOptions__fields[0],
- UPB_SIZE(8, 16), 3, false,
+ UPB_SIZE(8, 16), 3, false, 255,
};
static const upb_msglayout *const google_protobuf_EnumValueOptions_submsgs[1] = {
@@ -2769,7 +4013,7 @@
const upb_msglayout google_protobuf_EnumValueOptions_msginit = {
&google_protobuf_EnumValueOptions_submsgs[0],
&google_protobuf_EnumValueOptions__fields[0],
- UPB_SIZE(8, 16), 2, false,
+ UPB_SIZE(8, 16), 2, false, 255,
};
static const upb_msglayout *const google_protobuf_ServiceOptions_submsgs[1] = {
@@ -2784,7 +4028,7 @@
const upb_msglayout google_protobuf_ServiceOptions_msginit = {
&google_protobuf_ServiceOptions_submsgs[0],
&google_protobuf_ServiceOptions__fields[0],
- UPB_SIZE(8, 16), 2, false,
+ UPB_SIZE(8, 16), 2, false, 255,
};
static const upb_msglayout *const google_protobuf_MethodOptions_submsgs[1] = {
@@ -2792,15 +4036,15 @@
};
static const upb_msglayout_field google_protobuf_MethodOptions__fields[3] = {
- {33, UPB_SIZE(8, 8), 2, 0, 8, 1},
- {34, UPB_SIZE(4, 4), 1, 0, 14, 1},
+ {33, UPB_SIZE(8, 8), 1, 0, 8, 1},
+ {34, UPB_SIZE(4, 4), 2, 0, 14, 1},
{999, UPB_SIZE(12, 16), 0, 0, 11, 3},
};
const upb_msglayout google_protobuf_MethodOptions_msginit = {
&google_protobuf_MethodOptions_submsgs[0],
&google_protobuf_MethodOptions__fields[0],
- UPB_SIZE(16, 24), 3, false,
+ UPB_SIZE(16, 24), 3, false, 255,
};
static const upb_msglayout *const google_protobuf_UninterpretedOption_submsgs[1] = {
@@ -2809,10 +4053,10 @@
static const upb_msglayout_field google_protobuf_UninterpretedOption__fields[7] = {
{2, UPB_SIZE(56, 80), 0, 0, 11, 3},
- {3, UPB_SIZE(32, 32), 4, 0, 12, 1},
- {4, UPB_SIZE(8, 8), 1, 0, 4, 1},
- {5, UPB_SIZE(16, 16), 2, 0, 3, 1},
- {6, UPB_SIZE(24, 24), 3, 0, 1, 1},
+ {3, UPB_SIZE(32, 32), 1, 0, 12, 1},
+ {4, UPB_SIZE(8, 8), 2, 0, 4, 1},
+ {5, UPB_SIZE(16, 16), 3, 0, 3, 1},
+ {6, UPB_SIZE(24, 24), 4, 0, 1, 1},
{7, UPB_SIZE(40, 48), 5, 0, 12, 1},
{8, UPB_SIZE(48, 64), 6, 0, 12, 1},
};
@@ -2820,18 +4064,18 @@
const upb_msglayout google_protobuf_UninterpretedOption_msginit = {
&google_protobuf_UninterpretedOption_submsgs[0],
&google_protobuf_UninterpretedOption__fields[0],
- UPB_SIZE(64, 96), 7, false,
+ UPB_SIZE(64, 96), 7, false, 255,
};
static const upb_msglayout_field google_protobuf_UninterpretedOption_NamePart__fields[2] = {
- {1, UPB_SIZE(4, 8), 2, 0, 12, 2},
- {2, UPB_SIZE(1, 1), 1, 0, 8, 2},
+ {1, UPB_SIZE(4, 8), 1, 0, 12, 2},
+ {2, UPB_SIZE(1, 1), 2, 0, 8, 2},
};
const upb_msglayout google_protobuf_UninterpretedOption_NamePart_msginit = {
NULL,
&google_protobuf_UninterpretedOption_NamePart__fields[0],
- UPB_SIZE(16, 32), 2, false,
+ UPB_SIZE(16, 32), 2, false, 255,
};
static const upb_msglayout *const google_protobuf_SourceCodeInfo_submsgs[1] = {
@@ -2845,7 +4089,7 @@
const upb_msglayout google_protobuf_SourceCodeInfo_msginit = {
&google_protobuf_SourceCodeInfo_submsgs[0],
&google_protobuf_SourceCodeInfo__fields[0],
- UPB_SIZE(4, 8), 1, false,
+ UPB_SIZE(8, 8), 1, false, 255,
};
static const upb_msglayout_field google_protobuf_SourceCodeInfo_Location__fields[5] = {
@@ -2859,7 +4103,7 @@
const upb_msglayout google_protobuf_SourceCodeInfo_Location_msginit = {
NULL,
&google_protobuf_SourceCodeInfo_Location__fields[0],
- UPB_SIZE(32, 64), 5, false,
+ UPB_SIZE(32, 64), 5, false, 255,
};
static const upb_msglayout *const google_protobuf_GeneratedCodeInfo_submsgs[1] = {
@@ -2873,20 +4117,20 @@
const upb_msglayout google_protobuf_GeneratedCodeInfo_msginit = {
&google_protobuf_GeneratedCodeInfo_submsgs[0],
&google_protobuf_GeneratedCodeInfo__fields[0],
- UPB_SIZE(4, 8), 1, false,
+ UPB_SIZE(8, 8), 1, false, 255,
};
static const upb_msglayout_field google_protobuf_GeneratedCodeInfo_Annotation__fields[4] = {
{1, UPB_SIZE(20, 32), 0, 0, 5, _UPB_LABEL_PACKED},
- {2, UPB_SIZE(12, 16), 3, 0, 12, 1},
- {3, UPB_SIZE(4, 4), 1, 0, 5, 1},
- {4, UPB_SIZE(8, 8), 2, 0, 5, 1},
+ {2, UPB_SIZE(12, 16), 1, 0, 12, 1},
+ {3, UPB_SIZE(4, 4), 2, 0, 5, 1},
+ {4, UPB_SIZE(8, 8), 3, 0, 5, 1},
};
const upb_msglayout google_protobuf_GeneratedCodeInfo_Annotation_msginit = {
NULL,
&google_protobuf_GeneratedCodeInfo_Annotation__fields[0],
- UPB_SIZE(24, 48), 4, false,
+ UPB_SIZE(24, 48), 4, false, 255,
};
@@ -3283,6 +4527,8 @@
#include <string.h>
+/* Must be last. */
+
typedef struct {
size_t len;
char str[1]; /* Null-terminated string data follows. */
@@ -3366,17 +4612,18 @@
const char *package;
const char *phpprefix;
const char *phpnamespace;
- upb_syntax_t syntax;
const upb_filedef **deps;
const upb_msgdef *msgs;
const upb_enumdef *enums;
const upb_fielddef *exts;
+ const upb_symtab *symtab;
int dep_count;
int msg_count;
int enum_count;
int ext_count;
+ upb_syntax_t syntax;
};
struct upb_symtab {
@@ -3679,6 +4926,23 @@
return f->oneof;
}
+upb_msgval upb_fielddef_default(const upb_fielddef *f) {
+ UPB_ASSERT(!upb_fielddef_issubmsg(f));
+ upb_msgval ret;
+ if (upb_fielddef_isstring(f)) {
+ str_t *str = f->defaultval.str;
+ if (str) {
+ ret.str_val.data = str->str;
+ ret.str_val.size = str->len;
+ } else {
+ ret.str_val.size = 0;
+ }
+ } else {
+ memcpy(&ret, &f->defaultval, 8);
+ }
+ return ret;
+}
+
static void chkdefaulttype(const upb_fielddef *f, int ctype) {
UPB_UNUSED(f);
UPB_UNUSED(ctype);
@@ -4096,6 +5360,10 @@
return i < 0 || i >= f->enum_count ? NULL : &f->enums[i];
}
+const upb_symtab *upb_filedef_symtab(const upb_filedef *f) {
+ return f->symtab;
+}
+
void upb_symtab_free(upb_symtab *s) {
upb_arena_free(s->arena);
upb_gfree(s);
@@ -4177,19 +5445,19 @@
jmp_buf err; /* longjmp() on error. */
} symtab_addctx;
-UPB_NORETURN UPB_NOINLINE
+UPB_NORETURN UPB_NOINLINE UPB_PRINTF(2, 3)
static void symtab_errf(symtab_addctx *ctx, const char *fmt, ...) {
va_list argp;
va_start(argp, fmt);
upb_status_vseterrf(ctx->status, fmt, argp);
va_end(argp);
- longjmp(ctx->err, 1);
+ UPB_LONGJMP(ctx->err, 1);
}
UPB_NORETURN UPB_NOINLINE
static void symtab_oomerr(symtab_addctx *ctx) {
upb_status_setoom(ctx->status);
- longjmp(ctx->err, 1);
+ UPB_LONGJMP(ctx->err, 1);
}
void *symtab_alloc(symtab_addctx *ctx, size_t bytes) {
@@ -4304,7 +5572,7 @@
const upb_msglayout **submsgs;
upb_msglayout_field *fields;
- memset(l, 0, sizeof(*l));
+ memset(l, 0, sizeof(*l) + sizeof(_upb_fasttable_entry));
fields = symtab_alloc(ctx, upb_msgdef_numfields(m) * sizeof(*fields));
submsgs = symtab_alloc(ctx, submsg_count * sizeof(*submsgs));
@@ -4312,6 +5580,12 @@
l->field_count = upb_msgdef_numfields(m);
l->fields = fields;
l->submsgs = submsgs;
+ l->table_mask = 0;
+
+ /* TODO(haberman): initialize fast tables so that reflection-based parsing
+ * can get the same speeds as linked-in types. */
+ l->fasttable[0].field_parser = &fastdecode_generic;
+ l->fasttable[0].field_data = 0;
if (upb_msgdef_mapentry(m)) {
/* TODO(haberman): refactor this method so this special case is more
@@ -4785,7 +6059,7 @@
return;
invalid:
- symtab_errf(ctx, "Invalid default '%.*s' for field %f", (int)len, str,
+ symtab_errf(ctx, "Invalid default '%.*s' for field %s", (int)len, str,
upb_fielddef_fullname(f));
}
@@ -5074,7 +6348,8 @@
ctx->layouts++;
} else {
/* Allocate now (to allow cross-linking), populate later. */
- m->layout = symtab_alloc(ctx, sizeof(*m->layout));
+ m->layout = symtab_alloc(
+ ctx, sizeof(*m->layout) + sizeof(_upb_fasttable_entry));
}
m->oneof_count = 0;
@@ -5359,8 +6634,9 @@
file->msg_count = 0;
file->enum_count = 0;
file->ext_count = 0;
+ file->symtab = s;
- if (UPB_UNLIKELY(setjmp(ctx.err))) {
+ if (UPB_UNLIKELY(UPB_SETJMP(ctx.err))) {
UPB_ASSERT(!upb_ok(status));
remove_filedef(s, file);
file = NULL;
@@ -5406,8 +6682,8 @@
if (!_upb_symtab_loaddefinit(s, *deps)) goto err;
}
- file = google_protobuf_FileDescriptorProto_parse(
- init->descriptor.data, init->descriptor.size, arena);
+ file = google_protobuf_FileDescriptorProto_parse_ex(
+ init->descriptor.data, init->descriptor.size, arena, UPB_DECODE_ALIAS);
s->bytes_loaded += init->descriptor.size;
if (!file) {
@@ -5570,7 +6846,7 @@
val.double_val = upb_fielddef_defaultdouble(f);
break;
case UPB_TYPE_BOOL:
- val.double_val = upb_fielddef_defaultbool(f);
+ val.bool_val = upb_fielddef_defaultbool(f);
break;
case UPB_TYPE_STRING:
case UPB_TYPE_BYTES:
@@ -5795,6 +7071,10 @@
return _upb_map_get(map, &key, map->key_size, val, map->val_size);
}
+void upb_map_clear(upb_map *map) {
+ _upb_map_clear(map);
+}
+
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);
@@ -5838,31 +7118,6 @@
/* void upb_mapiter_setvalue(upb_map *map, size_t iter, upb_msgval value); */
-#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
-
-
#include <errno.h>
#include <float.h>
#include <inttypes.h>
@@ -5918,9 +7173,10 @@
UPB_NORETURN static void jsondec_err(jsondec *d, const char *msg) {
upb_status_seterrf(d->status, "Error parsing JSON @%d:%d: %s", d->line,
(int)(d->ptr - d->line_begin), msg);
- longjmp(d->err, 1);
+ UPB_LONGJMP(d->err, 1);
}
+UPB_PRINTF(2, 3)
UPB_NORETURN static void jsondec_errf(jsondec *d, const char *fmt, ...) {
va_list argp;
upb_status_seterrf(d->status, "Error parsing JSON @%d:%d: ", d->line,
@@ -5928,7 +7184,7 @@
va_start(argp, fmt);
upb_status_vappenderrf(d->status, fmt, argp);
va_end(argp);
- longjmp(d->err, 1);
+ UPB_LONGJMP(d->err, 1);
}
static void jsondec_skipws(jsondec *d) {
@@ -6537,7 +7793,7 @@
}
val.int64_val = dbl; /* must be guarded, overflow here is UB */
if (val.int64_val != dbl) {
- jsondec_errf(d, "JSON number was not integral (%d != %" PRId64 ")", dbl,
+ jsondec_errf(d, "JSON number was not integral (%f != %" PRId64 ")", dbl,
val.int64_val);
}
break;
@@ -6563,7 +7819,7 @@
/* Parse UINT32 or UINT64 value. */
static upb_msgval jsondec_uint(jsondec *d, const upb_fielddef *f) {
- upb_msgval val;
+ upb_msgval val = {0};
switch (jsondec_peek(d)) {
case JD_NUMBER: {
@@ -6573,7 +7829,7 @@
}
val.uint64_val = dbl; /* must be guarded, overflow here is UB */
if (val.uint64_val != dbl) {
- jsondec_errf(d, "JSON number was not integral (%d != %" PRIu64 ")", dbl,
+ jsondec_errf(d, "JSON number was not integral (%f != %" PRIu64 ")", dbl,
val.uint64_val);
}
break;
@@ -6600,7 +7856,7 @@
/* Parse DOUBLE or FLOAT value. */
static upb_msgval jsondec_double(jsondec *d, const upb_fielddef *f) {
upb_strview str;
- upb_msgval val;
+ upb_msgval val = {0};
switch (jsondec_peek(d)) {
case JD_NUMBER:
@@ -7295,7 +8551,7 @@
d.debug_field = NULL;
d.is_first = false;
- if (setjmp(d.err)) return false;
+ if (UPB_SETJMP(d.err)) return false;
jsondec_tomsg(&d, msg, m);
return true;
@@ -7338,6 +8594,7 @@
longjmp(e->err, 1);
}
+UPB_PRINTF(2, 3)
UPB_NORETURN static void jsonenc_errf(jsonenc *e, const char *fmt, ...) {
va_list argp;
va_start(argp, fmt);
@@ -7370,6 +8627,7 @@
jsonenc_putbytes(e, str, strlen(str));
}
+UPB_PRINTF(2, 3)
static void jsonenc_printf(jsonenc *e, const char *fmt, ...) {
size_t n;
size_t have = e->end - e->ptr;
@@ -7400,7 +8658,7 @@
digits -= 3;
}
- jsonenc_printf(e, ".%0.*" PRId32, digits, nanos);
+ jsonenc_printf(e, ".%.*" PRId32, digits, nanos);
}
static void jsonenc_timestamp(jsonenc *e, const upb_msg *msg,
@@ -7892,7 +9150,7 @@
static void jsonenc_array(jsonenc *e, const upb_array *arr,
const upb_fielddef *f) {
size_t i;
- size_t size = upb_array_size(arr);
+ size_t size = arr ? upb_array_size(arr) : 0;
bool first = true;
jsonenc_putstr(e, "[");
@@ -7914,10 +9172,12 @@
jsonenc_putstr(e, "{");
- while (upb_mapiter_next(map, &iter)) {
- jsonenc_putsep(e, ",", &first);
- jsonenc_mapkey(e, upb_mapiter_key(map, iter), key_f);
- jsonenc_scalar(e, upb_mapiter_value(map, iter), val_f);
+ if (map) {
+ while (upb_mapiter_next(map, &iter)) {
+ jsonenc_putsep(e, ",", &first);
+ jsonenc_mapkey(e, upb_mapiter_key(map, iter), key_f);
+ jsonenc_scalar(e, upb_mapiter_value(map, iter), val_f);
+ }
}
jsonenc_putstr(e, "}");
@@ -7957,7 +9217,9 @@
int n = upb_msgdef_fieldcount(m);
for (i = 0; i < n; i++) {
f = upb_msgdef_field(m, i);
- jsonenc_fieldval(e, f, upb_msg_get(msg, f), &first);
+ if (!upb_fielddef_haspresence(f) || upb_msg_has(msg, f)) {
+ jsonenc_fieldval(e, f, upb_msg_get(msg, f), &first);
+ }
}
} else {
/* Iterate over non-empty fields. */
diff --git a/php/ext/google/protobuf/php-upb.h b/php/ext/google/protobuf/php-upb.h
index d22b4aa..996a6d8 100644
--- a/php/ext/google/protobuf/php-upb.h
+++ b/php/ext/google/protobuf/php-upb.h
@@ -22,12 +22,10 @@
* This file is private and must not be included by users!
*/
-#if !(__STDC_VERSION__ >= 199901L || __cplusplus >= 201103L)
-#error upb requires C99 or C++11
-#endif
-
-#if (defined(_MSC_VER) && _MSC_VER < 1900)
-#error upb requires MSVC >= 2015.
+#if !((defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || \
+ (defined(__cplusplus) && __cplusplus >= 201103L) || \
+ (defined(_MSC_VER) && _MSC_VER >= 1900))
+#error upb requires C99 or C++11 or MSVC >= 2015.
#endif
#include <stdint.h>
@@ -83,14 +81,17 @@
#define UPB_FORCEINLINE __inline__ __attribute__((always_inline))
#define UPB_NOINLINE __attribute__((noinline))
#define UPB_NORETURN __attribute__((__noreturn__))
+#define UPB_PRINTF(str, first_vararg) __attribute__((format (printf, str, first_vararg)))
#elif defined(_MSC_VER)
#define UPB_NOINLINE
#define UPB_FORCEINLINE
#define UPB_NORETURN __declspec(noreturn)
+#define UPB_PRINTF(str, first_vararg)
#else /* !defined(__GNUC__) */
#define UPB_FORCEINLINE
#define UPB_NOINLINE
#define UPB_NORETURN
+#define UPB_PRINTF(str, first_vararg)
#endif
#define UPB_MAX(x, y) ((x) > (y) ? (x) : (y))
@@ -126,6 +127,52 @@
#define UPB_UNREACHABLE() do { assert(0); } while(0)
#endif
+/* UPB_SETJMP() / UPB_LONGJMP(): avoid setting/restoring signal mask. */
+#ifdef __APPLE__
+#define UPB_SETJMP(buf) _setjmp(buf)
+#define UPB_LONGJMP(buf, val) _longjmp(buf, val)
+#else
+#define UPB_SETJMP(buf) setjmp(buf)
+#define UPB_LONGJMP(buf, val) longjmp(buf, val)
+#endif
+
+/* Configure whether fasttable is switched on or not. *************************/
+
+#if defined(__x86_64__) && defined(__GNUC__)
+#define UPB_FASTTABLE_SUPPORTED 1
+#else
+#define UPB_FASTTABLE_SUPPORTED 0
+#endif
+
+/* define UPB_ENABLE_FASTTABLE to force fast table support.
+ * This is useful when we want to ensure we are really getting fasttable,
+ * for example for testing or benchmarking. */
+#if defined(UPB_ENABLE_FASTTABLE)
+#if !UPB_FASTTABLE_SUPPORTED
+#error fasttable is x86-64 + Clang/GCC only
+#endif
+#define UPB_FASTTABLE 1
+/* Define UPB_TRY_ENABLE_FASTTABLE to use fasttable if possible.
+ * This is useful for releasing code that might be used on multiple platforms,
+ * for example the PHP or Ruby C extensions. */
+#elif defined(UPB_TRY_ENABLE_FASTTABLE)
+#define UPB_FASTTABLE UPB_FASTTABLE_SUPPORTED
+#else
+#define UPB_FASTTABLE 0
+#endif
+
+/* UPB_FASTTABLE_INIT() allows protos compiled for fasttable to gracefully
+ * degrade to non-fasttable if we are using UPB_TRY_ENABLE_FASTTABLE. */
+#if !UPB_FASTTABLE && defined(UPB_TRY_ENABLE_FASTTABLE)
+#define UPB_FASTTABLE_INIT(...)
+#else
+#define UPB_FASTTABLE_INIT(...) __VA_ARGS__
+#endif
+
+#undef UPB_FASTTABLE_SUPPORTED
+
+/* ASAN poisoning (for arena) *************************************************/
+
#if defined(__SANITIZE_ADDRESS__)
#define UPB_ASAN 1
#ifdef __cplusplus
@@ -165,6 +212,7 @@
#define UPB_MSG_H_
#include <stdint.h>
+#include <stdlib.h>
#include <string.h>
/*
@@ -225,9 +273,12 @@
/* 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);
-void upb_status_vappenderrf(upb_status *status, const char *fmt, va_list args);
+void upb_status_seterrf(upb_status *status, const char *fmt, ...)
+ UPB_PRINTF(2, 3);
+void upb_status_vseterrf(upb_status *status, const char *fmt, va_list args)
+ UPB_PRINTF(2, 0);
+void upb_status_vappenderrf(upb_status *status, const char *fmt, va_list args)
+ UPB_PRINTF(2, 0);
/** upb_strview ************************************************************/
@@ -353,9 +404,9 @@
UPB_INLINE upb_alloc *upb_arena_alloc(upb_arena *a) { return (upb_alloc*)a; }
-UPB_INLINE bool _upb_arenahas(upb_arena *a, size_t size) {
+UPB_INLINE size_t _upb_arenahas(upb_arena *a) {
_upb_arena_head *h = (_upb_arena_head*)a;
- return (size_t)(h->end - h->ptr) >= size;
+ return (size_t)(h->end - h->ptr);
}
UPB_INLINE void *upb_arena_malloc(upb_arena *a, size_t size) {
@@ -363,7 +414,7 @@
void* ret;
size = UPB_ALIGN_MALLOC(size);
- if (UPB_UNLIKELY(!_upb_arenahas(a, size))) {
+ if (UPB_UNLIKELY(_upb_arenahas(a) < size)) {
return _upb_arena_slowmalloc(a, size);
}
@@ -374,7 +425,7 @@
#if UPB_ASAN
{
size_t guard_size = 32;
- if (_upb_arenahas(a, guard_size)) {
+ if (_upb_arenahas(a) >= guard_size) {
h->ptr += guard_size;
} else {
h->ptr = h->end;
@@ -516,6 +567,10 @@
#endif
}
+UPB_INLINE int _upb_lg2ceilsize(int x) {
+ return 1 << _upb_lg2ceil(x);
+}
+
#ifdef __cplusplus
} /* extern "C" */
@@ -645,10 +700,17 @@
return mem + sizeof(*len);
}
+UPB_INLINE upb_strview upb_tabstrview(upb_tabkey key) {
+ upb_strview ret;
+ uint32_t len;
+ ret.data = upb_tabstr(key, &len);
+ ret.size = len;
+ return ret;
+}
/* upb_tabval *****************************************************************/
-typedef struct {
+typedef struct upb_tabval {
uint64_t val;
} upb_tabval;
@@ -964,6 +1026,7 @@
#endif /* UPB_TABLE_H_ */
+/* Must be last. */
#ifdef __cplusplus
extern "C" {
@@ -995,6 +1058,18 @@
uint8_t label; /* google.protobuf.Label or _UPB_LABEL_* above. */
} upb_msglayout_field;
+struct upb_decstate;
+struct upb_msglayout;
+
+typedef const char *_upb_field_parser(struct upb_decstate *d, const char *ptr,
+ upb_msg *msg, intptr_t table,
+ uint64_t hasbits, uint64_t data);
+
+typedef struct {
+ uint64_t field_data;
+ _upb_field_parser *field_parser;
+} _upb_fasttable_entry;
+
typedef struct upb_msglayout {
const struct upb_msglayout *const* submsgs;
const upb_msglayout_field *fields;
@@ -1003,6 +1078,10 @@
uint16_t size;
uint16_t field_count;
bool extendable;
+ uint8_t table_mask;
+ /* To constant-initialize the tables of variable length, we need a flexible
+ * array member, and we need to compile in C99 mode. */
+ _upb_fasttable_entry fasttable[];
} upb_msglayout;
/** upb_msg *******************************************************************/
@@ -1147,6 +1226,11 @@
return (void*)(arr->data & ~(uintptr_t)7);
}
+UPB_INLINE uintptr_t _upb_array_tagptr(void* ptr, int elem_size_lg2) {
+ UPB_ASSERT(elem_size_lg2 <= 4);
+ return (uintptr_t)ptr | elem_size_lg2;
+}
+
UPB_INLINE void *_upb_array_ptr(upb_array *arr) {
return (void*)_upb_array_constptr(arr);
}
@@ -1481,6 +1565,53 @@
}
}
+/** _upb_mapsorter *************************************************************/
+
+/* _upb_mapsorter sorts maps and provides ordered iteration over the entries.
+ * Since maps can be recursive (map values can be messages which contain other maps).
+ * _upb_mapsorter can contain a stack of maps. */
+
+typedef struct {
+ upb_tabent const**entries;
+ int size;
+ int cap;
+} _upb_mapsorter;
+
+typedef struct {
+ int start;
+ int pos;
+ int end;
+} _upb_sortedmap;
+
+UPB_INLINE void _upb_mapsorter_init(_upb_mapsorter *s) {
+ s->entries = NULL;
+ s->size = 0;
+ s->cap = 0;
+}
+
+UPB_INLINE void _upb_mapsorter_destroy(_upb_mapsorter *s) {
+ if (s->entries) free(s->entries);
+}
+
+bool _upb_mapsorter_pushmap(_upb_mapsorter *s, upb_descriptortype_t key_type,
+ const upb_map *map, _upb_sortedmap *sorted);
+
+UPB_INLINE void _upb_mapsorter_popmap(_upb_mapsorter *s, _upb_sortedmap *sorted) {
+ s->size = sorted->start;
+}
+
+UPB_INLINE bool _upb_sortedmap_next(_upb_mapsorter *s, const upb_map *map,
+ _upb_sortedmap *sorted,
+ upb_map_entry *ent) {
+ if (sorted->pos == sorted->end) return false;
+ const upb_tabent *tabent = s->entries[sorted->pos++];
+ upb_strview key = upb_tabstrview(tabent->key);
+ _upb_map_fromkey(key, &ent->k, map->key_size);
+ upb_value val = {tabent->val.val};
+ _upb_map_fromvalue(val, &ent->v, map->val_size);
+ return true;
+}
+
#undef PTR_AT
#ifdef __cplusplus
@@ -1490,18 +1621,45 @@
#endif /* UPB_MSG_H_ */
+/* Must be last. */
+
#ifdef __cplusplus
extern "C" {
#endif
+enum {
+ /* If set, strings will alias the input buffer instead of copying into the
+ * arena. */
+ UPB_DECODE_ALIAS = 1,
+};
+
+#define UPB_DECODE_MAXDEPTH(depth) ((depth) << 16)
+
+bool _upb_decode(const char *buf, size_t size, upb_msg *msg,
+ const upb_msglayout *l, upb_arena *arena, int options);
+
+UPB_INLINE
bool upb_decode(const char *buf, size_t size, upb_msg *msg,
- const upb_msglayout *l, upb_arena *arena);
+ const upb_msglayout *l, upb_arena *arena) {
+ return _upb_decode(buf, size, msg, l, arena, 0);
+}
#ifdef __cplusplus
} /* extern "C" */
#endif
+
#endif /* UPB_DECODE_H_ */
+/*
+** Internal implementation details of the decoder that are shared between
+** decode.c and decode_fast.c.
+*/
+
+#ifndef UPB_DECODE_INT_H_
+#define UPB_DECODE_INT_H_
+
+#include <setjmp.h>
+
#ifndef UPB_INT_H_
#define UPB_INT_H_
@@ -1530,6 +1688,155 @@
};
#endif /* UPB_INT_H_ */
+
+/* Must be last. */
+
+#define DECODE_NOGROUP (uint32_t)-1
+
+typedef struct upb_decstate {
+ const char *end; /* Can read up to 16 bytes slop beyond this. */
+ const char *limit_ptr; /* = end + UPB_MIN(limit, 0) */
+ upb_msg *unknown_msg; /* If non-NULL, add unknown data at buffer flip. */
+ const char *unknown; /* Start of unknown data. */
+ int limit; /* Submessage limit relative to end. */
+ int depth;
+ uint32_t end_group; /* field number of END_GROUP tag, else DECODE_NOGROUP */
+ bool alias;
+ char patch[32];
+ upb_arena arena;
+ jmp_buf err;
+} upb_decstate;
+
+/* Error function that will abort decoding with longjmp(). We can't declare this
+ * UPB_NORETURN, even though it is appropriate, because if we do then compilers
+ * will "helpfully" refuse to tailcall to it
+ * (see: https://stackoverflow.com/a/55657013), which will defeat a major goal
+ * of our optimizations. That is also why we must declare it in a separate file,
+ * otherwise the compiler will see that it calls longjmp() and deduce that it is
+ * noreturn. */
+const char *fastdecode_err(upb_decstate *d);
+
+extern const uint8_t upb_utf8_offsets[];
+
+UPB_INLINE
+bool decode_verifyutf8_inl(const char *buf, int len) {
+ int i, j;
+ uint8_t offset;
+
+ i = 0;
+ while (i < len) {
+ offset = upb_utf8_offsets[(uint8_t)buf[i]];
+ if (offset == 0 || i + offset > len) {
+ return false;
+ }
+ for (j = i + 1; j < i + offset; j++) {
+ if ((buf[j] & 0xc0) != 0x80) {
+ return false;
+ }
+ }
+ i += offset;
+ }
+ return i == len;
+}
+
+/* x86-64 pointers always have the high 16 bits matching. So we can shift
+ * left 8 and right 8 without loss of information. */
+UPB_INLINE intptr_t decode_totable(const upb_msglayout *tablep) {
+ return ((intptr_t)tablep << 8) | tablep->table_mask;
+}
+
+UPB_INLINE const upb_msglayout *decode_totablep(intptr_t table) {
+ return (const upb_msglayout*)(table >> 8);
+}
+
+UPB_INLINE
+const char *decode_isdonefallback_inl(upb_decstate *d, const char *ptr,
+ int overrun) {
+ if (overrun < d->limit) {
+ /* Need to copy remaining data into patch buffer. */
+ UPB_ASSERT(overrun < 16);
+ if (d->unknown_msg) {
+ if (!_upb_msg_addunknown(d->unknown_msg, d->unknown, ptr - d->unknown,
+ &d->arena)) {
+ return NULL;
+ }
+ d->unknown = &d->patch[0] + overrun;
+ }
+ memset(d->patch + 16, 0, 16);
+ memcpy(d->patch, d->end, 16);
+ ptr = &d->patch[0] + overrun;
+ d->end = &d->patch[16];
+ d->limit -= 16;
+ d->limit_ptr = d->end + d->limit;
+ d->alias = false;
+ UPB_ASSERT(ptr < d->limit_ptr);
+ return ptr;
+ } else {
+ return NULL;
+ }
+}
+
+const char *decode_isdonefallback(upb_decstate *d, const char *ptr,
+ int overrun);
+
+UPB_INLINE
+bool decode_isdone(upb_decstate *d, const char **ptr) {
+ int overrun = *ptr - d->end;
+ if (UPB_LIKELY(*ptr < d->limit_ptr)) {
+ return false;
+ } else if (UPB_LIKELY(overrun == d->limit)) {
+ return true;
+ } else {
+ *ptr = decode_isdonefallback(d, *ptr, overrun);
+ return false;
+ }
+}
+
+UPB_INLINE
+const char *fastdecode_tagdispatch(upb_decstate *d, const char *ptr,
+ upb_msg *msg, intptr_t table,
+ uint64_t hasbits, uint32_t tag) {
+ const upb_msglayout *table_p = decode_totablep(table);
+ uint8_t mask = table;
+ uint64_t data;
+ size_t idx = tag & mask;
+ UPB_ASSUME((idx & 7) == 0);
+ idx >>= 3;
+ data = table_p->fasttable[idx].field_data ^ tag;
+ return table_p->fasttable[idx].field_parser(d, ptr, msg, table, hasbits, data);
+}
+
+UPB_INLINE uint32_t fastdecode_loadtag(const char* ptr) {
+ uint16_t tag;
+ memcpy(&tag, ptr, 2);
+ return tag;
+}
+
+UPB_INLINE void decode_checklimit(upb_decstate *d) {
+ UPB_ASSERT(d->limit_ptr == d->end + UPB_MIN(0, d->limit));
+}
+
+UPB_INLINE int decode_pushlimit(upb_decstate *d, const char *ptr, int size) {
+ int limit = size + (int)(ptr - d->end);
+ int delta = d->limit - limit;
+ decode_checklimit(d);
+ d->limit = limit;
+ d->limit_ptr = d->end + UPB_MIN(0, limit);
+ decode_checklimit(d);
+ return delta;
+}
+
+UPB_INLINE void decode_poplimit(upb_decstate *d, const char *ptr,
+ int saved_delta) {
+ UPB_ASSERT(ptr - d->end == d->limit);
+ decode_checklimit(d);
+ d->limit += saved_delta;
+ d->limit_ptr = d->end + UPB_MIN(0, d->limit);
+ decode_checklimit(d);
+}
+
+
+#endif /* UPB_DECODE_INT_H_ */
/*
** upb_encode: parsing into a upb_msg using a upb_msglayout.
*/
@@ -1538,18 +1845,166 @@
#define UPB_ENCODE_H_
+/* Must be last. */
+
#ifdef __cplusplus
extern "C" {
#endif
-char *upb_encode(const void *msg, const upb_msglayout *l, upb_arena *arena,
- size_t *size);
+enum {
+ /* If set, the results of serializing will be deterministic across all
+ * instances of this binary. There are no guarantees across different
+ * binary builds.
+ *
+ * If your proto contains maps, the encoder will need to malloc()/free()
+ * memory during encode. */
+ UPB_ENCODE_DETERMINISTIC = 1,
+
+ /* When set, unknown fields are not printed. */
+ UPB_ENCODE_SKIPUNKNOWN = 2,
+};
+
+#define UPB_ENCODE_MAXDEPTH(depth) ((depth) << 16)
+
+char *upb_encode_ex(const void *msg, const upb_msglayout *l, int options,
+ upb_arena *arena, size_t *size);
+
+UPB_INLINE char *upb_encode(const void *msg, const upb_msglayout *l,
+ upb_arena *arena, size_t *size) {
+ return upb_encode_ex(msg, l, 0, arena, size);
+}
+
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* UPB_ENCODE_H_ */
+// These are the specialized field parser functions for the fast parser.
+// Generated tables will refer to these by name.
+//
+// The function names are encoded with names like:
+//
+// // 123 4
+// upb_pss_1bt(); // Parse singular string, 1 byte tag.
+//
+// In position 1:
+// - 'p' for parse, most function use this
+// - 'c' for copy, for when we are copying strings instead of aliasing
+//
+// In position 2 (cardinality):
+// - 's' for singular, with or without hasbit
+// - 'o' for oneof
+// - 'r' for non-packed repeated
+// - 'p' for packed repeated
+//
+// In position 3 (type):
+// - 'b1' for bool
+// - 'v4' for 4-byte varint
+// - 'v8' for 8-byte varint
+// - 'z4' for zig-zag-encoded 4-byte varint
+// - 'z8' for zig-zag-encoded 8-byte varint
+// - 'f4' for 4-byte fixed
+// - 'f8' for 8-byte fixed
+// - 'm' for sub-message
+// - 's' for string (validate UTF-8)
+// - 'b' for bytes
+//
+// In position 4 (tag length):
+// - '1' for one-byte tags (field numbers 1-15)
+// - '2' for two-byte tags (field numbers 16-2048)
+
+#ifndef UPB_DECODE_FAST_H_
+#define UPB_DECODE_FAST_H_
+
+
+struct upb_decstate;
+
+// The fallback, generic parsing function that can handle any field type.
+// This just uses the regular (non-fast) parser to parse a single field.
+const char *fastdecode_generic(struct upb_decstate *d, const char *ptr,
+ upb_msg *msg, intptr_t table, uint64_t hasbits,
+ uint64_t data);
+
+#define UPB_PARSE_PARAMS \
+ struct upb_decstate *d, const char *ptr, upb_msg *msg, intptr_t table, \
+ uint64_t hasbits, uint64_t data
+
+/* primitive fields ***********************************************************/
+
+#define F(card, type, valbytes, tagbytes) \
+ const char *upb_p##card##type##valbytes##_##tagbytes##bt(UPB_PARSE_PARAMS);
+
+#define TYPES(card, tagbytes) \
+ F(card, b, 1, tagbytes) \
+ F(card, v, 4, tagbytes) \
+ F(card, v, 8, tagbytes) \
+ F(card, z, 4, tagbytes) \
+ F(card, z, 8, tagbytes) \
+ F(card, f, 4, tagbytes) \
+ F(card, f, 8, tagbytes)
+
+#define TAGBYTES(card) \
+ TYPES(card, 1) \
+ TYPES(card, 2)
+
+TAGBYTES(s)
+TAGBYTES(o)
+TAGBYTES(r)
+TAGBYTES(p)
+
+#undef F
+#undef TYPES
+#undef TAGBYTES
+
+/* string fields **************************************************************/
+
+#define F(card, tagbytes, type) \
+ const char *upb_p##card##type##_##tagbytes##bt(UPB_PARSE_PARAMS); \
+ const char *upb_c##card##type##_##tagbytes##bt(UPB_PARSE_PARAMS);
+
+#define UTF8(card, tagbytes) \
+ F(card, tagbytes, s) \
+ F(card, tagbytes, b)
+
+#define TAGBYTES(card) \
+ UTF8(card, 1) \
+ UTF8(card, 2)
+
+TAGBYTES(s)
+TAGBYTES(o)
+TAGBYTES(r)
+
+#undef F
+#undef TAGBYTES
+
+/* sub-message fields *********************************************************/
+
+#define F(card, tagbytes, size_ceil, ceil_arg) \
+ const char *upb_p##card##m_##tagbytes##bt_max##size_ceil##b(UPB_PARSE_PARAMS);
+
+#define SIZES(card, tagbytes) \
+ F(card, tagbytes, 64, 64) \
+ F(card, tagbytes, 128, 128) \
+ F(card, tagbytes, 192, 192) \
+ F(card, tagbytes, 256, 256) \
+ F(card, tagbytes, max, -1)
+
+#define TAGBYTES(card) \
+ SIZES(card, 1) \
+ SIZES(card, 2)
+
+TAGBYTES(s)
+TAGBYTES(o)
+TAGBYTES(r)
+
+#undef TAGBYTES
+#undef SIZES
+#undef F
+
+#undef UPB_PARSE_PARAMS
+
+#endif /* UPB_DECODE_FAST_H_ */
/* This file was generated by upbc (the upb compiler) from the input
* file:
*
@@ -1711,6 +2166,12 @@
google_protobuf_FileDescriptorSet *ret = google_protobuf_FileDescriptorSet_new(arena);
return (ret && upb_decode(buf, size, ret, &google_protobuf_FileDescriptorSet_msginit, arena)) ? ret : NULL;
}
+UPB_INLINE google_protobuf_FileDescriptorSet *google_protobuf_FileDescriptorSet_parse_ex(const char *buf, size_t size,
+ upb_arena *arena, int options) {
+ google_protobuf_FileDescriptorSet *ret = google_protobuf_FileDescriptorSet_new(arena);
+ return (ret && _upb_decode(buf, size, ret, &google_protobuf_FileDescriptorSet_msginit, arena, options))
+ ? ret : NULL;
+}
UPB_INLINE char *google_protobuf_FileDescriptorSet_serialize(const google_protobuf_FileDescriptorSet *msg, upb_arena *arena, size_t *len) {
return upb_encode(msg, &google_protobuf_FileDescriptorSet_msginit, arena, len);
}
@@ -1742,6 +2203,12 @@
google_protobuf_FileDescriptorProto *ret = google_protobuf_FileDescriptorProto_new(arena);
return (ret && upb_decode(buf, size, ret, &google_protobuf_FileDescriptorProto_msginit, arena)) ? ret : NULL;
}
+UPB_INLINE google_protobuf_FileDescriptorProto *google_protobuf_FileDescriptorProto_parse_ex(const char *buf, size_t size,
+ upb_arena *arena, int options) {
+ google_protobuf_FileDescriptorProto *ret = google_protobuf_FileDescriptorProto_new(arena);
+ return (ret && _upb_decode(buf, size, ret, &google_protobuf_FileDescriptorProto_msginit, arena, options))
+ ? ret : NULL;
+}
UPB_INLINE char *google_protobuf_FileDescriptorProto_serialize(const google_protobuf_FileDescriptorProto *msg, upb_arena *arena, size_t *len) {
return upb_encode(msg, &google_protobuf_FileDescriptorProto_msginit, arena, len);
}
@@ -1759,13 +2226,13 @@
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_hasbit(msg, 4); }
+UPB_INLINE bool google_protobuf_FileDescriptorProto_has_options(const google_protobuf_FileDescriptorProto *msg) { return _upb_hasbit(msg, 3); }
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_hasbit(msg, 5); }
+UPB_INLINE bool google_protobuf_FileDescriptorProto_has_source_code_info(const google_protobuf_FileDescriptorProto *msg) { return _upb_hasbit(msg, 4); }
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_hasbit(msg, 3); }
+UPB_INLINE bool google_protobuf_FileDescriptorProto_has_syntax(const google_protobuf_FileDescriptorProto *msg) { return _upb_hasbit(msg, 5); }
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) {
@@ -1839,7 +2306,7 @@
return sub;
}
UPB_INLINE void google_protobuf_FileDescriptorProto_set_options(google_protobuf_FileDescriptorProto *msg, google_protobuf_FileOptions* value) {
- _upb_sethas(msg, 4);
+ _upb_sethas(msg, 3);
*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) {
@@ -1852,7 +2319,7 @@
return sub;
}
UPB_INLINE void google_protobuf_FileDescriptorProto_set_source_code_info(google_protobuf_FileDescriptorProto *msg, google_protobuf_SourceCodeInfo* value) {
- _upb_sethas(msg, 5);
+ _upb_sethas(msg, 4);
*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) {
@@ -1885,7 +2352,7 @@
arena);
}
UPB_INLINE void google_protobuf_FileDescriptorProto_set_syntax(google_protobuf_FileDescriptorProto *msg, upb_strview value) {
- _upb_sethas(msg, 3);
+ _upb_sethas(msg, 5);
*UPB_PTR_AT(msg, UPB_SIZE(20, 40), upb_strview) = value;
}
@@ -1899,6 +2366,12 @@
google_protobuf_DescriptorProto *ret = google_protobuf_DescriptorProto_new(arena);
return (ret && upb_decode(buf, size, ret, &google_protobuf_DescriptorProto_msginit, arena)) ? ret : NULL;
}
+UPB_INLINE google_protobuf_DescriptorProto *google_protobuf_DescriptorProto_parse_ex(const char *buf, size_t size,
+ upb_arena *arena, int options) {
+ google_protobuf_DescriptorProto *ret = google_protobuf_DescriptorProto_new(arena);
+ return (ret && _upb_decode(buf, size, ret, &google_protobuf_DescriptorProto_msginit, arena, options))
+ ? ret : NULL;
+}
UPB_INLINE char *google_protobuf_DescriptorProto_serialize(const google_protobuf_DescriptorProto *msg, upb_arena *arena, size_t *len) {
return upb_encode(msg, &google_protobuf_DescriptorProto_msginit, arena, len);
}
@@ -2052,6 +2525,12 @@
google_protobuf_DescriptorProto_ExtensionRange *ret = google_protobuf_DescriptorProto_ExtensionRange_new(arena);
return (ret && upb_decode(buf, size, ret, &google_protobuf_DescriptorProto_ExtensionRange_msginit, arena)) ? ret : NULL;
}
+UPB_INLINE google_protobuf_DescriptorProto_ExtensionRange *google_protobuf_DescriptorProto_ExtensionRange_parse_ex(const char *buf, size_t size,
+ upb_arena *arena, int options) {
+ google_protobuf_DescriptorProto_ExtensionRange *ret = google_protobuf_DescriptorProto_ExtensionRange_new(arena);
+ return (ret && _upb_decode(buf, size, ret, &google_protobuf_DescriptorProto_ExtensionRange_msginit, arena, options))
+ ? ret : NULL;
+}
UPB_INLINE char *google_protobuf_DescriptorProto_ExtensionRange_serialize(const google_protobuf_DescriptorProto_ExtensionRange *msg, upb_arena *arena, size_t *len) {
return upb_encode(msg, &google_protobuf_DescriptorProto_ExtensionRange_msginit, arena, len);
}
@@ -2095,6 +2574,12 @@
google_protobuf_DescriptorProto_ReservedRange *ret = google_protobuf_DescriptorProto_ReservedRange_new(arena);
return (ret && upb_decode(buf, size, ret, &google_protobuf_DescriptorProto_ReservedRange_msginit, arena)) ? ret : NULL;
}
+UPB_INLINE google_protobuf_DescriptorProto_ReservedRange *google_protobuf_DescriptorProto_ReservedRange_parse_ex(const char *buf, size_t size,
+ upb_arena *arena, int options) {
+ google_protobuf_DescriptorProto_ReservedRange *ret = google_protobuf_DescriptorProto_ReservedRange_new(arena);
+ return (ret && _upb_decode(buf, size, ret, &google_protobuf_DescriptorProto_ReservedRange_msginit, arena, options))
+ ? ret : NULL;
+}
UPB_INLINE char *google_protobuf_DescriptorProto_ReservedRange_serialize(const google_protobuf_DescriptorProto_ReservedRange *msg, upb_arena *arena, size_t *len) {
return upb_encode(msg, &google_protobuf_DescriptorProto_ReservedRange_msginit, arena, len);
}
@@ -2123,6 +2608,12 @@
google_protobuf_ExtensionRangeOptions *ret = google_protobuf_ExtensionRangeOptions_new(arena);
return (ret && upb_decode(buf, size, ret, &google_protobuf_ExtensionRangeOptions_msginit, arena)) ? ret : NULL;
}
+UPB_INLINE google_protobuf_ExtensionRangeOptions *google_protobuf_ExtensionRangeOptions_parse_ex(const char *buf, size_t size,
+ upb_arena *arena, int options) {
+ google_protobuf_ExtensionRangeOptions *ret = google_protobuf_ExtensionRangeOptions_new(arena);
+ return (ret && _upb_decode(buf, size, ret, &google_protobuf_ExtensionRangeOptions_msginit, arena, options))
+ ? ret : NULL;
+}
UPB_INLINE char *google_protobuf_ExtensionRangeOptions_serialize(const google_protobuf_ExtensionRangeOptions *msg, upb_arena *arena, size_t *len) {
return upb_encode(msg, &google_protobuf_ExtensionRangeOptions_msginit, arena, len);
}
@@ -2154,39 +2645,45 @@
google_protobuf_FieldDescriptorProto *ret = google_protobuf_FieldDescriptorProto_new(arena);
return (ret && upb_decode(buf, size, ret, &google_protobuf_FieldDescriptorProto_msginit, arena)) ? ret : NULL;
}
+UPB_INLINE google_protobuf_FieldDescriptorProto *google_protobuf_FieldDescriptorProto_parse_ex(const char *buf, size_t size,
+ upb_arena *arena, int options) {
+ google_protobuf_FieldDescriptorProto *ret = google_protobuf_FieldDescriptorProto_new(arena);
+ return (ret && _upb_decode(buf, size, ret, &google_protobuf_FieldDescriptorProto_msginit, arena, options))
+ ? ret : NULL;
+}
UPB_INLINE char *google_protobuf_FieldDescriptorProto_serialize(const google_protobuf_FieldDescriptorProto *msg, upb_arena *arena, size_t *len) {
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_hasbit(msg, 6); }
+UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_name(const google_protobuf_FieldDescriptorProto *msg) { return _upb_hasbit(msg, 1); }
UPB_INLINE upb_strview google_protobuf_FieldDescriptorProto_name(const google_protobuf_FieldDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(24, 24), upb_strview); }
-UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_extendee(const google_protobuf_FieldDescriptorProto *msg) { return _upb_hasbit(msg, 7); }
+UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_extendee(const google_protobuf_FieldDescriptorProto *msg) { return _upb_hasbit(msg, 2); }
UPB_INLINE upb_strview google_protobuf_FieldDescriptorProto_extendee(const google_protobuf_FieldDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(32, 40), upb_strview); }
UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_number(const google_protobuf_FieldDescriptorProto *msg) { return _upb_hasbit(msg, 3); }
UPB_INLINE int32_t google_protobuf_FieldDescriptorProto_number(const google_protobuf_FieldDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(12, 12), int32_t); }
-UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_label(const google_protobuf_FieldDescriptorProto *msg) { return _upb_hasbit(msg, 1); }
+UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_label(const google_protobuf_FieldDescriptorProto *msg) { return _upb_hasbit(msg, 4); }
UPB_INLINE int32_t google_protobuf_FieldDescriptorProto_label(const google_protobuf_FieldDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 4), int32_t); }
-UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_type(const google_protobuf_FieldDescriptorProto *msg) { return _upb_hasbit(msg, 2); }
+UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_type(const google_protobuf_FieldDescriptorProto *msg) { return _upb_hasbit(msg, 5); }
UPB_INLINE int32_t google_protobuf_FieldDescriptorProto_type(const google_protobuf_FieldDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 8), int32_t); }
-UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_type_name(const google_protobuf_FieldDescriptorProto *msg) { return _upb_hasbit(msg, 8); }
+UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_type_name(const google_protobuf_FieldDescriptorProto *msg) { return _upb_hasbit(msg, 6); }
UPB_INLINE upb_strview google_protobuf_FieldDescriptorProto_type_name(const google_protobuf_FieldDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(40, 56), upb_strview); }
-UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_default_value(const google_protobuf_FieldDescriptorProto *msg) { return _upb_hasbit(msg, 9); }
+UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_default_value(const google_protobuf_FieldDescriptorProto *msg) { return _upb_hasbit(msg, 7); }
UPB_INLINE upb_strview google_protobuf_FieldDescriptorProto_default_value(const google_protobuf_FieldDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(48, 72), upb_strview); }
-UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_options(const google_protobuf_FieldDescriptorProto *msg) { return _upb_hasbit(msg, 11); }
+UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_options(const google_protobuf_FieldDescriptorProto *msg) { return _upb_hasbit(msg, 8); }
UPB_INLINE const google_protobuf_FieldOptions* google_protobuf_FieldDescriptorProto_options(const google_protobuf_FieldDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(64, 104), const google_protobuf_FieldOptions*); }
-UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_oneof_index(const google_protobuf_FieldDescriptorProto *msg) { return _upb_hasbit(msg, 4); }
+UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_oneof_index(const google_protobuf_FieldDescriptorProto *msg) { return _upb_hasbit(msg, 9); }
UPB_INLINE int32_t google_protobuf_FieldDescriptorProto_oneof_index(const google_protobuf_FieldDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(16, 16), int32_t); }
UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_json_name(const google_protobuf_FieldDescriptorProto *msg) { return _upb_hasbit(msg, 10); }
UPB_INLINE upb_strview google_protobuf_FieldDescriptorProto_json_name(const google_protobuf_FieldDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(56, 88), upb_strview); }
-UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_proto3_optional(const google_protobuf_FieldDescriptorProto *msg) { return _upb_hasbit(msg, 5); }
+UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_proto3_optional(const google_protobuf_FieldDescriptorProto *msg) { return _upb_hasbit(msg, 11); }
UPB_INLINE bool google_protobuf_FieldDescriptorProto_proto3_optional(const google_protobuf_FieldDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(20, 20), bool); }
UPB_INLINE void google_protobuf_FieldDescriptorProto_set_name(google_protobuf_FieldDescriptorProto *msg, upb_strview value) {
- _upb_sethas(msg, 6);
+ _upb_sethas(msg, 1);
*UPB_PTR_AT(msg, UPB_SIZE(24, 24), upb_strview) = value;
}
UPB_INLINE void google_protobuf_FieldDescriptorProto_set_extendee(google_protobuf_FieldDescriptorProto *msg, upb_strview value) {
- _upb_sethas(msg, 7);
+ _upb_sethas(msg, 2);
*UPB_PTR_AT(msg, UPB_SIZE(32, 40), upb_strview) = value;
}
UPB_INLINE void google_protobuf_FieldDescriptorProto_set_number(google_protobuf_FieldDescriptorProto *msg, int32_t value) {
@@ -2194,23 +2691,23 @@
*UPB_PTR_AT(msg, UPB_SIZE(12, 12), int32_t) = value;
}
UPB_INLINE void google_protobuf_FieldDescriptorProto_set_label(google_protobuf_FieldDescriptorProto *msg, int32_t value) {
- _upb_sethas(msg, 1);
+ _upb_sethas(msg, 4);
*UPB_PTR_AT(msg, UPB_SIZE(4, 4), int32_t) = value;
}
UPB_INLINE void google_protobuf_FieldDescriptorProto_set_type(google_protobuf_FieldDescriptorProto *msg, int32_t value) {
- _upb_sethas(msg, 2);
+ _upb_sethas(msg, 5);
*UPB_PTR_AT(msg, UPB_SIZE(8, 8), int32_t) = value;
}
UPB_INLINE void google_protobuf_FieldDescriptorProto_set_type_name(google_protobuf_FieldDescriptorProto *msg, upb_strview value) {
- _upb_sethas(msg, 8);
+ _upb_sethas(msg, 6);
*UPB_PTR_AT(msg, UPB_SIZE(40, 56), upb_strview) = value;
}
UPB_INLINE void google_protobuf_FieldDescriptorProto_set_default_value(google_protobuf_FieldDescriptorProto *msg, upb_strview value) {
- _upb_sethas(msg, 9);
+ _upb_sethas(msg, 7);
*UPB_PTR_AT(msg, UPB_SIZE(48, 72), upb_strview) = value;
}
UPB_INLINE void google_protobuf_FieldDescriptorProto_set_options(google_protobuf_FieldDescriptorProto *msg, google_protobuf_FieldOptions* value) {
- _upb_sethas(msg, 11);
+ _upb_sethas(msg, 8);
*UPB_PTR_AT(msg, UPB_SIZE(64, 104), google_protobuf_FieldOptions*) = value;
}
UPB_INLINE struct google_protobuf_FieldOptions* google_protobuf_FieldDescriptorProto_mutable_options(google_protobuf_FieldDescriptorProto *msg, upb_arena *arena) {
@@ -2223,7 +2720,7 @@
return sub;
}
UPB_INLINE void google_protobuf_FieldDescriptorProto_set_oneof_index(google_protobuf_FieldDescriptorProto *msg, int32_t value) {
- _upb_sethas(msg, 4);
+ _upb_sethas(msg, 9);
*UPB_PTR_AT(msg, UPB_SIZE(16, 16), int32_t) = value;
}
UPB_INLINE void google_protobuf_FieldDescriptorProto_set_json_name(google_protobuf_FieldDescriptorProto *msg, upb_strview value) {
@@ -2231,7 +2728,7 @@
*UPB_PTR_AT(msg, UPB_SIZE(56, 88), upb_strview) = value;
}
UPB_INLINE void google_protobuf_FieldDescriptorProto_set_proto3_optional(google_protobuf_FieldDescriptorProto *msg, bool value) {
- _upb_sethas(msg, 5);
+ _upb_sethas(msg, 11);
*UPB_PTR_AT(msg, UPB_SIZE(20, 20), bool) = value;
}
@@ -2245,6 +2742,12 @@
google_protobuf_OneofDescriptorProto *ret = google_protobuf_OneofDescriptorProto_new(arena);
return (ret && upb_decode(buf, size, ret, &google_protobuf_OneofDescriptorProto_msginit, arena)) ? ret : NULL;
}
+UPB_INLINE google_protobuf_OneofDescriptorProto *google_protobuf_OneofDescriptorProto_parse_ex(const char *buf, size_t size,
+ upb_arena *arena, int options) {
+ google_protobuf_OneofDescriptorProto *ret = google_protobuf_OneofDescriptorProto_new(arena);
+ return (ret && _upb_decode(buf, size, ret, &google_protobuf_OneofDescriptorProto_msginit, arena, options))
+ ? ret : NULL;
+}
UPB_INLINE char *google_protobuf_OneofDescriptorProto_serialize(const google_protobuf_OneofDescriptorProto *msg, upb_arena *arena, size_t *len) {
return upb_encode(msg, &google_protobuf_OneofDescriptorProto_msginit, arena, len);
}
@@ -2282,6 +2785,12 @@
google_protobuf_EnumDescriptorProto *ret = google_protobuf_EnumDescriptorProto_new(arena);
return (ret && upb_decode(buf, size, ret, &google_protobuf_EnumDescriptorProto_msginit, arena)) ? ret : NULL;
}
+UPB_INLINE google_protobuf_EnumDescriptorProto *google_protobuf_EnumDescriptorProto_parse_ex(const char *buf, size_t size,
+ upb_arena *arena, int options) {
+ google_protobuf_EnumDescriptorProto *ret = google_protobuf_EnumDescriptorProto_new(arena);
+ return (ret && _upb_decode(buf, size, ret, &google_protobuf_EnumDescriptorProto_msginit, arena, options))
+ ? ret : NULL;
+}
UPB_INLINE char *google_protobuf_EnumDescriptorProto_serialize(const google_protobuf_EnumDescriptorProto *msg, upb_arena *arena, size_t *len) {
return upb_encode(msg, &google_protobuf_EnumDescriptorProto_msginit, arena, len);
}
@@ -2360,6 +2869,12 @@
google_protobuf_EnumDescriptorProto_EnumReservedRange *ret = google_protobuf_EnumDescriptorProto_EnumReservedRange_new(arena);
return (ret && upb_decode(buf, size, ret, &google_protobuf_EnumDescriptorProto_EnumReservedRange_msginit, arena)) ? ret : NULL;
}
+UPB_INLINE google_protobuf_EnumDescriptorProto_EnumReservedRange *google_protobuf_EnumDescriptorProto_EnumReservedRange_parse_ex(const char *buf, size_t size,
+ upb_arena *arena, int options) {
+ google_protobuf_EnumDescriptorProto_EnumReservedRange *ret = google_protobuf_EnumDescriptorProto_EnumReservedRange_new(arena);
+ return (ret && _upb_decode(buf, size, ret, &google_protobuf_EnumDescriptorProto_EnumReservedRange_msginit, arena, options))
+ ? ret : NULL;
+}
UPB_INLINE char *google_protobuf_EnumDescriptorProto_EnumReservedRange_serialize(const google_protobuf_EnumDescriptorProto_EnumReservedRange *msg, upb_arena *arena, size_t *len) {
return upb_encode(msg, &google_protobuf_EnumDescriptorProto_EnumReservedRange_msginit, arena, len);
}
@@ -2388,23 +2903,29 @@
google_protobuf_EnumValueDescriptorProto *ret = google_protobuf_EnumValueDescriptorProto_new(arena);
return (ret && upb_decode(buf, size, ret, &google_protobuf_EnumValueDescriptorProto_msginit, arena)) ? ret : NULL;
}
+UPB_INLINE google_protobuf_EnumValueDescriptorProto *google_protobuf_EnumValueDescriptorProto_parse_ex(const char *buf, size_t size,
+ upb_arena *arena, int options) {
+ google_protobuf_EnumValueDescriptorProto *ret = google_protobuf_EnumValueDescriptorProto_new(arena);
+ return (ret && _upb_decode(buf, size, ret, &google_protobuf_EnumValueDescriptorProto_msginit, arena, options))
+ ? ret : NULL;
+}
UPB_INLINE char *google_protobuf_EnumValueDescriptorProto_serialize(const google_protobuf_EnumValueDescriptorProto *msg, upb_arena *arena, size_t *len) {
return upb_encode(msg, &google_protobuf_EnumValueDescriptorProto_msginit, arena, len);
}
-UPB_INLINE bool google_protobuf_EnumValueDescriptorProto_has_name(const google_protobuf_EnumValueDescriptorProto *msg) { return _upb_hasbit(msg, 2); }
+UPB_INLINE bool google_protobuf_EnumValueDescriptorProto_has_name(const google_protobuf_EnumValueDescriptorProto *msg) { return _upb_hasbit(msg, 1); }
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_hasbit(msg, 1); }
+UPB_INLINE bool google_protobuf_EnumValueDescriptorProto_has_number(const google_protobuf_EnumValueDescriptorProto *msg) { return _upb_hasbit(msg, 2); }
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_hasbit(msg, 3); }
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_sethas(msg, 1);
*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_sethas(msg, 2);
*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) {
@@ -2431,6 +2952,12 @@
google_protobuf_ServiceDescriptorProto *ret = google_protobuf_ServiceDescriptorProto_new(arena);
return (ret && upb_decode(buf, size, ret, &google_protobuf_ServiceDescriptorProto_msginit, arena)) ? ret : NULL;
}
+UPB_INLINE google_protobuf_ServiceDescriptorProto *google_protobuf_ServiceDescriptorProto_parse_ex(const char *buf, size_t size,
+ upb_arena *arena, int options) {
+ google_protobuf_ServiceDescriptorProto *ret = google_protobuf_ServiceDescriptorProto_new(arena);
+ return (ret && _upb_decode(buf, size, ret, &google_protobuf_ServiceDescriptorProto_msginit, arena, options))
+ ? ret : NULL;
+}
UPB_INLINE char *google_protobuf_ServiceDescriptorProto_serialize(const google_protobuf_ServiceDescriptorProto *msg, upb_arena *arena, size_t *len) {
return upb_encode(msg, &google_protobuf_ServiceDescriptorProto_msginit, arena, len);
}
@@ -2483,37 +3010,43 @@
google_protobuf_MethodDescriptorProto *ret = google_protobuf_MethodDescriptorProto_new(arena);
return (ret && upb_decode(buf, size, ret, &google_protobuf_MethodDescriptorProto_msginit, arena)) ? ret : NULL;
}
+UPB_INLINE google_protobuf_MethodDescriptorProto *google_protobuf_MethodDescriptorProto_parse_ex(const char *buf, size_t size,
+ upb_arena *arena, int options) {
+ google_protobuf_MethodDescriptorProto *ret = google_protobuf_MethodDescriptorProto_new(arena);
+ return (ret && _upb_decode(buf, size, ret, &google_protobuf_MethodDescriptorProto_msginit, arena, options))
+ ? ret : NULL;
+}
UPB_INLINE char *google_protobuf_MethodDescriptorProto_serialize(const google_protobuf_MethodDescriptorProto *msg, upb_arena *arena, size_t *len) {
return upb_encode(msg, &google_protobuf_MethodDescriptorProto_msginit, arena, len);
}
-UPB_INLINE bool google_protobuf_MethodDescriptorProto_has_name(const google_protobuf_MethodDescriptorProto *msg) { return _upb_hasbit(msg, 3); }
+UPB_INLINE bool google_protobuf_MethodDescriptorProto_has_name(const google_protobuf_MethodDescriptorProto *msg) { return _upb_hasbit(msg, 1); }
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_hasbit(msg, 4); }
+UPB_INLINE bool google_protobuf_MethodDescriptorProto_has_input_type(const google_protobuf_MethodDescriptorProto *msg) { return _upb_hasbit(msg, 2); }
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_hasbit(msg, 5); }
+UPB_INLINE bool google_protobuf_MethodDescriptorProto_has_output_type(const google_protobuf_MethodDescriptorProto *msg) { return _upb_hasbit(msg, 3); }
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_hasbit(msg, 6); }
+UPB_INLINE bool google_protobuf_MethodDescriptorProto_has_options(const google_protobuf_MethodDescriptorProto *msg) { return _upb_hasbit(msg, 4); }
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_hasbit(msg, 1); }
+UPB_INLINE bool google_protobuf_MethodDescriptorProto_has_client_streaming(const google_protobuf_MethodDescriptorProto *msg) { return _upb_hasbit(msg, 5); }
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_hasbit(msg, 2); }
+UPB_INLINE bool google_protobuf_MethodDescriptorProto_has_server_streaming(const google_protobuf_MethodDescriptorProto *msg) { return _upb_hasbit(msg, 6); }
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_sethas(msg, 1);
*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_sethas(msg, 2);
*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_sethas(msg, 3);
*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_sethas(msg, 4);
*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) {
@@ -2526,11 +3059,11 @@
return sub;
}
UPB_INLINE void google_protobuf_MethodDescriptorProto_set_client_streaming(google_protobuf_MethodDescriptorProto *msg, bool value) {
- _upb_sethas(msg, 1);
+ _upb_sethas(msg, 5);
*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_sethas(msg, 6);
*UPB_PTR_AT(msg, UPB_SIZE(2, 2), bool) = value;
}
@@ -2544,45 +3077,51 @@
google_protobuf_FileOptions *ret = google_protobuf_FileOptions_new(arena);
return (ret && upb_decode(buf, size, ret, &google_protobuf_FileOptions_msginit, arena)) ? ret : NULL;
}
+UPB_INLINE google_protobuf_FileOptions *google_protobuf_FileOptions_parse_ex(const char *buf, size_t size,
+ upb_arena *arena, int options) {
+ google_protobuf_FileOptions *ret = google_protobuf_FileOptions_new(arena);
+ return (ret && _upb_decode(buf, size, ret, &google_protobuf_FileOptions_msginit, arena, options))
+ ? ret : NULL;
+}
UPB_INLINE char *google_protobuf_FileOptions_serialize(const google_protobuf_FileOptions *msg, upb_arena *arena, size_t *len) {
return upb_encode(msg, &google_protobuf_FileOptions_msginit, arena, len);
}
-UPB_INLINE bool google_protobuf_FileOptions_has_java_package(const google_protobuf_FileOptions *msg) { return _upb_hasbit(msg, 11); }
+UPB_INLINE bool google_protobuf_FileOptions_has_java_package(const google_protobuf_FileOptions *msg) { return _upb_hasbit(msg, 1); }
UPB_INLINE upb_strview google_protobuf_FileOptions_java_package(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(20, 24), upb_strview); }
-UPB_INLINE bool google_protobuf_FileOptions_has_java_outer_classname(const google_protobuf_FileOptions *msg) { return _upb_hasbit(msg, 12); }
+UPB_INLINE bool google_protobuf_FileOptions_has_java_outer_classname(const google_protobuf_FileOptions *msg) { return _upb_hasbit(msg, 2); }
UPB_INLINE upb_strview google_protobuf_FileOptions_java_outer_classname(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(28, 40), upb_strview); }
-UPB_INLINE bool google_protobuf_FileOptions_has_optimize_for(const google_protobuf_FileOptions *msg) { return _upb_hasbit(msg, 1); }
+UPB_INLINE bool google_protobuf_FileOptions_has_optimize_for(const google_protobuf_FileOptions *msg) { return _upb_hasbit(msg, 3); }
UPB_INLINE int32_t google_protobuf_FileOptions_optimize_for(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 4), int32_t); }
-UPB_INLINE bool google_protobuf_FileOptions_has_java_multiple_files(const google_protobuf_FileOptions *msg) { return _upb_hasbit(msg, 2); }
+UPB_INLINE bool google_protobuf_FileOptions_has_java_multiple_files(const google_protobuf_FileOptions *msg) { return _upb_hasbit(msg, 4); }
UPB_INLINE bool google_protobuf_FileOptions_java_multiple_files(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 8), bool); }
-UPB_INLINE bool google_protobuf_FileOptions_has_go_package(const google_protobuf_FileOptions *msg) { return _upb_hasbit(msg, 13); }
+UPB_INLINE bool google_protobuf_FileOptions_has_go_package(const google_protobuf_FileOptions *msg) { return _upb_hasbit(msg, 5); }
UPB_INLINE upb_strview google_protobuf_FileOptions_go_package(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(36, 56), upb_strview); }
-UPB_INLINE bool google_protobuf_FileOptions_has_cc_generic_services(const google_protobuf_FileOptions *msg) { return _upb_hasbit(msg, 3); }
+UPB_INLINE bool google_protobuf_FileOptions_has_cc_generic_services(const google_protobuf_FileOptions *msg) { return _upb_hasbit(msg, 6); }
UPB_INLINE bool google_protobuf_FileOptions_cc_generic_services(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(9, 9), bool); }
-UPB_INLINE bool google_protobuf_FileOptions_has_java_generic_services(const google_protobuf_FileOptions *msg) { return _upb_hasbit(msg, 4); }
+UPB_INLINE bool google_protobuf_FileOptions_has_java_generic_services(const google_protobuf_FileOptions *msg) { return _upb_hasbit(msg, 7); }
UPB_INLINE bool google_protobuf_FileOptions_java_generic_services(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(10, 10), bool); }
-UPB_INLINE bool google_protobuf_FileOptions_has_py_generic_services(const google_protobuf_FileOptions *msg) { return _upb_hasbit(msg, 5); }
+UPB_INLINE bool google_protobuf_FileOptions_has_py_generic_services(const google_protobuf_FileOptions *msg) { return _upb_hasbit(msg, 8); }
UPB_INLINE bool google_protobuf_FileOptions_py_generic_services(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(11, 11), bool); }
-UPB_INLINE bool google_protobuf_FileOptions_has_java_generate_equals_and_hash(const google_protobuf_FileOptions *msg) { return _upb_hasbit(msg, 6); }
+UPB_INLINE bool google_protobuf_FileOptions_has_java_generate_equals_and_hash(const google_protobuf_FileOptions *msg) { return _upb_hasbit(msg, 9); }
UPB_INLINE bool google_protobuf_FileOptions_java_generate_equals_and_hash(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(12, 12), bool); }
-UPB_INLINE bool google_protobuf_FileOptions_has_deprecated(const google_protobuf_FileOptions *msg) { return _upb_hasbit(msg, 7); }
+UPB_INLINE bool google_protobuf_FileOptions_has_deprecated(const google_protobuf_FileOptions *msg) { return _upb_hasbit(msg, 10); }
UPB_INLINE bool google_protobuf_FileOptions_deprecated(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(13, 13), bool); }
-UPB_INLINE bool google_protobuf_FileOptions_has_java_string_check_utf8(const google_protobuf_FileOptions *msg) { return _upb_hasbit(msg, 8); }
+UPB_INLINE bool google_protobuf_FileOptions_has_java_string_check_utf8(const google_protobuf_FileOptions *msg) { return _upb_hasbit(msg, 11); }
UPB_INLINE bool google_protobuf_FileOptions_java_string_check_utf8(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(14, 14), bool); }
-UPB_INLINE bool google_protobuf_FileOptions_has_cc_enable_arenas(const google_protobuf_FileOptions *msg) { return _upb_hasbit(msg, 9); }
+UPB_INLINE bool google_protobuf_FileOptions_has_cc_enable_arenas(const google_protobuf_FileOptions *msg) { return _upb_hasbit(msg, 12); }
UPB_INLINE bool google_protobuf_FileOptions_cc_enable_arenas(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(15, 15), bool); }
-UPB_INLINE bool google_protobuf_FileOptions_has_objc_class_prefix(const google_protobuf_FileOptions *msg) { return _upb_hasbit(msg, 14); }
+UPB_INLINE bool google_protobuf_FileOptions_has_objc_class_prefix(const google_protobuf_FileOptions *msg) { return _upb_hasbit(msg, 13); }
UPB_INLINE upb_strview google_protobuf_FileOptions_objc_class_prefix(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(44, 72), upb_strview); }
-UPB_INLINE bool google_protobuf_FileOptions_has_csharp_namespace(const google_protobuf_FileOptions *msg) { return _upb_hasbit(msg, 15); }
+UPB_INLINE bool google_protobuf_FileOptions_has_csharp_namespace(const google_protobuf_FileOptions *msg) { return _upb_hasbit(msg, 14); }
UPB_INLINE upb_strview google_protobuf_FileOptions_csharp_namespace(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(52, 88), upb_strview); }
-UPB_INLINE bool google_protobuf_FileOptions_has_swift_prefix(const google_protobuf_FileOptions *msg) { return _upb_hasbit(msg, 16); }
+UPB_INLINE bool google_protobuf_FileOptions_has_swift_prefix(const google_protobuf_FileOptions *msg) { return _upb_hasbit(msg, 15); }
UPB_INLINE upb_strview google_protobuf_FileOptions_swift_prefix(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(60, 104), upb_strview); }
-UPB_INLINE bool google_protobuf_FileOptions_has_php_class_prefix(const google_protobuf_FileOptions *msg) { return _upb_hasbit(msg, 17); }
+UPB_INLINE bool google_protobuf_FileOptions_has_php_class_prefix(const google_protobuf_FileOptions *msg) { return _upb_hasbit(msg, 16); }
UPB_INLINE upb_strview google_protobuf_FileOptions_php_class_prefix(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(68, 120), upb_strview); }
-UPB_INLINE bool google_protobuf_FileOptions_has_php_namespace(const google_protobuf_FileOptions *msg) { return _upb_hasbit(msg, 18); }
+UPB_INLINE bool google_protobuf_FileOptions_has_php_namespace(const google_protobuf_FileOptions *msg) { return _upb_hasbit(msg, 17); }
UPB_INLINE upb_strview google_protobuf_FileOptions_php_namespace(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(76, 136), upb_strview); }
-UPB_INLINE bool google_protobuf_FileOptions_has_php_generic_services(const google_protobuf_FileOptions *msg) { return _upb_hasbit(msg, 10); }
+UPB_INLINE bool google_protobuf_FileOptions_has_php_generic_services(const google_protobuf_FileOptions *msg) { return _upb_hasbit(msg, 18); }
UPB_INLINE bool google_protobuf_FileOptions_php_generic_services(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(16, 16), bool); }
UPB_INLINE bool google_protobuf_FileOptions_has_php_metadata_namespace(const google_protobuf_FileOptions *msg) { return _upb_hasbit(msg, 19); }
UPB_INLINE upb_strview google_protobuf_FileOptions_php_metadata_namespace(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(84, 152), upb_strview); }
@@ -2592,75 +3131,75 @@
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(100, 184), len); }
UPB_INLINE void google_protobuf_FileOptions_set_java_package(google_protobuf_FileOptions *msg, upb_strview value) {
- _upb_sethas(msg, 11);
+ _upb_sethas(msg, 1);
*UPB_PTR_AT(msg, UPB_SIZE(20, 24), 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_sethas(msg, 2);
*UPB_PTR_AT(msg, UPB_SIZE(28, 40), upb_strview) = value;
}
UPB_INLINE void google_protobuf_FileOptions_set_optimize_for(google_protobuf_FileOptions *msg, int32_t value) {
- _upb_sethas(msg, 1);
+ _upb_sethas(msg, 3);
*UPB_PTR_AT(msg, UPB_SIZE(4, 4), int32_t) = value;
}
UPB_INLINE void google_protobuf_FileOptions_set_java_multiple_files(google_protobuf_FileOptions *msg, bool value) {
- _upb_sethas(msg, 2);
+ _upb_sethas(msg, 4);
*UPB_PTR_AT(msg, UPB_SIZE(8, 8), bool) = value;
}
UPB_INLINE void google_protobuf_FileOptions_set_go_package(google_protobuf_FileOptions *msg, upb_strview value) {
- _upb_sethas(msg, 13);
+ _upb_sethas(msg, 5);
*UPB_PTR_AT(msg, UPB_SIZE(36, 56), upb_strview) = value;
}
UPB_INLINE void google_protobuf_FileOptions_set_cc_generic_services(google_protobuf_FileOptions *msg, bool value) {
- _upb_sethas(msg, 3);
+ _upb_sethas(msg, 6);
*UPB_PTR_AT(msg, UPB_SIZE(9, 9), bool) = value;
}
UPB_INLINE void google_protobuf_FileOptions_set_java_generic_services(google_protobuf_FileOptions *msg, bool value) {
- _upb_sethas(msg, 4);
+ _upb_sethas(msg, 7);
*UPB_PTR_AT(msg, UPB_SIZE(10, 10), bool) = value;
}
UPB_INLINE void google_protobuf_FileOptions_set_py_generic_services(google_protobuf_FileOptions *msg, bool value) {
- _upb_sethas(msg, 5);
+ _upb_sethas(msg, 8);
*UPB_PTR_AT(msg, UPB_SIZE(11, 11), 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_sethas(msg, 9);
*UPB_PTR_AT(msg, UPB_SIZE(12, 12), bool) = value;
}
UPB_INLINE void google_protobuf_FileOptions_set_deprecated(google_protobuf_FileOptions *msg, bool value) {
- _upb_sethas(msg, 7);
+ _upb_sethas(msg, 10);
*UPB_PTR_AT(msg, UPB_SIZE(13, 13), bool) = value;
}
UPB_INLINE void google_protobuf_FileOptions_set_java_string_check_utf8(google_protobuf_FileOptions *msg, bool value) {
- _upb_sethas(msg, 8);
+ _upb_sethas(msg, 11);
*UPB_PTR_AT(msg, UPB_SIZE(14, 14), bool) = value;
}
UPB_INLINE void google_protobuf_FileOptions_set_cc_enable_arenas(google_protobuf_FileOptions *msg, bool value) {
- _upb_sethas(msg, 9);
+ _upb_sethas(msg, 12);
*UPB_PTR_AT(msg, UPB_SIZE(15, 15), bool) = value;
}
UPB_INLINE void google_protobuf_FileOptions_set_objc_class_prefix(google_protobuf_FileOptions *msg, upb_strview value) {
- _upb_sethas(msg, 14);
+ _upb_sethas(msg, 13);
*UPB_PTR_AT(msg, UPB_SIZE(44, 72), upb_strview) = value;
}
UPB_INLINE void google_protobuf_FileOptions_set_csharp_namespace(google_protobuf_FileOptions *msg, upb_strview value) {
- _upb_sethas(msg, 15);
+ _upb_sethas(msg, 14);
*UPB_PTR_AT(msg, UPB_SIZE(52, 88), upb_strview) = value;
}
UPB_INLINE void google_protobuf_FileOptions_set_swift_prefix(google_protobuf_FileOptions *msg, upb_strview value) {
- _upb_sethas(msg, 16);
+ _upb_sethas(msg, 15);
*UPB_PTR_AT(msg, UPB_SIZE(60, 104), 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_sethas(msg, 16);
*UPB_PTR_AT(msg, UPB_SIZE(68, 120), upb_strview) = value;
}
UPB_INLINE void google_protobuf_FileOptions_set_php_namespace(google_protobuf_FileOptions *msg, upb_strview value) {
- _upb_sethas(msg, 18);
+ _upb_sethas(msg, 17);
*UPB_PTR_AT(msg, UPB_SIZE(76, 136), upb_strview) = value;
}
UPB_INLINE void google_protobuf_FileOptions_set_php_generic_services(google_protobuf_FileOptions *msg, bool value) {
- _upb_sethas(msg, 10);
+ _upb_sethas(msg, 18);
*UPB_PTR_AT(msg, UPB_SIZE(16, 16), bool) = value;
}
UPB_INLINE void google_protobuf_FileOptions_set_php_metadata_namespace(google_protobuf_FileOptions *msg, upb_strview value) {
@@ -2695,6 +3234,12 @@
google_protobuf_MessageOptions *ret = google_protobuf_MessageOptions_new(arena);
return (ret && upb_decode(buf, size, ret, &google_protobuf_MessageOptions_msginit, arena)) ? ret : NULL;
}
+UPB_INLINE google_protobuf_MessageOptions *google_protobuf_MessageOptions_parse_ex(const char *buf, size_t size,
+ upb_arena *arena, int options) {
+ google_protobuf_MessageOptions *ret = google_protobuf_MessageOptions_new(arena);
+ return (ret && _upb_decode(buf, size, ret, &google_protobuf_MessageOptions_msginit, arena, options))
+ ? ret : NULL;
+}
UPB_INLINE char *google_protobuf_MessageOptions_serialize(const google_protobuf_MessageOptions *msg, upb_arena *arena, size_t *len) {
return upb_encode(msg, &google_protobuf_MessageOptions_msginit, arena, len);
}
@@ -2750,19 +3295,25 @@
google_protobuf_FieldOptions *ret = google_protobuf_FieldOptions_new(arena);
return (ret && upb_decode(buf, size, ret, &google_protobuf_FieldOptions_msginit, arena)) ? ret : NULL;
}
+UPB_INLINE google_protobuf_FieldOptions *google_protobuf_FieldOptions_parse_ex(const char *buf, size_t size,
+ upb_arena *arena, int options) {
+ google_protobuf_FieldOptions *ret = google_protobuf_FieldOptions_new(arena);
+ return (ret && _upb_decode(buf, size, ret, &google_protobuf_FieldOptions_msginit, arena, options))
+ ? ret : NULL;
+}
UPB_INLINE char *google_protobuf_FieldOptions_serialize(const google_protobuf_FieldOptions *msg, upb_arena *arena, size_t *len) {
return upb_encode(msg, &google_protobuf_FieldOptions_msginit, arena, len);
}
UPB_INLINE bool google_protobuf_FieldOptions_has_ctype(const google_protobuf_FieldOptions *msg) { return _upb_hasbit(msg, 1); }
UPB_INLINE int32_t google_protobuf_FieldOptions_ctype(const google_protobuf_FieldOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 4), int32_t); }
-UPB_INLINE bool google_protobuf_FieldOptions_has_packed(const google_protobuf_FieldOptions *msg) { return _upb_hasbit(msg, 3); }
+UPB_INLINE bool google_protobuf_FieldOptions_has_packed(const google_protobuf_FieldOptions *msg) { return _upb_hasbit(msg, 2); }
UPB_INLINE bool google_protobuf_FieldOptions_packed(const google_protobuf_FieldOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(12, 12), bool); }
-UPB_INLINE bool google_protobuf_FieldOptions_has_deprecated(const google_protobuf_FieldOptions *msg) { return _upb_hasbit(msg, 4); }
+UPB_INLINE bool google_protobuf_FieldOptions_has_deprecated(const google_protobuf_FieldOptions *msg) { return _upb_hasbit(msg, 3); }
UPB_INLINE bool google_protobuf_FieldOptions_deprecated(const google_protobuf_FieldOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(13, 13), bool); }
-UPB_INLINE bool google_protobuf_FieldOptions_has_lazy(const google_protobuf_FieldOptions *msg) { return _upb_hasbit(msg, 5); }
+UPB_INLINE bool google_protobuf_FieldOptions_has_lazy(const google_protobuf_FieldOptions *msg) { return _upb_hasbit(msg, 4); }
UPB_INLINE bool google_protobuf_FieldOptions_lazy(const google_protobuf_FieldOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(14, 14), bool); }
-UPB_INLINE bool google_protobuf_FieldOptions_has_jstype(const google_protobuf_FieldOptions *msg) { return _upb_hasbit(msg, 2); }
+UPB_INLINE bool google_protobuf_FieldOptions_has_jstype(const google_protobuf_FieldOptions *msg) { return _upb_hasbit(msg, 5); }
UPB_INLINE int32_t google_protobuf_FieldOptions_jstype(const google_protobuf_FieldOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 8), int32_t); }
UPB_INLINE bool google_protobuf_FieldOptions_has_weak(const google_protobuf_FieldOptions *msg) { return _upb_hasbit(msg, 6); }
UPB_INLINE bool google_protobuf_FieldOptions_weak(const google_protobuf_FieldOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(15, 15), bool); }
@@ -2774,19 +3325,19 @@
*UPB_PTR_AT(msg, UPB_SIZE(4, 4), int32_t) = value;
}
UPB_INLINE void google_protobuf_FieldOptions_set_packed(google_protobuf_FieldOptions *msg, bool value) {
- _upb_sethas(msg, 3);
+ _upb_sethas(msg, 2);
*UPB_PTR_AT(msg, UPB_SIZE(12, 12), bool) = value;
}
UPB_INLINE void google_protobuf_FieldOptions_set_deprecated(google_protobuf_FieldOptions *msg, bool value) {
- _upb_sethas(msg, 4);
+ _upb_sethas(msg, 3);
*UPB_PTR_AT(msg, UPB_SIZE(13, 13), bool) = value;
}
UPB_INLINE void google_protobuf_FieldOptions_set_lazy(google_protobuf_FieldOptions *msg, bool value) {
- _upb_sethas(msg, 5);
+ _upb_sethas(msg, 4);
*UPB_PTR_AT(msg, UPB_SIZE(14, 14), bool) = value;
}
UPB_INLINE void google_protobuf_FieldOptions_set_jstype(google_protobuf_FieldOptions *msg, int32_t value) {
- _upb_sethas(msg, 2);
+ _upb_sethas(msg, 5);
*UPB_PTR_AT(msg, UPB_SIZE(8, 8), int32_t) = value;
}
UPB_INLINE void google_protobuf_FieldOptions_set_weak(google_protobuf_FieldOptions *msg, bool value) {
@@ -2817,6 +3368,12 @@
google_protobuf_OneofOptions *ret = google_protobuf_OneofOptions_new(arena);
return (ret && upb_decode(buf, size, ret, &google_protobuf_OneofOptions_msginit, arena)) ? ret : NULL;
}
+UPB_INLINE google_protobuf_OneofOptions *google_protobuf_OneofOptions_parse_ex(const char *buf, size_t size,
+ upb_arena *arena, int options) {
+ google_protobuf_OneofOptions *ret = google_protobuf_OneofOptions_new(arena);
+ return (ret && _upb_decode(buf, size, ret, &google_protobuf_OneofOptions_msginit, arena, options))
+ ? ret : NULL;
+}
UPB_INLINE char *google_protobuf_OneofOptions_serialize(const google_protobuf_OneofOptions *msg, upb_arena *arena, size_t *len) {
return upb_encode(msg, &google_protobuf_OneofOptions_msginit, arena, len);
}
@@ -2848,6 +3405,12 @@
google_protobuf_EnumOptions *ret = google_protobuf_EnumOptions_new(arena);
return (ret && upb_decode(buf, size, ret, &google_protobuf_EnumOptions_msginit, arena)) ? ret : NULL;
}
+UPB_INLINE google_protobuf_EnumOptions *google_protobuf_EnumOptions_parse_ex(const char *buf, size_t size,
+ upb_arena *arena, int options) {
+ google_protobuf_EnumOptions *ret = google_protobuf_EnumOptions_new(arena);
+ return (ret && _upb_decode(buf, size, ret, &google_protobuf_EnumOptions_msginit, arena, options))
+ ? ret : NULL;
+}
UPB_INLINE char *google_protobuf_EnumOptions_serialize(const google_protobuf_EnumOptions *msg, upb_arena *arena, size_t *len) {
return upb_encode(msg, &google_protobuf_EnumOptions_msginit, arena, len);
}
@@ -2891,6 +3454,12 @@
google_protobuf_EnumValueOptions *ret = google_protobuf_EnumValueOptions_new(arena);
return (ret && upb_decode(buf, size, ret, &google_protobuf_EnumValueOptions_msginit, arena)) ? ret : NULL;
}
+UPB_INLINE google_protobuf_EnumValueOptions *google_protobuf_EnumValueOptions_parse_ex(const char *buf, size_t size,
+ upb_arena *arena, int options) {
+ google_protobuf_EnumValueOptions *ret = google_protobuf_EnumValueOptions_new(arena);
+ return (ret && _upb_decode(buf, size, ret, &google_protobuf_EnumValueOptions_msginit, arena, options))
+ ? ret : NULL;
+}
UPB_INLINE char *google_protobuf_EnumValueOptions_serialize(const google_protobuf_EnumValueOptions *msg, upb_arena *arena, size_t *len) {
return upb_encode(msg, &google_protobuf_EnumValueOptions_msginit, arena, len);
}
@@ -2928,6 +3497,12 @@
google_protobuf_ServiceOptions *ret = google_protobuf_ServiceOptions_new(arena);
return (ret && upb_decode(buf, size, ret, &google_protobuf_ServiceOptions_msginit, arena)) ? ret : NULL;
}
+UPB_INLINE google_protobuf_ServiceOptions *google_protobuf_ServiceOptions_parse_ex(const char *buf, size_t size,
+ upb_arena *arena, int options) {
+ google_protobuf_ServiceOptions *ret = google_protobuf_ServiceOptions_new(arena);
+ return (ret && _upb_decode(buf, size, ret, &google_protobuf_ServiceOptions_msginit, arena, options))
+ ? ret : NULL;
+}
UPB_INLINE char *google_protobuf_ServiceOptions_serialize(const google_protobuf_ServiceOptions *msg, upb_arena *arena, size_t *len) {
return upb_encode(msg, &google_protobuf_ServiceOptions_msginit, arena, len);
}
@@ -2965,23 +3540,29 @@
google_protobuf_MethodOptions *ret = google_protobuf_MethodOptions_new(arena);
return (ret && upb_decode(buf, size, ret, &google_protobuf_MethodOptions_msginit, arena)) ? ret : NULL;
}
+UPB_INLINE google_protobuf_MethodOptions *google_protobuf_MethodOptions_parse_ex(const char *buf, size_t size,
+ upb_arena *arena, int options) {
+ google_protobuf_MethodOptions *ret = google_protobuf_MethodOptions_new(arena);
+ return (ret && _upb_decode(buf, size, ret, &google_protobuf_MethodOptions_msginit, arena, options))
+ ? ret : NULL;
+}
UPB_INLINE char *google_protobuf_MethodOptions_serialize(const google_protobuf_MethodOptions *msg, upb_arena *arena, size_t *len) {
return upb_encode(msg, &google_protobuf_MethodOptions_msginit, arena, len);
}
-UPB_INLINE bool google_protobuf_MethodOptions_has_deprecated(const google_protobuf_MethodOptions *msg) { return _upb_hasbit(msg, 2); }
+UPB_INLINE bool google_protobuf_MethodOptions_has_deprecated(const google_protobuf_MethodOptions *msg) { return _upb_hasbit(msg, 1); }
UPB_INLINE bool google_protobuf_MethodOptions_deprecated(const google_protobuf_MethodOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 8), bool); }
-UPB_INLINE bool google_protobuf_MethodOptions_has_idempotency_level(const google_protobuf_MethodOptions *msg) { return _upb_hasbit(msg, 1); }
+UPB_INLINE bool google_protobuf_MethodOptions_has_idempotency_level(const google_protobuf_MethodOptions *msg) { return _upb_hasbit(msg, 2); }
UPB_INLINE int32_t google_protobuf_MethodOptions_idempotency_level(const google_protobuf_MethodOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 4), int32_t); }
UPB_INLINE bool google_protobuf_MethodOptions_has_uninterpreted_option(const google_protobuf_MethodOptions *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(12, 16)); }
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(12, 16), len); }
UPB_INLINE void google_protobuf_MethodOptions_set_deprecated(google_protobuf_MethodOptions *msg, bool value) {
- _upb_sethas(msg, 2);
+ _upb_sethas(msg, 1);
*UPB_PTR_AT(msg, UPB_SIZE(8, 8), bool) = value;
}
UPB_INLINE void google_protobuf_MethodOptions_set_idempotency_level(google_protobuf_MethodOptions *msg, int32_t value) {
- _upb_sethas(msg, 1);
+ _upb_sethas(msg, 2);
*UPB_PTR_AT(msg, UPB_SIZE(4, 4), int32_t) = value;
}
UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_MethodOptions_mutable_uninterpreted_option(google_protobuf_MethodOptions *msg, size_t *len) {
@@ -3008,19 +3589,25 @@
google_protobuf_UninterpretedOption *ret = google_protobuf_UninterpretedOption_new(arena);
return (ret && upb_decode(buf, size, ret, &google_protobuf_UninterpretedOption_msginit, arena)) ? ret : NULL;
}
+UPB_INLINE google_protobuf_UninterpretedOption *google_protobuf_UninterpretedOption_parse_ex(const char *buf, size_t size,
+ upb_arena *arena, int options) {
+ google_protobuf_UninterpretedOption *ret = google_protobuf_UninterpretedOption_new(arena);
+ return (ret && _upb_decode(buf, size, ret, &google_protobuf_UninterpretedOption_msginit, arena, options))
+ ? ret : NULL;
+}
UPB_INLINE char *google_protobuf_UninterpretedOption_serialize(const google_protobuf_UninterpretedOption *msg, upb_arena *arena, size_t *len) {
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_hasbit(msg, 4); }
+UPB_INLINE bool google_protobuf_UninterpretedOption_has_identifier_value(const google_protobuf_UninterpretedOption *msg) { return _upb_hasbit(msg, 1); }
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_hasbit(msg, 1); }
+UPB_INLINE bool google_protobuf_UninterpretedOption_has_positive_int_value(const google_protobuf_UninterpretedOption *msg) { return _upb_hasbit(msg, 2); }
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_hasbit(msg, 2); }
+UPB_INLINE bool google_protobuf_UninterpretedOption_has_negative_int_value(const google_protobuf_UninterpretedOption *msg) { return _upb_hasbit(msg, 3); }
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_hasbit(msg, 3); }
+UPB_INLINE bool google_protobuf_UninterpretedOption_has_double_value(const google_protobuf_UninterpretedOption *msg) { return _upb_hasbit(msg, 4); }
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_hasbit(msg, 5); }
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); }
@@ -3041,19 +3628,19 @@
return sub;
}
UPB_INLINE void google_protobuf_UninterpretedOption_set_identifier_value(google_protobuf_UninterpretedOption *msg, upb_strview value) {
- _upb_sethas(msg, 4);
+ _upb_sethas(msg, 1);
*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_sethas(msg, 2);
*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_sethas(msg, 3);
*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_sethas(msg, 4);
*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) {
@@ -3075,21 +3662,27 @@
google_protobuf_UninterpretedOption_NamePart *ret = google_protobuf_UninterpretedOption_NamePart_new(arena);
return (ret && upb_decode(buf, size, ret, &google_protobuf_UninterpretedOption_NamePart_msginit, arena)) ? ret : NULL;
}
+UPB_INLINE google_protobuf_UninterpretedOption_NamePart *google_protobuf_UninterpretedOption_NamePart_parse_ex(const char *buf, size_t size,
+ upb_arena *arena, int options) {
+ google_protobuf_UninterpretedOption_NamePart *ret = google_protobuf_UninterpretedOption_NamePart_new(arena);
+ return (ret && _upb_decode(buf, size, ret, &google_protobuf_UninterpretedOption_NamePart_msginit, arena, options))
+ ? ret : NULL;
+}
UPB_INLINE char *google_protobuf_UninterpretedOption_NamePart_serialize(const google_protobuf_UninterpretedOption_NamePart *msg, upb_arena *arena, size_t *len) {
return upb_encode(msg, &google_protobuf_UninterpretedOption_NamePart_msginit, arena, len);
}
-UPB_INLINE bool google_protobuf_UninterpretedOption_NamePart_has_name_part(const google_protobuf_UninterpretedOption_NamePart *msg) { return _upb_hasbit(msg, 2); }
+UPB_INLINE bool google_protobuf_UninterpretedOption_NamePart_has_name_part(const google_protobuf_UninterpretedOption_NamePart *msg) { return _upb_hasbit(msg, 1); }
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_hasbit(msg, 1); }
+UPB_INLINE bool google_protobuf_UninterpretedOption_NamePart_has_is_extension(const google_protobuf_UninterpretedOption_NamePart *msg) { return _upb_hasbit(msg, 2); }
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_sethas(msg, 1);
*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_sethas(msg, 2);
*UPB_PTR_AT(msg, UPB_SIZE(1, 1), bool) = value;
}
@@ -3103,6 +3696,12 @@
google_protobuf_SourceCodeInfo *ret = google_protobuf_SourceCodeInfo_new(arena);
return (ret && upb_decode(buf, size, ret, &google_protobuf_SourceCodeInfo_msginit, arena)) ? ret : NULL;
}
+UPB_INLINE google_protobuf_SourceCodeInfo *google_protobuf_SourceCodeInfo_parse_ex(const char *buf, size_t size,
+ upb_arena *arena, int options) {
+ google_protobuf_SourceCodeInfo *ret = google_protobuf_SourceCodeInfo_new(arena);
+ return (ret && _upb_decode(buf, size, ret, &google_protobuf_SourceCodeInfo_msginit, arena, options))
+ ? ret : NULL;
+}
UPB_INLINE char *google_protobuf_SourceCodeInfo_serialize(const google_protobuf_SourceCodeInfo *msg, upb_arena *arena, size_t *len) {
return upb_encode(msg, &google_protobuf_SourceCodeInfo_msginit, arena, len);
}
@@ -3134,6 +3733,12 @@
google_protobuf_SourceCodeInfo_Location *ret = google_protobuf_SourceCodeInfo_Location_new(arena);
return (ret && upb_decode(buf, size, ret, &google_protobuf_SourceCodeInfo_Location_msginit, arena)) ? ret : NULL;
}
+UPB_INLINE google_protobuf_SourceCodeInfo_Location *google_protobuf_SourceCodeInfo_Location_parse_ex(const char *buf, size_t size,
+ upb_arena *arena, int options) {
+ google_protobuf_SourceCodeInfo_Location *ret = google_protobuf_SourceCodeInfo_Location_new(arena);
+ return (ret && _upb_decode(buf, size, ret, &google_protobuf_SourceCodeInfo_Location_msginit, arena, options))
+ ? ret : NULL;
+}
UPB_INLINE char *google_protobuf_SourceCodeInfo_Location_serialize(const google_protobuf_SourceCodeInfo_Location *msg, upb_arena *arena, size_t *len) {
return upb_encode(msg, &google_protobuf_SourceCodeInfo_Location_msginit, arena, len);
}
@@ -3195,6 +3800,12 @@
google_protobuf_GeneratedCodeInfo *ret = google_protobuf_GeneratedCodeInfo_new(arena);
return (ret && upb_decode(buf, size, ret, &google_protobuf_GeneratedCodeInfo_msginit, arena)) ? ret : NULL;
}
+UPB_INLINE google_protobuf_GeneratedCodeInfo *google_protobuf_GeneratedCodeInfo_parse_ex(const char *buf, size_t size,
+ upb_arena *arena, int options) {
+ google_protobuf_GeneratedCodeInfo *ret = google_protobuf_GeneratedCodeInfo_new(arena);
+ return (ret && _upb_decode(buf, size, ret, &google_protobuf_GeneratedCodeInfo_msginit, arena, options))
+ ? ret : NULL;
+}
UPB_INLINE char *google_protobuf_GeneratedCodeInfo_serialize(const google_protobuf_GeneratedCodeInfo *msg, upb_arena *arena, size_t *len) {
return upb_encode(msg, &google_protobuf_GeneratedCodeInfo_msginit, arena, len);
}
@@ -3226,16 +3837,22 @@
google_protobuf_GeneratedCodeInfo_Annotation *ret = google_protobuf_GeneratedCodeInfo_Annotation_new(arena);
return (ret && upb_decode(buf, size, ret, &google_protobuf_GeneratedCodeInfo_Annotation_msginit, arena)) ? ret : NULL;
}
+UPB_INLINE google_protobuf_GeneratedCodeInfo_Annotation *google_protobuf_GeneratedCodeInfo_Annotation_parse_ex(const char *buf, size_t size,
+ upb_arena *arena, int options) {
+ google_protobuf_GeneratedCodeInfo_Annotation *ret = google_protobuf_GeneratedCodeInfo_Annotation_new(arena);
+ return (ret && _upb_decode(buf, size, ret, &google_protobuf_GeneratedCodeInfo_Annotation_msginit, arena, options))
+ ? ret : NULL;
+}
UPB_INLINE char *google_protobuf_GeneratedCodeInfo_Annotation_serialize(const google_protobuf_GeneratedCodeInfo_Annotation *msg, upb_arena *arena, size_t *len) {
return upb_encode(msg, &google_protobuf_GeneratedCodeInfo_Annotation_msginit, arena, len);
}
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_hasbit(msg, 3); }
+UPB_INLINE bool google_protobuf_GeneratedCodeInfo_Annotation_has_source_file(const google_protobuf_GeneratedCodeInfo_Annotation *msg) { return _upb_hasbit(msg, 1); }
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_hasbit(msg, 1); }
+UPB_INLINE bool google_protobuf_GeneratedCodeInfo_Annotation_has_begin(const google_protobuf_GeneratedCodeInfo_Annotation *msg) { return _upb_hasbit(msg, 2); }
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_hasbit(msg, 2); }
+UPB_INLINE bool google_protobuf_GeneratedCodeInfo_Annotation_has_end(const google_protobuf_GeneratedCodeInfo_Annotation *msg) { return _upb_hasbit(msg, 3); }
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) {
@@ -3249,15 +3866,15 @@
arena);
}
UPB_INLINE void google_protobuf_GeneratedCodeInfo_Annotation_set_source_file(google_protobuf_GeneratedCodeInfo_Annotation *msg, upb_strview value) {
- _upb_sethas(msg, 3);
+ _upb_sethas(msg, 1);
*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_sethas(msg, 2);
*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_sethas(msg, 3);
*UPB_PTR_AT(msg, UPB_SIZE(8, 8), int32_t) = value;
}
@@ -3284,6 +3901,7 @@
#define UPB_DEF_H_
+/* Must be last. */
#ifdef __cplusplus
extern "C" {
@@ -3542,6 +4160,7 @@
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);
+const upb_symtab *upb_filedef_symtab(const upb_filedef *f);
/* upb_symtab *****************************************************************/
@@ -3742,6 +4361,10 @@
+#ifdef __cplusplus
+extern "C" {
+#endif
+
typedef union {
bool bool_val;
float float_val;
@@ -3762,6 +4385,8 @@
upb_array* array;
} upb_mutmsgval;
+upb_msgval upb_fielddef_default(const upb_fielddef *f);
+
/** upb_msg *******************************************************************/
/* Creates a new message of the given type in the given arena. */
@@ -3897,6 +4522,10 @@
* 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_REFLECTION_H_ */
diff --git a/php/src/Google/Protobuf/Internal/GPBWire.php b/php/src/Google/Protobuf/Internal/GPBWire.php
index 7f1eab3..2956953 100644
--- a/php/src/Google/Protobuf/Internal/GPBWire.php
+++ b/php/src/Google/Protobuf/Internal/GPBWire.php
@@ -50,8 +50,8 @@
public static function getTagFieldNumber($tag)
{
- return ($tag >> self::TAG_TYPE_BITS) &
- (1 << ((PHP_INT_SIZE * 8) - self::TAG_TYPE_BITS)) - 1;
+ // We have to mask because PHP has no arithmetic shift.
+ return ($tag >> self::TAG_TYPE_BITS) & 0x1fffffff;
}
public static function getTagWireType($tag)
diff --git a/php/tests/EncodeDecodeTest.php b/php/tests/EncodeDecodeTest.php
index 6368a18..d471a5a 100644
--- a/php/tests/EncodeDecodeTest.php
+++ b/php/tests/EncodeDecodeTest.php
@@ -14,6 +14,7 @@
use Foo\TestBytesValue;
use Foo\TestAny;
use Foo\TestEnum;
+use Foo\TestLargeFieldNumber;
use Foo\TestMessage;
use Foo\TestMessage\Sub;
use Foo\TestPackedMessage;
@@ -529,6 +530,15 @@
$this->assertSame("", $data);
}
+ public function testLargeFieldNumber()
+ {
+ $m = new TestLargeFieldNumber(['large_field_number' => 5]);
+ $data = $m->serializeToString();
+ $m2 = new TestLargeFieldNumber();
+ $m2->mergeFromString($data);
+ $this->assertSame(5, $m2->getLargeFieldNumber());
+ }
+
public function testDecodeInvalidInt32()
{
$this->expectException(Exception::class);
diff --git a/php/tests/proto/test.proto b/php/tests/proto/test.proto
index 368b19e..8835729 100644
--- a/php/tests/proto/test.proto
+++ b/php/tests/proto/test.proto
@@ -220,6 +220,10 @@
string tag14 = 160;
}
+message TestLargeFieldNumber {
+ int32 large_field_number = 536870911;
+}
+
message TestReverseFieldOrder {
repeated int32 a = 2;
string b = 1;