1 /* Amalgamated source file */
2 #include "php-upb.h"
3 /*
4 * This is where we define macros used across upb.
5 *
6 * All of these macros are undef'd in port_undef.inc to avoid leaking them to
7 * users.
8 *
9 * The correct usage is:
10 *
11 * #include "upb/foobar.h"
12 * #include "upb/baz.h"
13 *
14 * // MUST be last included header.
15 * #include "upb/port_def.inc"
16 *
17 * // Code for this file.
18 * // <...>
19 *
20 * // Can be omitted for .c files, required for .h.
21 * #include "upb/port_undef.inc"
22 *
23 * This file is private and must not be included by users!
24 */
25
26 #if !(__STDC_VERSION__ >= 199901L || __cplusplus >= 201103L)
27 #error upb requires C99 or C++11
28 #endif
29
30 #if (defined(_MSC_VER) && _MSC_VER < 1900)
31 #error upb requires MSVC >= 2015.
32 #endif
33
34 #include <stdint.h>
35 #include <stddef.h>
36
37 #if UINTPTR_MAX == 0xffffffff
38 #define UPB_SIZE(size32, size64) size32
39 #else
40 #define UPB_SIZE(size32, size64) size64
41 #endif
42
43 /* If we always read/write as a consistent type to each address, this shouldn't
44 * violate aliasing.
45 */
46 #define UPB_PTR_AT(msg, ofs, type) ((type*)((char*)(msg) + (ofs)))
47
48 #define UPB_READ_ONEOF(msg, fieldtype, offset, case_offset, case_val, default) \
49 *UPB_PTR_AT(msg, case_offset, int) == case_val \
50 ? *UPB_PTR_AT(msg, offset, fieldtype) \
51 : default
52
53 #define UPB_WRITE_ONEOF(msg, fieldtype, offset, value, case_offset, case_val) \
54 *UPB_PTR_AT(msg, case_offset, int) = case_val; \
55 *UPB_PTR_AT(msg, offset, fieldtype) = value;
56
57 #define UPB_MAPTYPE_STRING 0
58
59 /* UPB_INLINE: inline if possible, emit standalone code if required. */
60 #ifdef __cplusplus
61 #define UPB_INLINE inline
62 #elif defined (__GNUC__) || defined(__clang__)
63 #define UPB_INLINE static __inline__
64 #else
65 #define UPB_INLINE static
66 #endif
67
68 #define UPB_ALIGN_UP(size, align) (((size) + (align) - 1) / (align) * (align))
69 #define UPB_ALIGN_DOWN(size, align) ((size) / (align) * (align))
70 #define UPB_ALIGN_MALLOC(size) UPB_ALIGN_UP(size, 16)
71 #define UPB_ALIGN_OF(type) offsetof (struct { char c; type member; }, member)
72
73 /* Hints to the compiler about likely/unlikely branches. */
74 #if defined (__GNUC__) || defined(__clang__)
75 #define UPB_LIKELY(x) __builtin_expect((x),1)
76 #define UPB_UNLIKELY(x) __builtin_expect((x),0)
77 #else
78 #define UPB_LIKELY(x) (x)
79 #define UPB_UNLIKELY(x) (x)
80 #endif
81
82 /* Macros for function attributes on compilers that support them. */
83 #ifdef __GNUC__
84 #define UPB_FORCEINLINE __inline__ __attribute__((always_inline))
85 #define UPB_NOINLINE __attribute__((noinline))
86 #define UPB_NORETURN __attribute__((__noreturn__))
87 #elif defined(_MSC_VER)
88 #define UPB_NOINLINE
89 #define UPB_FORCEINLINE
90 #define UPB_NORETURN __declspec(noreturn)
91 #else /* !defined(__GNUC__) */
92 #define UPB_FORCEINLINE
93 #define UPB_NOINLINE
94 #define UPB_NORETURN
95 #endif
96
97 #define UPB_MAX(x, y) ((x) > (y) ? (x) : (y))
98 #define UPB_MIN(x, y) ((x) < (y) ? (x) : (y))
99
100 #define UPB_UNUSED(var) (void)var
101
102 /* UPB_ASSUME(): in release mode, we tell the compiler to assume this is true.
103 */
104 #ifdef NDEBUG
105 #ifdef __GNUC__
106 #define UPB_ASSUME(expr) if (!(expr)) __builtin_unreachable()
107 #elif defined _MSC_VER
108 #define UPB_ASSUME(expr) if (!(expr)) __assume(0)
109 #else
110 #define UPB_ASSUME(expr) do {} while (false && (expr))
111 #endif
112 #else
113 #define UPB_ASSUME(expr) assert(expr)
114 #endif
115
116 /* UPB_ASSERT(): in release mode, we use the expression without letting it be
117 * evaluated. This prevents "unused variable" warnings. */
118 #ifdef NDEBUG
119 #define UPB_ASSERT(expr) do {} while (false && (expr))
120 #else
121 #define UPB_ASSERT(expr) assert(expr)
122 #endif
123
124 #if defined(__GNUC__) || defined(__clang__)
125 #define UPB_UNREACHABLE() do { assert(0); __builtin_unreachable(); } while(0)
126 #else
127 #define UPB_UNREACHABLE() do { assert(0); } while(0)
128 #endif
129
130 #if defined(__SANITIZE_ADDRESS__)
131 #define UPB_ASAN 1
132 #ifdef __cplusplus
133 extern "C" {
134 #endif
135 void __asan_poison_memory_region(void const volatile *addr, size_t size);
136 void __asan_unpoison_memory_region(void const volatile *addr, size_t size);
137 #ifdef __cplusplus
138 } /* extern "C" */
139 #endif
140 #define UPB_POISON_MEMORY_REGION(addr, size) \
141 __asan_poison_memory_region((addr), (size))
142 #define UPB_UNPOISON_MEMORY_REGION(addr, size) \
143 __asan_unpoison_memory_region((addr), (size))
144 #else
145 #define UPB_ASAN 0
146 #define UPB_POISON_MEMORY_REGION(addr, size) \
147 ((void)(addr), (void)(size))
148 #define UPB_UNPOISON_MEMORY_REGION(addr, size) \
149 ((void)(addr), (void)(size))
150 #endif
151
152
153 #include <setjmp.h>
154 #include <string.h>
155
156
157 /* Must be last. */
158
159 /* Maps descriptor type -> elem_size_lg2. */
160 static const uint8_t desctype_to_elem_size_lg2[] = {
161 -1, /* invalid descriptor type */
162 3, /* DOUBLE */
163 2, /* FLOAT */
164 3, /* INT64 */
165 3, /* UINT64 */
166 2, /* INT32 */
167 3, /* FIXED64 */
168 2, /* FIXED32 */
169 0, /* BOOL */
170 UPB_SIZE(3, 4), /* STRING */
171 UPB_SIZE(2, 3), /* GROUP */
172 UPB_SIZE(2, 3), /* MESSAGE */
173 UPB_SIZE(3, 4), /* BYTES */
174 2, /* UINT32 */
175 2, /* ENUM */
176 2, /* SFIXED32 */
177 3, /* SFIXED64 */
178 2, /* SINT32 */
179 3, /* SINT64 */
180 };
181
182 /* Maps descriptor type -> upb map size. */
183 static const uint8_t desctype_to_mapsize[] = {
184 -1, /* invalid descriptor type */
185 8, /* DOUBLE */
186 4, /* FLOAT */
187 8, /* INT64 */
188 8, /* UINT64 */
189 4, /* INT32 */
190 8, /* FIXED64 */
191 4, /* FIXED32 */
192 1, /* BOOL */
193 UPB_MAPTYPE_STRING, /* STRING */
194 sizeof(void *), /* GROUP */
195 sizeof(void *), /* MESSAGE */
196 UPB_MAPTYPE_STRING, /* BYTES */
197 4, /* UINT32 */
198 4, /* ENUM */
199 4, /* SFIXED32 */
200 8, /* SFIXED64 */
201 4, /* SINT32 */
202 8, /* SINT64 */
203 };
204
205 static const unsigned fixed32_ok = (1 << UPB_DTYPE_FLOAT) |
206 (1 << UPB_DTYPE_FIXED32) |
207 (1 << UPB_DTYPE_SFIXED32);
208
209 static const unsigned fixed64_ok = (1 << UPB_DTYPE_DOUBLE) |
210 (1 << UPB_DTYPE_FIXED64) |
211 (1 << UPB_DTYPE_SFIXED64);
212
213 /* Op: an action to be performed for a wire-type/field-type combination. */
214 #define OP_SCALAR_LG2(n) (n) /* n in [0, 2, 3] => op in [0, 2, 3] */
215 #define OP_STRING 4
216 #define OP_BYTES 5
217 #define OP_SUBMSG 6
218 /* Ops above are scalar-only. Repeated fields can use any op. */
219 #define OP_FIXPCK_LG2(n) (n + 5) /* n in [2, 3] => op in [7, 8] */
220 #define OP_VARPCK_LG2(n) (n + 9) /* n in [0, 2, 3] => op in [9, 11, 12] */
221
222 static const int8_t varint_ops[19] = {
223 -1, /* field not found */
224 -1, /* DOUBLE */
225 -1, /* FLOAT */
226 OP_SCALAR_LG2(3), /* INT64 */
227 OP_SCALAR_LG2(3), /* UINT64 */
228 OP_SCALAR_LG2(2), /* INT32 */
229 -1, /* FIXED64 */
230 -1, /* FIXED32 */
231 OP_SCALAR_LG2(0), /* BOOL */
232 -1, /* STRING */
233 -1, /* GROUP */
234 -1, /* MESSAGE */
235 -1, /* BYTES */
236 OP_SCALAR_LG2(2), /* UINT32 */
237 OP_SCALAR_LG2(2), /* ENUM */
238 -1, /* SFIXED32 */
239 -1, /* SFIXED64 */
240 OP_SCALAR_LG2(2), /* SINT32 */
241 OP_SCALAR_LG2(3), /* SINT64 */
242 };
243
244 static const int8_t delim_ops[37] = {
245 /* For non-repeated field type. */
246 -1, /* field not found */
247 -1, /* DOUBLE */
248 -1, /* FLOAT */
249 -1, /* INT64 */
250 -1, /* UINT64 */
251 -1, /* INT32 */
252 -1, /* FIXED64 */
253 -1, /* FIXED32 */
254 -1, /* BOOL */
255 OP_STRING, /* STRING */
256 -1, /* GROUP */
257 OP_SUBMSG, /* MESSAGE */
258 OP_BYTES, /* BYTES */
259 -1, /* UINT32 */
260 -1, /* ENUM */
261 -1, /* SFIXED32 */
262 -1, /* SFIXED64 */
263 -1, /* SINT32 */
264 -1, /* SINT64 */
265 /* For repeated field type. */
266 OP_FIXPCK_LG2(3), /* REPEATED DOUBLE */
267 OP_FIXPCK_LG2(2), /* REPEATED FLOAT */
268 OP_VARPCK_LG2(3), /* REPEATED INT64 */
269 OP_VARPCK_LG2(3), /* REPEATED UINT64 */
270 OP_VARPCK_LG2(2), /* REPEATED INT32 */
271 OP_FIXPCK_LG2(3), /* REPEATED FIXED64 */
272 OP_FIXPCK_LG2(2), /* REPEATED FIXED32 */
273 OP_VARPCK_LG2(0), /* REPEATED BOOL */
274 OP_STRING, /* REPEATED STRING */
275 OP_SUBMSG, /* REPEATED GROUP */
276 OP_SUBMSG, /* REPEATED MESSAGE */
277 OP_BYTES, /* REPEATED BYTES */
278 OP_VARPCK_LG2(2), /* REPEATED UINT32 */
279 OP_VARPCK_LG2(2), /* REPEATED ENUM */
280 OP_FIXPCK_LG2(2), /* REPEATED SFIXED32 */
281 OP_FIXPCK_LG2(3), /* REPEATED SFIXED64 */
282 OP_VARPCK_LG2(2), /* REPEATED SINT32 */
283 OP_VARPCK_LG2(3), /* REPEATED SINT64 */
284 };
285
286 /* Data pertaining to the parse. */
287 typedef struct {
288 const char *end; /* Can read up to 16 bytes slop beyond this. */
289 const char *limit_ptr; /* = end + UPB_MIN(limit, 0) */
290 int limit; /* Submessage limit relative to end. */
291 int depth;
292 uint32_t end_group; /* Set to field number of END_GROUP tag, if any. */
293 bool alias;
294 char patch[32];
295 upb_arena arena;
296 jmp_buf err;
297 } upb_decstate;
298
299 typedef union {
300 bool bool_val;
301 uint32_t uint32_val;
302 uint64_t uint64_val;
303 uint32_t size;
304 } wireval;
305
306 static const char *decode_msg(upb_decstate *d, const char *ptr, upb_msg *msg,
307 const upb_msglayout *layout);
308
decode_err(upb_decstate * d)309 UPB_NORETURN static void decode_err(upb_decstate *d) { longjmp(d->err, 1); }
310
decode_verifyutf8(upb_decstate * d,const char * buf,int len)311 void decode_verifyutf8(upb_decstate *d, const char *buf, int len) {
312 static const uint8_t utf8_offset[] = {
313 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
314 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
315 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
316 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
317 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
318 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
319 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
320 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
321 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
322 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
323 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0,
324 };
325
326 int i, j;
327 uint8_t offset;
328
329 i = 0;
330 while (i < len) {
331 offset = utf8_offset[(uint8_t)buf[i]];
332 if (offset == 0 || i + offset > len) {
333 decode_err(d);
334 }
335 for (j = i + 1; j < i + offset; j++) {
336 if ((buf[j] & 0xc0) != 0x80) {
337 decode_err(d);
338 }
339 }
340 i += offset;
341 }
342 if (i != len) decode_err(d);
343 }
344
decode_reserve(upb_decstate * d,upb_array * arr,size_t elem)345 static bool decode_reserve(upb_decstate *d, upb_array *arr, size_t elem) {
346 bool need_realloc = arr->size - arr->len < elem;
347 if (need_realloc && !_upb_array_realloc(arr, arr->len + elem, &d->arena)) {
348 decode_err(d);
349 }
350 return need_realloc;
351 }
352
353 typedef struct {
354 const char *ptr;
355 uint64_t val;
356 } decode_vret;
357
358 UPB_NOINLINE
decode_longvarint64(const char * ptr,uint64_t val)359 static decode_vret decode_longvarint64(const char *ptr, uint64_t val) {
360 decode_vret ret = {NULL, 0};
361 uint64_t byte;
362 int i;
363 for (i = 1; i < 10; i++) {
364 byte = (uint8_t)ptr[i];
365 val += (byte - 1) << (i * 7);
366 if (!(byte & 0x80)) {
367 ret.ptr = ptr + i + 1;
368 ret.val = val;
369 return ret;
370 }
371 }
372 return ret;
373 }
374
375 UPB_FORCEINLINE
decode_varint64(upb_decstate * d,const char * ptr,uint64_t * val)376 static const char *decode_varint64(upb_decstate *d, const char *ptr,
377 uint64_t *val) {
378 uint64_t byte = (uint8_t)*ptr;
379 if (UPB_LIKELY((byte & 0x80) == 0)) {
380 *val = byte;
381 return ptr + 1;
382 } else {
383 decode_vret res = decode_longvarint64(ptr, byte);
384 if (!res.ptr) decode_err(d);
385 *val = res.val;
386 return res.ptr;
387 }
388 }
389
390 UPB_FORCEINLINE
decode_varint32(upb_decstate * d,const char * ptr,uint32_t * val)391 static const char *decode_varint32(upb_decstate *d, const char *ptr,
392 uint32_t *val) {
393 uint64_t u64;
394 ptr = decode_varint64(d, ptr, &u64);
395 if (u64 > UINT32_MAX) decode_err(d);
396 *val = (uint32_t)u64;
397 return ptr;
398 }
399
decode_munge(int type,wireval * val)400 static void decode_munge(int type, wireval *val) {
401 switch (type) {
402 case UPB_DESCRIPTOR_TYPE_BOOL:
403 val->bool_val = val->uint64_val != 0;
404 break;
405 case UPB_DESCRIPTOR_TYPE_SINT32: {
406 uint32_t n = val->uint32_val;
407 val->uint32_val = (n >> 1) ^ -(int32_t)(n & 1);
408 break;
409 }
410 case UPB_DESCRIPTOR_TYPE_SINT64: {
411 uint64_t n = val->uint64_val;
412 val->uint64_val = (n >> 1) ^ -(int64_t)(n & 1);
413 break;
414 }
415 case UPB_DESCRIPTOR_TYPE_INT32:
416 case UPB_DESCRIPTOR_TYPE_UINT32:
417 if (!_upb_isle()) {
418 /* The next stage will memcpy(dst, &val, 4) */
419 val->uint32_val = val->uint64_val;
420 }
421 break;
422 }
423 }
424
upb_find_field(const upb_msglayout * l,uint32_t field_number)425 static const upb_msglayout_field *upb_find_field(const upb_msglayout *l,
426 uint32_t field_number) {
427 static upb_msglayout_field none = {0, 0, 0, 0, 0, 0};
428
429 /* Lots of optimization opportunities here. */
430 int i;
431 if (l == NULL) return &none;
432 for (i = 0; i < l->field_count; i++) {
433 if (l->fields[i].number == field_number) {
434 return &l->fields[i];
435 }
436 }
437
438 return &none; /* Unknown field. */
439 }
440
decode_newsubmsg(upb_decstate * d,const upb_msglayout * layout,const upb_msglayout_field * field)441 static upb_msg *decode_newsubmsg(upb_decstate *d, const upb_msglayout *layout,
442 const upb_msglayout_field *field) {
443 const upb_msglayout *subl = layout->submsgs[field->submsg_index];
444 return _upb_msg_new_inl(subl, &d->arena);
445 }
446
decode_pushlimit(upb_decstate * d,const char * ptr,int size)447 static int decode_pushlimit(upb_decstate *d, const char *ptr, int size) {
448 int limit = size + (int)(ptr - d->end);
449 int delta = d->limit - limit;
450 d->limit = limit;
451 d->limit_ptr = d->end + UPB_MIN(0, limit);
452 return delta;
453 }
454
decode_poplimit(upb_decstate * d,int saved_delta)455 static void decode_poplimit(upb_decstate *d, int saved_delta) {
456 d->limit += saved_delta;
457 d->limit_ptr = d->end + UPB_MIN(0, d->limit);
458 }
459
460 typedef struct {
461 bool ok;
462 const char *ptr;
463 } decode_doneret;
464
465 UPB_NOINLINE
decode_isdonefallback(upb_decstate * d,const char * ptr,int overrun)466 static const char *decode_isdonefallback(upb_decstate *d, const char *ptr,
467 int overrun) {
468 if (overrun < d->limit) {
469 /* Need to copy remaining data into patch buffer. */
470 UPB_ASSERT(overrun < 16);
471 memset(d->patch + 16, 0, 16);
472 memcpy(d->patch, d->end, 16);
473 ptr = &d->patch[0] + overrun;
474 d->end = &d->patch[16];
475 d->limit -= 16;
476 d->limit_ptr = d->end + d->limit;
477 d->alias = false;
478 UPB_ASSERT(ptr < d->limit_ptr);
479 return ptr;
480 } else {
481 decode_err(d);
482 }
483 }
484
485 UPB_FORCEINLINE
decode_isdone(upb_decstate * d,const char ** ptr)486 static bool decode_isdone(upb_decstate *d, const char **ptr) {
487 int overrun = *ptr - d->end;
488 if (UPB_LIKELY(*ptr < d->limit_ptr)) {
489 return false;
490 } else if (UPB_LIKELY(overrun == d->limit)) {
491 return true;
492 } else {
493 *ptr = decode_isdonefallback(d, *ptr, overrun);
494 return false;
495 }
496 }
497
decode_readstr(upb_decstate * d,const char * ptr,int size,upb_strview * str)498 static const char *decode_readstr(upb_decstate *d, const char *ptr, int size,
499 upb_strview *str) {
500 if (d->alias) {
501 str->data = ptr;
502 } else {
503 char *data = upb_arena_malloc(&d->arena, size);
504 if (!data) decode_err(d);
505 memcpy(data, ptr, size);
506 str->data = data;
507 }
508 str->size = size;
509 return ptr + size;
510 }
511
decode_tosubmsg(upb_decstate * d,const char * ptr,upb_msg * submsg,const upb_msglayout * layout,const upb_msglayout_field * field,int size)512 static const char *decode_tosubmsg(upb_decstate *d, const char *ptr,
513 upb_msg *submsg, const upb_msglayout *layout,
514 const upb_msglayout_field *field, int size) {
515 const upb_msglayout *subl = layout->submsgs[field->submsg_index];
516 int saved_delta = decode_pushlimit(d, ptr, size);
517 if (--d->depth < 0) decode_err(d);
518 ptr = decode_msg(d, ptr, submsg, subl);
519 decode_poplimit(d, saved_delta);
520 if (d->end_group != 0) decode_err(d);
521 d->depth++;
522 return ptr;
523 }
524
decode_group(upb_decstate * d,const char * ptr,upb_msg * submsg,const upb_msglayout * subl,uint32_t number)525 static const char *decode_group(upb_decstate *d, const char *ptr,
526 upb_msg *submsg, const upb_msglayout *subl,
527 uint32_t number) {
528 if (--d->depth < 0) decode_err(d);
529 ptr = decode_msg(d, ptr, submsg, subl);
530 if (d->end_group != number) decode_err(d);
531 d->end_group = 0;
532 d->depth++;
533 return ptr;
534 }
535
decode_togroup(upb_decstate * d,const char * ptr,upb_msg * submsg,const upb_msglayout * layout,const upb_msglayout_field * field)536 static const char *decode_togroup(upb_decstate *d, const char *ptr,
537 upb_msg *submsg, const upb_msglayout *layout,
538 const upb_msglayout_field *field) {
539 const upb_msglayout *subl = layout->submsgs[field->submsg_index];
540 return decode_group(d, ptr, submsg, subl, field->number);
541 }
542
decode_toarray(upb_decstate * d,const char * ptr,upb_msg * msg,const upb_msglayout * layout,const upb_msglayout_field * field,wireval val,int op)543 static const char *decode_toarray(upb_decstate *d, const char *ptr,
544 upb_msg *msg, const upb_msglayout *layout,
545 const upb_msglayout_field *field, wireval val,
546 int op) {
547 upb_array **arrp = UPB_PTR_AT(msg, field->offset, void);
548 upb_array *arr = *arrp;
549 void *mem;
550
551 if (arr) {
552 decode_reserve(d, arr, 1);
553 } else {
554 size_t lg2 = desctype_to_elem_size_lg2[field->descriptortype];
555 arr = _upb_array_new(&d->arena, 4, lg2);
556 if (!arr) decode_err(d);
557 *arrp = arr;
558 }
559
560 switch (op) {
561 case OP_SCALAR_LG2(0):
562 case OP_SCALAR_LG2(2):
563 case OP_SCALAR_LG2(3):
564 /* Append scalar value. */
565 mem = UPB_PTR_AT(_upb_array_ptr(arr), arr->len << op, void);
566 arr->len++;
567 memcpy(mem, &val, 1 << op);
568 return ptr;
569 case OP_STRING:
570 decode_verifyutf8(d, ptr, val.size);
571 /* Fallthrough. */
572 case OP_BYTES: {
573 /* Append bytes. */
574 upb_strview *str = (upb_strview*)_upb_array_ptr(arr) + arr->len;
575 arr->len++;
576 return decode_readstr(d, ptr, val.size, str);
577 }
578 case OP_SUBMSG: {
579 /* Append submessage / group. */
580 upb_msg *submsg = decode_newsubmsg(d, layout, field);
581 *UPB_PTR_AT(_upb_array_ptr(arr), arr->len * sizeof(void *), upb_msg *) =
582 submsg;
583 arr->len++;
584 if (UPB_UNLIKELY(field->descriptortype == UPB_DTYPE_GROUP)) {
585 return decode_togroup(d, ptr, submsg, layout, field);
586 } else {
587 return decode_tosubmsg(d, ptr, submsg, layout, field, val.size);
588 }
589 }
590 case OP_FIXPCK_LG2(2):
591 case OP_FIXPCK_LG2(3): {
592 /* Fixed packed. */
593 int lg2 = op - OP_FIXPCK_LG2(0);
594 int mask = (1 << lg2) - 1;
595 size_t count = val.size >> lg2;
596 if ((val.size & mask) != 0) {
597 decode_err(d); /* Length isn't a round multiple of elem size. */
598 }
599 decode_reserve(d, arr, count);
600 mem = UPB_PTR_AT(_upb_array_ptr(arr), arr->len << lg2, void);
601 arr->len += count;
602 memcpy(mem, ptr, val.size); /* XXX: ptr boundary. */
603 return ptr + val.size;
604 }
605 case OP_VARPCK_LG2(0):
606 case OP_VARPCK_LG2(2):
607 case OP_VARPCK_LG2(3): {
608 /* Varint packed. */
609 int lg2 = op - OP_VARPCK_LG2(0);
610 int scale = 1 << lg2;
611 int saved_limit = decode_pushlimit(d, ptr, val.size);
612 char *out = UPB_PTR_AT(_upb_array_ptr(arr), arr->len << lg2, void);
613 while (!decode_isdone(d, &ptr)) {
614 wireval elem;
615 ptr = decode_varint64(d, ptr, &elem.uint64_val);
616 decode_munge(field->descriptortype, &elem);
617 if (decode_reserve(d, arr, 1)) {
618 out = UPB_PTR_AT(_upb_array_ptr(arr), arr->len << lg2, void);
619 }
620 arr->len++;
621 memcpy(out, &elem, scale);
622 out += scale;
623 }
624 decode_poplimit(d, saved_limit);
625 return ptr;
626 }
627 default:
628 UPB_UNREACHABLE();
629 }
630 }
631
decode_tomap(upb_decstate * d,const char * ptr,upb_msg * msg,const upb_msglayout * layout,const upb_msglayout_field * field,wireval val)632 static const char *decode_tomap(upb_decstate *d, const char *ptr, upb_msg *msg,
633 const upb_msglayout *layout,
634 const upb_msglayout_field *field, wireval val) {
635 upb_map **map_p = UPB_PTR_AT(msg, field->offset, upb_map *);
636 upb_map *map = *map_p;
637 upb_map_entry ent;
638 const upb_msglayout *entry = layout->submsgs[field->submsg_index];
639
640 if (!map) {
641 /* Lazily create map. */
642 const upb_msglayout *entry = layout->submsgs[field->submsg_index];
643 const upb_msglayout_field *key_field = &entry->fields[0];
644 const upb_msglayout_field *val_field = &entry->fields[1];
645 char key_size = desctype_to_mapsize[key_field->descriptortype];
646 char val_size = desctype_to_mapsize[val_field->descriptortype];
647 UPB_ASSERT(key_field->offset == 0);
648 UPB_ASSERT(val_field->offset == sizeof(upb_strview));
649 map = _upb_map_new(&d->arena, key_size, val_size);
650 *map_p = map;
651 }
652
653 /* Parse map entry. */
654 memset(&ent, 0, sizeof(ent));
655
656 if (entry->fields[1].descriptortype == UPB_DESCRIPTOR_TYPE_MESSAGE ||
657 entry->fields[1].descriptortype == UPB_DESCRIPTOR_TYPE_GROUP) {
658 /* Create proactively to handle the case where it doesn't appear. */
659 ent.v.val = upb_value_ptr(_upb_msg_new(entry->submsgs[0], &d->arena));
660 }
661
662 ptr = decode_tosubmsg(d, ptr, &ent.k, layout, field, val.size);
663 _upb_map_set(map, &ent.k, map->key_size, &ent.v, map->val_size, &d->arena);
664 return ptr;
665 }
666
decode_tomsg(upb_decstate * d,const char * ptr,upb_msg * msg,const upb_msglayout * layout,const upb_msglayout_field * field,wireval val,int op)667 static const char *decode_tomsg(upb_decstate *d, const char *ptr, upb_msg *msg,
668 const upb_msglayout *layout,
669 const upb_msglayout_field *field, wireval val,
670 int op) {
671 void *mem = UPB_PTR_AT(msg, field->offset, void);
672 int type = field->descriptortype;
673
674 /* Set presence if necessary. */
675 if (field->presence < 0) {
676 /* Oneof case */
677 uint32_t *oneof_case = _upb_oneofcase_field(msg, field);
678 if (op == OP_SUBMSG && *oneof_case != field->number) {
679 memset(mem, 0, sizeof(void*));
680 }
681 *oneof_case = field->number;
682 } else if (field->presence > 0) {
683 _upb_sethas_field(msg, field);
684 }
685
686 /* Store into message. */
687 switch (op) {
688 case OP_SUBMSG: {
689 upb_msg **submsgp = mem;
690 upb_msg *submsg = *submsgp;
691 if (!submsg) {
692 submsg = decode_newsubmsg(d, layout, field);
693 *submsgp = submsg;
694 }
695 if (UPB_UNLIKELY(type == UPB_DTYPE_GROUP)) {
696 ptr = decode_togroup(d, ptr, submsg, layout, field);
697 } else {
698 ptr = decode_tosubmsg(d, ptr, submsg, layout, field, val.size);
699 }
700 break;
701 }
702 case OP_STRING:
703 decode_verifyutf8(d, ptr, val.size);
704 /* Fallthrough. */
705 case OP_BYTES:
706 return decode_readstr(d, ptr, val.size, mem);
707 case OP_SCALAR_LG2(3):
708 memcpy(mem, &val, 8);
709 break;
710 case OP_SCALAR_LG2(2):
711 memcpy(mem, &val, 4);
712 break;
713 case OP_SCALAR_LG2(0):
714 memcpy(mem, &val, 1);
715 break;
716 default:
717 UPB_UNREACHABLE();
718 }
719
720 return ptr;
721 }
722
decode_msg(upb_decstate * d,const char * ptr,upb_msg * msg,const upb_msglayout * layout)723 static const char *decode_msg(upb_decstate *d, const char *ptr, upb_msg *msg,
724 const upb_msglayout *layout) {
725 while (!decode_isdone(d, &ptr)) {
726 uint32_t tag;
727 const upb_msglayout_field *field;
728 int field_number;
729 int wire_type;
730 const char *field_start = ptr;
731 wireval val;
732 int op;
733
734 ptr = decode_varint32(d, ptr, &tag);
735 field_number = tag >> 3;
736 wire_type = tag & 7;
737
738 field = upb_find_field(layout, field_number);
739
740 switch (wire_type) {
741 case UPB_WIRE_TYPE_VARINT:
742 ptr = decode_varint64(d, ptr, &val.uint64_val);
743 op = varint_ops[field->descriptortype];
744 decode_munge(field->descriptortype, &val);
745 break;
746 case UPB_WIRE_TYPE_32BIT:
747 memcpy(&val.uint32_val, ptr, 4);
748 val.uint32_val = _upb_be_swap32(val.uint32_val);
749 ptr += 4;
750 op = OP_SCALAR_LG2(2);
751 if (((1 << field->descriptortype) & fixed32_ok) == 0) goto unknown;
752 break;
753 case UPB_WIRE_TYPE_64BIT:
754 memcpy(&val.uint64_val, ptr, 8);
755 val.uint64_val = _upb_be_swap64(val.uint64_val);
756 ptr += 8;
757 op = OP_SCALAR_LG2(3);
758 if (((1 << field->descriptortype) & fixed64_ok) == 0) goto unknown;
759 break;
760 case UPB_WIRE_TYPE_DELIMITED: {
761 int ndx = field->descriptortype;
762 if (_upb_isrepeated(field)) ndx += 18;
763 ptr = decode_varint32(d, ptr, &val.size);
764 if (val.size >= INT32_MAX ||
765 ptr - d->end + (int32_t)val.size > d->limit) {
766 decode_err(d); /* Length overflow. */
767 }
768 op = delim_ops[ndx];
769 break;
770 }
771 case UPB_WIRE_TYPE_START_GROUP:
772 val.uint32_val = field_number;
773 op = OP_SUBMSG;
774 if (field->descriptortype != UPB_DTYPE_GROUP) goto unknown;
775 break;
776 case UPB_WIRE_TYPE_END_GROUP:
777 d->end_group = field_number;
778 return ptr;
779 default:
780 decode_err(d);
781 }
782
783 if (op >= 0) {
784 /* Parse, using op for dispatch. */
785 switch (field->label) {
786 case UPB_LABEL_REPEATED:
787 case _UPB_LABEL_PACKED:
788 ptr = decode_toarray(d, ptr, msg, layout, field, val, op);
789 break;
790 case _UPB_LABEL_MAP:
791 ptr = decode_tomap(d, ptr, msg, layout, field, val);
792 break;
793 default:
794 ptr = decode_tomsg(d, ptr, msg, layout, field, val, op);
795 break;
796 }
797 } else {
798 unknown:
799 /* Skip unknown field. */
800 if (field_number == 0) decode_err(d);
801 if (wire_type == UPB_WIRE_TYPE_START_GROUP) {
802 ptr = decode_group(d, ptr, NULL, NULL, field_number);
803 }
804 if (msg) {
805 if (wire_type == UPB_WIRE_TYPE_DELIMITED) ptr += val.size;
806 if (!_upb_msg_addunknown(msg, field_start, ptr - field_start,
807 &d->arena)) {
808 decode_err(d);
809 }
810 }
811 }
812 }
813
814 return ptr;
815 }
816
upb_decode(const char * buf,size_t size,void * msg,const upb_msglayout * l,upb_arena * arena)817 bool upb_decode(const char *buf, size_t size, void *msg, const upb_msglayout *l,
818 upb_arena *arena) {
819 bool ok;
820 upb_decstate state;
821
822 if (size == 0) {
823 return true;
824 } else if (size < 16) {
825 memset(&state.patch, 0, 32);
826 memcpy(&state.patch, buf, size);
827 buf = state.patch;
828 state.end = buf + size;
829 state.limit = 0;
830 state.alias = false;
831 } else {
832 state.end = buf + size - 16;
833 state.limit = 16;
834 state.alias = true;
835 }
836
837 state.limit_ptr = state.end;
838 state.depth = 64;
839 state.end_group = 0;
840 state.arena.head = arena->head;
841 state.arena.last_size = arena->last_size;
842 state.arena.parent = arena;
843
844 if (UPB_UNLIKELY(setjmp(state.err))) {
845 ok = false;
846 } else {
847 decode_msg(&state, buf, msg, l);
848 ok = state.end_group == 0;
849 }
850
851 arena->head.ptr = state.arena.head.ptr;
852 arena->head.end = state.arena.head.end;
853 return ok;
854 }
855
856 #undef OP_SCALAR_LG2
857 #undef OP_FIXPCK_LG2
858 #undef OP_VARPCK_LG2
859 #undef OP_STRING
860 #undef OP_SUBMSG
861 /* We encode backwards, to avoid pre-computing lengths (one-pass encode). */
862
863
864 #include <setjmp.h>
865 #include <string.h>
866
867
868
869 #define UPB_PB_VARINT_MAX_LEN 10
870
871 UPB_NOINLINE
encode_varint64(uint64_t val,char * buf)872 static size_t encode_varint64(uint64_t val, char *buf) {
873 size_t i = 0;
874 do {
875 uint8_t byte = val & 0x7fU;
876 val >>= 7;
877 if (val) byte |= 0x80U;
878 buf[i++] = byte;
879 } while (val);
880 return i;
881 }
882
encode_zz32(int32_t n)883 static uint32_t encode_zz32(int32_t n) { return ((uint32_t)n << 1) ^ (n >> 31); }
encode_zz64(int64_t n)884 static uint64_t encode_zz64(int64_t n) { return ((uint64_t)n << 1) ^ (n >> 63); }
885
886 typedef struct {
887 jmp_buf err;
888 upb_alloc *alloc;
889 char *buf, *ptr, *limit;
890 } upb_encstate;
891
upb_roundup_pow2(size_t bytes)892 static size_t upb_roundup_pow2(size_t bytes) {
893 size_t ret = 128;
894 while (ret < bytes) {
895 ret *= 2;
896 }
897 return ret;
898 }
899
encode_err(upb_encstate * e)900 UPB_NORETURN static void encode_err(upb_encstate *e) { longjmp(e->err, 1); }
901
902 UPB_NOINLINE
encode_growbuffer(upb_encstate * e,size_t bytes)903 static void encode_growbuffer(upb_encstate *e, size_t bytes) {
904 size_t old_size = e->limit - e->buf;
905 size_t new_size = upb_roundup_pow2(bytes + (e->limit - e->ptr));
906 char *new_buf = upb_realloc(e->alloc, e->buf, old_size, new_size);
907
908 if (!new_buf) encode_err(e);
909
910 /* We want previous data at the end, realloc() put it at the beginning. */
911 if (old_size > 0) {
912 memmove(new_buf + new_size - old_size, e->buf, old_size);
913 }
914
915 e->ptr = new_buf + new_size - (e->limit - e->ptr);
916 e->limit = new_buf + new_size;
917 e->buf = new_buf;
918
919 e->ptr -= bytes;
920 }
921
922 /* Call to ensure that at least "bytes" bytes are available for writing at
923 * e->ptr. Returns false if the bytes could not be allocated. */
924 UPB_FORCEINLINE
encode_reserve(upb_encstate * e,size_t bytes)925 static void encode_reserve(upb_encstate *e, size_t bytes) {
926 if ((size_t)(e->ptr - e->buf) < bytes) {
927 encode_growbuffer(e, bytes);
928 return;
929 }
930
931 e->ptr -= bytes;
932 }
933
934 /* Writes the given bytes to the buffer, handling reserve/advance. */
encode_bytes(upb_encstate * e,const void * data,size_t len)935 static void encode_bytes(upb_encstate *e, const void *data, size_t len) {
936 if (len == 0) return; /* memcpy() with zero size is UB */
937 encode_reserve(e, len);
938 memcpy(e->ptr, data, len);
939 }
940
encode_fixed64(upb_encstate * e,uint64_t val)941 static void encode_fixed64(upb_encstate *e, uint64_t val) {
942 val = _upb_be_swap64(val);
943 encode_bytes(e, &val, sizeof(uint64_t));
944 }
945
encode_fixed32(upb_encstate * e,uint32_t val)946 static void encode_fixed32(upb_encstate *e, uint32_t val) {
947 val = _upb_be_swap32(val);
948 encode_bytes(e, &val, sizeof(uint32_t));
949 }
950
951 UPB_NOINLINE
encode_longvarint(upb_encstate * e,uint64_t val)952 static void encode_longvarint(upb_encstate *e, uint64_t val) {
953 size_t len;
954 char *start;
955
956 encode_reserve(e, UPB_PB_VARINT_MAX_LEN);
957 len = encode_varint64(val, e->ptr);
958 start = e->ptr + UPB_PB_VARINT_MAX_LEN - len;
959 memmove(start, e->ptr, len);
960 e->ptr = start;
961 }
962
963 UPB_FORCEINLINE
encode_varint(upb_encstate * e,uint64_t val)964 static void encode_varint(upb_encstate *e, uint64_t val) {
965 if (val < 128 && e->ptr != e->buf) {
966 --e->ptr;
967 *e->ptr = val;
968 } else {
969 encode_longvarint(e, val);
970 }
971 }
972
encode_double(upb_encstate * e,double d)973 static void encode_double(upb_encstate *e, double d) {
974 uint64_t u64;
975 UPB_ASSERT(sizeof(double) == sizeof(uint64_t));
976 memcpy(&u64, &d, sizeof(uint64_t));
977 encode_fixed64(e, u64);
978 }
979
encode_float(upb_encstate * e,float d)980 static void encode_float(upb_encstate *e, float d) {
981 uint32_t u32;
982 UPB_ASSERT(sizeof(float) == sizeof(uint32_t));
983 memcpy(&u32, &d, sizeof(uint32_t));
984 encode_fixed32(e, u32);
985 }
986
encode_tag(upb_encstate * e,int field_number,int wire_type)987 static void encode_tag(upb_encstate *e, int field_number, int wire_type) {
988 encode_varint(e, (field_number << 3) | wire_type);
989 }
990
encode_fixedarray(upb_encstate * e,const upb_array * arr,size_t elem_size,uint32_t tag)991 static void encode_fixedarray(upb_encstate *e, const upb_array *arr,
992 size_t elem_size, uint32_t tag) {
993 size_t bytes = arr->len * elem_size;
994 const char* data = _upb_array_constptr(arr);
995 const char* ptr = data + bytes - elem_size;
996 if (tag) {
997 while (true) {
998 encode_bytes(e, ptr, elem_size);
999 encode_varint(e, tag);
1000 if (ptr == data) break;
1001 ptr -= elem_size;
1002 }
1003 } else {
1004 encode_bytes(e, data, bytes);
1005 }
1006 }
1007
1008 static void encode_message(upb_encstate *e, const char *msg,
1009 const upb_msglayout *m, size_t *size);
1010
encode_scalar(upb_encstate * e,const void * _field_mem,const upb_msglayout * m,const upb_msglayout_field * f,bool skip_zero_value)1011 static void encode_scalar(upb_encstate *e, const void *_field_mem,
1012 const upb_msglayout *m, const upb_msglayout_field *f,
1013 bool skip_zero_value) {
1014 const char *field_mem = _field_mem;
1015 int wire_type;
1016
1017 #define CASE(ctype, type, wtype, encodeval) \
1018 { \
1019 ctype val = *(ctype *)field_mem; \
1020 if (skip_zero_value && val == 0) { \
1021 return; \
1022 } \
1023 encode_##type(e, encodeval); \
1024 wire_type = wtype; \
1025 break; \
1026 }
1027
1028 switch (f->descriptortype) {
1029 case UPB_DESCRIPTOR_TYPE_DOUBLE:
1030 CASE(double, double, UPB_WIRE_TYPE_64BIT, val);
1031 case UPB_DESCRIPTOR_TYPE_FLOAT:
1032 CASE(float, float, UPB_WIRE_TYPE_32BIT, val);
1033 case UPB_DESCRIPTOR_TYPE_INT64:
1034 case UPB_DESCRIPTOR_TYPE_UINT64:
1035 CASE(uint64_t, varint, UPB_WIRE_TYPE_VARINT, val);
1036 case UPB_DESCRIPTOR_TYPE_UINT32:
1037 CASE(uint32_t, varint, UPB_WIRE_TYPE_VARINT, val);
1038 case UPB_DESCRIPTOR_TYPE_INT32:
1039 case UPB_DESCRIPTOR_TYPE_ENUM:
1040 CASE(int32_t, varint, UPB_WIRE_TYPE_VARINT, (int64_t)val);
1041 case UPB_DESCRIPTOR_TYPE_SFIXED64:
1042 case UPB_DESCRIPTOR_TYPE_FIXED64:
1043 CASE(uint64_t, fixed64, UPB_WIRE_TYPE_64BIT, val);
1044 case UPB_DESCRIPTOR_TYPE_FIXED32:
1045 case UPB_DESCRIPTOR_TYPE_SFIXED32:
1046 CASE(uint32_t, fixed32, UPB_WIRE_TYPE_32BIT, val);
1047 case UPB_DESCRIPTOR_TYPE_BOOL:
1048 CASE(bool, varint, UPB_WIRE_TYPE_VARINT, val);
1049 case UPB_DESCRIPTOR_TYPE_SINT32:
1050 CASE(int32_t, varint, UPB_WIRE_TYPE_VARINT, encode_zz32(val));
1051 case UPB_DESCRIPTOR_TYPE_SINT64:
1052 CASE(int64_t, varint, UPB_WIRE_TYPE_VARINT, encode_zz64(val));
1053 case UPB_DESCRIPTOR_TYPE_STRING:
1054 case UPB_DESCRIPTOR_TYPE_BYTES: {
1055 upb_strview view = *(upb_strview*)field_mem;
1056 if (skip_zero_value && view.size == 0) {
1057 return;
1058 }
1059 encode_bytes(e, view.data, view.size);
1060 encode_varint(e, view.size);
1061 wire_type = UPB_WIRE_TYPE_DELIMITED;
1062 break;
1063 }
1064 case UPB_DESCRIPTOR_TYPE_GROUP: {
1065 size_t size;
1066 void *submsg = *(void **)field_mem;
1067 const upb_msglayout *subm = m->submsgs[f->submsg_index];
1068 if (submsg == NULL) {
1069 return;
1070 }
1071 encode_tag(e, f->number, UPB_WIRE_TYPE_END_GROUP);
1072 encode_message(e, submsg, subm, &size);
1073 wire_type = UPB_WIRE_TYPE_START_GROUP;
1074 break;
1075 }
1076 case UPB_DESCRIPTOR_TYPE_MESSAGE: {
1077 size_t size;
1078 void *submsg = *(void **)field_mem;
1079 const upb_msglayout *subm = m->submsgs[f->submsg_index];
1080 if (submsg == NULL) {
1081 return;
1082 }
1083 encode_message(e, submsg, subm, &size);
1084 encode_varint(e, size);
1085 wire_type = UPB_WIRE_TYPE_DELIMITED;
1086 break;
1087 }
1088 default:
1089 UPB_UNREACHABLE();
1090 }
1091 #undef CASE
1092
1093 encode_tag(e, f->number, wire_type);
1094 }
1095
encode_array(upb_encstate * e,const char * field_mem,const upb_msglayout * m,const upb_msglayout_field * f)1096 static void encode_array(upb_encstate *e, const char *field_mem,
1097 const upb_msglayout *m, const upb_msglayout_field *f) {
1098 const upb_array *arr = *(const upb_array**)field_mem;
1099 bool packed = f->label == _UPB_LABEL_PACKED;
1100 size_t pre_len = e->limit - e->ptr;
1101
1102 if (arr == NULL || arr->len == 0) {
1103 return;
1104 }
1105
1106 #define VARINT_CASE(ctype, encode) \
1107 { \
1108 const ctype *start = _upb_array_constptr(arr); \
1109 const ctype *ptr = start + arr->len; \
1110 uint32_t tag = packed ? 0 : (f->number << 3) | UPB_WIRE_TYPE_VARINT; \
1111 do { \
1112 ptr--; \
1113 encode_varint(e, encode); \
1114 if (tag) encode_varint(e, tag); \
1115 } while (ptr != start); \
1116 } \
1117 break;
1118
1119 #define TAG(wire_type) (packed ? 0 : (f->number << 3 | wire_type))
1120
1121 switch (f->descriptortype) {
1122 case UPB_DESCRIPTOR_TYPE_DOUBLE:
1123 encode_fixedarray(e, arr, sizeof(double), TAG(UPB_WIRE_TYPE_64BIT));
1124 break;
1125 case UPB_DESCRIPTOR_TYPE_FLOAT:
1126 encode_fixedarray(e, arr, sizeof(float), TAG(UPB_WIRE_TYPE_32BIT));
1127 break;
1128 case UPB_DESCRIPTOR_TYPE_SFIXED64:
1129 case UPB_DESCRIPTOR_TYPE_FIXED64:
1130 encode_fixedarray(e, arr, sizeof(uint64_t), TAG(UPB_WIRE_TYPE_64BIT));
1131 break;
1132 case UPB_DESCRIPTOR_TYPE_FIXED32:
1133 case UPB_DESCRIPTOR_TYPE_SFIXED32:
1134 encode_fixedarray(e, arr, sizeof(uint32_t), TAG(UPB_WIRE_TYPE_32BIT));
1135 break;
1136 case UPB_DESCRIPTOR_TYPE_INT64:
1137 case UPB_DESCRIPTOR_TYPE_UINT64:
1138 VARINT_CASE(uint64_t, *ptr);
1139 case UPB_DESCRIPTOR_TYPE_UINT32:
1140 VARINT_CASE(uint32_t, *ptr);
1141 case UPB_DESCRIPTOR_TYPE_INT32:
1142 case UPB_DESCRIPTOR_TYPE_ENUM:
1143 VARINT_CASE(int32_t, (int64_t)*ptr);
1144 case UPB_DESCRIPTOR_TYPE_BOOL:
1145 VARINT_CASE(bool, *ptr);
1146 case UPB_DESCRIPTOR_TYPE_SINT32:
1147 VARINT_CASE(int32_t, encode_zz32(*ptr));
1148 case UPB_DESCRIPTOR_TYPE_SINT64:
1149 VARINT_CASE(int64_t, encode_zz64(*ptr));
1150 case UPB_DESCRIPTOR_TYPE_STRING:
1151 case UPB_DESCRIPTOR_TYPE_BYTES: {
1152 const upb_strview *start = _upb_array_constptr(arr);
1153 const upb_strview *ptr = start + arr->len;
1154 do {
1155 ptr--;
1156 encode_bytes(e, ptr->data, ptr->size);
1157 encode_varint(e, ptr->size);
1158 encode_tag(e, f->number, UPB_WIRE_TYPE_DELIMITED);
1159 } while (ptr != start);
1160 return;
1161 }
1162 case UPB_DESCRIPTOR_TYPE_GROUP: {
1163 const void *const*start = _upb_array_constptr(arr);
1164 const void *const*ptr = start + arr->len;
1165 const upb_msglayout *subm = m->submsgs[f->submsg_index];
1166 do {
1167 size_t size;
1168 ptr--;
1169 encode_tag(e, f->number, UPB_WIRE_TYPE_END_GROUP);
1170 encode_message(e, *ptr, subm, &size);
1171 encode_tag(e, f->number, UPB_WIRE_TYPE_START_GROUP);
1172 } while (ptr != start);
1173 return;
1174 }
1175 case UPB_DESCRIPTOR_TYPE_MESSAGE: {
1176 const void *const*start = _upb_array_constptr(arr);
1177 const void *const*ptr = start + arr->len;
1178 const upb_msglayout *subm = m->submsgs[f->submsg_index];
1179 do {
1180 size_t size;
1181 ptr--;
1182 encode_message(e, *ptr, subm, &size);
1183 encode_varint(e, size);
1184 encode_tag(e, f->number, UPB_WIRE_TYPE_DELIMITED);
1185 } while (ptr != start);
1186 return;
1187 }
1188 }
1189 #undef VARINT_CASE
1190
1191 if (packed) {
1192 encode_varint(e, e->limit - e->ptr - pre_len);
1193 encode_tag(e, f->number, UPB_WIRE_TYPE_DELIMITED);
1194 }
1195 }
1196
encode_map(upb_encstate * e,const char * field_mem,const upb_msglayout * m,const upb_msglayout_field * f)1197 static void encode_map(upb_encstate *e, const char *field_mem,
1198 const upb_msglayout *m, const upb_msglayout_field *f) {
1199 const upb_map *map = *(const upb_map**)field_mem;
1200 const upb_msglayout *entry = m->submsgs[f->submsg_index];
1201 const upb_msglayout_field *key_field = &entry->fields[0];
1202 const upb_msglayout_field *val_field = &entry->fields[1];
1203 upb_strtable_iter i;
1204 if (map == NULL) {
1205 return;
1206 }
1207
1208 upb_strtable_begin(&i, &map->table);
1209 for(; !upb_strtable_done(&i); upb_strtable_next(&i)) {
1210 size_t pre_len = e->limit - e->ptr;
1211 size_t size;
1212 upb_strview key = upb_strtable_iter_key(&i);
1213 const upb_value val = upb_strtable_iter_value(&i);
1214 upb_map_entry ent;
1215 _upb_map_fromkey(key, &ent.k, map->key_size);
1216 _upb_map_fromvalue(val, &ent.v, map->val_size);
1217 encode_scalar(e, &ent.v, entry, val_field, false);
1218 encode_scalar(e, &ent.k, entry, key_field, false);
1219 size = (e->limit - e->ptr) - pre_len;
1220 encode_varint(e, size);
1221 encode_tag(e, f->number, UPB_WIRE_TYPE_DELIMITED);
1222 }
1223 }
1224
encode_scalarfield(upb_encstate * e,const char * msg,const upb_msglayout * m,const upb_msglayout_field * f)1225 static void encode_scalarfield(upb_encstate *e, const char *msg,
1226 const upb_msglayout *m,
1227 const upb_msglayout_field *f) {
1228 bool skip_empty = false;
1229 if (f->presence == 0) {
1230 /* Proto3 presence. */
1231 skip_empty = true;
1232 } else if (f->presence > 0) {
1233 /* Proto2 presence: hasbit. */
1234 if (!_upb_hasbit_field(msg, f)) return;
1235 } else {
1236 /* Field is in a oneof. */
1237 if (_upb_getoneofcase_field(msg, f) != f->number) return;
1238 }
1239 encode_scalar(e, msg + f->offset, m, f, skip_empty);
1240 }
1241
encode_message(upb_encstate * e,const char * msg,const upb_msglayout * m,size_t * size)1242 static void encode_message(upb_encstate *e, const char *msg,
1243 const upb_msglayout *m, size_t *size) {
1244 size_t pre_len = e->limit - e->ptr;
1245 const char *unknown;
1246 size_t unknown_size;
1247 const upb_msglayout_field *f = &m->fields[m->field_count];
1248 const upb_msglayout_field *first = &m->fields[0];
1249
1250 unknown = upb_msg_getunknown(msg, &unknown_size);
1251
1252 if (unknown) {
1253 encode_bytes(e, unknown, unknown_size);
1254 }
1255
1256 while (f != first) {
1257 f--;
1258 if (_upb_isrepeated(f)) {
1259 encode_array(e, msg + f->offset, m, f);
1260 } else if (f->label == _UPB_LABEL_MAP) {
1261 encode_map(e, msg + f->offset, m, f);
1262 } else {
1263 encode_scalarfield(e, msg, m, f);
1264 }
1265 }
1266
1267 *size = (e->limit - e->ptr) - pre_len;
1268 }
1269
upb_encode(const void * msg,const upb_msglayout * m,upb_arena * arena,size_t * size)1270 char *upb_encode(const void *msg, const upb_msglayout *m, upb_arena *arena,
1271 size_t *size) {
1272 upb_encstate e;
1273 e.alloc = upb_arena_alloc(arena);
1274 e.buf = NULL;
1275 e.limit = NULL;
1276 e.ptr = NULL;
1277
1278 if (setjmp(e.err)) {
1279 *size = 0;
1280 return NULL;
1281 }
1282
1283 encode_message(&e, msg, m, size);
1284
1285 *size = e.limit - e.ptr;
1286
1287 if (*size == 0) {
1288 static char ch;
1289 return &ch;
1290 } else {
1291 UPB_ASSERT(e.ptr);
1292 return e.ptr;
1293 }
1294 }
1295
1296
1297
1298
1299 /** upb_msg *******************************************************************/
1300
1301 static const size_t overhead = sizeof(upb_msg_internal);
1302
upb_msg_getinternal_const(const upb_msg * msg)1303 static const upb_msg_internal *upb_msg_getinternal_const(const upb_msg *msg) {
1304 ptrdiff_t size = sizeof(upb_msg_internal);
1305 return (upb_msg_internal*)((char*)msg - size);
1306 }
1307
_upb_msg_new(const upb_msglayout * l,upb_arena * a)1308 upb_msg *_upb_msg_new(const upb_msglayout *l, upb_arena *a) {
1309 return _upb_msg_new_inl(l, a);
1310 }
1311
_upb_msg_clear(upb_msg * msg,const upb_msglayout * l)1312 void _upb_msg_clear(upb_msg *msg, const upb_msglayout *l) {
1313 void *mem = UPB_PTR_AT(msg, -sizeof(upb_msg_internal), char);
1314 memset(mem, 0, upb_msg_sizeof(l));
1315 }
1316
_upb_msg_addunknown(upb_msg * msg,const char * data,size_t len,upb_arena * arena)1317 bool _upb_msg_addunknown(upb_msg *msg, const char *data, size_t len,
1318 upb_arena *arena) {
1319
1320 upb_msg_internal *in = upb_msg_getinternal(msg);
1321 if (!in->unknown) {
1322 size_t size = 128;
1323 while (size < len) size *= 2;
1324 in->unknown = upb_arena_malloc(arena, size + overhead);
1325 if (!in->unknown) return false;
1326 in->unknown->size = size;
1327 in->unknown->len = 0;
1328 } else if (in->unknown->size - in->unknown->len < len) {
1329 size_t need = in->unknown->len + len;
1330 size_t size = in->unknown->size;
1331 while (size < need) size *= 2;
1332 in->unknown = upb_arena_realloc(
1333 arena, in->unknown, in->unknown->size + overhead, size + overhead);
1334 if (!in->unknown) return false;
1335 in->unknown->size = size;
1336 }
1337 memcpy(UPB_PTR_AT(in->unknown + 1, in->unknown->len, char), data, len);
1338 in->unknown->len += len;
1339 return true;
1340 }
1341
_upb_msg_discardunknown_shallow(upb_msg * msg)1342 void _upb_msg_discardunknown_shallow(upb_msg *msg) {
1343 upb_msg_internal *in = upb_msg_getinternal(msg);
1344 if (in->unknown) {
1345 in->unknown->len = 0;
1346 }
1347 }
1348
upb_msg_getunknown(const upb_msg * msg,size_t * len)1349 const char *upb_msg_getunknown(const upb_msg *msg, size_t *len) {
1350 const upb_msg_internal *in = upb_msg_getinternal_const(msg);
1351 if (in->unknown) {
1352 *len = in->unknown->len;
1353 return (char*)(in->unknown + 1);
1354 } else {
1355 *len = 0;
1356 return NULL;
1357 }
1358 }
1359
1360 /** upb_array *****************************************************************/
1361
_upb_array_realloc(upb_array * arr,size_t min_size,upb_arena * arena)1362 bool _upb_array_realloc(upb_array *arr, size_t min_size, upb_arena *arena) {
1363 size_t new_size = UPB_MAX(arr->size, 4);
1364 int elem_size_lg2 = arr->data & 7;
1365 size_t old_bytes = arr->size << elem_size_lg2;
1366 size_t new_bytes;
1367 void* ptr = _upb_array_ptr(arr);
1368
1369 /* Log2 ceiling of size. */
1370 while (new_size < min_size) new_size *= 2;
1371
1372 new_bytes = new_size << elem_size_lg2;
1373 ptr = upb_arena_realloc(arena, ptr, old_bytes, new_bytes);
1374
1375 if (!ptr) {
1376 return false;
1377 }
1378
1379 arr->data = _upb_tag_arrptr(ptr, elem_size_lg2);
1380 arr->size = new_size;
1381 return true;
1382 }
1383
getorcreate_array(upb_array ** arr_ptr,int elem_size_lg2,upb_arena * arena)1384 static upb_array *getorcreate_array(upb_array **arr_ptr, int elem_size_lg2,
1385 upb_arena *arena) {
1386 upb_array *arr = *arr_ptr;
1387 if (!arr) {
1388 arr = _upb_array_new(arena, 4, elem_size_lg2);
1389 if (!arr) return NULL;
1390 *arr_ptr = arr;
1391 }
1392 return arr;
1393 }
1394
_upb_array_resize_fallback(upb_array ** arr_ptr,size_t size,int elem_size_lg2,upb_arena * arena)1395 void *_upb_array_resize_fallback(upb_array **arr_ptr, size_t size,
1396 int elem_size_lg2, upb_arena *arena) {
1397 upb_array *arr = getorcreate_array(arr_ptr, elem_size_lg2, arena);
1398 return arr && _upb_array_resize(arr, size, arena) ? _upb_array_ptr(arr)
1399 : NULL;
1400 }
1401
_upb_array_append_fallback(upb_array ** arr_ptr,const void * value,int elem_size_lg2,upb_arena * arena)1402 bool _upb_array_append_fallback(upb_array **arr_ptr, const void *value,
1403 int elem_size_lg2, upb_arena *arena) {
1404 upb_array *arr = getorcreate_array(arr_ptr, elem_size_lg2, arena);
1405 if (!arr) return false;
1406
1407 size_t elems = arr->len;
1408
1409 if (!_upb_array_resize(arr, elems + 1, arena)) {
1410 return false;
1411 }
1412
1413 char *data = _upb_array_ptr(arr);
1414 memcpy(data + (elems << elem_size_lg2), value, 1 << elem_size_lg2);
1415 return true;
1416 }
1417
1418 /** upb_map *******************************************************************/
1419
_upb_map_new(upb_arena * a,size_t key_size,size_t value_size)1420 upb_map *_upb_map_new(upb_arena *a, size_t key_size, size_t value_size) {
1421 upb_map *map = upb_arena_malloc(a, sizeof(upb_map));
1422
1423 if (!map) {
1424 return NULL;
1425 }
1426
1427 upb_strtable_init2(&map->table, UPB_CTYPE_INT32, 4, upb_arena_alloc(a));
1428 map->key_size = key_size;
1429 map->val_size = value_size;
1430
1431 return map;
1432 }
1433 /*
1434 ** upb_table Implementation
1435 **
1436 ** Implementation is heavily inspired by Lua's ltable.c.
1437 */
1438
1439 #include <string.h>
1440
1441 #include "third_party/wyhash/wyhash.h"
1442
1443 /* Must be last. */
1444
1445 #define UPB_MAXARRSIZE 16 /* 64k. */
1446
1447 /* From Chromium. */
1448 #define ARRAY_SIZE(x) \
1449 ((sizeof(x)/sizeof(0[x])) / ((size_t)(!(sizeof(x) % sizeof(0[x])))))
1450
1451 static const double MAX_LOAD = 0.85;
1452
1453 /* The minimum utilization of the array part of a mixed hash/array table. This
1454 * is a speed/memory-usage tradeoff (though it's not straightforward because of
1455 * cache effects). The lower this is, the more memory we'll use. */
1456 static const double MIN_DENSITY = 0.1;
1457
is_pow2(uint64_t v)1458 bool is_pow2(uint64_t v) { return v == 0 || (v & (v - 1)) == 0; }
1459
log2ceil(uint64_t v)1460 int log2ceil(uint64_t v) {
1461 int ret = 0;
1462 bool pow2 = is_pow2(v);
1463 while (v >>= 1) ret++;
1464 ret = pow2 ? ret : ret + 1; /* Ceiling. */
1465 return UPB_MIN(UPB_MAXARRSIZE, ret);
1466 }
1467
upb_strdup(const char * s,upb_alloc * a)1468 char *upb_strdup(const char *s, upb_alloc *a) {
1469 return upb_strdup2(s, strlen(s), a);
1470 }
1471
upb_strdup2(const char * s,size_t len,upb_alloc * a)1472 char *upb_strdup2(const char *s, size_t len, upb_alloc *a) {
1473 size_t n;
1474 char *p;
1475
1476 /* Prevent overflow errors. */
1477 if (len == SIZE_MAX) return NULL;
1478 /* Always null-terminate, even if binary data; but don't rely on the input to
1479 * have a null-terminating byte since it may be a raw binary buffer. */
1480 n = len + 1;
1481 p = upb_malloc(a, n);
1482 if (p) {
1483 memcpy(p, s, len);
1484 p[len] = 0;
1485 }
1486 return p;
1487 }
1488
1489 /* A type to represent the lookup key of either a strtable or an inttable. */
1490 typedef union {
1491 uintptr_t num;
1492 struct {
1493 const char *str;
1494 size_t len;
1495 } str;
1496 } lookupkey_t;
1497
strkey2(const char * str,size_t len)1498 static lookupkey_t strkey2(const char *str, size_t len) {
1499 lookupkey_t k;
1500 k.str.str = str;
1501 k.str.len = len;
1502 return k;
1503 }
1504
intkey(uintptr_t key)1505 static lookupkey_t intkey(uintptr_t key) {
1506 lookupkey_t k;
1507 k.num = key;
1508 return k;
1509 }
1510
1511 typedef uint32_t hashfunc_t(upb_tabkey key);
1512 typedef bool eqlfunc_t(upb_tabkey k1, lookupkey_t k2);
1513
1514 /* Base table (shared code) ***************************************************/
1515
1516 /* For when we need to cast away const. */
mutable_entries(upb_table * t)1517 static upb_tabent *mutable_entries(upb_table *t) {
1518 return (upb_tabent*)t->entries;
1519 }
1520
isfull(upb_table * t)1521 static bool isfull(upb_table *t) {
1522 return t->count == t->max_count;
1523 }
1524
init(upb_table * t,uint8_t size_lg2,upb_alloc * a)1525 static bool init(upb_table *t, uint8_t size_lg2, upb_alloc *a) {
1526 size_t bytes;
1527
1528 t->count = 0;
1529 t->size_lg2 = size_lg2;
1530 t->mask = upb_table_size(t) ? upb_table_size(t) - 1 : 0;
1531 t->max_count = upb_table_size(t) * MAX_LOAD;
1532 bytes = upb_table_size(t) * sizeof(upb_tabent);
1533 if (bytes > 0) {
1534 t->entries = upb_malloc(a, bytes);
1535 if (!t->entries) return false;
1536 memset(mutable_entries(t), 0, bytes);
1537 } else {
1538 t->entries = NULL;
1539 }
1540 return true;
1541 }
1542
uninit(upb_table * t,upb_alloc * a)1543 static void uninit(upb_table *t, upb_alloc *a) {
1544 upb_free(a, mutable_entries(t));
1545 }
1546
emptyent(upb_table * t,upb_tabent * e)1547 static upb_tabent *emptyent(upb_table *t, upb_tabent *e) {
1548 upb_tabent *begin = mutable_entries(t);
1549 upb_tabent *end = begin + upb_table_size(t);
1550 for (e = e + 1; e < end; e++) {
1551 if (upb_tabent_isempty(e)) return e;
1552 }
1553 for (e = begin; e < end; e++) {
1554 if (upb_tabent_isempty(e)) return e;
1555 }
1556 UPB_ASSERT(false);
1557 return NULL;
1558 }
1559
getentry_mutable(upb_table * t,uint32_t hash)1560 static upb_tabent *getentry_mutable(upb_table *t, uint32_t hash) {
1561 return (upb_tabent*)upb_getentry(t, hash);
1562 }
1563
findentry(const upb_table * t,lookupkey_t key,uint32_t hash,eqlfunc_t * eql)1564 static const upb_tabent *findentry(const upb_table *t, lookupkey_t key,
1565 uint32_t hash, eqlfunc_t *eql) {
1566 const upb_tabent *e;
1567
1568 if (t->size_lg2 == 0) return NULL;
1569 e = upb_getentry(t, hash);
1570 if (upb_tabent_isempty(e)) return NULL;
1571 while (1) {
1572 if (eql(e->key, key)) return e;
1573 if ((e = e->next) == NULL) return NULL;
1574 }
1575 }
1576
findentry_mutable(upb_table * t,lookupkey_t key,uint32_t hash,eqlfunc_t * eql)1577 static upb_tabent *findentry_mutable(upb_table *t, lookupkey_t key,
1578 uint32_t hash, eqlfunc_t *eql) {
1579 return (upb_tabent*)findentry(t, key, hash, eql);
1580 }
1581
lookup(const upb_table * t,lookupkey_t key,upb_value * v,uint32_t hash,eqlfunc_t * eql)1582 static bool lookup(const upb_table *t, lookupkey_t key, upb_value *v,
1583 uint32_t hash, eqlfunc_t *eql) {
1584 const upb_tabent *e = findentry(t, key, hash, eql);
1585 if (e) {
1586 if (v) {
1587 _upb_value_setval(v, e->val.val);
1588 }
1589 return true;
1590 } else {
1591 return false;
1592 }
1593 }
1594
1595 /* The given key must not already exist in the table. */
insert(upb_table * t,lookupkey_t key,upb_tabkey tabkey,upb_value val,uint32_t hash,hashfunc_t * hashfunc,eqlfunc_t * eql)1596 static void insert(upb_table *t, lookupkey_t key, upb_tabkey tabkey,
1597 upb_value val, uint32_t hash,
1598 hashfunc_t *hashfunc, eqlfunc_t *eql) {
1599 upb_tabent *mainpos_e;
1600 upb_tabent *our_e;
1601
1602 UPB_ASSERT(findentry(t, key, hash, eql) == NULL);
1603
1604 t->count++;
1605 mainpos_e = getentry_mutable(t, hash);
1606 our_e = mainpos_e;
1607
1608 if (upb_tabent_isempty(mainpos_e)) {
1609 /* Our main position is empty; use it. */
1610 our_e->next = NULL;
1611 } else {
1612 /* Collision. */
1613 upb_tabent *new_e = emptyent(t, mainpos_e);
1614 /* Head of collider's chain. */
1615 upb_tabent *chain = getentry_mutable(t, hashfunc(mainpos_e->key));
1616 if (chain == mainpos_e) {
1617 /* Existing ent is in its main posisiton (it has the same hash as us, and
1618 * is the head of our chain). Insert to new ent and append to this chain. */
1619 new_e->next = mainpos_e->next;
1620 mainpos_e->next = new_e;
1621 our_e = new_e;
1622 } else {
1623 /* Existing ent is not in its main position (it is a node in some other
1624 * chain). This implies that no existing ent in the table has our hash.
1625 * Evict it (updating its chain) and use its ent for head of our chain. */
1626 *new_e = *mainpos_e; /* copies next. */
1627 while (chain->next != mainpos_e) {
1628 chain = (upb_tabent*)chain->next;
1629 UPB_ASSERT(chain);
1630 }
1631 chain->next = new_e;
1632 our_e = mainpos_e;
1633 our_e->next = NULL;
1634 }
1635 }
1636 our_e->key = tabkey;
1637 our_e->val.val = val.val;
1638 UPB_ASSERT(findentry(t, key, hash, eql) == our_e);
1639 }
1640
rm(upb_table * t,lookupkey_t key,upb_value * val,upb_tabkey * removed,uint32_t hash,eqlfunc_t * eql)1641 static bool rm(upb_table *t, lookupkey_t key, upb_value *val,
1642 upb_tabkey *removed, uint32_t hash, eqlfunc_t *eql) {
1643 upb_tabent *chain = getentry_mutable(t, hash);
1644 if (upb_tabent_isempty(chain)) return false;
1645 if (eql(chain->key, key)) {
1646 /* Element to remove is at the head of its chain. */
1647 t->count--;
1648 if (val) _upb_value_setval(val, chain->val.val);
1649 if (removed) *removed = chain->key;
1650 if (chain->next) {
1651 upb_tabent *move = (upb_tabent*)chain->next;
1652 *chain = *move;
1653 move->key = 0; /* Make the slot empty. */
1654 } else {
1655 chain->key = 0; /* Make the slot empty. */
1656 }
1657 return true;
1658 } else {
1659 /* Element to remove is either in a non-head position or not in the
1660 * table. */
1661 while (chain->next && !eql(chain->next->key, key)) {
1662 chain = (upb_tabent*)chain->next;
1663 }
1664 if (chain->next) {
1665 /* Found element to remove. */
1666 upb_tabent *rm = (upb_tabent*)chain->next;
1667 t->count--;
1668 if (val) _upb_value_setval(val, chain->next->val.val);
1669 if (removed) *removed = rm->key;
1670 rm->key = 0; /* Make the slot empty. */
1671 chain->next = rm->next;
1672 return true;
1673 } else {
1674 /* Element to remove is not in the table. */
1675 return false;
1676 }
1677 }
1678 }
1679
next(const upb_table * t,size_t i)1680 static size_t next(const upb_table *t, size_t i) {
1681 do {
1682 if (++i >= upb_table_size(t))
1683 return SIZE_MAX - 1; /* Distinct from -1. */
1684 } while(upb_tabent_isempty(&t->entries[i]));
1685
1686 return i;
1687 }
1688
begin(const upb_table * t)1689 static size_t begin(const upb_table *t) {
1690 return next(t, -1);
1691 }
1692
1693
1694 /* upb_strtable ***************************************************************/
1695
1696 /* A simple "subclass" of upb_table that only adds a hash function for strings. */
1697
strcopy(lookupkey_t k2,upb_alloc * a)1698 static upb_tabkey strcopy(lookupkey_t k2, upb_alloc *a) {
1699 uint32_t len = (uint32_t) k2.str.len;
1700 char *str = upb_malloc(a, k2.str.len + sizeof(uint32_t) + 1);
1701 if (str == NULL) return 0;
1702 memcpy(str, &len, sizeof(uint32_t));
1703 if (k2.str.len) memcpy(str + sizeof(uint32_t), k2.str.str, k2.str.len);
1704 str[sizeof(uint32_t) + k2.str.len] = '\0';
1705 return (uintptr_t)str;
1706 }
1707
table_hash(const char * p,size_t n)1708 static uint32_t table_hash(const char *p, size_t n) {
1709 return wyhash(p, n, 0, _wyp);
1710 }
1711
strhash(upb_tabkey key)1712 static uint32_t strhash(upb_tabkey key) {
1713 uint32_t len;
1714 char *str = upb_tabstr(key, &len);
1715 return table_hash(str, len);
1716 }
1717
streql(upb_tabkey k1,lookupkey_t k2)1718 static bool streql(upb_tabkey k1, lookupkey_t k2) {
1719 uint32_t len;
1720 char *str = upb_tabstr(k1, &len);
1721 return len == k2.str.len && (len == 0 || memcmp(str, k2.str.str, len) == 0);
1722 }
1723
upb_strtable_init2(upb_strtable * t,upb_ctype_t ctype,size_t expected_size,upb_alloc * a)1724 bool upb_strtable_init2(upb_strtable *t, upb_ctype_t ctype,
1725 size_t expected_size, upb_alloc *a) {
1726 UPB_UNUSED(ctype); /* TODO(haberman): rm */
1727 // Multiply by approximate reciprocal of MAX_LOAD (0.85), with pow2 denominator.
1728 size_t need_entries = (expected_size + 1) * 1204 / 1024;
1729 UPB_ASSERT(need_entries >= expected_size * 0.85);
1730 int size_lg2 = _upb_lg2ceil(need_entries);
1731 return init(&t->t, size_lg2, a);
1732 }
1733
upb_strtable_clear(upb_strtable * t)1734 void upb_strtable_clear(upb_strtable *t) {
1735 size_t bytes = upb_table_size(&t->t) * sizeof(upb_tabent);
1736 t->t.count = 0;
1737 memset((char*)t->t.entries, 0, bytes);
1738 }
1739
upb_strtable_uninit2(upb_strtable * t,upb_alloc * a)1740 void upb_strtable_uninit2(upb_strtable *t, upb_alloc *a) {
1741 size_t i;
1742 for (i = 0; i < upb_table_size(&t->t); i++)
1743 upb_free(a, (void*)t->t.entries[i].key);
1744 uninit(&t->t, a);
1745 }
1746
upb_strtable_resize(upb_strtable * t,size_t size_lg2,upb_alloc * a)1747 bool upb_strtable_resize(upb_strtable *t, size_t size_lg2, upb_alloc *a) {
1748 upb_strtable new_table;
1749 upb_strtable_iter i;
1750
1751 if (!init(&new_table.t, size_lg2, a))
1752 return false;
1753 upb_strtable_begin(&i, t);
1754 for ( ; !upb_strtable_done(&i); upb_strtable_next(&i)) {
1755 upb_strview key = upb_strtable_iter_key(&i);
1756 upb_strtable_insert3(
1757 &new_table, key.data, key.size,
1758 upb_strtable_iter_value(&i), a);
1759 }
1760 upb_strtable_uninit2(t, a);
1761 *t = new_table;
1762 return true;
1763 }
1764
upb_strtable_insert3(upb_strtable * t,const char * k,size_t len,upb_value v,upb_alloc * a)1765 bool upb_strtable_insert3(upb_strtable *t, const char *k, size_t len,
1766 upb_value v, upb_alloc *a) {
1767 lookupkey_t key;
1768 upb_tabkey tabkey;
1769 uint32_t hash;
1770
1771 if (isfull(&t->t)) {
1772 /* Need to resize. New table of double the size, add old elements to it. */
1773 if (!upb_strtable_resize(t, t->t.size_lg2 + 1, a)) {
1774 return false;
1775 }
1776 }
1777
1778 key = strkey2(k, len);
1779 tabkey = strcopy(key, a);
1780 if (tabkey == 0) return false;
1781
1782 hash = table_hash(key.str.str, key.str.len);
1783 insert(&t->t, key, tabkey, v, hash, &strhash, &streql);
1784 return true;
1785 }
1786
upb_strtable_lookup2(const upb_strtable * t,const char * key,size_t len,upb_value * v)1787 bool upb_strtable_lookup2(const upb_strtable *t, const char *key, size_t len,
1788 upb_value *v) {
1789 uint32_t hash = table_hash(key, len);
1790 return lookup(&t->t, strkey2(key, len), v, hash, &streql);
1791 }
1792
upb_strtable_remove3(upb_strtable * t,const char * key,size_t len,upb_value * val,upb_alloc * alloc)1793 bool upb_strtable_remove3(upb_strtable *t, const char *key, size_t len,
1794 upb_value *val, upb_alloc *alloc) {
1795 uint32_t hash = table_hash(key, len);
1796 upb_tabkey tabkey;
1797 if (rm(&t->t, strkey2(key, len), val, &tabkey, hash, &streql)) {
1798 if (alloc) {
1799 /* Arena-based allocs don't need to free and won't pass this. */
1800 upb_free(alloc, (void*)tabkey);
1801 }
1802 return true;
1803 } else {
1804 return false;
1805 }
1806 }
1807
1808 /* Iteration */
1809
upb_strtable_begin(upb_strtable_iter * i,const upb_strtable * t)1810 void upb_strtable_begin(upb_strtable_iter *i, const upb_strtable *t) {
1811 i->t = t;
1812 i->index = begin(&t->t);
1813 }
1814
upb_strtable_next(upb_strtable_iter * i)1815 void upb_strtable_next(upb_strtable_iter *i) {
1816 i->index = next(&i->t->t, i->index);
1817 }
1818
upb_strtable_done(const upb_strtable_iter * i)1819 bool upb_strtable_done(const upb_strtable_iter *i) {
1820 if (!i->t) return true;
1821 return i->index >= upb_table_size(&i->t->t) ||
1822 upb_tabent_isempty(str_tabent(i));
1823 }
1824
upb_strtable_iter_key(const upb_strtable_iter * i)1825 upb_strview upb_strtable_iter_key(const upb_strtable_iter *i) {
1826 upb_strview key;
1827 uint32_t len;
1828 UPB_ASSERT(!upb_strtable_done(i));
1829 key.data = upb_tabstr(str_tabent(i)->key, &len);
1830 key.size = len;
1831 return key;
1832 }
1833
upb_strtable_iter_value(const upb_strtable_iter * i)1834 upb_value upb_strtable_iter_value(const upb_strtable_iter *i) {
1835 UPB_ASSERT(!upb_strtable_done(i));
1836 return _upb_value_val(str_tabent(i)->val.val);
1837 }
1838
upb_strtable_iter_setdone(upb_strtable_iter * i)1839 void upb_strtable_iter_setdone(upb_strtable_iter *i) {
1840 i->t = NULL;
1841 i->index = SIZE_MAX;
1842 }
1843
upb_strtable_iter_isequal(const upb_strtable_iter * i1,const upb_strtable_iter * i2)1844 bool upb_strtable_iter_isequal(const upb_strtable_iter *i1,
1845 const upb_strtable_iter *i2) {
1846 if (upb_strtable_done(i1) && upb_strtable_done(i2))
1847 return true;
1848 return i1->t == i2->t && i1->index == i2->index;
1849 }
1850
1851
1852 /* upb_inttable ***************************************************************/
1853
1854 /* For inttables we use a hybrid structure where small keys are kept in an
1855 * array and large keys are put in the hash table. */
1856
inthash(upb_tabkey key)1857 static uint32_t inthash(upb_tabkey key) { return upb_inthash(key); }
1858
inteql(upb_tabkey k1,lookupkey_t k2)1859 static bool inteql(upb_tabkey k1, lookupkey_t k2) {
1860 return k1 == k2.num;
1861 }
1862
mutable_array(upb_inttable * t)1863 static upb_tabval *mutable_array(upb_inttable *t) {
1864 return (upb_tabval*)t->array;
1865 }
1866
inttable_val(upb_inttable * t,uintptr_t key)1867 static upb_tabval *inttable_val(upb_inttable *t, uintptr_t key) {
1868 if (key < t->array_size) {
1869 return upb_arrhas(t->array[key]) ? &(mutable_array(t)[key]) : NULL;
1870 } else {
1871 upb_tabent *e =
1872 findentry_mutable(&t->t, intkey(key), upb_inthash(key), &inteql);
1873 return e ? &e->val : NULL;
1874 }
1875 }
1876
inttable_val_const(const upb_inttable * t,uintptr_t key)1877 static const upb_tabval *inttable_val_const(const upb_inttable *t,
1878 uintptr_t key) {
1879 return inttable_val((upb_inttable*)t, key);
1880 }
1881
upb_inttable_count(const upb_inttable * t)1882 size_t upb_inttable_count(const upb_inttable *t) {
1883 return t->t.count + t->array_count;
1884 }
1885
check(upb_inttable * t)1886 static void check(upb_inttable *t) {
1887 UPB_UNUSED(t);
1888 #if defined(UPB_DEBUG_TABLE) && !defined(NDEBUG)
1889 {
1890 /* This check is very expensive (makes inserts/deletes O(N)). */
1891 size_t count = 0;
1892 upb_inttable_iter i;
1893 upb_inttable_begin(&i, t);
1894 for(; !upb_inttable_done(&i); upb_inttable_next(&i), count++) {
1895 UPB_ASSERT(upb_inttable_lookup(t, upb_inttable_iter_key(&i), NULL));
1896 }
1897 UPB_ASSERT(count == upb_inttable_count(t));
1898 }
1899 #endif
1900 }
1901
upb_inttable_sizedinit(upb_inttable * t,size_t asize,int hsize_lg2,upb_alloc * a)1902 bool upb_inttable_sizedinit(upb_inttable *t, size_t asize, int hsize_lg2,
1903 upb_alloc *a) {
1904 size_t array_bytes;
1905
1906 if (!init(&t->t, hsize_lg2, a)) return false;
1907 /* Always make the array part at least 1 long, so that we know key 0
1908 * won't be in the hash part, which simplifies things. */
1909 t->array_size = UPB_MAX(1, asize);
1910 t->array_count = 0;
1911 array_bytes = t->array_size * sizeof(upb_value);
1912 t->array = upb_malloc(a, array_bytes);
1913 if (!t->array) {
1914 uninit(&t->t, a);
1915 return false;
1916 }
1917 memset(mutable_array(t), 0xff, array_bytes);
1918 check(t);
1919 return true;
1920 }
1921
upb_inttable_init2(upb_inttable * t,upb_ctype_t ctype,upb_alloc * a)1922 bool upb_inttable_init2(upb_inttable *t, upb_ctype_t ctype, upb_alloc *a) {
1923 UPB_UNUSED(ctype); /* TODO(haberman): rm */
1924 return upb_inttable_sizedinit(t, 0, 4, a);
1925 }
1926
upb_inttable_uninit2(upb_inttable * t,upb_alloc * a)1927 void upb_inttable_uninit2(upb_inttable *t, upb_alloc *a) {
1928 uninit(&t->t, a);
1929 upb_free(a, mutable_array(t));
1930 }
1931
upb_inttable_insert2(upb_inttable * t,uintptr_t key,upb_value val,upb_alloc * a)1932 bool upb_inttable_insert2(upb_inttable *t, uintptr_t key, upb_value val,
1933 upb_alloc *a) {
1934 upb_tabval tabval;
1935 tabval.val = val.val;
1936 UPB_ASSERT(upb_arrhas(tabval)); /* This will reject (uint64_t)-1. Fix this. */
1937
1938 if (key < t->array_size) {
1939 UPB_ASSERT(!upb_arrhas(t->array[key]));
1940 t->array_count++;
1941 mutable_array(t)[key].val = val.val;
1942 } else {
1943 if (isfull(&t->t)) {
1944 /* Need to resize the hash part, but we re-use the array part. */
1945 size_t i;
1946 upb_table new_table;
1947
1948 if (!init(&new_table, t->t.size_lg2 + 1, a)) {
1949 return false;
1950 }
1951
1952 for (i = begin(&t->t); i < upb_table_size(&t->t); i = next(&t->t, i)) {
1953 const upb_tabent *e = &t->t.entries[i];
1954 uint32_t hash;
1955 upb_value v;
1956
1957 _upb_value_setval(&v, e->val.val);
1958 hash = upb_inthash(e->key);
1959 insert(&new_table, intkey(e->key), e->key, v, hash, &inthash, &inteql);
1960 }
1961
1962 UPB_ASSERT(t->t.count == new_table.count);
1963
1964 uninit(&t->t, a);
1965 t->t = new_table;
1966 }
1967 insert(&t->t, intkey(key), key, val, upb_inthash(key), &inthash, &inteql);
1968 }
1969 check(t);
1970 return true;
1971 }
1972
upb_inttable_lookup(const upb_inttable * t,uintptr_t key,upb_value * v)1973 bool upb_inttable_lookup(const upb_inttable *t, uintptr_t key, upb_value *v) {
1974 const upb_tabval *table_v = inttable_val_const(t, key);
1975 if (!table_v) return false;
1976 if (v) _upb_value_setval(v, table_v->val);
1977 return true;
1978 }
1979
upb_inttable_replace(upb_inttable * t,uintptr_t key,upb_value val)1980 bool upb_inttable_replace(upb_inttable *t, uintptr_t key, upb_value val) {
1981 upb_tabval *table_v = inttable_val(t, key);
1982 if (!table_v) return false;
1983 table_v->val = val.val;
1984 return true;
1985 }
1986
upb_inttable_remove(upb_inttable * t,uintptr_t key,upb_value * val)1987 bool upb_inttable_remove(upb_inttable *t, uintptr_t key, upb_value *val) {
1988 bool success;
1989 if (key < t->array_size) {
1990 if (upb_arrhas(t->array[key])) {
1991 upb_tabval empty = UPB_TABVALUE_EMPTY_INIT;
1992 t->array_count--;
1993 if (val) {
1994 _upb_value_setval(val, t->array[key].val);
1995 }
1996 mutable_array(t)[key] = empty;
1997 success = true;
1998 } else {
1999 success = false;
2000 }
2001 } else {
2002 success = rm(&t->t, intkey(key), val, NULL, upb_inthash(key), &inteql);
2003 }
2004 check(t);
2005 return success;
2006 }
2007
upb_inttable_insertptr2(upb_inttable * t,const void * key,upb_value val,upb_alloc * a)2008 bool upb_inttable_insertptr2(upb_inttable *t, const void *key, upb_value val,
2009 upb_alloc *a) {
2010 return upb_inttable_insert2(t, (uintptr_t)key, val, a);
2011 }
2012
upb_inttable_lookupptr(const upb_inttable * t,const void * key,upb_value * v)2013 bool upb_inttable_lookupptr(const upb_inttable *t, const void *key,
2014 upb_value *v) {
2015 return upb_inttable_lookup(t, (uintptr_t)key, v);
2016 }
2017
upb_inttable_removeptr(upb_inttable * t,const void * key,upb_value * val)2018 bool upb_inttable_removeptr(upb_inttable *t, const void *key, upb_value *val) {
2019 return upb_inttable_remove(t, (uintptr_t)key, val);
2020 }
2021
upb_inttable_compact2(upb_inttable * t,upb_alloc * a)2022 void upb_inttable_compact2(upb_inttable *t, upb_alloc *a) {
2023 /* A power-of-two histogram of the table keys. */
2024 size_t counts[UPB_MAXARRSIZE + 1] = {0};
2025
2026 /* The max key in each bucket. */
2027 uintptr_t max[UPB_MAXARRSIZE + 1] = {0};
2028
2029 upb_inttable_iter i;
2030 size_t arr_count;
2031 int size_lg2;
2032 upb_inttable new_t;
2033
2034 upb_inttable_begin(&i, t);
2035 for (; !upb_inttable_done(&i); upb_inttable_next(&i)) {
2036 uintptr_t key = upb_inttable_iter_key(&i);
2037 int bucket = log2ceil(key);
2038 max[bucket] = UPB_MAX(max[bucket], key);
2039 counts[bucket]++;
2040 }
2041
2042 /* Find the largest power of two that satisfies the MIN_DENSITY
2043 * definition (while actually having some keys). */
2044 arr_count = upb_inttable_count(t);
2045
2046 for (size_lg2 = ARRAY_SIZE(counts) - 1; size_lg2 > 0; size_lg2--) {
2047 if (counts[size_lg2] == 0) {
2048 /* We can halve again without losing any entries. */
2049 continue;
2050 } else if (arr_count >= (1 << size_lg2) * MIN_DENSITY) {
2051 break;
2052 }
2053
2054 arr_count -= counts[size_lg2];
2055 }
2056
2057 UPB_ASSERT(arr_count <= upb_inttable_count(t));
2058
2059 {
2060 /* Insert all elements into new, perfectly-sized table. */
2061 size_t arr_size = max[size_lg2] + 1; /* +1 so arr[max] will fit. */
2062 size_t hash_count = upb_inttable_count(t) - arr_count;
2063 size_t hash_size = hash_count ? (hash_count / MAX_LOAD) + 1 : 0;
2064 int hashsize_lg2 = log2ceil(hash_size);
2065
2066 upb_inttable_sizedinit(&new_t, arr_size, hashsize_lg2, a);
2067 upb_inttable_begin(&i, t);
2068 for (; !upb_inttable_done(&i); upb_inttable_next(&i)) {
2069 uintptr_t k = upb_inttable_iter_key(&i);
2070 upb_inttable_insert2(&new_t, k, upb_inttable_iter_value(&i), a);
2071 }
2072 UPB_ASSERT(new_t.array_size == arr_size);
2073 UPB_ASSERT(new_t.t.size_lg2 == hashsize_lg2);
2074 }
2075 upb_inttable_uninit2(t, a);
2076 *t = new_t;
2077 }
2078
2079 /* Iteration. */
2080
int_tabent(const upb_inttable_iter * i)2081 static const upb_tabent *int_tabent(const upb_inttable_iter *i) {
2082 UPB_ASSERT(!i->array_part);
2083 return &i->t->t.entries[i->index];
2084 }
2085
int_arrent(const upb_inttable_iter * i)2086 static upb_tabval int_arrent(const upb_inttable_iter *i) {
2087 UPB_ASSERT(i->array_part);
2088 return i->t->array[i->index];
2089 }
2090
upb_inttable_begin(upb_inttable_iter * i,const upb_inttable * t)2091 void upb_inttable_begin(upb_inttable_iter *i, const upb_inttable *t) {
2092 i->t = t;
2093 i->index = -1;
2094 i->array_part = true;
2095 upb_inttable_next(i);
2096 }
2097
upb_inttable_next(upb_inttable_iter * iter)2098 void upb_inttable_next(upb_inttable_iter *iter) {
2099 const upb_inttable *t = iter->t;
2100 if (iter->array_part) {
2101 while (++iter->index < t->array_size) {
2102 if (upb_arrhas(int_arrent(iter))) {
2103 return;
2104 }
2105 }
2106 iter->array_part = false;
2107 iter->index = begin(&t->t);
2108 } else {
2109 iter->index = next(&t->t, iter->index);
2110 }
2111 }
2112
upb_inttable_done(const upb_inttable_iter * i)2113 bool upb_inttable_done(const upb_inttable_iter *i) {
2114 if (!i->t) return true;
2115 if (i->array_part) {
2116 return i->index >= i->t->array_size ||
2117 !upb_arrhas(int_arrent(i));
2118 } else {
2119 return i->index >= upb_table_size(&i->t->t) ||
2120 upb_tabent_isempty(int_tabent(i));
2121 }
2122 }
2123
upb_inttable_iter_key(const upb_inttable_iter * i)2124 uintptr_t upb_inttable_iter_key(const upb_inttable_iter *i) {
2125 UPB_ASSERT(!upb_inttable_done(i));
2126 return i->array_part ? i->index : int_tabent(i)->key;
2127 }
2128
upb_inttable_iter_value(const upb_inttable_iter * i)2129 upb_value upb_inttable_iter_value(const upb_inttable_iter *i) {
2130 UPB_ASSERT(!upb_inttable_done(i));
2131 return _upb_value_val(
2132 i->array_part ? i->t->array[i->index].val : int_tabent(i)->val.val);
2133 }
2134
upb_inttable_iter_setdone(upb_inttable_iter * i)2135 void upb_inttable_iter_setdone(upb_inttable_iter *i) {
2136 i->t = NULL;
2137 i->index = SIZE_MAX;
2138 i->array_part = false;
2139 }
2140
upb_inttable_iter_isequal(const upb_inttable_iter * i1,const upb_inttable_iter * i2)2141 bool upb_inttable_iter_isequal(const upb_inttable_iter *i1,
2142 const upb_inttable_iter *i2) {
2143 if (upb_inttable_done(i1) && upb_inttable_done(i2))
2144 return true;
2145 return i1->t == i2->t && i1->index == i2->index &&
2146 i1->array_part == i2->array_part;
2147 }
2148
2149
2150 #include <errno.h>
2151 #include <stdarg.h>
2152 #include <stddef.h>
2153 #include <stdint.h>
2154 #include <stdio.h>
2155 #include <stdlib.h>
2156 #include <string.h>
2157
2158
2159 /* upb_status *****************************************************************/
2160
upb_status_clear(upb_status * status)2161 void upb_status_clear(upb_status *status) {
2162 if (!status) return;
2163 status->ok = true;
2164 status->msg[0] = '\0';
2165 }
2166
upb_ok(const upb_status * status)2167 bool upb_ok(const upb_status *status) { return status->ok; }
2168
upb_status_errmsg(const upb_status * status)2169 const char *upb_status_errmsg(const upb_status *status) { return status->msg; }
2170
upb_status_seterrmsg(upb_status * status,const char * msg)2171 void upb_status_seterrmsg(upb_status *status, const char *msg) {
2172 if (!status) return;
2173 status->ok = false;
2174 strncpy(status->msg, msg, UPB_STATUS_MAX_MESSAGE - 1);
2175 status->msg[UPB_STATUS_MAX_MESSAGE - 1] = '\0';
2176 }
2177
upb_status_seterrf(upb_status * status,const char * fmt,...)2178 void upb_status_seterrf(upb_status *status, const char *fmt, ...) {
2179 va_list args;
2180 va_start(args, fmt);
2181 upb_status_vseterrf(status, fmt, args);
2182 va_end(args);
2183 }
2184
upb_status_vseterrf(upb_status * status,const char * fmt,va_list args)2185 void upb_status_vseterrf(upb_status *status, const char *fmt, va_list args) {
2186 if (!status) return;
2187 status->ok = false;
2188 vsnprintf(status->msg, sizeof(status->msg), fmt, args);
2189 status->msg[UPB_STATUS_MAX_MESSAGE - 1] = '\0';
2190 }
2191
upb_status_vappenderrf(upb_status * status,const char * fmt,va_list args)2192 void upb_status_vappenderrf(upb_status *status, const char *fmt, va_list args) {
2193 size_t len;
2194 if (!status) return;
2195 status->ok = false;
2196 len = strlen(status->msg);
2197 vsnprintf(status->msg + len, sizeof(status->msg) - len, fmt, args);
2198 status->msg[UPB_STATUS_MAX_MESSAGE - 1] = '\0';
2199 }
2200
2201 /* upb_alloc ******************************************************************/
2202
upb_global_allocfunc(upb_alloc * alloc,void * ptr,size_t oldsize,size_t size)2203 static void *upb_global_allocfunc(upb_alloc *alloc, void *ptr, size_t oldsize,
2204 size_t size) {
2205 UPB_UNUSED(alloc);
2206 UPB_UNUSED(oldsize);
2207 if (size == 0) {
2208 free(ptr);
2209 return NULL;
2210 } else {
2211 return realloc(ptr, size);
2212 }
2213 }
2214
2215 upb_alloc upb_alloc_global = {&upb_global_allocfunc};
2216
2217 /* upb_arena ******************************************************************/
2218
2219 /* Be conservative and choose 16 in case anyone is using SSE. */
2220
2221 struct mem_block {
2222 struct mem_block *next;
2223 uint32_t size;
2224 uint32_t cleanups;
2225 /* Data follows. */
2226 };
2227
2228 typedef struct cleanup_ent {
2229 upb_cleanup_func *cleanup;
2230 void *ud;
2231 } cleanup_ent;
2232
2233 static const size_t memblock_reserve = UPB_ALIGN_UP(sizeof(mem_block), 16);
2234
arena_findroot(upb_arena * a)2235 static upb_arena *arena_findroot(upb_arena *a) {
2236 /* Path splitting keeps time complexity down, see:
2237 * https://en.wikipedia.org/wiki/Disjoint-set_data_structure */
2238 while (a->parent != a) {
2239 upb_arena *next = a->parent;
2240 a->parent = next->parent;
2241 a = next;
2242 }
2243 return a;
2244 }
2245
upb_arena_addblock(upb_arena * a,upb_arena * root,void * ptr,size_t size)2246 static void upb_arena_addblock(upb_arena *a, upb_arena *root, void *ptr,
2247 size_t size) {
2248 mem_block *block = ptr;
2249
2250 /* The block is for arena |a|, but should appear in the freelist of |root|. */
2251 block->next = root->freelist;
2252 block->size = (uint32_t)size;
2253 block->cleanups = 0;
2254 root->freelist = block;
2255 a->last_size = block->size;
2256 if (!root->freelist_tail) root->freelist_tail = block;
2257
2258 a->head.ptr = UPB_PTR_AT(block, memblock_reserve, char);
2259 a->head.end = UPB_PTR_AT(block, size, char);
2260 a->cleanups = &block->cleanups;
2261
2262 UPB_POISON_MEMORY_REGION(a->head.ptr, a->head.end - a->head.ptr);
2263 }
2264
upb_arena_allocblock(upb_arena * a,size_t size)2265 static bool upb_arena_allocblock(upb_arena *a, size_t size) {
2266 upb_arena *root = arena_findroot(a);
2267 size_t block_size = UPB_MAX(size, a->last_size * 2) + memblock_reserve;
2268 mem_block *block = upb_malloc(root->block_alloc, block_size);
2269
2270 if (!block) return false;
2271 upb_arena_addblock(a, root, block, block_size);
2272 return true;
2273 }
2274
_upb_arena_slowmalloc(upb_arena * a,size_t size)2275 void *_upb_arena_slowmalloc(upb_arena *a, size_t size) {
2276 if (!upb_arena_allocblock(a, size)) return NULL; /* Out of memory. */
2277 UPB_ASSERT(_upb_arenahas(a, size));
2278 return upb_arena_malloc(a, size);
2279 }
2280
upb_arena_doalloc(upb_alloc * alloc,void * ptr,size_t oldsize,size_t size)2281 static void *upb_arena_doalloc(upb_alloc *alloc, void *ptr, size_t oldsize,
2282 size_t size) {
2283 upb_arena *a = (upb_arena*)alloc; /* upb_alloc is initial member. */
2284 return upb_arena_realloc(a, ptr, oldsize, size);
2285 }
2286
2287 /* Public Arena API ***********************************************************/
2288
arena_initslow(void * mem,size_t n,upb_alloc * alloc)2289 upb_arena *arena_initslow(void *mem, size_t n, upb_alloc *alloc) {
2290 const size_t first_block_overhead = sizeof(upb_arena) + memblock_reserve;
2291 upb_arena *a;
2292
2293 /* We need to malloc the initial block. */
2294 n = first_block_overhead + 256;
2295 if (!alloc || !(mem = upb_malloc(alloc, n))) {
2296 return NULL;
2297 }
2298
2299 a = UPB_PTR_AT(mem, n - sizeof(*a), upb_arena);
2300 n -= sizeof(*a);
2301
2302 a->head.alloc.func = &upb_arena_doalloc;
2303 a->block_alloc = alloc;
2304 a->parent = a;
2305 a->refcount = 1;
2306 a->freelist = NULL;
2307 a->freelist_tail = NULL;
2308
2309 upb_arena_addblock(a, a, mem, n);
2310
2311 return a;
2312 }
2313
upb_arena_init(void * mem,size_t n,upb_alloc * alloc)2314 upb_arena *upb_arena_init(void *mem, size_t n, upb_alloc *alloc) {
2315 upb_arena *a;
2316
2317 /* Round block size down to alignof(*a) since we will allocate the arena
2318 * itself at the end. */
2319 n = UPB_ALIGN_DOWN(n, UPB_ALIGN_OF(upb_arena));
2320
2321 if (UPB_UNLIKELY(n < sizeof(upb_arena))) {
2322 return arena_initslow(mem, n, alloc);
2323 }
2324
2325 a = UPB_PTR_AT(mem, n - sizeof(*a), upb_arena);
2326 n -= sizeof(*a);
2327
2328 a->head.alloc.func = &upb_arena_doalloc;
2329 a->block_alloc = alloc;
2330 a->parent = a;
2331 a->refcount = 1;
2332 a->last_size = 128;
2333 a->head.ptr = mem;
2334 a->head.end = UPB_PTR_AT(mem, n, char);
2335 a->freelist = NULL;
2336 a->cleanups = NULL;
2337
2338 return a;
2339 }
2340
arena_dofree(upb_arena * a)2341 static void arena_dofree(upb_arena *a) {
2342 mem_block *block = a->freelist;
2343 UPB_ASSERT(a->parent == a);
2344 UPB_ASSERT(a->refcount == 0);
2345
2346 while (block) {
2347 /* Load first since we are deleting block. */
2348 mem_block *next = block->next;
2349
2350 if (block->cleanups > 0) {
2351 cleanup_ent *end = UPB_PTR_AT(block, block->size, void);
2352 cleanup_ent *ptr = end - block->cleanups;
2353
2354 for (; ptr < end; ptr++) {
2355 ptr->cleanup(ptr->ud);
2356 }
2357 }
2358
2359 upb_free(a->block_alloc, block);
2360 block = next;
2361 }
2362 }
2363
upb_arena_free(upb_arena * a)2364 void upb_arena_free(upb_arena *a) {
2365 a = arena_findroot(a);
2366 if (--a->refcount == 0) arena_dofree(a);
2367 }
2368
upb_arena_addcleanup(upb_arena * a,void * ud,upb_cleanup_func * func)2369 bool upb_arena_addcleanup(upb_arena *a, void *ud, upb_cleanup_func *func) {
2370 cleanup_ent *ent;
2371
2372 if (!a->cleanups || !_upb_arenahas(a, sizeof(cleanup_ent))) {
2373 if (!upb_arena_allocblock(a, 128)) return false; /* Out of memory. */
2374 UPB_ASSERT(_upb_arenahas(a, sizeof(cleanup_ent)));
2375 }
2376
2377 a->head.end -= sizeof(cleanup_ent);
2378 ent = (cleanup_ent*)a->head.end;
2379 (*a->cleanups)++;
2380 UPB_UNPOISON_MEMORY_REGION(ent, sizeof(cleanup_ent));
2381
2382 ent->cleanup = func;
2383 ent->ud = ud;
2384
2385 return true;
2386 }
2387
upb_arena_fuse(upb_arena * a1,upb_arena * a2)2388 void upb_arena_fuse(upb_arena *a1, upb_arena *a2) {
2389 upb_arena *r1 = arena_findroot(a1);
2390 upb_arena *r2 = arena_findroot(a2);
2391
2392 if (r1 == r2) return; /* Already fused. */
2393
2394 /* We want to join the smaller tree to the larger tree.
2395 * So swap first if they are backwards. */
2396 if (r1->refcount < r2->refcount) {
2397 upb_arena *tmp = r1;
2398 r1 = r2;
2399 r2 = tmp;
2400 }
2401
2402 /* r1 takes over r2's freelist and refcount. */
2403 r1->refcount += r2->refcount;
2404 if (r2->freelist_tail) {
2405 UPB_ASSERT(r2->freelist_tail->next == NULL);
2406 r2->freelist_tail->next = r1->freelist;
2407 r1->freelist = r2->freelist;
2408 }
2409 r2->parent = r1;
2410 }
2411 /* This file was generated by upbc (the upb compiler) from the input
2412 * file:
2413 *
2414 * google/protobuf/descriptor.proto
2415 *
2416 * Do not edit -- your changes will be discarded when the file is
2417 * regenerated. */
2418
2419 #include <stddef.h>
2420
2421
2422 static const upb_msglayout *const google_protobuf_FileDescriptorSet_submsgs[1] = {
2423 &google_protobuf_FileDescriptorProto_msginit,
2424 };
2425
2426 static const upb_msglayout_field google_protobuf_FileDescriptorSet__fields[1] = {
2427 {1, UPB_SIZE(0, 0), 0, 0, 11, 3},
2428 };
2429
2430 const upb_msglayout google_protobuf_FileDescriptorSet_msginit = {
2431 &google_protobuf_FileDescriptorSet_submsgs[0],
2432 &google_protobuf_FileDescriptorSet__fields[0],
2433 UPB_SIZE(4, 8), 1, false,
2434 };
2435
2436 static const upb_msglayout *const google_protobuf_FileDescriptorProto_submsgs[6] = {
2437 &google_protobuf_DescriptorProto_msginit,
2438 &google_protobuf_EnumDescriptorProto_msginit,
2439 &google_protobuf_FieldDescriptorProto_msginit,
2440 &google_protobuf_FileOptions_msginit,
2441 &google_protobuf_ServiceDescriptorProto_msginit,
2442 &google_protobuf_SourceCodeInfo_msginit,
2443 };
2444
2445 static const upb_msglayout_field google_protobuf_FileDescriptorProto__fields[12] = {
2446 {1, UPB_SIZE(4, 8), 1, 0, 12, 1},
2447 {2, UPB_SIZE(12, 24), 2, 0, 12, 1},
2448 {3, UPB_SIZE(36, 72), 0, 0, 12, 3},
2449 {4, UPB_SIZE(40, 80), 0, 0, 11, 3},
2450 {5, UPB_SIZE(44, 88), 0, 1, 11, 3},
2451 {6, UPB_SIZE(48, 96), 0, 4, 11, 3},
2452 {7, UPB_SIZE(52, 104), 0, 2, 11, 3},
2453 {8, UPB_SIZE(28, 56), 4, 3, 11, 1},
2454 {9, UPB_SIZE(32, 64), 5, 5, 11, 1},
2455 {10, UPB_SIZE(56, 112), 0, 0, 5, 3},
2456 {11, UPB_SIZE(60, 120), 0, 0, 5, 3},
2457 {12, UPB_SIZE(20, 40), 3, 0, 12, 1},
2458 };
2459
2460 const upb_msglayout google_protobuf_FileDescriptorProto_msginit = {
2461 &google_protobuf_FileDescriptorProto_submsgs[0],
2462 &google_protobuf_FileDescriptorProto__fields[0],
2463 UPB_SIZE(64, 128), 12, false,
2464 };
2465
2466 static const upb_msglayout *const google_protobuf_DescriptorProto_submsgs[7] = {
2467 &google_protobuf_DescriptorProto_msginit,
2468 &google_protobuf_DescriptorProto_ExtensionRange_msginit,
2469 &google_protobuf_DescriptorProto_ReservedRange_msginit,
2470 &google_protobuf_EnumDescriptorProto_msginit,
2471 &google_protobuf_FieldDescriptorProto_msginit,
2472 &google_protobuf_MessageOptions_msginit,
2473 &google_protobuf_OneofDescriptorProto_msginit,
2474 };
2475
2476 static const upb_msglayout_field google_protobuf_DescriptorProto__fields[10] = {
2477 {1, UPB_SIZE(4, 8), 1, 0, 12, 1},
2478 {2, UPB_SIZE(16, 32), 0, 4, 11, 3},
2479 {3, UPB_SIZE(20, 40), 0, 0, 11, 3},
2480 {4, UPB_SIZE(24, 48), 0, 3, 11, 3},
2481 {5, UPB_SIZE(28, 56), 0, 1, 11, 3},
2482 {6, UPB_SIZE(32, 64), 0, 4, 11, 3},
2483 {7, UPB_SIZE(12, 24), 2, 5, 11, 1},
2484 {8, UPB_SIZE(36, 72), 0, 6, 11, 3},
2485 {9, UPB_SIZE(40, 80), 0, 2, 11, 3},
2486 {10, UPB_SIZE(44, 88), 0, 0, 12, 3},
2487 };
2488
2489 const upb_msglayout google_protobuf_DescriptorProto_msginit = {
2490 &google_protobuf_DescriptorProto_submsgs[0],
2491 &google_protobuf_DescriptorProto__fields[0],
2492 UPB_SIZE(48, 96), 10, false,
2493 };
2494
2495 static const upb_msglayout *const google_protobuf_DescriptorProto_ExtensionRange_submsgs[1] = {
2496 &google_protobuf_ExtensionRangeOptions_msginit,
2497 };
2498
2499 static const upb_msglayout_field google_protobuf_DescriptorProto_ExtensionRange__fields[3] = {
2500 {1, UPB_SIZE(4, 4), 1, 0, 5, 1},
2501 {2, UPB_SIZE(8, 8), 2, 0, 5, 1},
2502 {3, UPB_SIZE(12, 16), 3, 0, 11, 1},
2503 };
2504
2505 const upb_msglayout google_protobuf_DescriptorProto_ExtensionRange_msginit = {
2506 &google_protobuf_DescriptorProto_ExtensionRange_submsgs[0],
2507 &google_protobuf_DescriptorProto_ExtensionRange__fields[0],
2508 UPB_SIZE(16, 24), 3, false,
2509 };
2510
2511 static const upb_msglayout_field google_protobuf_DescriptorProto_ReservedRange__fields[2] = {
2512 {1, UPB_SIZE(4, 4), 1, 0, 5, 1},
2513 {2, UPB_SIZE(8, 8), 2, 0, 5, 1},
2514 };
2515
2516 const upb_msglayout google_protobuf_DescriptorProto_ReservedRange_msginit = {
2517 NULL,
2518 &google_protobuf_DescriptorProto_ReservedRange__fields[0],
2519 UPB_SIZE(12, 12), 2, false,
2520 };
2521
2522 static const upb_msglayout *const google_protobuf_ExtensionRangeOptions_submsgs[1] = {
2523 &google_protobuf_UninterpretedOption_msginit,
2524 };
2525
2526 static const upb_msglayout_field google_protobuf_ExtensionRangeOptions__fields[1] = {
2527 {999, UPB_SIZE(0, 0), 0, 0, 11, 3},
2528 };
2529
2530 const upb_msglayout google_protobuf_ExtensionRangeOptions_msginit = {
2531 &google_protobuf_ExtensionRangeOptions_submsgs[0],
2532 &google_protobuf_ExtensionRangeOptions__fields[0],
2533 UPB_SIZE(4, 8), 1, false,
2534 };
2535
2536 static const upb_msglayout *const google_protobuf_FieldDescriptorProto_submsgs[1] = {
2537 &google_protobuf_FieldOptions_msginit,
2538 };
2539
2540 static const upb_msglayout_field google_protobuf_FieldDescriptorProto__fields[11] = {
2541 {1, UPB_SIZE(24, 24), 6, 0, 12, 1},
2542 {2, UPB_SIZE(32, 40), 7, 0, 12, 1},
2543 {3, UPB_SIZE(12, 12), 3, 0, 5, 1},
2544 {4, UPB_SIZE(4, 4), 1, 0, 14, 1},
2545 {5, UPB_SIZE(8, 8), 2, 0, 14, 1},
2546 {6, UPB_SIZE(40, 56), 8, 0, 12, 1},
2547 {7, UPB_SIZE(48, 72), 9, 0, 12, 1},
2548 {8, UPB_SIZE(64, 104), 11, 0, 11, 1},
2549 {9, UPB_SIZE(16, 16), 4, 0, 5, 1},
2550 {10, UPB_SIZE(56, 88), 10, 0, 12, 1},
2551 {17, UPB_SIZE(20, 20), 5, 0, 8, 1},
2552 };
2553
2554 const upb_msglayout google_protobuf_FieldDescriptorProto_msginit = {
2555 &google_protobuf_FieldDescriptorProto_submsgs[0],
2556 &google_protobuf_FieldDescriptorProto__fields[0],
2557 UPB_SIZE(72, 112), 11, false,
2558 };
2559
2560 static const upb_msglayout *const google_protobuf_OneofDescriptorProto_submsgs[1] = {
2561 &google_protobuf_OneofOptions_msginit,
2562 };
2563
2564 static const upb_msglayout_field google_protobuf_OneofDescriptorProto__fields[2] = {
2565 {1, UPB_SIZE(4, 8), 1, 0, 12, 1},
2566 {2, UPB_SIZE(12, 24), 2, 0, 11, 1},
2567 };
2568
2569 const upb_msglayout google_protobuf_OneofDescriptorProto_msginit = {
2570 &google_protobuf_OneofDescriptorProto_submsgs[0],
2571 &google_protobuf_OneofDescriptorProto__fields[0],
2572 UPB_SIZE(16, 32), 2, false,
2573 };
2574
2575 static const upb_msglayout *const google_protobuf_EnumDescriptorProto_submsgs[3] = {
2576 &google_protobuf_EnumDescriptorProto_EnumReservedRange_msginit,
2577 &google_protobuf_EnumOptions_msginit,
2578 &google_protobuf_EnumValueDescriptorProto_msginit,
2579 };
2580
2581 static const upb_msglayout_field google_protobuf_EnumDescriptorProto__fields[5] = {
2582 {1, UPB_SIZE(4, 8), 1, 0, 12, 1},
2583 {2, UPB_SIZE(16, 32), 0, 2, 11, 3},
2584 {3, UPB_SIZE(12, 24), 2, 1, 11, 1},
2585 {4, UPB_SIZE(20, 40), 0, 0, 11, 3},
2586 {5, UPB_SIZE(24, 48), 0, 0, 12, 3},
2587 };
2588
2589 const upb_msglayout google_protobuf_EnumDescriptorProto_msginit = {
2590 &google_protobuf_EnumDescriptorProto_submsgs[0],
2591 &google_protobuf_EnumDescriptorProto__fields[0],
2592 UPB_SIZE(32, 64), 5, false,
2593 };
2594
2595 static const upb_msglayout_field google_protobuf_EnumDescriptorProto_EnumReservedRange__fields[2] = {
2596 {1, UPB_SIZE(4, 4), 1, 0, 5, 1},
2597 {2, UPB_SIZE(8, 8), 2, 0, 5, 1},
2598 };
2599
2600 const upb_msglayout google_protobuf_EnumDescriptorProto_EnumReservedRange_msginit = {
2601 NULL,
2602 &google_protobuf_EnumDescriptorProto_EnumReservedRange__fields[0],
2603 UPB_SIZE(12, 12), 2, false,
2604 };
2605
2606 static const upb_msglayout *const google_protobuf_EnumValueDescriptorProto_submsgs[1] = {
2607 &google_protobuf_EnumValueOptions_msginit,
2608 };
2609
2610 static const upb_msglayout_field google_protobuf_EnumValueDescriptorProto__fields[3] = {
2611 {1, UPB_SIZE(8, 8), 2, 0, 12, 1},
2612 {2, UPB_SIZE(4, 4), 1, 0, 5, 1},
2613 {3, UPB_SIZE(16, 24), 3, 0, 11, 1},
2614 };
2615
2616 const upb_msglayout google_protobuf_EnumValueDescriptorProto_msginit = {
2617 &google_protobuf_EnumValueDescriptorProto_submsgs[0],
2618 &google_protobuf_EnumValueDescriptorProto__fields[0],
2619 UPB_SIZE(24, 32), 3, false,
2620 };
2621
2622 static const upb_msglayout *const google_protobuf_ServiceDescriptorProto_submsgs[2] = {
2623 &google_protobuf_MethodDescriptorProto_msginit,
2624 &google_protobuf_ServiceOptions_msginit,
2625 };
2626
2627 static const upb_msglayout_field google_protobuf_ServiceDescriptorProto__fields[3] = {
2628 {1, UPB_SIZE(4, 8), 1, 0, 12, 1},
2629 {2, UPB_SIZE(16, 32), 0, 0, 11, 3},
2630 {3, UPB_SIZE(12, 24), 2, 1, 11, 1},
2631 };
2632
2633 const upb_msglayout google_protobuf_ServiceDescriptorProto_msginit = {
2634 &google_protobuf_ServiceDescriptorProto_submsgs[0],
2635 &google_protobuf_ServiceDescriptorProto__fields[0],
2636 UPB_SIZE(24, 48), 3, false,
2637 };
2638
2639 static const upb_msglayout *const google_protobuf_MethodDescriptorProto_submsgs[1] = {
2640 &google_protobuf_MethodOptions_msginit,
2641 };
2642
2643 static const upb_msglayout_field google_protobuf_MethodDescriptorProto__fields[6] = {
2644 {1, UPB_SIZE(4, 8), 3, 0, 12, 1},
2645 {2, UPB_SIZE(12, 24), 4, 0, 12, 1},
2646 {3, UPB_SIZE(20, 40), 5, 0, 12, 1},
2647 {4, UPB_SIZE(28, 56), 6, 0, 11, 1},
2648 {5, UPB_SIZE(1, 1), 1, 0, 8, 1},
2649 {6, UPB_SIZE(2, 2), 2, 0, 8, 1},
2650 };
2651
2652 const upb_msglayout google_protobuf_MethodDescriptorProto_msginit = {
2653 &google_protobuf_MethodDescriptorProto_submsgs[0],
2654 &google_protobuf_MethodDescriptorProto__fields[0],
2655 UPB_SIZE(32, 64), 6, false,
2656 };
2657
2658 static const upb_msglayout *const google_protobuf_FileOptions_submsgs[1] = {
2659 &google_protobuf_UninterpretedOption_msginit,
2660 };
2661
2662 static const upb_msglayout_field google_protobuf_FileOptions__fields[21] = {
2663 {1, UPB_SIZE(20, 24), 11, 0, 12, 1},
2664 {8, UPB_SIZE(28, 40), 12, 0, 12, 1},
2665 {9, UPB_SIZE(4, 4), 1, 0, 14, 1},
2666 {10, UPB_SIZE(8, 8), 2, 0, 8, 1},
2667 {11, UPB_SIZE(36, 56), 13, 0, 12, 1},
2668 {16, UPB_SIZE(9, 9), 3, 0, 8, 1},
2669 {17, UPB_SIZE(10, 10), 4, 0, 8, 1},
2670 {18, UPB_SIZE(11, 11), 5, 0, 8, 1},
2671 {20, UPB_SIZE(12, 12), 6, 0, 8, 1},
2672 {23, UPB_SIZE(13, 13), 7, 0, 8, 1},
2673 {27, UPB_SIZE(14, 14), 8, 0, 8, 1},
2674 {31, UPB_SIZE(15, 15), 9, 0, 8, 1},
2675 {36, UPB_SIZE(44, 72), 14, 0, 12, 1},
2676 {37, UPB_SIZE(52, 88), 15, 0, 12, 1},
2677 {39, UPB_SIZE(60, 104), 16, 0, 12, 1},
2678 {40, UPB_SIZE(68, 120), 17, 0, 12, 1},
2679 {41, UPB_SIZE(76, 136), 18, 0, 12, 1},
2680 {42, UPB_SIZE(16, 16), 10, 0, 8, 1},
2681 {44, UPB_SIZE(84, 152), 19, 0, 12, 1},
2682 {45, UPB_SIZE(92, 168), 20, 0, 12, 1},
2683 {999, UPB_SIZE(100, 184), 0, 0, 11, 3},
2684 };
2685
2686 const upb_msglayout google_protobuf_FileOptions_msginit = {
2687 &google_protobuf_FileOptions_submsgs[0],
2688 &google_protobuf_FileOptions__fields[0],
2689 UPB_SIZE(104, 192), 21, false,
2690 };
2691
2692 static const upb_msglayout *const google_protobuf_MessageOptions_submsgs[1] = {
2693 &google_protobuf_UninterpretedOption_msginit,
2694 };
2695
2696 static const upb_msglayout_field google_protobuf_MessageOptions__fields[5] = {
2697 {1, UPB_SIZE(1, 1), 1, 0, 8, 1},
2698 {2, UPB_SIZE(2, 2), 2, 0, 8, 1},
2699 {3, UPB_SIZE(3, 3), 3, 0, 8, 1},
2700 {7, UPB_SIZE(4, 4), 4, 0, 8, 1},
2701 {999, UPB_SIZE(8, 8), 0, 0, 11, 3},
2702 };
2703
2704 const upb_msglayout google_protobuf_MessageOptions_msginit = {
2705 &google_protobuf_MessageOptions_submsgs[0],
2706 &google_protobuf_MessageOptions__fields[0],
2707 UPB_SIZE(12, 16), 5, false,
2708 };
2709
2710 static const upb_msglayout *const google_protobuf_FieldOptions_submsgs[1] = {
2711 &google_protobuf_UninterpretedOption_msginit,
2712 };
2713
2714 static const upb_msglayout_field google_protobuf_FieldOptions__fields[7] = {
2715 {1, UPB_SIZE(4, 4), 1, 0, 14, 1},
2716 {2, UPB_SIZE(12, 12), 3, 0, 8, 1},
2717 {3, UPB_SIZE(13, 13), 4, 0, 8, 1},
2718 {5, UPB_SIZE(14, 14), 5, 0, 8, 1},
2719 {6, UPB_SIZE(8, 8), 2, 0, 14, 1},
2720 {10, UPB_SIZE(15, 15), 6, 0, 8, 1},
2721 {999, UPB_SIZE(16, 16), 0, 0, 11, 3},
2722 };
2723
2724 const upb_msglayout google_protobuf_FieldOptions_msginit = {
2725 &google_protobuf_FieldOptions_submsgs[0],
2726 &google_protobuf_FieldOptions__fields[0],
2727 UPB_SIZE(20, 24), 7, false,
2728 };
2729
2730 static const upb_msglayout *const google_protobuf_OneofOptions_submsgs[1] = {
2731 &google_protobuf_UninterpretedOption_msginit,
2732 };
2733
2734 static const upb_msglayout_field google_protobuf_OneofOptions__fields[1] = {
2735 {999, UPB_SIZE(0, 0), 0, 0, 11, 3},
2736 };
2737
2738 const upb_msglayout google_protobuf_OneofOptions_msginit = {
2739 &google_protobuf_OneofOptions_submsgs[0],
2740 &google_protobuf_OneofOptions__fields[0],
2741 UPB_SIZE(4, 8), 1, false,
2742 };
2743
2744 static const upb_msglayout *const google_protobuf_EnumOptions_submsgs[1] = {
2745 &google_protobuf_UninterpretedOption_msginit,
2746 };
2747
2748 static const upb_msglayout_field google_protobuf_EnumOptions__fields[3] = {
2749 {2, UPB_SIZE(1, 1), 1, 0, 8, 1},
2750 {3, UPB_SIZE(2, 2), 2, 0, 8, 1},
2751 {999, UPB_SIZE(4, 8), 0, 0, 11, 3},
2752 };
2753
2754 const upb_msglayout google_protobuf_EnumOptions_msginit = {
2755 &google_protobuf_EnumOptions_submsgs[0],
2756 &google_protobuf_EnumOptions__fields[0],
2757 UPB_SIZE(8, 16), 3, false,
2758 };
2759
2760 static const upb_msglayout *const google_protobuf_EnumValueOptions_submsgs[1] = {
2761 &google_protobuf_UninterpretedOption_msginit,
2762 };
2763
2764 static const upb_msglayout_field google_protobuf_EnumValueOptions__fields[2] = {
2765 {1, UPB_SIZE(1, 1), 1, 0, 8, 1},
2766 {999, UPB_SIZE(4, 8), 0, 0, 11, 3},
2767 };
2768
2769 const upb_msglayout google_protobuf_EnumValueOptions_msginit = {
2770 &google_protobuf_EnumValueOptions_submsgs[0],
2771 &google_protobuf_EnumValueOptions__fields[0],
2772 UPB_SIZE(8, 16), 2, false,
2773 };
2774
2775 static const upb_msglayout *const google_protobuf_ServiceOptions_submsgs[1] = {
2776 &google_protobuf_UninterpretedOption_msginit,
2777 };
2778
2779 static const upb_msglayout_field google_protobuf_ServiceOptions__fields[2] = {
2780 {33, UPB_SIZE(1, 1), 1, 0, 8, 1},
2781 {999, UPB_SIZE(4, 8), 0, 0, 11, 3},
2782 };
2783
2784 const upb_msglayout google_protobuf_ServiceOptions_msginit = {
2785 &google_protobuf_ServiceOptions_submsgs[0],
2786 &google_protobuf_ServiceOptions__fields[0],
2787 UPB_SIZE(8, 16), 2, false,
2788 };
2789
2790 static const upb_msglayout *const google_protobuf_MethodOptions_submsgs[1] = {
2791 &google_protobuf_UninterpretedOption_msginit,
2792 };
2793
2794 static const upb_msglayout_field google_protobuf_MethodOptions__fields[3] = {
2795 {33, UPB_SIZE(8, 8), 2, 0, 8, 1},
2796 {34, UPB_SIZE(4, 4), 1, 0, 14, 1},
2797 {999, UPB_SIZE(12, 16), 0, 0, 11, 3},
2798 };
2799
2800 const upb_msglayout google_protobuf_MethodOptions_msginit = {
2801 &google_protobuf_MethodOptions_submsgs[0],
2802 &google_protobuf_MethodOptions__fields[0],
2803 UPB_SIZE(16, 24), 3, false,
2804 };
2805
2806 static const upb_msglayout *const google_protobuf_UninterpretedOption_submsgs[1] = {
2807 &google_protobuf_UninterpretedOption_NamePart_msginit,
2808 };
2809
2810 static const upb_msglayout_field google_protobuf_UninterpretedOption__fields[7] = {
2811 {2, UPB_SIZE(56, 80), 0, 0, 11, 3},
2812 {3, UPB_SIZE(32, 32), 4, 0, 12, 1},
2813 {4, UPB_SIZE(8, 8), 1, 0, 4, 1},
2814 {5, UPB_SIZE(16, 16), 2, 0, 3, 1},
2815 {6, UPB_SIZE(24, 24), 3, 0, 1, 1},
2816 {7, UPB_SIZE(40, 48), 5, 0, 12, 1},
2817 {8, UPB_SIZE(48, 64), 6, 0, 12, 1},
2818 };
2819
2820 const upb_msglayout google_protobuf_UninterpretedOption_msginit = {
2821 &google_protobuf_UninterpretedOption_submsgs[0],
2822 &google_protobuf_UninterpretedOption__fields[0],
2823 UPB_SIZE(64, 96), 7, false,
2824 };
2825
2826 static const upb_msglayout_field google_protobuf_UninterpretedOption_NamePart__fields[2] = {
2827 {1, UPB_SIZE(4, 8), 2, 0, 12, 2},
2828 {2, UPB_SIZE(1, 1), 1, 0, 8, 2},
2829 };
2830
2831 const upb_msglayout google_protobuf_UninterpretedOption_NamePart_msginit = {
2832 NULL,
2833 &google_protobuf_UninterpretedOption_NamePart__fields[0],
2834 UPB_SIZE(16, 32), 2, false,
2835 };
2836
2837 static const upb_msglayout *const google_protobuf_SourceCodeInfo_submsgs[1] = {
2838 &google_protobuf_SourceCodeInfo_Location_msginit,
2839 };
2840
2841 static const upb_msglayout_field google_protobuf_SourceCodeInfo__fields[1] = {
2842 {1, UPB_SIZE(0, 0), 0, 0, 11, 3},
2843 };
2844
2845 const upb_msglayout google_protobuf_SourceCodeInfo_msginit = {
2846 &google_protobuf_SourceCodeInfo_submsgs[0],
2847 &google_protobuf_SourceCodeInfo__fields[0],
2848 UPB_SIZE(4, 8), 1, false,
2849 };
2850
2851 static const upb_msglayout_field google_protobuf_SourceCodeInfo_Location__fields[5] = {
2852 {1, UPB_SIZE(20, 40), 0, 0, 5, _UPB_LABEL_PACKED},
2853 {2, UPB_SIZE(24, 48), 0, 0, 5, _UPB_LABEL_PACKED},
2854 {3, UPB_SIZE(4, 8), 1, 0, 12, 1},
2855 {4, UPB_SIZE(12, 24), 2, 0, 12, 1},
2856 {6, UPB_SIZE(28, 56), 0, 0, 12, 3},
2857 };
2858
2859 const upb_msglayout google_protobuf_SourceCodeInfo_Location_msginit = {
2860 NULL,
2861 &google_protobuf_SourceCodeInfo_Location__fields[0],
2862 UPB_SIZE(32, 64), 5, false,
2863 };
2864
2865 static const upb_msglayout *const google_protobuf_GeneratedCodeInfo_submsgs[1] = {
2866 &google_protobuf_GeneratedCodeInfo_Annotation_msginit,
2867 };
2868
2869 static const upb_msglayout_field google_protobuf_GeneratedCodeInfo__fields[1] = {
2870 {1, UPB_SIZE(0, 0), 0, 0, 11, 3},
2871 };
2872
2873 const upb_msglayout google_protobuf_GeneratedCodeInfo_msginit = {
2874 &google_protobuf_GeneratedCodeInfo_submsgs[0],
2875 &google_protobuf_GeneratedCodeInfo__fields[0],
2876 UPB_SIZE(4, 8), 1, false,
2877 };
2878
2879 static const upb_msglayout_field google_protobuf_GeneratedCodeInfo_Annotation__fields[4] = {
2880 {1, UPB_SIZE(20, 32), 0, 0, 5, _UPB_LABEL_PACKED},
2881 {2, UPB_SIZE(12, 16), 3, 0, 12, 1},
2882 {3, UPB_SIZE(4, 4), 1, 0, 5, 1},
2883 {4, UPB_SIZE(8, 8), 2, 0, 5, 1},
2884 };
2885
2886 const upb_msglayout google_protobuf_GeneratedCodeInfo_Annotation_msginit = {
2887 NULL,
2888 &google_protobuf_GeneratedCodeInfo_Annotation__fields[0],
2889 UPB_SIZE(24, 48), 4, false,
2890 };
2891
2892
2893 /* This file was generated by upbc (the upb compiler) from the input
2894 * file:
2895 *
2896 * google/protobuf/descriptor.proto
2897 *
2898 * Do not edit -- your changes will be discarded when the file is
2899 * regenerated. */
2900
2901
2902 extern const upb_msglayout google_protobuf_FileDescriptorSet_msginit;
2903 extern const upb_msglayout google_protobuf_FileDescriptorProto_msginit;
2904 extern const upb_msglayout google_protobuf_DescriptorProto_msginit;
2905 extern const upb_msglayout google_protobuf_DescriptorProto_ExtensionRange_msginit;
2906 extern const upb_msglayout google_protobuf_DescriptorProto_ReservedRange_msginit;
2907 extern const upb_msglayout google_protobuf_ExtensionRangeOptions_msginit;
2908 extern const upb_msglayout google_protobuf_FieldDescriptorProto_msginit;
2909 extern const upb_msglayout google_protobuf_OneofDescriptorProto_msginit;
2910 extern const upb_msglayout google_protobuf_EnumDescriptorProto_msginit;
2911 extern const upb_msglayout google_protobuf_EnumDescriptorProto_EnumReservedRange_msginit;
2912 extern const upb_msglayout google_protobuf_EnumValueDescriptorProto_msginit;
2913 extern const upb_msglayout google_protobuf_ServiceDescriptorProto_msginit;
2914 extern const upb_msglayout google_protobuf_MethodDescriptorProto_msginit;
2915 extern const upb_msglayout google_protobuf_FileOptions_msginit;
2916 extern const upb_msglayout google_protobuf_MessageOptions_msginit;
2917 extern const upb_msglayout google_protobuf_FieldOptions_msginit;
2918 extern const upb_msglayout google_protobuf_OneofOptions_msginit;
2919 extern const upb_msglayout google_protobuf_EnumOptions_msginit;
2920 extern const upb_msglayout google_protobuf_EnumValueOptions_msginit;
2921 extern const upb_msglayout google_protobuf_ServiceOptions_msginit;
2922 extern const upb_msglayout google_protobuf_MethodOptions_msginit;
2923 extern const upb_msglayout google_protobuf_UninterpretedOption_msginit;
2924 extern const upb_msglayout google_protobuf_UninterpretedOption_NamePart_msginit;
2925 extern const upb_msglayout google_protobuf_SourceCodeInfo_msginit;
2926 extern const upb_msglayout google_protobuf_SourceCodeInfo_Location_msginit;
2927 extern const upb_msglayout google_protobuf_GeneratedCodeInfo_msginit;
2928 extern const upb_msglayout google_protobuf_GeneratedCodeInfo_Annotation_msginit;
2929
2930 static const upb_msglayout *layouts[27] = {
2931 &google_protobuf_FileDescriptorSet_msginit,
2932 &google_protobuf_FileDescriptorProto_msginit,
2933 &google_protobuf_DescriptorProto_msginit,
2934 &google_protobuf_DescriptorProto_ExtensionRange_msginit,
2935 &google_protobuf_DescriptorProto_ReservedRange_msginit,
2936 &google_protobuf_ExtensionRangeOptions_msginit,
2937 &google_protobuf_FieldDescriptorProto_msginit,
2938 &google_protobuf_OneofDescriptorProto_msginit,
2939 &google_protobuf_EnumDescriptorProto_msginit,
2940 &google_protobuf_EnumDescriptorProto_EnumReservedRange_msginit,
2941 &google_protobuf_EnumValueDescriptorProto_msginit,
2942 &google_protobuf_ServiceDescriptorProto_msginit,
2943 &google_protobuf_MethodDescriptorProto_msginit,
2944 &google_protobuf_FileOptions_msginit,
2945 &google_protobuf_MessageOptions_msginit,
2946 &google_protobuf_FieldOptions_msginit,
2947 &google_protobuf_OneofOptions_msginit,
2948 &google_protobuf_EnumOptions_msginit,
2949 &google_protobuf_EnumValueOptions_msginit,
2950 &google_protobuf_ServiceOptions_msginit,
2951 &google_protobuf_MethodOptions_msginit,
2952 &google_protobuf_UninterpretedOption_msginit,
2953 &google_protobuf_UninterpretedOption_NamePart_msginit,
2954 &google_protobuf_SourceCodeInfo_msginit,
2955 &google_protobuf_SourceCodeInfo_Location_msginit,
2956 &google_protobuf_GeneratedCodeInfo_msginit,
2957 &google_protobuf_GeneratedCodeInfo_Annotation_msginit,
2958 };
2959
2960 static const char descriptor[7601] = {'\n', ' ', 'g', 'o', 'o', 'g', 'l', 'e', '/', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '/', 'd', 'e', 's', 'c', 'r', 'i', 'p',
2961 't', 'o', 'r', '.', 'p', 'r', 'o', 't', 'o', '\022', '\017', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u',
2962 'f', '\"', 'M', '\n', '\021', 'F', 'i', 'l', 'e', 'D', 'e', 's', 'c', 'r', 'i', 'p', 't', 'o', 'r', 'S', 'e', 't', '\022', '8', '\n',
2963 '\004', 'f', 'i', 'l', 'e', '\030', '\001', ' ', '\003', '(', '\013', '2', '$', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't',
2964 'o', 'b', 'u', 'f', '.', 'F', 'i', 'l', 'e', 'D', 'e', 's', 'c', 'r', 'i', 'p', 't', 'o', 'r', 'P', 'r', 'o', 't', 'o', 'R',
2965 '\004', 'f', 'i', 'l', 'e', '\"', '\344', '\004', '\n', '\023', 'F', 'i', 'l', 'e', 'D', 'e', 's', 'c', 'r', 'i', 'p', 't', 'o', 'r', 'P',
2966 'r', 'o', 't', 'o', '\022', '\022', '\n', '\004', 'n', 'a', 'm', 'e', '\030', '\001', ' ', '\001', '(', '\t', 'R', '\004', 'n', 'a', 'm', 'e', '\022',
2967 '\030', '\n', '\007', 'p', 'a', 'c', 'k', 'a', 'g', 'e', '\030', '\002', ' ', '\001', '(', '\t', 'R', '\007', 'p', 'a', 'c', 'k', 'a', 'g', 'e',
2968 '\022', '\036', '\n', '\n', 'd', 'e', 'p', 'e', 'n', 'd', 'e', 'n', 'c', 'y', '\030', '\003', ' ', '\003', '(', '\t', 'R', '\n', 'd', 'e', 'p',
2969 'e', 'n', 'd', 'e', 'n', 'c', 'y', '\022', '+', '\n', '\021', 'p', 'u', 'b', 'l', 'i', 'c', '_', 'd', 'e', 'p', 'e', 'n', 'd', 'e',
2970 'n', 'c', 'y', '\030', '\n', ' ', '\003', '(', '\005', 'R', '\020', 'p', 'u', 'b', 'l', 'i', 'c', 'D', 'e', 'p', 'e', 'n', 'd', 'e', 'n',
2971 'c', 'y', '\022', '\'', '\n', '\017', 'w', 'e', 'a', 'k', '_', 'd', 'e', 'p', 'e', 'n', 'd', 'e', 'n', 'c', 'y', '\030', '\013', ' ', '\003',
2972 '(', '\005', 'R', '\016', 'w', 'e', 'a', 'k', 'D', 'e', 'p', 'e', 'n', 'd', 'e', 'n', 'c', 'y', '\022', 'C', '\n', '\014', 'm', 'e', 's',
2973 's', 'a', 'g', 'e', '_', 't', 'y', 'p', 'e', '\030', '\004', ' ', '\003', '(', '\013', '2', ' ', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.',
2974 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'D', 'e', 's', 'c', 'r', 'i', 'p', 't', 'o', 'r', 'P', 'r', 'o', 't', 'o', 'R',
2975 '\013', 'm', 'e', 's', 's', 'a', 'g', 'e', 'T', 'y', 'p', 'e', '\022', 'A', '\n', '\t', 'e', 'n', 'u', 'm', '_', 't', 'y', 'p', 'e',
2976 '\030', '\005', ' ', '\003', '(', '\013', '2', '$', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.',
2977 'E', 'n', 'u', 'm', 'D', 'e', 's', 'c', 'r', 'i', 'p', 't', 'o', 'r', 'P', 'r', 'o', 't', 'o', 'R', '\010', 'e', 'n', 'u', 'm',
2978 'T', 'y', 'p', 'e', '\022', 'A', '\n', '\007', 's', 'e', 'r', 'v', 'i', 'c', 'e', '\030', '\006', ' ', '\003', '(', '\013', '2', '\'', '.', 'g',
2979 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'S', 'e', 'r', 'v', 'i', 'c', 'e', 'D', 'e', 's',
2980 'c', 'r', 'i', 'p', 't', 'o', 'r', 'P', 'r', 'o', 't', 'o', 'R', '\007', 's', 'e', 'r', 'v', 'i', 'c', 'e', '\022', 'C', '\n', '\t',
2981 'e', 'x', 't', 'e', 'n', 's', 'i', 'o', 'n', '\030', '\007', ' ', '\003', '(', '\013', '2', '%', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.',
2982 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'F', 'i', 'e', 'l', 'd', 'D', 'e', 's', 'c', 'r', 'i', 'p', 't', 'o', 'r', 'P',
2983 'r', 'o', 't', 'o', 'R', '\t', 'e', 'x', 't', 'e', 'n', 's', 'i', 'o', 'n', '\022', '6', '\n', '\007', 'o', 'p', 't', 'i', 'o', 'n',
2984 's', '\030', '\010', ' ', '\001', '(', '\013', '2', '\034', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f',
2985 '.', 'F', 'i', 'l', 'e', 'O', 'p', 't', 'i', 'o', 'n', 's', 'R', '\007', 'o', 'p', 't', 'i', 'o', 'n', 's', '\022', 'I', '\n', '\020',
2986 's', 'o', 'u', 'r', 'c', 'e', '_', 'c', 'o', 'd', 'e', '_', 'i', 'n', 'f', 'o', '\030', '\t', ' ', '\001', '(', '\013', '2', '\037', '.',
2987 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'S', 'o', 'u', 'r', 'c', 'e', 'C', 'o', 'd',
2988 'e', 'I', 'n', 'f', 'o', 'R', '\016', 's', 'o', 'u', 'r', 'c', 'e', 'C', 'o', 'd', 'e', 'I', 'n', 'f', 'o', '\022', '\026', '\n', '\006',
2989 's', 'y', 'n', 't', 'a', 'x', '\030', '\014', ' ', '\001', '(', '\t', 'R', '\006', 's', 'y', 'n', 't', 'a', 'x', '\"', '\271', '\006', '\n', '\017',
2990 'D', 'e', 's', 'c', 'r', 'i', 'p', 't', 'o', 'r', 'P', 'r', 'o', 't', 'o', '\022', '\022', '\n', '\004', 'n', 'a', 'm', 'e', '\030', '\001',
2991 ' ', '\001', '(', '\t', 'R', '\004', 'n', 'a', 'm', 'e', '\022', ';', '\n', '\005', 'f', 'i', 'e', 'l', 'd', '\030', '\002', ' ', '\003', '(', '\013',
2992 '2', '%', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'F', 'i', 'e', 'l', 'd', 'D',
2993 'e', 's', 'c', 'r', 'i', 'p', 't', 'o', 'r', 'P', 'r', 'o', 't', 'o', 'R', '\005', 'f', 'i', 'e', 'l', 'd', '\022', 'C', '\n', '\t',
2994 'e', 'x', 't', 'e', 'n', 's', 'i', 'o', 'n', '\030', '\006', ' ', '\003', '(', '\013', '2', '%', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.',
2995 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'F', 'i', 'e', 'l', 'd', 'D', 'e', 's', 'c', 'r', 'i', 'p', 't', 'o', 'r', 'P',
2996 'r', 'o', 't', 'o', 'R', '\t', 'e', 'x', 't', 'e', 'n', 's', 'i', 'o', 'n', '\022', 'A', '\n', '\013', 'n', 'e', 's', 't', 'e', 'd',
2997 '_', 't', 'y', 'p', 'e', '\030', '\003', ' ', '\003', '(', '\013', '2', ' ', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't',
2998 'o', 'b', 'u', 'f', '.', 'D', 'e', 's', 'c', 'r', 'i', 'p', 't', 'o', 'r', 'P', 'r', 'o', 't', 'o', 'R', '\n', 'n', 'e', 's',
2999 't', 'e', 'd', 'T', 'y', 'p', 'e', '\022', 'A', '\n', '\t', 'e', 'n', 'u', 'm', '_', 't', 'y', 'p', 'e', '\030', '\004', ' ', '\003', '(',
3000 '\013', '2', '$', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'E', 'n', 'u', 'm', 'D',
3001 'e', 's', 'c', 'r', 'i', 'p', 't', 'o', 'r', 'P', 'r', 'o', 't', 'o', 'R', '\010', 'e', 'n', 'u', 'm', 'T', 'y', 'p', 'e', '\022',
3002 'X', '\n', '\017', 'e', 'x', 't', 'e', 'n', 's', 'i', 'o', 'n', '_', 'r', 'a', 'n', 'g', 'e', '\030', '\005', ' ', '\003', '(', '\013', '2',
3003 '/', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'D', 'e', 's', 'c', 'r', 'i', 'p',
3004 't', 'o', 'r', 'P', 'r', 'o', 't', 'o', '.', 'E', 'x', 't', 'e', 'n', 's', 'i', 'o', 'n', 'R', 'a', 'n', 'g', 'e', 'R', '\016',
3005 'e', 'x', 't', 'e', 'n', 's', 'i', 'o', 'n', 'R', 'a', 'n', 'g', 'e', '\022', 'D', '\n', '\n', 'o', 'n', 'e', 'o', 'f', '_', 'd',
3006 'e', 'c', 'l', '\030', '\010', ' ', '\003', '(', '\013', '2', '%', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b',
3007 'u', 'f', '.', 'O', 'n', 'e', 'o', 'f', 'D', 'e', 's', 'c', 'r', 'i', 'p', 't', 'o', 'r', 'P', 'r', 'o', 't', 'o', 'R', '\t',
3008 'o', 'n', 'e', 'o', 'f', 'D', 'e', 'c', 'l', '\022', '9', '\n', '\007', 'o', 'p', 't', 'i', 'o', 'n', 's', '\030', '\007', ' ', '\001', '(',
3009 '\013', '2', '\037', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'M', 'e', 's', 's', 'a',
3010 'g', 'e', 'O', 'p', 't', 'i', 'o', 'n', 's', 'R', '\007', 'o', 'p', 't', 'i', 'o', 'n', 's', '\022', 'U', '\n', '\016', 'r', 'e', 's',
3011 'e', 'r', 'v', 'e', 'd', '_', 'r', 'a', 'n', 'g', 'e', '\030', '\t', ' ', '\003', '(', '\013', '2', '.', '.', 'g', 'o', 'o', 'g', 'l',
3012 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'D', 'e', 's', 'c', 'r', 'i', 'p', 't', 'o', 'r', 'P', 'r', 'o', 't',
3013 'o', '.', 'R', 'e', 's', 'e', 'r', 'v', 'e', 'd', 'R', 'a', 'n', 'g', 'e', 'R', '\r', 'r', 'e', 's', 'e', 'r', 'v', 'e', 'd',
3014 'R', 'a', 'n', 'g', 'e', '\022', '#', '\n', '\r', 'r', 'e', 's', 'e', 'r', 'v', 'e', 'd', '_', 'n', 'a', 'm', 'e', '\030', '\n', ' ',
3015 '\003', '(', '\t', 'R', '\014', 'r', 'e', 's', 'e', 'r', 'v', 'e', 'd', 'N', 'a', 'm', 'e', '\032', 'z', '\n', '\016', 'E', 'x', 't', 'e',
3016 'n', 's', 'i', 'o', 'n', 'R', 'a', 'n', 'g', 'e', '\022', '\024', '\n', '\005', 's', 't', 'a', 'r', 't', '\030', '\001', ' ', '\001', '(', '\005',
3017 'R', '\005', 's', 't', 'a', 'r', 't', '\022', '\020', '\n', '\003', 'e', 'n', 'd', '\030', '\002', ' ', '\001', '(', '\005', 'R', '\003', 'e', 'n', 'd',
3018 '\022', '@', '\n', '\007', 'o', 'p', 't', 'i', 'o', 'n', 's', '\030', '\003', ' ', '\001', '(', '\013', '2', '&', '.', 'g', 'o', 'o', 'g', 'l',
3019 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'E', 'x', 't', 'e', 'n', 's', 'i', 'o', 'n', 'R', 'a', 'n', 'g', 'e',
3020 'O', 'p', 't', 'i', 'o', 'n', 's', 'R', '\007', 'o', 'p', 't', 'i', 'o', 'n', 's', '\032', '7', '\n', '\r', 'R', 'e', 's', 'e', 'r',
3021 'v', 'e', 'd', 'R', 'a', 'n', 'g', 'e', '\022', '\024', '\n', '\005', 's', 't', 'a', 'r', 't', '\030', '\001', ' ', '\001', '(', '\005', 'R', '\005',
3022 's', 't', 'a', 'r', 't', '\022', '\020', '\n', '\003', 'e', 'n', 'd', '\030', '\002', ' ', '\001', '(', '\005', 'R', '\003', 'e', 'n', 'd', '\"', '|',
3023 '\n', '\025', 'E', 'x', 't', 'e', 'n', 's', 'i', 'o', 'n', 'R', 'a', 'n', 'g', 'e', 'O', 'p', 't', 'i', 'o', 'n', 's', '\022', 'X',
3024 '\n', '\024', 'u', 'n', 'i', 'n', 't', 'e', 'r', 'p', 'r', 'e', 't', 'e', 'd', '_', 'o', 'p', 't', 'i', 'o', 'n', '\030', '\347', '\007',
3025 ' ', '\003', '(', '\013', '2', '$', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'U', 'n',
3026 'i', 'n', 't', 'e', 'r', 'p', 'r', 'e', 't', 'e', 'd', 'O', 'p', 't', 'i', 'o', 'n', 'R', '\023', 'u', 'n', 'i', 'n', 't', 'e',
3027 'r', 'p', 'r', 'e', 't', 'e', 'd', 'O', 'p', 't', 'i', 'o', 'n', '*', '\t', '\010', '\350', '\007', '\020', '\200', '\200', '\200', '\200', '\002', '\"',
3028 '\301', '\006', '\n', '\024', 'F', 'i', 'e', 'l', 'd', 'D', 'e', 's', 'c', 'r', 'i', 'p', 't', 'o', 'r', 'P', 'r', 'o', 't', 'o', '\022',
3029 '\022', '\n', '\004', 'n', 'a', 'm', 'e', '\030', '\001', ' ', '\001', '(', '\t', 'R', '\004', 'n', 'a', 'm', 'e', '\022', '\026', '\n', '\006', 'n', 'u',
3030 'm', 'b', 'e', 'r', '\030', '\003', ' ', '\001', '(', '\005', 'R', '\006', 'n', 'u', 'm', 'b', 'e', 'r', '\022', 'A', '\n', '\005', 'l', 'a', 'b',
3031 'e', 'l', '\030', '\004', ' ', '\001', '(', '\016', '2', '+', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u',
3032 'f', '.', 'F', 'i', 'e', 'l', 'd', 'D', 'e', 's', 'c', 'r', 'i', 'p', 't', 'o', 'r', 'P', 'r', 'o', 't', 'o', '.', 'L', 'a',
3033 'b', 'e', 'l', 'R', '\005', 'l', 'a', 'b', 'e', 'l', '\022', '>', '\n', '\004', 't', 'y', 'p', 'e', '\030', '\005', ' ', '\001', '(', '\016', '2',
3034 '*', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'F', 'i', 'e', 'l', 'd', 'D', 'e',
3035 's', 'c', 'r', 'i', 'p', 't', 'o', 'r', 'P', 'r', 'o', 't', 'o', '.', 'T', 'y', 'p', 'e', 'R', '\004', 't', 'y', 'p', 'e', '\022',
3036 '\033', '\n', '\t', 't', 'y', 'p', 'e', '_', 'n', 'a', 'm', 'e', '\030', '\006', ' ', '\001', '(', '\t', 'R', '\010', 't', 'y', 'p', 'e', 'N',
3037 'a', 'm', 'e', '\022', '\032', '\n', '\010', 'e', 'x', 't', 'e', 'n', 'd', 'e', 'e', '\030', '\002', ' ', '\001', '(', '\t', 'R', '\010', 'e', 'x',
3038 't', 'e', 'n', 'd', 'e', 'e', '\022', '#', '\n', '\r', 'd', 'e', 'f', 'a', 'u', 'l', 't', '_', 'v', 'a', 'l', 'u', 'e', '\030', '\007',
3039 ' ', '\001', '(', '\t', 'R', '\014', 'd', 'e', 'f', 'a', 'u', 'l', 't', 'V', 'a', 'l', 'u', 'e', '\022', '\037', '\n', '\013', 'o', 'n', 'e',
3040 'o', 'f', '_', 'i', 'n', 'd', 'e', 'x', '\030', '\t', ' ', '\001', '(', '\005', 'R', '\n', 'o', 'n', 'e', 'o', 'f', 'I', 'n', 'd', 'e',
3041 'x', '\022', '\033', '\n', '\t', 'j', 's', 'o', 'n', '_', 'n', 'a', 'm', 'e', '\030', '\n', ' ', '\001', '(', '\t', 'R', '\010', 'j', 's', 'o',
3042 'n', 'N', 'a', 'm', 'e', '\022', '7', '\n', '\007', 'o', 'p', 't', 'i', 'o', 'n', 's', '\030', '\010', ' ', '\001', '(', '\013', '2', '\035', '.',
3043 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'F', 'i', 'e', 'l', 'd', 'O', 'p', 't', 'i',
3044 'o', 'n', 's', 'R', '\007', 'o', 'p', 't', 'i', 'o', 'n', 's', '\022', '\'', '\n', '\017', 'p', 'r', 'o', 't', 'o', '3', '_', 'o', 'p',
3045 't', 'i', 'o', 'n', 'a', 'l', '\030', '\021', ' ', '\001', '(', '\010', 'R', '\016', 'p', 'r', 'o', 't', 'o', '3', 'O', 'p', 't', 'i', 'o',
3046 'n', 'a', 'l', '\"', '\266', '\002', '\n', '\004', 'T', 'y', 'p', 'e', '\022', '\017', '\n', '\013', 'T', 'Y', 'P', 'E', '_', 'D', 'O', 'U', 'B',
3047 'L', 'E', '\020', '\001', '\022', '\016', '\n', '\n', 'T', 'Y', 'P', 'E', '_', 'F', 'L', 'O', 'A', 'T', '\020', '\002', '\022', '\016', '\n', '\n', 'T',
3048 'Y', 'P', 'E', '_', 'I', 'N', 'T', '6', '4', '\020', '\003', '\022', '\017', '\n', '\013', 'T', 'Y', 'P', 'E', '_', 'U', 'I', 'N', 'T', '6',
3049 '4', '\020', '\004', '\022', '\016', '\n', '\n', 'T', 'Y', 'P', 'E', '_', 'I', 'N', 'T', '3', '2', '\020', '\005', '\022', '\020', '\n', '\014', 'T', 'Y',
3050 'P', 'E', '_', 'F', 'I', 'X', 'E', 'D', '6', '4', '\020', '\006', '\022', '\020', '\n', '\014', 'T', 'Y', 'P', 'E', '_', 'F', 'I', 'X', 'E',
3051 'D', '3', '2', '\020', '\007', '\022', '\r', '\n', '\t', 'T', 'Y', 'P', 'E', '_', 'B', 'O', 'O', 'L', '\020', '\010', '\022', '\017', '\n', '\013', 'T',
3052 'Y', 'P', 'E', '_', 'S', 'T', 'R', 'I', 'N', 'G', '\020', '\t', '\022', '\016', '\n', '\n', 'T', 'Y', 'P', 'E', '_', 'G', 'R', 'O', 'U',
3053 'P', '\020', '\n', '\022', '\020', '\n', '\014', 'T', 'Y', 'P', 'E', '_', 'M', 'E', 'S', 'S', 'A', 'G', 'E', '\020', '\013', '\022', '\016', '\n', '\n',
3054 'T', 'Y', 'P', 'E', '_', 'B', 'Y', 'T', 'E', 'S', '\020', '\014', '\022', '\017', '\n', '\013', 'T', 'Y', 'P', 'E', '_', 'U', 'I', 'N', 'T',
3055 '3', '2', '\020', '\r', '\022', '\r', '\n', '\t', 'T', 'Y', 'P', 'E', '_', 'E', 'N', 'U', 'M', '\020', '\016', '\022', '\021', '\n', '\r', 'T', 'Y',
3056 'P', 'E', '_', 'S', 'F', 'I', 'X', 'E', 'D', '3', '2', '\020', '\017', '\022', '\021', '\n', '\r', 'T', 'Y', 'P', 'E', '_', 'S', 'F', 'I',
3057 'X', 'E', 'D', '6', '4', '\020', '\020', '\022', '\017', '\n', '\013', 'T', 'Y', 'P', 'E', '_', 'S', 'I', 'N', 'T', '3', '2', '\020', '\021', '\022',
3058 '\017', '\n', '\013', 'T', 'Y', 'P', 'E', '_', 'S', 'I', 'N', 'T', '6', '4', '\020', '\022', '\"', 'C', '\n', '\005', 'L', 'a', 'b', 'e', 'l',
3059 '\022', '\022', '\n', '\016', 'L', 'A', 'B', 'E', 'L', '_', 'O', 'P', 'T', 'I', 'O', 'N', 'A', 'L', '\020', '\001', '\022', '\022', '\n', '\016', 'L',
3060 'A', 'B', 'E', 'L', '_', 'R', 'E', 'Q', 'U', 'I', 'R', 'E', 'D', '\020', '\002', '\022', '\022', '\n', '\016', 'L', 'A', 'B', 'E', 'L', '_',
3061 'R', 'E', 'P', 'E', 'A', 'T', 'E', 'D', '\020', '\003', '\"', 'c', '\n', '\024', 'O', 'n', 'e', 'o', 'f', 'D', 'e', 's', 'c', 'r', 'i',
3062 'p', 't', 'o', 'r', 'P', 'r', 'o', 't', 'o', '\022', '\022', '\n', '\004', 'n', 'a', 'm', 'e', '\030', '\001', ' ', '\001', '(', '\t', 'R', '\004',
3063 'n', 'a', 'm', 'e', '\022', '7', '\n', '\007', 'o', 'p', 't', 'i', 'o', 'n', 's', '\030', '\002', ' ', '\001', '(', '\013', '2', '\035', '.', 'g',
3064 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'O', 'n', 'e', 'o', 'f', 'O', 'p', 't', 'i', 'o',
3065 'n', 's', 'R', '\007', 'o', 'p', 't', 'i', 'o', 'n', 's', '\"', '\343', '\002', '\n', '\023', 'E', 'n', 'u', 'm', 'D', 'e', 's', 'c', 'r',
3066 'i', 'p', 't', 'o', 'r', 'P', 'r', 'o', 't', 'o', '\022', '\022', '\n', '\004', 'n', 'a', 'm', 'e', '\030', '\001', ' ', '\001', '(', '\t', 'R',
3067 '\004', 'n', 'a', 'm', 'e', '\022', '?', '\n', '\005', 'v', 'a', 'l', 'u', 'e', '\030', '\002', ' ', '\003', '(', '\013', '2', ')', '.', 'g', 'o',
3068 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'E', 'n', 'u', 'm', 'V', 'a', 'l', 'u', 'e', 'D', 'e',
3069 's', 'c', 'r', 'i', 'p', 't', 'o', 'r', 'P', 'r', 'o', 't', 'o', 'R', '\005', 'v', 'a', 'l', 'u', 'e', '\022', '6', '\n', '\007', 'o',
3070 'p', 't', 'i', 'o', 'n', 's', '\030', '\003', ' ', '\001', '(', '\013', '2', '\034', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o',
3071 't', 'o', 'b', 'u', 'f', '.', 'E', 'n', 'u', 'm', 'O', 'p', 't', 'i', 'o', 'n', 's', 'R', '\007', 'o', 'p', 't', 'i', 'o', 'n',
3072 's', '\022', ']', '\n', '\016', 'r', 'e', 's', 'e', 'r', 'v', 'e', 'd', '_', 'r', 'a', 'n', 'g', 'e', '\030', '\004', ' ', '\003', '(', '\013',
3073 '2', '6', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'E', 'n', 'u', 'm', 'D', 'e',
3074 's', 'c', 'r', 'i', 'p', 't', 'o', 'r', 'P', 'r', 'o', 't', 'o', '.', 'E', 'n', 'u', 'm', 'R', 'e', 's', 'e', 'r', 'v', 'e',
3075 'd', 'R', 'a', 'n', 'g', 'e', 'R', '\r', 'r', 'e', 's', 'e', 'r', 'v', 'e', 'd', 'R', 'a', 'n', 'g', 'e', '\022', '#', '\n', '\r',
3076 'r', 'e', 's', 'e', 'r', 'v', 'e', 'd', '_', 'n', 'a', 'm', 'e', '\030', '\005', ' ', '\003', '(', '\t', 'R', '\014', 'r', 'e', 's', 'e',
3077 'r', 'v', 'e', 'd', 'N', 'a', 'm', 'e', '\032', ';', '\n', '\021', 'E', 'n', 'u', 'm', 'R', 'e', 's', 'e', 'r', 'v', 'e', 'd', 'R',
3078 'a', 'n', 'g', 'e', '\022', '\024', '\n', '\005', 's', 't', 'a', 'r', 't', '\030', '\001', ' ', '\001', '(', '\005', 'R', '\005', 's', 't', 'a', 'r',
3079 't', '\022', '\020', '\n', '\003', 'e', 'n', 'd', '\030', '\002', ' ', '\001', '(', '\005', 'R', '\003', 'e', 'n', 'd', '\"', '\203', '\001', '\n', '\030', 'E',
3080 'n', 'u', 'm', 'V', 'a', 'l', 'u', 'e', 'D', 'e', 's', 'c', 'r', 'i', 'p', 't', 'o', 'r', 'P', 'r', 'o', 't', 'o', '\022', '\022',
3081 '\n', '\004', 'n', 'a', 'm', 'e', '\030', '\001', ' ', '\001', '(', '\t', 'R', '\004', 'n', 'a', 'm', 'e', '\022', '\026', '\n', '\006', 'n', 'u', 'm',
3082 'b', 'e', 'r', '\030', '\002', ' ', '\001', '(', '\005', 'R', '\006', 'n', 'u', 'm', 'b', 'e', 'r', '\022', ';', '\n', '\007', 'o', 'p', 't', 'i',
3083 'o', 'n', 's', '\030', '\003', ' ', '\001', '(', '\013', '2', '!', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b',
3084 'u', 'f', '.', 'E', 'n', 'u', 'm', 'V', 'a', 'l', 'u', 'e', 'O', 'p', 't', 'i', 'o', 'n', 's', 'R', '\007', 'o', 'p', 't', 'i',
3085 'o', 'n', 's', '\"', '\247', '\001', '\n', '\026', 'S', 'e', 'r', 'v', 'i', 'c', 'e', 'D', 'e', 's', 'c', 'r', 'i', 'p', 't', 'o', 'r',
3086 'P', 'r', 'o', 't', 'o', '\022', '\022', '\n', '\004', 'n', 'a', 'm', 'e', '\030', '\001', ' ', '\001', '(', '\t', 'R', '\004', 'n', 'a', 'm', 'e',
3087 '\022', '>', '\n', '\006', 'm', 'e', 't', 'h', 'o', 'd', '\030', '\002', ' ', '\003', '(', '\013', '2', '&', '.', 'g', 'o', 'o', 'g', 'l', 'e',
3088 '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'M', 'e', 't', 'h', 'o', 'd', 'D', 'e', 's', 'c', 'r', 'i', 'p', 't', 'o',
3089 'r', 'P', 'r', 'o', 't', 'o', 'R', '\006', 'm', 'e', 't', 'h', 'o', 'd', '\022', '9', '\n', '\007', 'o', 'p', 't', 'i', 'o', 'n', 's',
3090 '\030', '\003', ' ', '\001', '(', '\013', '2', '\037', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.',
3091 'S', 'e', 'r', 'v', 'i', 'c', 'e', 'O', 'p', 't', 'i', 'o', 'n', 's', 'R', '\007', 'o', 'p', 't', 'i', 'o', 'n', 's', '\"', '\211',
3092 '\002', '\n', '\025', 'M', 'e', 't', 'h', 'o', 'd', 'D', 'e', 's', 'c', 'r', 'i', 'p', 't', 'o', 'r', 'P', 'r', 'o', 't', 'o', '\022',
3093 '\022', '\n', '\004', 'n', 'a', 'm', 'e', '\030', '\001', ' ', '\001', '(', '\t', 'R', '\004', 'n', 'a', 'm', 'e', '\022', '\035', '\n', '\n', 'i', 'n',
3094 'p', 'u', 't', '_', 't', 'y', 'p', 'e', '\030', '\002', ' ', '\001', '(', '\t', 'R', '\t', 'i', 'n', 'p', 'u', 't', 'T', 'y', 'p', 'e',
3095 '\022', '\037', '\n', '\013', 'o', 'u', 't', 'p', 'u', 't', '_', 't', 'y', 'p', 'e', '\030', '\003', ' ', '\001', '(', '\t', 'R', '\n', 'o', 'u',
3096 't', 'p', 'u', 't', 'T', 'y', 'p', 'e', '\022', '8', '\n', '\007', 'o', 'p', 't', 'i', 'o', 'n', 's', '\030', '\004', ' ', '\001', '(', '\013',
3097 '2', '\036', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'M', 'e', 't', 'h', 'o', 'd',
3098 'O', 'p', 't', 'i', 'o', 'n', 's', 'R', '\007', 'o', 'p', 't', 'i', 'o', 'n', 's', '\022', '0', '\n', '\020', 'c', 'l', 'i', 'e', 'n',
3099 't', '_', 's', 't', 'r', 'e', 'a', 'm', 'i', 'n', 'g', '\030', '\005', ' ', '\001', '(', '\010', ':', '\005', 'f', 'a', 'l', 's', 'e', 'R',
3100 '\017', 'c', 'l', 'i', 'e', 'n', 't', 'S', 't', 'r', 'e', 'a', 'm', 'i', 'n', 'g', '\022', '0', '\n', '\020', 's', 'e', 'r', 'v', 'e',
3101 'r', '_', 's', 't', 'r', 'e', 'a', 'm', 'i', 'n', 'g', '\030', '\006', ' ', '\001', '(', '\010', ':', '\005', 'f', 'a', 'l', 's', 'e', 'R',
3102 '\017', 's', 'e', 'r', 'v', 'e', 'r', 'S', 't', 'r', 'e', 'a', 'm', 'i', 'n', 'g', '\"', '\221', '\t', '\n', '\013', 'F', 'i', 'l', 'e',
3103 'O', 'p', 't', 'i', 'o', 'n', 's', '\022', '!', '\n', '\014', 'j', 'a', 'v', 'a', '_', 'p', 'a', 'c', 'k', 'a', 'g', 'e', '\030', '\001',
3104 ' ', '\001', '(', '\t', 'R', '\013', 'j', 'a', 'v', 'a', 'P', 'a', 'c', 'k', 'a', 'g', 'e', '\022', '0', '\n', '\024', 'j', 'a', 'v', 'a',
3105 '_', 'o', 'u', 't', 'e', 'r', '_', 'c', 'l', 'a', 's', 's', 'n', 'a', 'm', 'e', '\030', '\010', ' ', '\001', '(', '\t', 'R', '\022', 'j',
3106 'a', 'v', 'a', 'O', 'u', 't', 'e', 'r', 'C', 'l', 'a', 's', 's', 'n', 'a', 'm', 'e', '\022', '5', '\n', '\023', 'j', 'a', 'v', 'a',
3107 '_', 'm', 'u', 'l', 't', 'i', 'p', 'l', 'e', '_', 'f', 'i', 'l', 'e', 's', '\030', '\n', ' ', '\001', '(', '\010', ':', '\005', 'f', 'a',
3108 'l', 's', 'e', 'R', '\021', 'j', 'a', 'v', 'a', 'M', 'u', 'l', 't', 'i', 'p', 'l', 'e', 'F', 'i', 'l', 'e', 's', '\022', 'D', '\n',
3109 '\035', 'j', 'a', 'v', 'a', '_', 'g', 'e', 'n', 'e', 'r', 'a', 't', 'e', '_', 'e', 'q', 'u', 'a', 'l', 's', '_', 'a', 'n', 'd',
3110 '_', 'h', 'a', 's', 'h', '\030', '\024', ' ', '\001', '(', '\010', 'B', '\002', '\030', '\001', 'R', '\031', 'j', 'a', 'v', 'a', 'G', 'e', 'n', 'e',
3111 'r', 'a', 't', 'e', 'E', 'q', 'u', 'a', 'l', 's', 'A', 'n', 'd', 'H', 'a', 's', 'h', '\022', ':', '\n', '\026', 'j', 'a', 'v', 'a',
3112 '_', 's', 't', 'r', 'i', 'n', 'g', '_', 'c', 'h', 'e', 'c', 'k', '_', 'u', 't', 'f', '8', '\030', '\033', ' ', '\001', '(', '\010', ':',
3113 '\005', 'f', 'a', 'l', 's', 'e', 'R', '\023', 'j', 'a', 'v', 'a', 'S', 't', 'r', 'i', 'n', 'g', 'C', 'h', 'e', 'c', 'k', 'U', 't',
3114 'f', '8', '\022', 'S', '\n', '\014', 'o', 'p', 't', 'i', 'm', 'i', 'z', 'e', '_', 'f', 'o', 'r', '\030', '\t', ' ', '\001', '(', '\016', '2',
3115 ')', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'F', 'i', 'l', 'e', 'O', 'p', 't',
3116 'i', 'o', 'n', 's', '.', 'O', 'p', 't', 'i', 'm', 'i', 'z', 'e', 'M', 'o', 'd', 'e', ':', '\005', 'S', 'P', 'E', 'E', 'D', 'R',
3117 '\013', 'o', 'p', 't', 'i', 'm', 'i', 'z', 'e', 'F', 'o', 'r', '\022', '\035', '\n', '\n', 'g', 'o', '_', 'p', 'a', 'c', 'k', 'a', 'g',
3118 'e', '\030', '\013', ' ', '\001', '(', '\t', 'R', '\t', 'g', 'o', 'P', 'a', 'c', 'k', 'a', 'g', 'e', '\022', '5', '\n', '\023', 'c', 'c', '_',
3119 'g', 'e', 'n', 'e', 'r', 'i', 'c', '_', 's', 'e', 'r', 'v', 'i', 'c', 'e', 's', '\030', '\020', ' ', '\001', '(', '\010', ':', '\005', 'f',
3120 'a', 'l', 's', 'e', 'R', '\021', 'c', 'c', 'G', 'e', 'n', 'e', 'r', 'i', 'c', 'S', 'e', 'r', 'v', 'i', 'c', 'e', 's', '\022', '9',
3121 '\n', '\025', 'j', 'a', 'v', 'a', '_', 'g', 'e', 'n', 'e', 'r', 'i', 'c', '_', 's', 'e', 'r', 'v', 'i', 'c', 'e', 's', '\030', '\021',
3122 ' ', '\001', '(', '\010', ':', '\005', 'f', 'a', 'l', 's', 'e', 'R', '\023', 'j', 'a', 'v', 'a', 'G', 'e', 'n', 'e', 'r', 'i', 'c', 'S',
3123 'e', 'r', 'v', 'i', 'c', 'e', 's', '\022', '5', '\n', '\023', 'p', 'y', '_', 'g', 'e', 'n', 'e', 'r', 'i', 'c', '_', 's', 'e', 'r',
3124 'v', 'i', 'c', 'e', 's', '\030', '\022', ' ', '\001', '(', '\010', ':', '\005', 'f', 'a', 'l', 's', 'e', 'R', '\021', 'p', 'y', 'G', 'e', 'n',
3125 'e', 'r', 'i', 'c', 'S', 'e', 'r', 'v', 'i', 'c', 'e', 's', '\022', '7', '\n', '\024', 'p', 'h', 'p', '_', 'g', 'e', 'n', 'e', 'r',
3126 'i', 'c', '_', 's', 'e', 'r', 'v', 'i', 'c', 'e', 's', '\030', '*', ' ', '\001', '(', '\010', ':', '\005', 'f', 'a', 'l', 's', 'e', 'R',
3127 '\022', 'p', 'h', 'p', 'G', 'e', 'n', 'e', 'r', 'i', 'c', 'S', 'e', 'r', 'v', 'i', 'c', 'e', 's', '\022', '%', '\n', '\n', 'd', 'e',
3128 'p', 'r', 'e', 'c', 'a', 't', 'e', 'd', '\030', '\027', ' ', '\001', '(', '\010', ':', '\005', 'f', 'a', 'l', 's', 'e', 'R', '\n', 'd', 'e',
3129 'p', 'r', 'e', 'c', 'a', 't', 'e', 'd', '\022', '.', '\n', '\020', 'c', 'c', '_', 'e', 'n', 'a', 'b', 'l', 'e', '_', 'a', 'r', 'e',
3130 'n', 'a', 's', '\030', '\037', ' ', '\001', '(', '\010', ':', '\004', 't', 'r', 'u', 'e', 'R', '\016', 'c', 'c', 'E', 'n', 'a', 'b', 'l', 'e',
3131 'A', 'r', 'e', 'n', 'a', 's', '\022', '*', '\n', '\021', 'o', 'b', 'j', 'c', '_', 'c', 'l', 'a', 's', 's', '_', 'p', 'r', 'e', 'f',
3132 'i', 'x', '\030', '$', ' ', '\001', '(', '\t', 'R', '\017', 'o', 'b', 'j', 'c', 'C', 'l', 'a', 's', 's', 'P', 'r', 'e', 'f', 'i', 'x',
3133 '\022', ')', '\n', '\020', 'c', 's', 'h', 'a', 'r', 'p', '_', 'n', 'a', 'm', 'e', 's', 'p', 'a', 'c', 'e', '\030', '%', ' ', '\001', '(',
3134 '\t', 'R', '\017', 'c', 's', 'h', 'a', 'r', 'p', 'N', 'a', 'm', 'e', 's', 'p', 'a', 'c', 'e', '\022', '!', '\n', '\014', 's', 'w', 'i',
3135 'f', 't', '_', 'p', 'r', 'e', 'f', 'i', 'x', '\030', '\'', ' ', '\001', '(', '\t', 'R', '\013', 's', 'w', 'i', 'f', 't', 'P', 'r', 'e',
3136 'f', 'i', 'x', '\022', '(', '\n', '\020', 'p', 'h', 'p', '_', 'c', 'l', 'a', 's', 's', '_', 'p', 'r', 'e', 'f', 'i', 'x', '\030', '(',
3137 ' ', '\001', '(', '\t', 'R', '\016', 'p', 'h', 'p', 'C', 'l', 'a', 's', 's', 'P', 'r', 'e', 'f', 'i', 'x', '\022', '#', '\n', '\r', 'p',
3138 'h', 'p', '_', 'n', 'a', 'm', 'e', 's', 'p', 'a', 'c', 'e', '\030', ')', ' ', '\001', '(', '\t', 'R', '\014', 'p', 'h', 'p', 'N', 'a',
3139 'm', 'e', 's', 'p', 'a', 'c', 'e', '\022', '4', '\n', '\026', 'p', 'h', 'p', '_', 'm', 'e', 't', 'a', 'd', 'a', 't', 'a', '_', 'n',
3140 'a', 'm', 'e', 's', 'p', 'a', 'c', 'e', '\030', ',', ' ', '\001', '(', '\t', 'R', '\024', 'p', 'h', 'p', 'M', 'e', 't', 'a', 'd', 'a',
3141 't', 'a', 'N', 'a', 'm', 'e', 's', 'p', 'a', 'c', 'e', '\022', '!', '\n', '\014', 'r', 'u', 'b', 'y', '_', 'p', 'a', 'c', 'k', 'a',
3142 'g', 'e', '\030', '-', ' ', '\001', '(', '\t', 'R', '\013', 'r', 'u', 'b', 'y', 'P', 'a', 'c', 'k', 'a', 'g', 'e', '\022', 'X', '\n', '\024',
3143 'u', 'n', 'i', 'n', 't', 'e', 'r', 'p', 'r', 'e', 't', 'e', 'd', '_', 'o', 'p', 't', 'i', 'o', 'n', '\030', '\347', '\007', ' ', '\003',
3144 '(', '\013', '2', '$', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'U', 'n', 'i', 'n',
3145 't', 'e', 'r', 'p', 'r', 'e', 't', 'e', 'd', 'O', 'p', 't', 'i', 'o', 'n', 'R', '\023', 'u', 'n', 'i', 'n', 't', 'e', 'r', 'p',
3146 'r', 'e', 't', 'e', 'd', 'O', 'p', 't', 'i', 'o', 'n', '\"', ':', '\n', '\014', 'O', 'p', 't', 'i', 'm', 'i', 'z', 'e', 'M', 'o',
3147 'd', 'e', '\022', '\t', '\n', '\005', 'S', 'P', 'E', 'E', 'D', '\020', '\001', '\022', '\r', '\n', '\t', 'C', 'O', 'D', 'E', '_', 'S', 'I', 'Z',
3148 'E', '\020', '\002', '\022', '\020', '\n', '\014', 'L', 'I', 'T', 'E', '_', 'R', 'U', 'N', 'T', 'I', 'M', 'E', '\020', '\003', '*', '\t', '\010', '\350',
3149 '\007', '\020', '\200', '\200', '\200', '\200', '\002', 'J', '\004', '\010', '&', '\020', '\'', '\"', '\321', '\002', '\n', '\016', 'M', 'e', 's', 's', 'a', 'g', 'e',
3150 'O', 'p', 't', 'i', 'o', 'n', 's', '\022', '<', '\n', '\027', 'm', 'e', 's', 's', 'a', 'g', 'e', '_', 's', 'e', 't', '_', 'w', 'i',
3151 'r', 'e', '_', 'f', 'o', 'r', 'm', 'a', 't', '\030', '\001', ' ', '\001', '(', '\010', ':', '\005', 'f', 'a', 'l', 's', 'e', 'R', '\024', 'm',
3152 'e', 's', 's', 'a', 'g', 'e', 'S', 'e', 't', 'W', 'i', 'r', 'e', 'F', 'o', 'r', 'm', 'a', 't', '\022', 'L', '\n', '\037', 'n', 'o',
3153 '_', 's', 't', 'a', 'n', 'd', 'a', 'r', 'd', '_', 'd', 'e', 's', 'c', 'r', 'i', 'p', 't', 'o', 'r', '_', 'a', 'c', 'c', 'e',
3154 's', 's', 'o', 'r', '\030', '\002', ' ', '\001', '(', '\010', ':', '\005', 'f', 'a', 'l', 's', 'e', 'R', '\034', 'n', 'o', 'S', 't', 'a', 'n',
3155 'd', 'a', 'r', 'd', 'D', 'e', 's', 'c', 'r', 'i', 'p', 't', 'o', 'r', 'A', 'c', 'c', 'e', 's', 's', 'o', 'r', '\022', '%', '\n',
3156 '\n', 'd', 'e', 'p', 'r', 'e', 'c', 'a', 't', 'e', 'd', '\030', '\003', ' ', '\001', '(', '\010', ':', '\005', 'f', 'a', 'l', 's', 'e', 'R',
3157 '\n', 'd', 'e', 'p', 'r', 'e', 'c', 'a', 't', 'e', 'd', '\022', '\033', '\n', '\t', 'm', 'a', 'p', '_', 'e', 'n', 't', 'r', 'y', '\030',
3158 '\007', ' ', '\001', '(', '\010', 'R', '\010', 'm', 'a', 'p', 'E', 'n', 't', 'r', 'y', '\022', 'X', '\n', '\024', 'u', 'n', 'i', 'n', 't', 'e',
3159 'r', 'p', 'r', 'e', 't', 'e', 'd', '_', 'o', 'p', 't', 'i', 'o', 'n', '\030', '\347', '\007', ' ', '\003', '(', '\013', '2', '$', '.', 'g',
3160 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'U', 'n', 'i', 'n', 't', 'e', 'r', 'p', 'r', 'e',
3161 't', 'e', 'd', 'O', 'p', 't', 'i', 'o', 'n', 'R', '\023', 'u', 'n', 'i', 'n', 't', 'e', 'r', 'p', 'r', 'e', 't', 'e', 'd', 'O',
3162 'p', 't', 'i', 'o', 'n', '*', '\t', '\010', '\350', '\007', '\020', '\200', '\200', '\200', '\200', '\002', 'J', '\004', '\010', '\010', '\020', '\t', 'J', '\004', '\010',
3163 '\t', '\020', '\n', '\"', '\342', '\003', '\n', '\014', 'F', 'i', 'e', 'l', 'd', 'O', 'p', 't', 'i', 'o', 'n', 's', '\022', 'A', '\n', '\005', 'c',
3164 't', 'y', 'p', 'e', '\030', '\001', ' ', '\001', '(', '\016', '2', '#', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o',
3165 'b', 'u', 'f', '.', 'F', 'i', 'e', 'l', 'd', 'O', 'p', 't', 'i', 'o', 'n', 's', '.', 'C', 'T', 'y', 'p', 'e', ':', '\006', 'S',
3166 'T', 'R', 'I', 'N', 'G', 'R', '\005', 'c', 't', 'y', 'p', 'e', '\022', '\026', '\n', '\006', 'p', 'a', 'c', 'k', 'e', 'd', '\030', '\002', ' ',
3167 '\001', '(', '\010', 'R', '\006', 'p', 'a', 'c', 'k', 'e', 'd', '\022', 'G', '\n', '\006', 'j', 's', 't', 'y', 'p', 'e', '\030', '\006', ' ', '\001',
3168 '(', '\016', '2', '$', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'F', 'i', 'e', 'l',
3169 'd', 'O', 'p', 't', 'i', 'o', 'n', 's', '.', 'J', 'S', 'T', 'y', 'p', 'e', ':', '\t', 'J', 'S', '_', 'N', 'O', 'R', 'M', 'A',
3170 'L', 'R', '\006', 'j', 's', 't', 'y', 'p', 'e', '\022', '\031', '\n', '\004', 'l', 'a', 'z', 'y', '\030', '\005', ' ', '\001', '(', '\010', ':', '\005',
3171 'f', 'a', 'l', 's', 'e', 'R', '\004', 'l', 'a', 'z', 'y', '\022', '%', '\n', '\n', 'd', 'e', 'p', 'r', 'e', 'c', 'a', 't', 'e', 'd',
3172 '\030', '\003', ' ', '\001', '(', '\010', ':', '\005', 'f', 'a', 'l', 's', 'e', 'R', '\n', 'd', 'e', 'p', 'r', 'e', 'c', 'a', 't', 'e', 'd',
3173 '\022', '\031', '\n', '\004', 'w', 'e', 'a', 'k', '\030', '\n', ' ', '\001', '(', '\010', ':', '\005', 'f', 'a', 'l', 's', 'e', 'R', '\004', 'w', 'e',
3174 'a', 'k', '\022', 'X', '\n', '\024', 'u', 'n', 'i', 'n', 't', 'e', 'r', 'p', 'r', 'e', 't', 'e', 'd', '_', 'o', 'p', 't', 'i', 'o',
3175 'n', '\030', '\347', '\007', ' ', '\003', '(', '\013', '2', '$', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u',
3176 'f', '.', 'U', 'n', 'i', 'n', 't', 'e', 'r', 'p', 'r', 'e', 't', 'e', 'd', 'O', 'p', 't', 'i', 'o', 'n', 'R', '\023', 'u', 'n',
3177 'i', 'n', 't', 'e', 'r', 'p', 'r', 'e', 't', 'e', 'd', 'O', 'p', 't', 'i', 'o', 'n', '\"', '/', '\n', '\005', 'C', 'T', 'y', 'p',
3178 'e', '\022', '\n', '\n', '\006', 'S', 'T', 'R', 'I', 'N', 'G', '\020', '\000', '\022', '\010', '\n', '\004', 'C', 'O', 'R', 'D', '\020', '\001', '\022', '\020',
3179 '\n', '\014', 'S', 'T', 'R', 'I', 'N', 'G', '_', 'P', 'I', 'E', 'C', 'E', '\020', '\002', '\"', '5', '\n', '\006', 'J', 'S', 'T', 'y', 'p',
3180 'e', '\022', '\r', '\n', '\t', 'J', 'S', '_', 'N', 'O', 'R', 'M', 'A', 'L', '\020', '\000', '\022', '\r', '\n', '\t', 'J', 'S', '_', 'S', 'T',
3181 'R', 'I', 'N', 'G', '\020', '\001', '\022', '\r', '\n', '\t', 'J', 'S', '_', 'N', 'U', 'M', 'B', 'E', 'R', '\020', '\002', '*', '\t', '\010', '\350',
3182 '\007', '\020', '\200', '\200', '\200', '\200', '\002', 'J', '\004', '\010', '\004', '\020', '\005', '\"', 's', '\n', '\014', 'O', 'n', 'e', 'o', 'f', 'O', 'p', 't',
3183 'i', 'o', 'n', 's', '\022', 'X', '\n', '\024', 'u', 'n', 'i', 'n', 't', 'e', 'r', 'p', 'r', 'e', 't', 'e', 'd', '_', 'o', 'p', 't',
3184 'i', 'o', 'n', '\030', '\347', '\007', ' ', '\003', '(', '\013', '2', '$', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o',
3185 'b', 'u', 'f', '.', 'U', 'n', 'i', 'n', 't', 'e', 'r', 'p', 'r', 'e', 't', 'e', 'd', 'O', 'p', 't', 'i', 'o', 'n', 'R', '\023',
3186 'u', 'n', 'i', 'n', 't', 'e', 'r', 'p', 'r', 'e', 't', 'e', 'd', 'O', 'p', 't', 'i', 'o', 'n', '*', '\t', '\010', '\350', '\007', '\020',
3187 '\200', '\200', '\200', '\200', '\002', '\"', '\300', '\001', '\n', '\013', 'E', 'n', 'u', 'm', 'O', 'p', 't', 'i', 'o', 'n', 's', '\022', '\037', '\n', '\013',
3188 'a', 'l', 'l', 'o', 'w', '_', 'a', 'l', 'i', 'a', 's', '\030', '\002', ' ', '\001', '(', '\010', 'R', '\n', 'a', 'l', 'l', 'o', 'w', 'A',
3189 'l', 'i', 'a', 's', '\022', '%', '\n', '\n', 'd', 'e', 'p', 'r', 'e', 'c', 'a', 't', 'e', 'd', '\030', '\003', ' ', '\001', '(', '\010', ':',
3190 '\005', 'f', 'a', 'l', 's', 'e', 'R', '\n', 'd', 'e', 'p', 'r', 'e', 'c', 'a', 't', 'e', 'd', '\022', 'X', '\n', '\024', 'u', 'n', 'i',
3191 'n', 't', 'e', 'r', 'p', 'r', 'e', 't', 'e', 'd', '_', 'o', 'p', 't', 'i', 'o', 'n', '\030', '\347', '\007', ' ', '\003', '(', '\013', '2',
3192 '$', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'U', 'n', 'i', 'n', 't', 'e', 'r',
3193 'p', 'r', 'e', 't', 'e', 'd', 'O', 'p', 't', 'i', 'o', 'n', 'R', '\023', 'u', 'n', 'i', 'n', 't', 'e', 'r', 'p', 'r', 'e', 't',
3194 'e', 'd', 'O', 'p', 't', 'i', 'o', 'n', '*', '\t', '\010', '\350', '\007', '\020', '\200', '\200', '\200', '\200', '\002', 'J', '\004', '\010', '\005', '\020', '\006',
3195 '\"', '\236', '\001', '\n', '\020', 'E', 'n', 'u', 'm', 'V', 'a', 'l', 'u', 'e', 'O', 'p', 't', 'i', 'o', 'n', 's', '\022', '%', '\n', '\n',
3196 'd', 'e', 'p', 'r', 'e', 'c', 'a', 't', 'e', 'd', '\030', '\001', ' ', '\001', '(', '\010', ':', '\005', 'f', 'a', 'l', 's', 'e', 'R', '\n',
3197 'd', 'e', 'p', 'r', 'e', 'c', 'a', 't', 'e', 'd', '\022', 'X', '\n', '\024', 'u', 'n', 'i', 'n', 't', 'e', 'r', 'p', 'r', 'e', 't',
3198 'e', 'd', '_', 'o', 'p', 't', 'i', 'o', 'n', '\030', '\347', '\007', ' ', '\003', '(', '\013', '2', '$', '.', 'g', 'o', 'o', 'g', 'l', 'e',
3199 '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'U', 'n', 'i', 'n', 't', 'e', 'r', 'p', 'r', 'e', 't', 'e', 'd', 'O', 'p',
3200 't', 'i', 'o', 'n', 'R', '\023', 'u', 'n', 'i', 'n', 't', 'e', 'r', 'p', 'r', 'e', 't', 'e', 'd', 'O', 'p', 't', 'i', 'o', 'n',
3201 '*', '\t', '\010', '\350', '\007', '\020', '\200', '\200', '\200', '\200', '\002', '\"', '\234', '\001', '\n', '\016', 'S', 'e', 'r', 'v', 'i', 'c', 'e', 'O', 'p',
3202 't', 'i', 'o', 'n', 's', '\022', '%', '\n', '\n', 'd', 'e', 'p', 'r', 'e', 'c', 'a', 't', 'e', 'd', '\030', '!', ' ', '\001', '(', '\010',
3203 ':', '\005', 'f', 'a', 'l', 's', 'e', 'R', '\n', 'd', 'e', 'p', 'r', 'e', 'c', 'a', 't', 'e', 'd', '\022', 'X', '\n', '\024', 'u', 'n',
3204 'i', 'n', 't', 'e', 'r', 'p', 'r', 'e', 't', 'e', 'd', '_', 'o', 'p', 't', 'i', 'o', 'n', '\030', '\347', '\007', ' ', '\003', '(', '\013',
3205 '2', '$', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'U', 'n', 'i', 'n', 't', 'e',
3206 'r', 'p', 'r', 'e', 't', 'e', 'd', 'O', 'p', 't', 'i', 'o', 'n', 'R', '\023', 'u', 'n', 'i', 'n', 't', 'e', 'r', 'p', 'r', 'e',
3207 't', 'e', 'd', 'O', 'p', 't', 'i', 'o', 'n', '*', '\t', '\010', '\350', '\007', '\020', '\200', '\200', '\200', '\200', '\002', '\"', '\340', '\002', '\n', '\r',
3208 'M', 'e', 't', 'h', 'o', 'd', 'O', 'p', 't', 'i', 'o', 'n', 's', '\022', '%', '\n', '\n', 'd', 'e', 'p', 'r', 'e', 'c', 'a', 't',
3209 'e', 'd', '\030', '!', ' ', '\001', '(', '\010', ':', '\005', 'f', 'a', 'l', 's', 'e', 'R', '\n', 'd', 'e', 'p', 'r', 'e', 'c', 'a', 't',
3210 'e', 'd', '\022', 'q', '\n', '\021', 'i', 'd', 'e', 'm', 'p', 'o', 't', 'e', 'n', 'c', 'y', '_', 'l', 'e', 'v', 'e', 'l', '\030', '\"',
3211 ' ', '\001', '(', '\016', '2', '/', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'M', 'e',
3212 't', 'h', 'o', 'd', 'O', 'p', 't', 'i', 'o', 'n', 's', '.', 'I', 'd', 'e', 'm', 'p', 'o', 't', 'e', 'n', 'c', 'y', 'L', 'e',
3213 'v', 'e', 'l', ':', '\023', 'I', 'D', 'E', 'M', 'P', 'O', 'T', 'E', 'N', 'C', 'Y', '_', 'U', 'N', 'K', 'N', 'O', 'W', 'N', 'R',
3214 '\020', 'i', 'd', 'e', 'm', 'p', 'o', 't', 'e', 'n', 'c', 'y', 'L', 'e', 'v', 'e', 'l', '\022', 'X', '\n', '\024', 'u', 'n', 'i', 'n',
3215 't', 'e', 'r', 'p', 'r', 'e', 't', 'e', 'd', '_', 'o', 'p', 't', 'i', 'o', 'n', '\030', '\347', '\007', ' ', '\003', '(', '\013', '2', '$',
3216 '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'U', 'n', 'i', 'n', 't', 'e', 'r', 'p',
3217 'r', 'e', 't', 'e', 'd', 'O', 'p', 't', 'i', 'o', 'n', 'R', '\023', 'u', 'n', 'i', 'n', 't', 'e', 'r', 'p', 'r', 'e', 't', 'e',
3218 'd', 'O', 'p', 't', 'i', 'o', 'n', '\"', 'P', '\n', '\020', 'I', 'd', 'e', 'm', 'p', 'o', 't', 'e', 'n', 'c', 'y', 'L', 'e', 'v',
3219 'e', 'l', '\022', '\027', '\n', '\023', 'I', 'D', 'E', 'M', 'P', 'O', 'T', 'E', 'N', 'C', 'Y', '_', 'U', 'N', 'K', 'N', 'O', 'W', 'N',
3220 '\020', '\000', '\022', '\023', '\n', '\017', 'N', 'O', '_', 'S', 'I', 'D', 'E', '_', 'E', 'F', 'F', 'E', 'C', 'T', 'S', '\020', '\001', '\022', '\016',
3221 '\n', '\n', 'I', 'D', 'E', 'M', 'P', 'O', 'T', 'E', 'N', 'T', '\020', '\002', '*', '\t', '\010', '\350', '\007', '\020', '\200', '\200', '\200', '\200', '\002',
3222 '\"', '\232', '\003', '\n', '\023', 'U', 'n', 'i', 'n', 't', 'e', 'r', 'p', 'r', 'e', 't', 'e', 'd', 'O', 'p', 't', 'i', 'o', 'n', '\022',
3223 'A', '\n', '\004', 'n', 'a', 'm', 'e', '\030', '\002', ' ', '\003', '(', '\013', '2', '-', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r',
3224 'o', 't', 'o', 'b', 'u', 'f', '.', 'U', 'n', 'i', 'n', 't', 'e', 'r', 'p', 'r', 'e', 't', 'e', 'd', 'O', 'p', 't', 'i', 'o',
3225 'n', '.', 'N', 'a', 'm', 'e', 'P', 'a', 'r', 't', 'R', '\004', 'n', 'a', 'm', 'e', '\022', ')', '\n', '\020', 'i', 'd', 'e', 'n', 't',
3226 'i', 'f', 'i', 'e', 'r', '_', 'v', 'a', 'l', 'u', 'e', '\030', '\003', ' ', '\001', '(', '\t', 'R', '\017', 'i', 'd', 'e', 'n', 't', 'i',
3227 'f', 'i', 'e', 'r', 'V', 'a', 'l', 'u', 'e', '\022', ',', '\n', '\022', 'p', 'o', 's', 'i', 't', 'i', 'v', 'e', '_', 'i', 'n', 't',
3228 '_', 'v', 'a', 'l', 'u', 'e', '\030', '\004', ' ', '\001', '(', '\004', 'R', '\020', 'p', 'o', 's', 'i', 't', 'i', 'v', 'e', 'I', 'n', 't',
3229 'V', 'a', 'l', 'u', 'e', '\022', ',', '\n', '\022', 'n', 'e', 'g', 'a', 't', 'i', 'v', 'e', '_', 'i', 'n', 't', '_', 'v', 'a', 'l',
3230 'u', 'e', '\030', '\005', ' ', '\001', '(', '\003', 'R', '\020', 'n', 'e', 'g', 'a', 't', 'i', 'v', 'e', 'I', 'n', 't', 'V', 'a', 'l', 'u',
3231 'e', '\022', '!', '\n', '\014', 'd', 'o', 'u', 'b', 'l', 'e', '_', 'v', 'a', 'l', 'u', 'e', '\030', '\006', ' ', '\001', '(', '\001', 'R', '\013',
3232 'd', 'o', 'u', 'b', 'l', 'e', 'V', 'a', 'l', 'u', 'e', '\022', '!', '\n', '\014', 's', 't', 'r', 'i', 'n', 'g', '_', 'v', 'a', 'l',
3233 'u', 'e', '\030', '\007', ' ', '\001', '(', '\014', 'R', '\013', 's', 't', 'r', 'i', 'n', 'g', 'V', 'a', 'l', 'u', 'e', '\022', '\'', '\n', '\017',
3234 'a', 'g', 'g', 'r', 'e', 'g', 'a', 't', 'e', '_', 'v', 'a', 'l', 'u', 'e', '\030', '\010', ' ', '\001', '(', '\t', 'R', '\016', 'a', 'g',
3235 'g', 'r', 'e', 'g', 'a', 't', 'e', 'V', 'a', 'l', 'u', 'e', '\032', 'J', '\n', '\010', 'N', 'a', 'm', 'e', 'P', 'a', 'r', 't', '\022',
3236 '\033', '\n', '\t', 'n', 'a', 'm', 'e', '_', 'p', 'a', 'r', 't', '\030', '\001', ' ', '\002', '(', '\t', 'R', '\010', 'n', 'a', 'm', 'e', 'P',
3237 'a', 'r', 't', '\022', '!', '\n', '\014', 'i', 's', '_', 'e', 'x', 't', 'e', 'n', 's', 'i', 'o', 'n', '\030', '\002', ' ', '\002', '(', '\010',
3238 'R', '\013', 'i', 's', 'E', 'x', 't', 'e', 'n', 's', 'i', 'o', 'n', '\"', '\247', '\002', '\n', '\016', 'S', 'o', 'u', 'r', 'c', 'e', 'C',
3239 'o', 'd', 'e', 'I', 'n', 'f', 'o', '\022', 'D', '\n', '\010', 'l', 'o', 'c', 'a', 't', 'i', 'o', 'n', '\030', '\001', ' ', '\003', '(', '\013',
3240 '2', '(', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'S', 'o', 'u', 'r', 'c', 'e',
3241 'C', 'o', 'd', 'e', 'I', 'n', 'f', 'o', '.', 'L', 'o', 'c', 'a', 't', 'i', 'o', 'n', 'R', '\010', 'l', 'o', 'c', 'a', 't', 'i',
3242 'o', 'n', '\032', '\316', '\001', '\n', '\010', 'L', 'o', 'c', 'a', 't', 'i', 'o', 'n', '\022', '\026', '\n', '\004', 'p', 'a', 't', 'h', '\030', '\001',
3243 ' ', '\003', '(', '\005', 'B', '\002', '\020', '\001', 'R', '\004', 'p', 'a', 't', 'h', '\022', '\026', '\n', '\004', 's', 'p', 'a', 'n', '\030', '\002', ' ',
3244 '\003', '(', '\005', 'B', '\002', '\020', '\001', 'R', '\004', 's', 'p', 'a', 'n', '\022', ')', '\n', '\020', 'l', 'e', 'a', 'd', 'i', 'n', 'g', '_',
3245 'c', 'o', 'm', 'm', 'e', 'n', 't', 's', '\030', '\003', ' ', '\001', '(', '\t', 'R', '\017', 'l', 'e', 'a', 'd', 'i', 'n', 'g', 'C', 'o',
3246 'm', 'm', 'e', 'n', 't', 's', '\022', '+', '\n', '\021', 't', 'r', 'a', 'i', 'l', 'i', 'n', 'g', '_', 'c', 'o', 'm', 'm', 'e', 'n',
3247 't', 's', '\030', '\004', ' ', '\001', '(', '\t', 'R', '\020', 't', 'r', 'a', 'i', 'l', 'i', 'n', 'g', 'C', 'o', 'm', 'm', 'e', 'n', 't',
3248 's', '\022', ':', '\n', '\031', 'l', 'e', 'a', 'd', 'i', 'n', 'g', '_', 'd', 'e', 't', 'a', 'c', 'h', 'e', 'd', '_', 'c', 'o', 'm',
3249 'm', 'e', 'n', 't', 's', '\030', '\006', ' ', '\003', '(', '\t', 'R', '\027', 'l', 'e', 'a', 'd', 'i', 'n', 'g', 'D', 'e', 't', 'a', 'c',
3250 'h', 'e', 'd', 'C', 'o', 'm', 'm', 'e', 'n', 't', 's', '\"', '\321', '\001', '\n', '\021', 'G', 'e', 'n', 'e', 'r', 'a', 't', 'e', 'd',
3251 'C', 'o', 'd', 'e', 'I', 'n', 'f', 'o', '\022', 'M', '\n', '\n', 'a', 'n', 'n', 'o', 't', 'a', 't', 'i', 'o', 'n', '\030', '\001', ' ',
3252 '\003', '(', '\013', '2', '-', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'G', 'e', 'n',
3253 'e', 'r', 'a', 't', 'e', 'd', 'C', 'o', 'd', 'e', 'I', 'n', 'f', 'o', '.', 'A', 'n', 'n', 'o', 't', 'a', 't', 'i', 'o', 'n',
3254 'R', '\n', 'a', 'n', 'n', 'o', 't', 'a', 't', 'i', 'o', 'n', '\032', 'm', '\n', '\n', 'A', 'n', 'n', 'o', 't', 'a', 't', 'i', 'o',
3255 'n', '\022', '\026', '\n', '\004', 'p', 'a', 't', 'h', '\030', '\001', ' ', '\003', '(', '\005', 'B', '\002', '\020', '\001', 'R', '\004', 'p', 'a', 't', 'h',
3256 '\022', '\037', '\n', '\013', 's', 'o', 'u', 'r', 'c', 'e', '_', 'f', 'i', 'l', 'e', '\030', '\002', ' ', '\001', '(', '\t', 'R', '\n', 's', 'o',
3257 'u', 'r', 'c', 'e', 'F', 'i', 'l', 'e', '\022', '\024', '\n', '\005', 'b', 'e', 'g', 'i', 'n', '\030', '\003', ' ', '\001', '(', '\005', 'R', '\005',
3258 'b', 'e', 'g', 'i', 'n', '\022', '\020', '\n', '\003', 'e', 'n', 'd', '\030', '\004', ' ', '\001', '(', '\005', 'R', '\003', 'e', 'n', 'd', 'B', '~',
3259 '\n', '\023', 'c', 'o', 'm', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', 'B', '\020', 'D', 'e',
3260 's', 'c', 'r', 'i', 'p', 't', 'o', 'r', 'P', 'r', 'o', 't', 'o', 's', 'H', '\001', 'Z', '-', 'g', 'o', 'o', 'g', 'l', 'e', '.',
3261 'g', 'o', 'l', 'a', 'n', 'g', '.', 'o', 'r', 'g', '/', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '/', 't', 'y', 'p', 'e', 's',
3262 '/', 'd', 'e', 's', 'c', 'r', 'i', 'p', 't', 'o', 'r', 'p', 'b', '\370', '\001', '\001', '\242', '\002', '\003', 'G', 'P', 'B', '\252', '\002', '\032',
3263 'G', 'o', 'o', 'g', 'l', 'e', '.', 'P', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'R', 'e', 'f', 'l', 'e', 'c', 't', 'i', 'o',
3264 'n',
3265 };
3266
3267 static upb_def_init *deps[1] = {
3268 NULL
3269 };
3270
3271 upb_def_init google_protobuf_descriptor_proto_upbdefinit = {
3272 deps,
3273 layouts,
3274 "google/protobuf/descriptor.proto",
3275 UPB_STRVIEW_INIT(descriptor, 7601)
3276 };
3277
3278
3279 #include <ctype.h>
3280 #include <errno.h>
3281 #include <setjmp.h>
3282 #include <stdlib.h>
3283 #include <string.h>
3284
3285
3286 typedef struct {
3287 size_t len;
3288 char str[1]; /* Null-terminated string data follows. */
3289 } str_t;
3290
3291 struct upb_fielddef {
3292 const upb_filedef *file;
3293 const upb_msgdef *msgdef;
3294 const char *full_name;
3295 const char *json_name;
3296 union {
3297 int64_t sint;
3298 uint64_t uint;
3299 double dbl;
3300 float flt;
3301 bool boolean;
3302 str_t *str;
3303 } defaultval;
3304 const upb_oneofdef *oneof;
3305 union {
3306 const upb_msgdef *msgdef;
3307 const upb_enumdef *enumdef;
3308 const google_protobuf_FieldDescriptorProto *unresolved;
3309 } sub;
3310 uint32_t number_;
3311 uint16_t index_;
3312 uint16_t layout_index;
3313 uint32_t selector_base; /* Used to index into a upb::Handlers table. */
3314 bool is_extension_;
3315 bool lazy_;
3316 bool packed_;
3317 bool proto3_optional_;
3318 upb_descriptortype_t type_;
3319 upb_label_t label_;
3320 };
3321
3322 struct upb_msgdef {
3323 const upb_msglayout *layout;
3324 const upb_filedef *file;
3325 const char *full_name;
3326 uint32_t selector_count;
3327 uint32_t submsg_field_count;
3328
3329 /* Tables for looking up fields by number and name. */
3330 upb_inttable itof;
3331 upb_strtable ntof;
3332
3333 const upb_fielddef *fields;
3334 const upb_oneofdef *oneofs;
3335 int field_count;
3336 int oneof_count;
3337 int real_oneof_count;
3338
3339 /* Is this a map-entry message? */
3340 bool map_entry;
3341 upb_wellknowntype_t well_known_type;
3342
3343 /* TODO(haberman): proper extension ranges (there can be multiple). */
3344 };
3345
3346 struct upb_enumdef {
3347 const upb_filedef *file;
3348 const char *full_name;
3349 upb_strtable ntoi;
3350 upb_inttable iton;
3351 int32_t defaultval;
3352 };
3353
3354 struct upb_oneofdef {
3355 const upb_msgdef *parent;
3356 const char *full_name;
3357 int field_count;
3358 bool synthetic;
3359 const upb_fielddef **fields;
3360 upb_strtable ntof;
3361 upb_inttable itof;
3362 };
3363
3364 struct upb_filedef {
3365 const char *name;
3366 const char *package;
3367 const char *phpprefix;
3368 const char *phpnamespace;
3369 upb_syntax_t syntax;
3370
3371 const upb_filedef **deps;
3372 const upb_msgdef *msgs;
3373 const upb_enumdef *enums;
3374 const upb_fielddef *exts;
3375
3376 int dep_count;
3377 int msg_count;
3378 int enum_count;
3379 int ext_count;
3380 };
3381
3382 struct upb_symtab {
3383 upb_arena *arena;
3384 upb_strtable syms; /* full_name -> packed def ptr */
3385 upb_strtable files; /* file_name -> upb_filedef* */
3386 size_t bytes_loaded;
3387 };
3388
3389 /* Inside a symtab we store tagged pointers to specific def types. */
3390 typedef enum {
3391 UPB_DEFTYPE_FIELD = 0,
3392
3393 /* Only inside symtab table. */
3394 UPB_DEFTYPE_MSG = 1,
3395 UPB_DEFTYPE_ENUM = 2,
3396
3397 /* Only inside message table. */
3398 UPB_DEFTYPE_ONEOF = 1,
3399 UPB_DEFTYPE_FIELD_JSONNAME = 2
3400 } upb_deftype_t;
3401
unpack_def(upb_value v,upb_deftype_t type)3402 static const void *unpack_def(upb_value v, upb_deftype_t type) {
3403 uintptr_t num = (uintptr_t)upb_value_getconstptr(v);
3404 return (num & 3) == type ? (const void*)(num & ~3) : NULL;
3405 }
3406
pack_def(const void * ptr,upb_deftype_t type)3407 static upb_value pack_def(const void *ptr, upb_deftype_t type) {
3408 uintptr_t num = (uintptr_t)ptr | type;
3409 return upb_value_constptr((const void*)num);
3410 }
3411
3412 /* isalpha() etc. from <ctype.h> are locale-dependent, which we don't want. */
upb_isbetween(char c,char low,char high)3413 static bool upb_isbetween(char c, char low, char high) {
3414 return c >= low && c <= high;
3415 }
3416
upb_isletter(char c)3417 static bool upb_isletter(char c) {
3418 return upb_isbetween(c, 'A', 'Z') || upb_isbetween(c, 'a', 'z') || c == '_';
3419 }
3420
upb_isalphanum(char c)3421 static bool upb_isalphanum(char c) {
3422 return upb_isletter(c) || upb_isbetween(c, '0', '9');
3423 }
3424
shortdefname(const char * fullname)3425 static const char *shortdefname(const char *fullname) {
3426 const char *p;
3427
3428 if (fullname == NULL) {
3429 return NULL;
3430 } else if ((p = strrchr(fullname, '.')) == NULL) {
3431 /* No '.' in the name, return the full string. */
3432 return fullname;
3433 } else {
3434 /* Return one past the last '.'. */
3435 return p + 1;
3436 }
3437 }
3438
3439 /* All submessage fields are lower than all other fields.
3440 * Secondly, fields are increasing in order. */
field_rank(const upb_fielddef * f)3441 uint32_t field_rank(const upb_fielddef *f) {
3442 uint32_t ret = upb_fielddef_number(f);
3443 const uint32_t high_bit = 1 << 30;
3444 UPB_ASSERT(ret < high_bit);
3445 if (!upb_fielddef_issubmsg(f))
3446 ret |= high_bit;
3447 return ret;
3448 }
3449
cmp_fields(const void * p1,const void * p2)3450 int cmp_fields(const void *p1, const void *p2) {
3451 const upb_fielddef *f1 = *(upb_fielddef*const*)p1;
3452 const upb_fielddef *f2 = *(upb_fielddef*const*)p2;
3453 return field_rank(f1) - field_rank(f2);
3454 }
3455
3456 /* A few implementation details of handlers. We put these here to avoid
3457 * a def -> handlers dependency. */
3458
3459 #define UPB_STATIC_SELECTOR_COUNT 3 /* Warning: also in upb/handlers.h. */
3460
upb_handlers_selectorbaseoffset(const upb_fielddef * f)3461 static uint32_t upb_handlers_selectorbaseoffset(const upb_fielddef *f) {
3462 return upb_fielddef_isseq(f) ? 2 : 0;
3463 }
3464
upb_handlers_selectorcount(const upb_fielddef * f)3465 static uint32_t upb_handlers_selectorcount(const upb_fielddef *f) {
3466 uint32_t ret = 1;
3467 if (upb_fielddef_isseq(f)) ret += 2; /* STARTSEQ/ENDSEQ */
3468 if (upb_fielddef_isstring(f)) ret += 2; /* [STRING]/STARTSTR/ENDSTR */
3469 if (upb_fielddef_issubmsg(f)) {
3470 /* ENDSUBMSG (STARTSUBMSG is at table beginning) */
3471 ret += 0;
3472 if (upb_fielddef_lazy(f)) {
3473 /* STARTSTR/ENDSTR/STRING (for lazy) */
3474 ret += 3;
3475 }
3476 }
3477 return ret;
3478 }
3479
upb_status_setoom(upb_status * status)3480 static void upb_status_setoom(upb_status *status) {
3481 upb_status_seterrmsg(status, "out of memory");
3482 }
3483
assign_msg_wellknowntype(upb_msgdef * m)3484 static void assign_msg_wellknowntype(upb_msgdef *m) {
3485 const char *name = upb_msgdef_fullname(m);
3486 if (name == NULL) {
3487 m->well_known_type = UPB_WELLKNOWN_UNSPECIFIED;
3488 return;
3489 }
3490 if (!strcmp(name, "google.protobuf.Any")) {
3491 m->well_known_type = UPB_WELLKNOWN_ANY;
3492 } else if (!strcmp(name, "google.protobuf.FieldMask")) {
3493 m->well_known_type = UPB_WELLKNOWN_FIELDMASK;
3494 } else if (!strcmp(name, "google.protobuf.Duration")) {
3495 m->well_known_type = UPB_WELLKNOWN_DURATION;
3496 } else if (!strcmp(name, "google.protobuf.Timestamp")) {
3497 m->well_known_type = UPB_WELLKNOWN_TIMESTAMP;
3498 } else if (!strcmp(name, "google.protobuf.DoubleValue")) {
3499 m->well_known_type = UPB_WELLKNOWN_DOUBLEVALUE;
3500 } else if (!strcmp(name, "google.protobuf.FloatValue")) {
3501 m->well_known_type = UPB_WELLKNOWN_FLOATVALUE;
3502 } else if (!strcmp(name, "google.protobuf.Int64Value")) {
3503 m->well_known_type = UPB_WELLKNOWN_INT64VALUE;
3504 } else if (!strcmp(name, "google.protobuf.UInt64Value")) {
3505 m->well_known_type = UPB_WELLKNOWN_UINT64VALUE;
3506 } else if (!strcmp(name, "google.protobuf.Int32Value")) {
3507 m->well_known_type = UPB_WELLKNOWN_INT32VALUE;
3508 } else if (!strcmp(name, "google.protobuf.UInt32Value")) {
3509 m->well_known_type = UPB_WELLKNOWN_UINT32VALUE;
3510 } else if (!strcmp(name, "google.protobuf.BoolValue")) {
3511 m->well_known_type = UPB_WELLKNOWN_BOOLVALUE;
3512 } else if (!strcmp(name, "google.protobuf.StringValue")) {
3513 m->well_known_type = UPB_WELLKNOWN_STRINGVALUE;
3514 } else if (!strcmp(name, "google.protobuf.BytesValue")) {
3515 m->well_known_type = UPB_WELLKNOWN_BYTESVALUE;
3516 } else if (!strcmp(name, "google.protobuf.Value")) {
3517 m->well_known_type = UPB_WELLKNOWN_VALUE;
3518 } else if (!strcmp(name, "google.protobuf.ListValue")) {
3519 m->well_known_type = UPB_WELLKNOWN_LISTVALUE;
3520 } else if (!strcmp(name, "google.protobuf.Struct")) {
3521 m->well_known_type = UPB_WELLKNOWN_STRUCT;
3522 } else {
3523 m->well_known_type = UPB_WELLKNOWN_UNSPECIFIED;
3524 }
3525 }
3526
3527
3528 /* upb_enumdef ****************************************************************/
3529
upb_enumdef_fullname(const upb_enumdef * e)3530 const char *upb_enumdef_fullname(const upb_enumdef *e) {
3531 return e->full_name;
3532 }
3533
upb_enumdef_name(const upb_enumdef * e)3534 const char *upb_enumdef_name(const upb_enumdef *e) {
3535 return shortdefname(e->full_name);
3536 }
3537
upb_enumdef_file(const upb_enumdef * e)3538 const upb_filedef *upb_enumdef_file(const upb_enumdef *e) {
3539 return e->file;
3540 }
3541
upb_enumdef_default(const upb_enumdef * e)3542 int32_t upb_enumdef_default(const upb_enumdef *e) {
3543 UPB_ASSERT(upb_enumdef_iton(e, e->defaultval));
3544 return e->defaultval;
3545 }
3546
upb_enumdef_numvals(const upb_enumdef * e)3547 int upb_enumdef_numvals(const upb_enumdef *e) {
3548 return (int)upb_strtable_count(&e->ntoi);
3549 }
3550
upb_enum_begin(upb_enum_iter * i,const upb_enumdef * e)3551 void upb_enum_begin(upb_enum_iter *i, const upb_enumdef *e) {
3552 /* We iterate over the ntoi table, to account for duplicate numbers. */
3553 upb_strtable_begin(i, &e->ntoi);
3554 }
3555
upb_enum_next(upb_enum_iter * iter)3556 void upb_enum_next(upb_enum_iter *iter) { upb_strtable_next(iter); }
upb_enum_done(upb_enum_iter * iter)3557 bool upb_enum_done(upb_enum_iter *iter) { return upb_strtable_done(iter); }
3558
upb_enumdef_ntoi(const upb_enumdef * def,const char * name,size_t len,int32_t * num)3559 bool upb_enumdef_ntoi(const upb_enumdef *def, const char *name,
3560 size_t len, int32_t *num) {
3561 upb_value v;
3562 if (!upb_strtable_lookup2(&def->ntoi, name, len, &v)) {
3563 return false;
3564 }
3565 if (num) *num = upb_value_getint32(v);
3566 return true;
3567 }
3568
upb_enumdef_iton(const upb_enumdef * def,int32_t num)3569 const char *upb_enumdef_iton(const upb_enumdef *def, int32_t num) {
3570 upb_value v;
3571 return upb_inttable_lookup32(&def->iton, num, &v) ?
3572 upb_value_getcstr(v) : NULL;
3573 }
3574
upb_enum_iter_name(upb_enum_iter * iter)3575 const char *upb_enum_iter_name(upb_enum_iter *iter) {
3576 return upb_strtable_iter_key(iter).data;
3577 }
3578
upb_enum_iter_number(upb_enum_iter * iter)3579 int32_t upb_enum_iter_number(upb_enum_iter *iter) {
3580 return upb_value_getint32(upb_strtable_iter_value(iter));
3581 }
3582
3583
3584 /* upb_fielddef ***************************************************************/
3585
upb_fielddef_fullname(const upb_fielddef * f)3586 const char *upb_fielddef_fullname(const upb_fielddef *f) {
3587 return f->full_name;
3588 }
3589
upb_fielddef_type(const upb_fielddef * f)3590 upb_fieldtype_t upb_fielddef_type(const upb_fielddef *f) {
3591 switch (f->type_) {
3592 case UPB_DESCRIPTOR_TYPE_DOUBLE:
3593 return UPB_TYPE_DOUBLE;
3594 case UPB_DESCRIPTOR_TYPE_FLOAT:
3595 return UPB_TYPE_FLOAT;
3596 case UPB_DESCRIPTOR_TYPE_INT64:
3597 case UPB_DESCRIPTOR_TYPE_SINT64:
3598 case UPB_DESCRIPTOR_TYPE_SFIXED64:
3599 return UPB_TYPE_INT64;
3600 case UPB_DESCRIPTOR_TYPE_INT32:
3601 case UPB_DESCRIPTOR_TYPE_SFIXED32:
3602 case UPB_DESCRIPTOR_TYPE_SINT32:
3603 return UPB_TYPE_INT32;
3604 case UPB_DESCRIPTOR_TYPE_UINT64:
3605 case UPB_DESCRIPTOR_TYPE_FIXED64:
3606 return UPB_TYPE_UINT64;
3607 case UPB_DESCRIPTOR_TYPE_UINT32:
3608 case UPB_DESCRIPTOR_TYPE_FIXED32:
3609 return UPB_TYPE_UINT32;
3610 case UPB_DESCRIPTOR_TYPE_ENUM:
3611 return UPB_TYPE_ENUM;
3612 case UPB_DESCRIPTOR_TYPE_BOOL:
3613 return UPB_TYPE_BOOL;
3614 case UPB_DESCRIPTOR_TYPE_STRING:
3615 return UPB_TYPE_STRING;
3616 case UPB_DESCRIPTOR_TYPE_BYTES:
3617 return UPB_TYPE_BYTES;
3618 case UPB_DESCRIPTOR_TYPE_GROUP:
3619 case UPB_DESCRIPTOR_TYPE_MESSAGE:
3620 return UPB_TYPE_MESSAGE;
3621 }
3622 UPB_UNREACHABLE();
3623 }
3624
upb_fielddef_descriptortype(const upb_fielddef * f)3625 upb_descriptortype_t upb_fielddef_descriptortype(const upb_fielddef *f) {
3626 return f->type_;
3627 }
3628
upb_fielddef_index(const upb_fielddef * f)3629 uint32_t upb_fielddef_index(const upb_fielddef *f) {
3630 return f->index_;
3631 }
3632
upb_fielddef_label(const upb_fielddef * f)3633 upb_label_t upb_fielddef_label(const upb_fielddef *f) {
3634 return f->label_;
3635 }
3636
upb_fielddef_number(const upb_fielddef * f)3637 uint32_t upb_fielddef_number(const upb_fielddef *f) {
3638 return f->number_;
3639 }
3640
upb_fielddef_isextension(const upb_fielddef * f)3641 bool upb_fielddef_isextension(const upb_fielddef *f) {
3642 return f->is_extension_;
3643 }
3644
upb_fielddef_lazy(const upb_fielddef * f)3645 bool upb_fielddef_lazy(const upb_fielddef *f) {
3646 return f->lazy_;
3647 }
3648
upb_fielddef_packed(const upb_fielddef * f)3649 bool upb_fielddef_packed(const upb_fielddef *f) {
3650 return f->packed_;
3651 }
3652
upb_fielddef_name(const upb_fielddef * f)3653 const char *upb_fielddef_name(const upb_fielddef *f) {
3654 return shortdefname(f->full_name);
3655 }
3656
upb_fielddef_jsonname(const upb_fielddef * f)3657 const char *upb_fielddef_jsonname(const upb_fielddef *f) {
3658 return f->json_name;
3659 }
3660
upb_fielddef_selectorbase(const upb_fielddef * f)3661 uint32_t upb_fielddef_selectorbase(const upb_fielddef *f) {
3662 return f->selector_base;
3663 }
3664
upb_fielddef_file(const upb_fielddef * f)3665 const upb_filedef *upb_fielddef_file(const upb_fielddef *f) {
3666 return f->file;
3667 }
3668
upb_fielddef_containingtype(const upb_fielddef * f)3669 const upb_msgdef *upb_fielddef_containingtype(const upb_fielddef *f) {
3670 return f->msgdef;
3671 }
3672
upb_fielddef_containingoneof(const upb_fielddef * f)3673 const upb_oneofdef *upb_fielddef_containingoneof(const upb_fielddef *f) {
3674 return f->oneof;
3675 }
3676
upb_fielddef_realcontainingoneof(const upb_fielddef * f)3677 const upb_oneofdef *upb_fielddef_realcontainingoneof(const upb_fielddef *f) {
3678 if (!f->oneof || upb_oneofdef_issynthetic(f->oneof)) return NULL;
3679 return f->oneof;
3680 }
3681
chkdefaulttype(const upb_fielddef * f,int ctype)3682 static void chkdefaulttype(const upb_fielddef *f, int ctype) {
3683 UPB_UNUSED(f);
3684 UPB_UNUSED(ctype);
3685 }
3686
upb_fielddef_defaultint64(const upb_fielddef * f)3687 int64_t upb_fielddef_defaultint64(const upb_fielddef *f) {
3688 chkdefaulttype(f, UPB_TYPE_INT64);
3689 return f->defaultval.sint;
3690 }
3691
upb_fielddef_defaultint32(const upb_fielddef * f)3692 int32_t upb_fielddef_defaultint32(const upb_fielddef *f) {
3693 chkdefaulttype(f, UPB_TYPE_INT32);
3694 return (int32_t)f->defaultval.sint;
3695 }
3696
upb_fielddef_defaultuint64(const upb_fielddef * f)3697 uint64_t upb_fielddef_defaultuint64(const upb_fielddef *f) {
3698 chkdefaulttype(f, UPB_TYPE_UINT64);
3699 return f->defaultval.uint;
3700 }
3701
upb_fielddef_defaultuint32(const upb_fielddef * f)3702 uint32_t upb_fielddef_defaultuint32(const upb_fielddef *f) {
3703 chkdefaulttype(f, UPB_TYPE_UINT32);
3704 return (uint32_t)f->defaultval.uint;
3705 }
3706
upb_fielddef_defaultbool(const upb_fielddef * f)3707 bool upb_fielddef_defaultbool(const upb_fielddef *f) {
3708 chkdefaulttype(f, UPB_TYPE_BOOL);
3709 return f->defaultval.boolean;
3710 }
3711
upb_fielddef_defaultfloat(const upb_fielddef * f)3712 float upb_fielddef_defaultfloat(const upb_fielddef *f) {
3713 chkdefaulttype(f, UPB_TYPE_FLOAT);
3714 return f->defaultval.flt;
3715 }
3716
upb_fielddef_defaultdouble(const upb_fielddef * f)3717 double upb_fielddef_defaultdouble(const upb_fielddef *f) {
3718 chkdefaulttype(f, UPB_TYPE_DOUBLE);
3719 return f->defaultval.dbl;
3720 }
3721
upb_fielddef_defaultstr(const upb_fielddef * f,size_t * len)3722 const char *upb_fielddef_defaultstr(const upb_fielddef *f, size_t *len) {
3723 str_t *str = f->defaultval.str;
3724 UPB_ASSERT(upb_fielddef_type(f) == UPB_TYPE_STRING ||
3725 upb_fielddef_type(f) == UPB_TYPE_BYTES ||
3726 upb_fielddef_type(f) == UPB_TYPE_ENUM);
3727 if (str) {
3728 if (len) *len = str->len;
3729 return str->str;
3730 } else {
3731 if (len) *len = 0;
3732 return NULL;
3733 }
3734 }
3735
upb_fielddef_msgsubdef(const upb_fielddef * f)3736 const upb_msgdef *upb_fielddef_msgsubdef(const upb_fielddef *f) {
3737 return upb_fielddef_type(f) == UPB_TYPE_MESSAGE ? f->sub.msgdef : NULL;
3738 }
3739
upb_fielddef_enumsubdef(const upb_fielddef * f)3740 const upb_enumdef *upb_fielddef_enumsubdef(const upb_fielddef *f) {
3741 return upb_fielddef_type(f) == UPB_TYPE_ENUM ? f->sub.enumdef : NULL;
3742 }
3743
upb_fielddef_layout(const upb_fielddef * f)3744 const upb_msglayout_field *upb_fielddef_layout(const upb_fielddef *f) {
3745 return &f->msgdef->layout->fields[f->layout_index];
3746 }
3747
upb_fielddef_issubmsg(const upb_fielddef * f)3748 bool upb_fielddef_issubmsg(const upb_fielddef *f) {
3749 return upb_fielddef_type(f) == UPB_TYPE_MESSAGE;
3750 }
3751
upb_fielddef_isstring(const upb_fielddef * f)3752 bool upb_fielddef_isstring(const upb_fielddef *f) {
3753 return upb_fielddef_type(f) == UPB_TYPE_STRING ||
3754 upb_fielddef_type(f) == UPB_TYPE_BYTES;
3755 }
3756
upb_fielddef_isseq(const upb_fielddef * f)3757 bool upb_fielddef_isseq(const upb_fielddef *f) {
3758 return upb_fielddef_label(f) == UPB_LABEL_REPEATED;
3759 }
3760
upb_fielddef_isprimitive(const upb_fielddef * f)3761 bool upb_fielddef_isprimitive(const upb_fielddef *f) {
3762 return !upb_fielddef_isstring(f) && !upb_fielddef_issubmsg(f);
3763 }
3764
upb_fielddef_ismap(const upb_fielddef * f)3765 bool upb_fielddef_ismap(const upb_fielddef *f) {
3766 return upb_fielddef_isseq(f) && upb_fielddef_issubmsg(f) &&
3767 upb_msgdef_mapentry(upb_fielddef_msgsubdef(f));
3768 }
3769
upb_fielddef_hassubdef(const upb_fielddef * f)3770 bool upb_fielddef_hassubdef(const upb_fielddef *f) {
3771 return upb_fielddef_issubmsg(f) || upb_fielddef_type(f) == UPB_TYPE_ENUM;
3772 }
3773
upb_fielddef_haspresence(const upb_fielddef * f)3774 bool upb_fielddef_haspresence(const upb_fielddef *f) {
3775 if (upb_fielddef_isseq(f)) return false;
3776 return upb_fielddef_issubmsg(f) || upb_fielddef_containingoneof(f) ||
3777 f->file->syntax == UPB_SYNTAX_PROTO2;
3778 }
3779
between(int32_t x,int32_t low,int32_t high)3780 static bool between(int32_t x, int32_t low, int32_t high) {
3781 return x >= low && x <= high;
3782 }
3783
upb_fielddef_checklabel(int32_t label)3784 bool upb_fielddef_checklabel(int32_t label) { return between(label, 1, 3); }
upb_fielddef_checktype(int32_t type)3785 bool upb_fielddef_checktype(int32_t type) { return between(type, 1, 11); }
upb_fielddef_checkintfmt(int32_t fmt)3786 bool upb_fielddef_checkintfmt(int32_t fmt) { return between(fmt, 1, 3); }
3787
upb_fielddef_checkdescriptortype(int32_t type)3788 bool upb_fielddef_checkdescriptortype(int32_t type) {
3789 return between(type, 1, 18);
3790 }
3791
3792 /* upb_msgdef *****************************************************************/
3793
upb_msgdef_fullname(const upb_msgdef * m)3794 const char *upb_msgdef_fullname(const upb_msgdef *m) {
3795 return m->full_name;
3796 }
3797
upb_msgdef_file(const upb_msgdef * m)3798 const upb_filedef *upb_msgdef_file(const upb_msgdef *m) {
3799 return m->file;
3800 }
3801
upb_msgdef_name(const upb_msgdef * m)3802 const char *upb_msgdef_name(const upb_msgdef *m) {
3803 return shortdefname(m->full_name);
3804 }
3805
upb_msgdef_syntax(const upb_msgdef * m)3806 upb_syntax_t upb_msgdef_syntax(const upb_msgdef *m) {
3807 return m->file->syntax;
3808 }
3809
upb_msgdef_selectorcount(const upb_msgdef * m)3810 size_t upb_msgdef_selectorcount(const upb_msgdef *m) {
3811 return m->selector_count;
3812 }
3813
upb_msgdef_submsgfieldcount(const upb_msgdef * m)3814 uint32_t upb_msgdef_submsgfieldcount(const upb_msgdef *m) {
3815 return m->submsg_field_count;
3816 }
3817
upb_msgdef_itof(const upb_msgdef * m,uint32_t i)3818 const upb_fielddef *upb_msgdef_itof(const upb_msgdef *m, uint32_t i) {
3819 upb_value val;
3820 return upb_inttable_lookup32(&m->itof, i, &val) ?
3821 upb_value_getconstptr(val) : NULL;
3822 }
3823
upb_msgdef_ntof(const upb_msgdef * m,const char * name,size_t len)3824 const upb_fielddef *upb_msgdef_ntof(const upb_msgdef *m, const char *name,
3825 size_t len) {
3826 upb_value val;
3827
3828 if (!upb_strtable_lookup2(&m->ntof, name, len, &val)) {
3829 return NULL;
3830 }
3831
3832 return unpack_def(val, UPB_DEFTYPE_FIELD);
3833 }
3834
upb_msgdef_ntoo(const upb_msgdef * m,const char * name,size_t len)3835 const upb_oneofdef *upb_msgdef_ntoo(const upb_msgdef *m, const char *name,
3836 size_t len) {
3837 upb_value val;
3838
3839 if (!upb_strtable_lookup2(&m->ntof, name, len, &val)) {
3840 return NULL;
3841 }
3842
3843 return unpack_def(val, UPB_DEFTYPE_ONEOF);
3844 }
3845
upb_msgdef_lookupname(const upb_msgdef * m,const char * name,size_t len,const upb_fielddef ** f,const upb_oneofdef ** o)3846 bool upb_msgdef_lookupname(const upb_msgdef *m, const char *name, size_t len,
3847 const upb_fielddef **f, const upb_oneofdef **o) {
3848 upb_value val;
3849
3850 if (!upb_strtable_lookup2(&m->ntof, name, len, &val)) {
3851 return false;
3852 }
3853
3854 *o = unpack_def(val, UPB_DEFTYPE_ONEOF);
3855 *f = unpack_def(val, UPB_DEFTYPE_FIELD);
3856 return *o || *f; /* False if this was a JSON name. */
3857 }
3858
upb_msgdef_lookupjsonname(const upb_msgdef * m,const char * name,size_t len)3859 const upb_fielddef *upb_msgdef_lookupjsonname(const upb_msgdef *m,
3860 const char *name, size_t len) {
3861 upb_value val;
3862 const upb_fielddef* f;
3863
3864 if (!upb_strtable_lookup2(&m->ntof, name, len, &val)) {
3865 return NULL;
3866 }
3867
3868 f = unpack_def(val, UPB_DEFTYPE_FIELD);
3869 if (!f) f = unpack_def(val, UPB_DEFTYPE_FIELD_JSONNAME);
3870
3871 return f;
3872 }
3873
upb_msgdef_numfields(const upb_msgdef * m)3874 int upb_msgdef_numfields(const upb_msgdef *m) {
3875 return m->field_count;
3876 }
3877
upb_msgdef_numoneofs(const upb_msgdef * m)3878 int upb_msgdef_numoneofs(const upb_msgdef *m) {
3879 return m->oneof_count;
3880 }
3881
upb_msgdef_numrealoneofs(const upb_msgdef * m)3882 int upb_msgdef_numrealoneofs(const upb_msgdef *m) {
3883 return m->real_oneof_count;
3884 }
3885
upb_msgdef_fieldcount(const upb_msgdef * m)3886 int upb_msgdef_fieldcount(const upb_msgdef *m) {
3887 return m->field_count;
3888 }
3889
upb_msgdef_oneofcount(const upb_msgdef * m)3890 int upb_msgdef_oneofcount(const upb_msgdef *m) {
3891 return m->oneof_count;
3892 }
3893
upb_msgdef_realoneofcount(const upb_msgdef * m)3894 int upb_msgdef_realoneofcount(const upb_msgdef *m) {
3895 return m->real_oneof_count;
3896 }
3897
upb_msgdef_layout(const upb_msgdef * m)3898 const upb_msglayout *upb_msgdef_layout(const upb_msgdef *m) {
3899 return m->layout;
3900 }
3901
upb_msgdef_field(const upb_msgdef * m,int i)3902 const upb_fielddef *upb_msgdef_field(const upb_msgdef *m, int i) {
3903 UPB_ASSERT(i >= 0 && i < m->field_count);
3904 return &m->fields[i];
3905 }
3906
upb_msgdef_oneof(const upb_msgdef * m,int i)3907 const upb_oneofdef *upb_msgdef_oneof(const upb_msgdef *m, int i) {
3908 UPB_ASSERT(i >= 0 && i < m->oneof_count);
3909 return &m->oneofs[i];
3910 }
3911
upb_msgdef_mapentry(const upb_msgdef * m)3912 bool upb_msgdef_mapentry(const upb_msgdef *m) {
3913 return m->map_entry;
3914 }
3915
upb_msgdef_wellknowntype(const upb_msgdef * m)3916 upb_wellknowntype_t upb_msgdef_wellknowntype(const upb_msgdef *m) {
3917 return m->well_known_type;
3918 }
3919
upb_msgdef_isnumberwrapper(const upb_msgdef * m)3920 bool upb_msgdef_isnumberwrapper(const upb_msgdef *m) {
3921 upb_wellknowntype_t type = upb_msgdef_wellknowntype(m);
3922 return type >= UPB_WELLKNOWN_DOUBLEVALUE &&
3923 type <= UPB_WELLKNOWN_UINT32VALUE;
3924 }
3925
upb_msgdef_iswrapper(const upb_msgdef * m)3926 bool upb_msgdef_iswrapper(const upb_msgdef *m) {
3927 upb_wellknowntype_t type = upb_msgdef_wellknowntype(m);
3928 return type >= UPB_WELLKNOWN_DOUBLEVALUE &&
3929 type <= UPB_WELLKNOWN_BOOLVALUE;
3930 }
3931
upb_msg_field_begin(upb_msg_field_iter * iter,const upb_msgdef * m)3932 void upb_msg_field_begin(upb_msg_field_iter *iter, const upb_msgdef *m) {
3933 upb_inttable_begin(iter, &m->itof);
3934 }
3935
upb_msg_field_next(upb_msg_field_iter * iter)3936 void upb_msg_field_next(upb_msg_field_iter *iter) { upb_inttable_next(iter); }
3937
upb_msg_field_done(const upb_msg_field_iter * iter)3938 bool upb_msg_field_done(const upb_msg_field_iter *iter) {
3939 return upb_inttable_done(iter);
3940 }
3941
upb_msg_iter_field(const upb_msg_field_iter * iter)3942 upb_fielddef *upb_msg_iter_field(const upb_msg_field_iter *iter) {
3943 return (upb_fielddef *)upb_value_getconstptr(upb_inttable_iter_value(iter));
3944 }
3945
upb_msg_field_iter_setdone(upb_msg_field_iter * iter)3946 void upb_msg_field_iter_setdone(upb_msg_field_iter *iter) {
3947 upb_inttable_iter_setdone(iter);
3948 }
3949
upb_msg_field_iter_isequal(const upb_msg_field_iter * iter1,const upb_msg_field_iter * iter2)3950 bool upb_msg_field_iter_isequal(const upb_msg_field_iter * iter1,
3951 const upb_msg_field_iter * iter2) {
3952 return upb_inttable_iter_isequal(iter1, iter2);
3953 }
3954
upb_msg_oneof_begin(upb_msg_oneof_iter * iter,const upb_msgdef * m)3955 void upb_msg_oneof_begin(upb_msg_oneof_iter *iter, const upb_msgdef *m) {
3956 upb_strtable_begin(iter, &m->ntof);
3957 /* We need to skip past any initial fields. */
3958 while (!upb_strtable_done(iter) &&
3959 !unpack_def(upb_strtable_iter_value(iter), UPB_DEFTYPE_ONEOF)) {
3960 upb_strtable_next(iter);
3961 }
3962 }
3963
upb_msg_oneof_next(upb_msg_oneof_iter * iter)3964 void upb_msg_oneof_next(upb_msg_oneof_iter *iter) {
3965 /* We need to skip past fields to return only oneofs. */
3966 do {
3967 upb_strtable_next(iter);
3968 } while (!upb_strtable_done(iter) &&
3969 !unpack_def(upb_strtable_iter_value(iter), UPB_DEFTYPE_ONEOF));
3970 }
3971
upb_msg_oneof_done(const upb_msg_oneof_iter * iter)3972 bool upb_msg_oneof_done(const upb_msg_oneof_iter *iter) {
3973 return upb_strtable_done(iter);
3974 }
3975
upb_msg_iter_oneof(const upb_msg_oneof_iter * iter)3976 const upb_oneofdef *upb_msg_iter_oneof(const upb_msg_oneof_iter *iter) {
3977 return unpack_def(upb_strtable_iter_value(iter), UPB_DEFTYPE_ONEOF);
3978 }
3979
upb_msg_oneof_iter_setdone(upb_msg_oneof_iter * iter)3980 void upb_msg_oneof_iter_setdone(upb_msg_oneof_iter *iter) {
3981 upb_strtable_iter_setdone(iter);
3982 }
3983
upb_msg_oneof_iter_isequal(const upb_msg_oneof_iter * iter1,const upb_msg_oneof_iter * iter2)3984 bool upb_msg_oneof_iter_isequal(const upb_msg_oneof_iter *iter1,
3985 const upb_msg_oneof_iter *iter2) {
3986 return upb_strtable_iter_isequal(iter1, iter2);
3987 }
3988
3989 /* upb_oneofdef ***************************************************************/
3990
upb_oneofdef_name(const upb_oneofdef * o)3991 const char *upb_oneofdef_name(const upb_oneofdef *o) {
3992 return shortdefname(o->full_name);
3993 }
3994
upb_oneofdef_containingtype(const upb_oneofdef * o)3995 const upb_msgdef *upb_oneofdef_containingtype(const upb_oneofdef *o) {
3996 return o->parent;
3997 }
3998
upb_oneofdef_fieldcount(const upb_oneofdef * o)3999 int upb_oneofdef_fieldcount(const upb_oneofdef *o) {
4000 return o->field_count;
4001 }
4002
upb_oneofdef_field(const upb_oneofdef * o,int i)4003 const upb_fielddef *upb_oneofdef_field(const upb_oneofdef *o, int i) {
4004 UPB_ASSERT(i < o->field_count);
4005 return o->fields[i];
4006 }
4007
upb_oneofdef_numfields(const upb_oneofdef * o)4008 int upb_oneofdef_numfields(const upb_oneofdef *o) {
4009 return o->field_count;
4010 }
4011
upb_oneofdef_index(const upb_oneofdef * o)4012 uint32_t upb_oneofdef_index(const upb_oneofdef *o) {
4013 return o - o->parent->oneofs;
4014 }
4015
upb_oneofdef_issynthetic(const upb_oneofdef * o)4016 bool upb_oneofdef_issynthetic(const upb_oneofdef *o) {
4017 return o->synthetic;
4018 }
4019
upb_oneofdef_ntof(const upb_oneofdef * o,const char * name,size_t length)4020 const upb_fielddef *upb_oneofdef_ntof(const upb_oneofdef *o,
4021 const char *name, size_t length) {
4022 upb_value val;
4023 return upb_strtable_lookup2(&o->ntof, name, length, &val) ?
4024 upb_value_getptr(val) : NULL;
4025 }
4026
upb_oneofdef_itof(const upb_oneofdef * o,uint32_t num)4027 const upb_fielddef *upb_oneofdef_itof(const upb_oneofdef *o, uint32_t num) {
4028 upb_value val;
4029 return upb_inttable_lookup32(&o->itof, num, &val) ?
4030 upb_value_getptr(val) : NULL;
4031 }
4032
upb_oneof_begin(upb_oneof_iter * iter,const upb_oneofdef * o)4033 void upb_oneof_begin(upb_oneof_iter *iter, const upb_oneofdef *o) {
4034 upb_inttable_begin(iter, &o->itof);
4035 }
4036
upb_oneof_next(upb_oneof_iter * iter)4037 void upb_oneof_next(upb_oneof_iter *iter) {
4038 upb_inttable_next(iter);
4039 }
4040
upb_oneof_done(upb_oneof_iter * iter)4041 bool upb_oneof_done(upb_oneof_iter *iter) {
4042 return upb_inttable_done(iter);
4043 }
4044
upb_oneof_iter_field(const upb_oneof_iter * iter)4045 upb_fielddef *upb_oneof_iter_field(const upb_oneof_iter *iter) {
4046 return (upb_fielddef *)upb_value_getconstptr(upb_inttable_iter_value(iter));
4047 }
4048
upb_oneof_iter_setdone(upb_oneof_iter * iter)4049 void upb_oneof_iter_setdone(upb_oneof_iter *iter) {
4050 upb_inttable_iter_setdone(iter);
4051 }
4052
4053 /* upb_filedef ****************************************************************/
4054
upb_filedef_name(const upb_filedef * f)4055 const char *upb_filedef_name(const upb_filedef *f) {
4056 return f->name;
4057 }
4058
upb_filedef_package(const upb_filedef * f)4059 const char *upb_filedef_package(const upb_filedef *f) {
4060 return f->package;
4061 }
4062
upb_filedef_phpprefix(const upb_filedef * f)4063 const char *upb_filedef_phpprefix(const upb_filedef *f) {
4064 return f->phpprefix;
4065 }
4066
upb_filedef_phpnamespace(const upb_filedef * f)4067 const char *upb_filedef_phpnamespace(const upb_filedef *f) {
4068 return f->phpnamespace;
4069 }
4070
upb_filedef_syntax(const upb_filedef * f)4071 upb_syntax_t upb_filedef_syntax(const upb_filedef *f) {
4072 return f->syntax;
4073 }
4074
upb_filedef_msgcount(const upb_filedef * f)4075 int upb_filedef_msgcount(const upb_filedef *f) {
4076 return f->msg_count;
4077 }
4078
upb_filedef_depcount(const upb_filedef * f)4079 int upb_filedef_depcount(const upb_filedef *f) {
4080 return f->dep_count;
4081 }
4082
upb_filedef_enumcount(const upb_filedef * f)4083 int upb_filedef_enumcount(const upb_filedef *f) {
4084 return f->enum_count;
4085 }
4086
upb_filedef_dep(const upb_filedef * f,int i)4087 const upb_filedef *upb_filedef_dep(const upb_filedef *f, int i) {
4088 return i < 0 || i >= f->dep_count ? NULL : f->deps[i];
4089 }
4090
upb_filedef_msg(const upb_filedef * f,int i)4091 const upb_msgdef *upb_filedef_msg(const upb_filedef *f, int i) {
4092 return i < 0 || i >= f->msg_count ? NULL : &f->msgs[i];
4093 }
4094
upb_filedef_enum(const upb_filedef * f,int i)4095 const upb_enumdef *upb_filedef_enum(const upb_filedef *f, int i) {
4096 return i < 0 || i >= f->enum_count ? NULL : &f->enums[i];
4097 }
4098
upb_symtab_free(upb_symtab * s)4099 void upb_symtab_free(upb_symtab *s) {
4100 upb_arena_free(s->arena);
4101 upb_gfree(s);
4102 }
4103
upb_symtab_new(void)4104 upb_symtab *upb_symtab_new(void) {
4105 upb_symtab *s = upb_gmalloc(sizeof(*s));
4106 upb_alloc *alloc;
4107
4108 if (!s) {
4109 return NULL;
4110 }
4111
4112 s->arena = upb_arena_new();
4113 s->bytes_loaded = 0;
4114 alloc = upb_arena_alloc(s->arena);
4115
4116 if (!upb_strtable_init2(&s->syms, UPB_CTYPE_CONSTPTR, 32, alloc) ||
4117 !upb_strtable_init2(&s->files, UPB_CTYPE_CONSTPTR, 4, alloc)) {
4118 upb_arena_free(s->arena);
4119 upb_gfree(s);
4120 s = NULL;
4121 }
4122 return s;
4123 }
4124
upb_symtab_lookupmsg(const upb_symtab * s,const char * sym)4125 const upb_msgdef *upb_symtab_lookupmsg(const upb_symtab *s, const char *sym) {
4126 upb_value v;
4127 return upb_strtable_lookup(&s->syms, sym, &v) ?
4128 unpack_def(v, UPB_DEFTYPE_MSG) : NULL;
4129 }
4130
upb_symtab_lookupmsg2(const upb_symtab * s,const char * sym,size_t len)4131 const upb_msgdef *upb_symtab_lookupmsg2(const upb_symtab *s, const char *sym,
4132 size_t len) {
4133 upb_value v;
4134 return upb_strtable_lookup2(&s->syms, sym, len, &v) ?
4135 unpack_def(v, UPB_DEFTYPE_MSG) : NULL;
4136 }
4137
upb_symtab_lookupenum(const upb_symtab * s,const char * sym)4138 const upb_enumdef *upb_symtab_lookupenum(const upb_symtab *s, const char *sym) {
4139 upb_value v;
4140 return upb_strtable_lookup(&s->syms, sym, &v) ?
4141 unpack_def(v, UPB_DEFTYPE_ENUM) : NULL;
4142 }
4143
upb_symtab_lookupfile(const upb_symtab * s,const char * name)4144 const upb_filedef *upb_symtab_lookupfile(const upb_symtab *s, const char *name) {
4145 upb_value v;
4146 return upb_strtable_lookup(&s->files, name, &v) ? upb_value_getconstptr(v)
4147 : NULL;
4148 }
4149
upb_symtab_lookupfile2(const upb_symtab * s,const char * name,size_t len)4150 const upb_filedef *upb_symtab_lookupfile2(
4151 const upb_symtab *s, const char *name, size_t len) {
4152 upb_value v;
4153 return upb_strtable_lookup2(&s->files, name, len, &v) ?
4154 upb_value_getconstptr(v) : NULL;
4155 }
4156
upb_symtab_filecount(const upb_symtab * s)4157 int upb_symtab_filecount(const upb_symtab *s) {
4158 return (int)upb_strtable_count(&s->files);
4159 }
4160
4161 /* Code to build defs from descriptor protos. *********************************/
4162
4163 /* There is a question of how much validation to do here. It will be difficult
4164 * to perfectly match the amount of validation performed by proto2. But since
4165 * this code is used to directly build defs from Ruby (for example) we do need
4166 * to validate important constraints like uniqueness of names and numbers. */
4167
4168 #define CHK_OOM(x) if (!(x)) { symtab_oomerr(ctx); }
4169
4170 typedef struct {
4171 upb_symtab *symtab;
4172 upb_filedef *file; /* File we are building. */
4173 upb_arena *file_arena; /* Allocate defs here. */
4174 upb_alloc *alloc; /* Alloc of file_arena, for tables. */
4175 const upb_msglayout **layouts; /* NULL if we should build layouts. */
4176 upb_status *status; /* Record errors here. */
4177 jmp_buf err; /* longjmp() on error. */
4178 } symtab_addctx;
4179
4180 UPB_NORETURN UPB_NOINLINE
symtab_errf(symtab_addctx * ctx,const char * fmt,...)4181 static void symtab_errf(symtab_addctx *ctx, const char *fmt, ...) {
4182 va_list argp;
4183 va_start(argp, fmt);
4184 upb_status_vseterrf(ctx->status, fmt, argp);
4185 va_end(argp);
4186 longjmp(ctx->err, 1);
4187 }
4188
4189 UPB_NORETURN UPB_NOINLINE
symtab_oomerr(symtab_addctx * ctx)4190 static void symtab_oomerr(symtab_addctx *ctx) {
4191 upb_status_setoom(ctx->status);
4192 longjmp(ctx->err, 1);
4193 }
4194
symtab_alloc(symtab_addctx * ctx,size_t bytes)4195 void *symtab_alloc(symtab_addctx *ctx, size_t bytes) {
4196 void *ret = upb_arena_malloc(ctx->file_arena, bytes);
4197 if (!ret) symtab_oomerr(ctx);
4198 return ret;
4199 }
4200
check_ident(symtab_addctx * ctx,upb_strview name,bool full)4201 static void check_ident(symtab_addctx *ctx, upb_strview name, bool full) {
4202 const char *str = name.data;
4203 size_t len = name.size;
4204 bool start = true;
4205 size_t i;
4206 for (i = 0; i < len; i++) {
4207 char c = str[i];
4208 if (c == '.') {
4209 if (start || !full) {
4210 symtab_errf(ctx, "invalid name: unexpected '.' (%.*s)", (int)len, str);
4211 }
4212 start = true;
4213 } else if (start) {
4214 if (!upb_isletter(c)) {
4215 symtab_errf(
4216 ctx,
4217 "invalid name: path components must start with a letter (%.*s)",
4218 (int)len, str);
4219 }
4220 start = false;
4221 } else {
4222 if (!upb_isalphanum(c)) {
4223 symtab_errf(ctx, "invalid name: non-alphanumeric character (%.*s)",
4224 (int)len, str);
4225 }
4226 }
4227 }
4228 if (start) {
4229 symtab_errf(ctx, "invalid name: empty part (%.*s)", (int)len, str);
4230 }
4231 }
4232
div_round_up(size_t n,size_t d)4233 static size_t div_round_up(size_t n, size_t d) {
4234 return (n + d - 1) / d;
4235 }
4236
upb_msgval_sizeof(upb_fieldtype_t type)4237 static size_t upb_msgval_sizeof(upb_fieldtype_t type) {
4238 switch (type) {
4239 case UPB_TYPE_DOUBLE:
4240 case UPB_TYPE_INT64:
4241 case UPB_TYPE_UINT64:
4242 return 8;
4243 case UPB_TYPE_ENUM:
4244 case UPB_TYPE_INT32:
4245 case UPB_TYPE_UINT32:
4246 case UPB_TYPE_FLOAT:
4247 return 4;
4248 case UPB_TYPE_BOOL:
4249 return 1;
4250 case UPB_TYPE_MESSAGE:
4251 return sizeof(void*);
4252 case UPB_TYPE_BYTES:
4253 case UPB_TYPE_STRING:
4254 return sizeof(upb_strview);
4255 }
4256 UPB_UNREACHABLE();
4257 }
4258
upb_msg_fielddefsize(const upb_fielddef * f)4259 static uint8_t upb_msg_fielddefsize(const upb_fielddef *f) {
4260 if (upb_msgdef_mapentry(upb_fielddef_containingtype(f))) {
4261 upb_map_entry ent;
4262 UPB_ASSERT(sizeof(ent.k) == sizeof(ent.v));
4263 return sizeof(ent.k);
4264 } else if (upb_fielddef_isseq(f)) {
4265 return sizeof(void*);
4266 } else {
4267 return upb_msgval_sizeof(upb_fielddef_type(f));
4268 }
4269 }
4270
upb_msglayout_place(upb_msglayout * l,size_t size)4271 static uint32_t upb_msglayout_place(upb_msglayout *l, size_t size) {
4272 uint32_t ret;
4273
4274 l->size = UPB_ALIGN_UP(l->size, size);
4275 ret = l->size;
4276 l->size += size;
4277 return ret;
4278 }
4279
field_number_cmp(const void * p1,const void * p2)4280 static int field_number_cmp(const void *p1, const void *p2) {
4281 const upb_msglayout_field *f1 = p1;
4282 const upb_msglayout_field *f2 = p2;
4283 return f1->number - f2->number;
4284 }
4285
assign_layout_indices(const upb_msgdef * m,upb_msglayout_field * fields)4286 static void assign_layout_indices(const upb_msgdef *m, upb_msglayout_field *fields) {
4287 int i;
4288 int n = upb_msgdef_numfields(m);
4289 for (i = 0; i < n; i++) {
4290 upb_fielddef *f = (upb_fielddef*)upb_msgdef_itof(m, fields[i].number);
4291 UPB_ASSERT(f);
4292 f->layout_index = i;
4293 }
4294 }
4295
4296 /* This function is the dynamic equivalent of message_layout.{cc,h} in upbc.
4297 * It computes a dynamic layout for all of the fields in |m|. */
make_layout(symtab_addctx * ctx,const upb_msgdef * m)4298 static void make_layout(symtab_addctx *ctx, const upb_msgdef *m) {
4299 upb_msglayout *l = (upb_msglayout*)m->layout;
4300 upb_msg_field_iter it;
4301 upb_msg_oneof_iter oit;
4302 size_t hasbit;
4303 size_t submsg_count = m->submsg_field_count;
4304 const upb_msglayout **submsgs;
4305 upb_msglayout_field *fields;
4306
4307 memset(l, 0, sizeof(*l));
4308
4309 fields = symtab_alloc(ctx, upb_msgdef_numfields(m) * sizeof(*fields));
4310 submsgs = symtab_alloc(ctx, submsg_count * sizeof(*submsgs));
4311
4312 l->field_count = upb_msgdef_numfields(m);
4313 l->fields = fields;
4314 l->submsgs = submsgs;
4315
4316 if (upb_msgdef_mapentry(m)) {
4317 /* TODO(haberman): refactor this method so this special case is more
4318 * elegant. */
4319 const upb_fielddef *key = upb_msgdef_itof(m, 1);
4320 const upb_fielddef *val = upb_msgdef_itof(m, 2);
4321 fields[0].number = 1;
4322 fields[1].number = 2;
4323 fields[0].label = UPB_LABEL_OPTIONAL;
4324 fields[1].label = UPB_LABEL_OPTIONAL;
4325 fields[0].presence = 0;
4326 fields[1].presence = 0;
4327 fields[0].descriptortype = upb_fielddef_descriptortype(key);
4328 fields[1].descriptortype = upb_fielddef_descriptortype(val);
4329 fields[0].offset = 0;
4330 fields[1].offset = sizeof(upb_strview);
4331 fields[1].submsg_index = 0;
4332
4333 if (upb_fielddef_type(val) == UPB_TYPE_MESSAGE) {
4334 submsgs[0] = upb_fielddef_msgsubdef(val)->layout;
4335 }
4336
4337 l->field_count = 2;
4338 l->size = 2 * sizeof(upb_strview);
4339 l->size = UPB_ALIGN_UP(l->size, 8);
4340 return;
4341 }
4342
4343 /* Allocate data offsets in three stages:
4344 *
4345 * 1. hasbits.
4346 * 2. regular fields.
4347 * 3. oneof fields.
4348 *
4349 * OPT: There is a lot of room for optimization here to minimize the size.
4350 */
4351
4352 /* Allocate hasbits and set basic field attributes. */
4353 submsg_count = 0;
4354 for (upb_msg_field_begin(&it, m), hasbit = 0;
4355 !upb_msg_field_done(&it);
4356 upb_msg_field_next(&it)) {
4357 upb_fielddef* f = upb_msg_iter_field(&it);
4358 upb_msglayout_field *field = &fields[upb_fielddef_index(f)];
4359
4360 field->number = upb_fielddef_number(f);
4361 field->descriptortype = upb_fielddef_descriptortype(f);
4362 field->label = upb_fielddef_label(f);
4363
4364 if (field->descriptortype == UPB_DTYPE_STRING &&
4365 f->file->syntax == UPB_SYNTAX_PROTO2) {
4366 /* See TableDescriptorType() in upbc/generator.cc for details and
4367 * rationale. */
4368 field->descriptortype = UPB_DTYPE_BYTES;
4369 }
4370
4371 if (upb_fielddef_ismap(f)) {
4372 field->label = _UPB_LABEL_MAP;
4373 } else if (upb_fielddef_packed(f)) {
4374 field->label = _UPB_LABEL_PACKED;
4375 }
4376
4377 if (upb_fielddef_issubmsg(f)) {
4378 const upb_msgdef *subm = upb_fielddef_msgsubdef(f);
4379 field->submsg_index = submsg_count++;
4380 submsgs[field->submsg_index] = subm->layout;
4381 }
4382
4383 if (upb_fielddef_haspresence(f) && !upb_fielddef_realcontainingoneof(f)) {
4384 /* We don't use hasbit 0, so that 0 can indicate "no presence" in the
4385 * table. This wastes one hasbit, but we don't worry about it for now. */
4386 field->presence = ++hasbit;
4387 } else {
4388 field->presence = 0;
4389 }
4390 }
4391
4392 /* Account for space used by hasbits. */
4393 l->size = div_round_up(hasbit, 8);
4394
4395 /* Allocate non-oneof fields. */
4396 for (upb_msg_field_begin(&it, m); !upb_msg_field_done(&it);
4397 upb_msg_field_next(&it)) {
4398 const upb_fielddef* f = upb_msg_iter_field(&it);
4399 size_t field_size = upb_msg_fielddefsize(f);
4400 size_t index = upb_fielddef_index(f);
4401
4402 if (upb_fielddef_realcontainingoneof(f)) {
4403 /* Oneofs are handled separately below. */
4404 continue;
4405 }
4406
4407 fields[index].offset = upb_msglayout_place(l, field_size);
4408 }
4409
4410 /* Allocate oneof fields. Each oneof field consists of a uint32 for the case
4411 * and space for the actual data. */
4412 for (upb_msg_oneof_begin(&oit, m); !upb_msg_oneof_done(&oit);
4413 upb_msg_oneof_next(&oit)) {
4414 const upb_oneofdef* o = upb_msg_iter_oneof(&oit);
4415 upb_oneof_iter fit;
4416
4417 size_t case_size = sizeof(uint32_t); /* Could potentially optimize this. */
4418 size_t field_size = 0;
4419 uint32_t case_offset;
4420 uint32_t data_offset;
4421
4422 if (upb_oneofdef_issynthetic(o)) continue;
4423
4424 /* Calculate field size: the max of all field sizes. */
4425 for (upb_oneof_begin(&fit, o);
4426 !upb_oneof_done(&fit);
4427 upb_oneof_next(&fit)) {
4428 const upb_fielddef* f = upb_oneof_iter_field(&fit);
4429 field_size = UPB_MAX(field_size, upb_msg_fielddefsize(f));
4430 }
4431
4432 /* Align and allocate case offset. */
4433 case_offset = upb_msglayout_place(l, case_size);
4434 data_offset = upb_msglayout_place(l, field_size);
4435
4436 for (upb_oneof_begin(&fit, o);
4437 !upb_oneof_done(&fit);
4438 upb_oneof_next(&fit)) {
4439 const upb_fielddef* f = upb_oneof_iter_field(&fit);
4440 fields[upb_fielddef_index(f)].offset = data_offset;
4441 fields[upb_fielddef_index(f)].presence = ~case_offset;
4442 }
4443 }
4444
4445 /* Size of the entire structure should be a multiple of its greatest
4446 * alignment. TODO: track overall alignment for real? */
4447 l->size = UPB_ALIGN_UP(l->size, 8);
4448
4449 /* Sort fields by number. */
4450 qsort(fields, upb_msgdef_numfields(m), sizeof(*fields), field_number_cmp);
4451 assign_layout_indices(m, fields);
4452 }
4453
assign_msg_indices(symtab_addctx * ctx,upb_msgdef * m)4454 static void assign_msg_indices(symtab_addctx *ctx, upb_msgdef *m) {
4455 /* Sort fields. upb internally relies on UPB_TYPE_MESSAGE fields having the
4456 * lowest indexes, but we do not publicly guarantee this. */
4457 upb_msg_field_iter j;
4458 int i;
4459 uint32_t selector;
4460 int n = upb_msgdef_numfields(m);
4461 upb_fielddef **fields;
4462
4463 if (n == 0) {
4464 m->selector_count = UPB_STATIC_SELECTOR_COUNT;
4465 m->submsg_field_count = 0;
4466 return;
4467 }
4468
4469 fields = upb_gmalloc(n * sizeof(*fields));
4470
4471 m->submsg_field_count = 0;
4472 for(i = 0, upb_msg_field_begin(&j, m);
4473 !upb_msg_field_done(&j);
4474 upb_msg_field_next(&j), i++) {
4475 upb_fielddef *f = upb_msg_iter_field(&j);
4476 UPB_ASSERT(f->msgdef == m);
4477 if (upb_fielddef_issubmsg(f)) {
4478 m->submsg_field_count++;
4479 }
4480 fields[i] = f;
4481 }
4482
4483 qsort(fields, n, sizeof(*fields), cmp_fields);
4484
4485 selector = UPB_STATIC_SELECTOR_COUNT + m->submsg_field_count;
4486 for (i = 0; i < n; i++) {
4487 upb_fielddef *f = fields[i];
4488 f->index_ = i;
4489 f->selector_base = selector + upb_handlers_selectorbaseoffset(f);
4490 selector += upb_handlers_selectorcount(f);
4491 }
4492 m->selector_count = selector;
4493
4494 upb_gfree(fields);
4495 }
4496
strviewdup(symtab_addctx * ctx,upb_strview view)4497 static char *strviewdup(symtab_addctx *ctx, upb_strview view) {
4498 return upb_strdup2(view.data, view.size, ctx->alloc);
4499 }
4500
streql2(const char * a,size_t n,const char * b)4501 static bool streql2(const char *a, size_t n, const char *b) {
4502 return n == strlen(b) && memcmp(a, b, n) == 0;
4503 }
4504
streql_view(upb_strview view,const char * b)4505 static bool streql_view(upb_strview view, const char *b) {
4506 return streql2(view.data, view.size, b);
4507 }
4508
makefullname(symtab_addctx * ctx,const char * prefix,upb_strview name)4509 static const char *makefullname(symtab_addctx *ctx, const char *prefix,
4510 upb_strview name) {
4511 if (prefix) {
4512 /* ret = prefix + '.' + name; */
4513 size_t n = strlen(prefix);
4514 char *ret = symtab_alloc(ctx, n + name.size + 2);
4515 strcpy(ret, prefix);
4516 ret[n] = '.';
4517 memcpy(&ret[n + 1], name.data, name.size);
4518 ret[n + 1 + name.size] = '\0';
4519 return ret;
4520 } else {
4521 return strviewdup(ctx, name);
4522 }
4523 }
4524
finalize_oneofs(symtab_addctx * ctx,upb_msgdef * m)4525 static void finalize_oneofs(symtab_addctx *ctx, upb_msgdef *m) {
4526 int i;
4527 int synthetic_count = 0;
4528 upb_oneofdef *mutable_oneofs = (upb_oneofdef*)m->oneofs;
4529
4530 for (i = 0; i < m->oneof_count; i++) {
4531 upb_oneofdef *o = &mutable_oneofs[i];
4532
4533 if (o->synthetic && o->field_count != 1) {
4534 symtab_errf(ctx, "Synthetic oneofs must have one field, not %d: %s",
4535 o->field_count, upb_oneofdef_name(o));
4536 }
4537
4538 if (o->synthetic) {
4539 synthetic_count++;
4540 } else if (synthetic_count != 0) {
4541 symtab_errf(ctx, "Synthetic oneofs must be after all other oneofs: %s",
4542 upb_oneofdef_name(o));
4543 }
4544
4545 o->fields = symtab_alloc(ctx, sizeof(upb_fielddef *) * o->field_count);
4546 o->field_count = 0;
4547 }
4548
4549 for (i = 0; i < m->field_count; i++) {
4550 const upb_fielddef *f = &m->fields[i];
4551 upb_oneofdef *o = (upb_oneofdef*)f->oneof;
4552 if (o) {
4553 o->fields[o->field_count++] = f;
4554 }
4555 }
4556
4557 m->real_oneof_count = m->oneof_count - synthetic_count;
4558 }
4559
getjsonname(const char * name,char * buf,size_t len)4560 size_t getjsonname(const char *name, char *buf, size_t len) {
4561 size_t src, dst = 0;
4562 bool ucase_next = false;
4563
4564 #define WRITE(byte) \
4565 ++dst; \
4566 if (dst < len) buf[dst - 1] = byte; \
4567 else if (dst == len) buf[dst - 1] = '\0'
4568
4569 if (!name) {
4570 WRITE('\0');
4571 return 0;
4572 }
4573
4574 /* Implement the transformation as described in the spec:
4575 * 1. upper case all letters after an underscore.
4576 * 2. remove all underscores.
4577 */
4578 for (src = 0; name[src]; src++) {
4579 if (name[src] == '_') {
4580 ucase_next = true;
4581 continue;
4582 }
4583
4584 if (ucase_next) {
4585 WRITE(toupper(name[src]));
4586 ucase_next = false;
4587 } else {
4588 WRITE(name[src]);
4589 }
4590 }
4591
4592 WRITE('\0');
4593 return dst;
4594
4595 #undef WRITE
4596 }
4597
makejsonname(symtab_addctx * ctx,const char * name)4598 static char* makejsonname(symtab_addctx *ctx, const char* name) {
4599 size_t size = getjsonname(name, NULL, 0);
4600 char* json_name = symtab_alloc(ctx, size);
4601 getjsonname(name, json_name, size);
4602 return json_name;
4603 }
4604
symtab_add(symtab_addctx * ctx,const char * name,upb_value v)4605 static void symtab_add(symtab_addctx *ctx, const char *name, upb_value v) {
4606 if (upb_strtable_lookup(&ctx->symtab->syms, name, NULL)) {
4607 symtab_errf(ctx, "duplicate symbol '%s'", name);
4608 }
4609 upb_alloc *alloc = upb_arena_alloc(ctx->symtab->arena);
4610 size_t len = strlen(name);
4611 CHK_OOM(upb_strtable_insert3(&ctx->symtab->syms, name, len, v, alloc));
4612 }
4613
4614 /* Given a symbol and the base symbol inside which it is defined, find the
4615 * symbol's definition in t. */
symtab_resolve(symtab_addctx * ctx,const upb_fielddef * f,const char * base,upb_strview sym,upb_deftype_t type)4616 static const void *symtab_resolve(symtab_addctx *ctx, const upb_fielddef *f,
4617 const char *base, upb_strview sym,
4618 upb_deftype_t type) {
4619 const upb_strtable *t = &ctx->symtab->syms;
4620 if(sym.size == 0) goto notfound;
4621 if(sym.data[0] == '.') {
4622 /* Symbols starting with '.' are absolute, so we do a single lookup.
4623 * Slice to omit the leading '.' */
4624 upb_value v;
4625 if (!upb_strtable_lookup2(t, sym.data + 1, sym.size - 1, &v)) {
4626 goto notfound;
4627 }
4628
4629 const void *ret = unpack_def(v, type);
4630 if (!ret) {
4631 symtab_errf(ctx, "type mismatch when resolving field %s, name %s",
4632 f->full_name, sym.data);
4633 }
4634 return ret;
4635 } else {
4636 /* Remove components from base until we find an entry or run out.
4637 * TODO: This branch is totally broken, but currently not used. */
4638 (void)base;
4639 UPB_ASSERT(false);
4640 goto notfound;
4641 }
4642
4643 notfound:
4644 symtab_errf(ctx, "couldn't resolve name '%s'", sym.data);
4645 }
4646
create_oneofdef(symtab_addctx * ctx,upb_msgdef * m,const google_protobuf_OneofDescriptorProto * oneof_proto)4647 static void create_oneofdef(
4648 symtab_addctx *ctx, upb_msgdef *m,
4649 const google_protobuf_OneofDescriptorProto *oneof_proto) {
4650 upb_oneofdef *o;
4651 upb_strview name = google_protobuf_OneofDescriptorProto_name(oneof_proto);
4652 upb_value v;
4653
4654 o = (upb_oneofdef*)&m->oneofs[m->oneof_count++];
4655 o->parent = m;
4656 o->full_name = makefullname(ctx, m->full_name, name);
4657 o->field_count = 0;
4658 o->synthetic = false;
4659
4660 v = pack_def(o, UPB_DEFTYPE_ONEOF);
4661 symtab_add(ctx, o->full_name, v);
4662 CHK_OOM(upb_strtable_insert3(&m->ntof, name.data, name.size, v, ctx->alloc));
4663
4664 CHK_OOM(upb_inttable_init2(&o->itof, UPB_CTYPE_CONSTPTR, ctx->alloc));
4665 CHK_OOM(upb_strtable_init2(&o->ntof, UPB_CTYPE_CONSTPTR, 4, ctx->alloc));
4666 }
4667
newstr(symtab_addctx * ctx,const char * data,size_t len)4668 static str_t *newstr(symtab_addctx *ctx, const char *data, size_t len) {
4669 str_t *ret = symtab_alloc(ctx, sizeof(*ret) + len);
4670 if (!ret) return NULL;
4671 ret->len = len;
4672 if (len) memcpy(ret->str, data, len);
4673 ret->str[len] = '\0';
4674 return ret;
4675 }
4676
parse_default(symtab_addctx * ctx,const char * str,size_t len,upb_fielddef * f)4677 static void parse_default(symtab_addctx *ctx, const char *str, size_t len,
4678 upb_fielddef *f) {
4679 char *end;
4680 char nullz[64];
4681 errno = 0;
4682
4683 switch (upb_fielddef_type(f)) {
4684 case UPB_TYPE_INT32:
4685 case UPB_TYPE_INT64:
4686 case UPB_TYPE_UINT32:
4687 case UPB_TYPE_UINT64:
4688 case UPB_TYPE_DOUBLE:
4689 case UPB_TYPE_FLOAT:
4690 /* Standard C number parsing functions expect null-terminated strings. */
4691 if (len >= sizeof(nullz) - 1) {
4692 symtab_errf(ctx, "Default too long: %.*s", (int)len, str);
4693 }
4694 memcpy(nullz, str, len);
4695 nullz[len] = '\0';
4696 str = nullz;
4697 break;
4698 default:
4699 break;
4700 }
4701
4702 switch (upb_fielddef_type(f)) {
4703 case UPB_TYPE_INT32: {
4704 long val = strtol(str, &end, 0);
4705 if (val > INT32_MAX || val < INT32_MIN || errno == ERANGE || *end) {
4706 goto invalid;
4707 }
4708 f->defaultval.sint = val;
4709 break;
4710 }
4711 case UPB_TYPE_ENUM: {
4712 const upb_enumdef *e = f->sub.enumdef;
4713 int32_t val;
4714 if (!upb_enumdef_ntoi(e, str, len, &val)) {
4715 goto invalid;
4716 }
4717 f->defaultval.sint = val;
4718 break;
4719 }
4720 case UPB_TYPE_INT64: {
4721 /* XXX: Need to write our own strtoll, since it's not available in c89. */
4722 int64_t val = strtol(str, &end, 0);
4723 if (val > INT64_MAX || val < INT64_MIN || errno == ERANGE || *end) {
4724 goto invalid;
4725 }
4726 f->defaultval.sint = val;
4727 break;
4728 }
4729 case UPB_TYPE_UINT32: {
4730 unsigned long val = strtoul(str, &end, 0);
4731 if (val > UINT32_MAX || errno == ERANGE || *end) {
4732 goto invalid;
4733 }
4734 f->defaultval.uint = val;
4735 break;
4736 }
4737 case UPB_TYPE_UINT64: {
4738 /* XXX: Need to write our own strtoull, since it's not available in c89. */
4739 uint64_t val = strtoul(str, &end, 0);
4740 if (val > UINT64_MAX || errno == ERANGE || *end) {
4741 goto invalid;
4742 }
4743 f->defaultval.uint = val;
4744 break;
4745 }
4746 case UPB_TYPE_DOUBLE: {
4747 double val = strtod(str, &end);
4748 if (errno == ERANGE || *end) {
4749 goto invalid;
4750 }
4751 f->defaultval.dbl = val;
4752 break;
4753 }
4754 case UPB_TYPE_FLOAT: {
4755 /* XXX: Need to write our own strtof, since it's not available in c89. */
4756 float val = strtod(str, &end);
4757 if (errno == ERANGE || *end) {
4758 goto invalid;
4759 }
4760 f->defaultval.flt = val;
4761 break;
4762 }
4763 case UPB_TYPE_BOOL: {
4764 if (streql2(str, len, "false")) {
4765 f->defaultval.boolean = false;
4766 } else if (streql2(str, len, "true")) {
4767 f->defaultval.boolean = true;
4768 } else {
4769 }
4770 break;
4771 }
4772 case UPB_TYPE_STRING:
4773 f->defaultval.str = newstr(ctx, str, len);
4774 break;
4775 case UPB_TYPE_BYTES:
4776 /* XXX: need to interpret the C-escaped value. */
4777 f->defaultval.str = newstr(ctx, str, len);
4778 break;
4779 case UPB_TYPE_MESSAGE:
4780 /* Should not have a default value. */
4781 symtab_errf(ctx, "Message should not have a default (%s)",
4782 upb_fielddef_fullname(f));
4783 }
4784
4785 return;
4786
4787 invalid:
4788 symtab_errf(ctx, "Invalid default '%.*s' for field %f", (int)len, str,
4789 upb_fielddef_fullname(f));
4790 }
4791
set_default_default(symtab_addctx * ctx,upb_fielddef * f)4792 static void set_default_default(symtab_addctx *ctx, upb_fielddef *f) {
4793 switch (upb_fielddef_type(f)) {
4794 case UPB_TYPE_INT32:
4795 case UPB_TYPE_INT64:
4796 case UPB_TYPE_ENUM:
4797 f->defaultval.sint = 0;
4798 break;
4799 case UPB_TYPE_UINT64:
4800 case UPB_TYPE_UINT32:
4801 f->defaultval.uint = 0;
4802 break;
4803 case UPB_TYPE_DOUBLE:
4804 case UPB_TYPE_FLOAT:
4805 f->defaultval.dbl = 0;
4806 break;
4807 case UPB_TYPE_STRING:
4808 case UPB_TYPE_BYTES:
4809 f->defaultval.str = newstr(ctx, NULL, 0);
4810 break;
4811 case UPB_TYPE_BOOL:
4812 f->defaultval.boolean = false;
4813 break;
4814 case UPB_TYPE_MESSAGE:
4815 break;
4816 }
4817 }
4818
create_fielddef(symtab_addctx * ctx,const char * prefix,upb_msgdef * m,const google_protobuf_FieldDescriptorProto * field_proto)4819 static void create_fielddef(
4820 symtab_addctx *ctx, const char *prefix, upb_msgdef *m,
4821 const google_protobuf_FieldDescriptorProto *field_proto) {
4822 upb_alloc *alloc = ctx->alloc;
4823 upb_fielddef *f;
4824 const google_protobuf_FieldOptions *options;
4825 upb_strview name;
4826 const char *full_name;
4827 const char *json_name;
4828 const char *shortname;
4829 uint32_t field_number;
4830
4831 if (!google_protobuf_FieldDescriptorProto_has_name(field_proto)) {
4832 symtab_errf(ctx, "field has no name (%s)", upb_msgdef_fullname(m));
4833 }
4834
4835 name = google_protobuf_FieldDescriptorProto_name(field_proto);
4836 check_ident(ctx, name, false);
4837 full_name = makefullname(ctx, prefix, name);
4838 shortname = shortdefname(full_name);
4839
4840 if (google_protobuf_FieldDescriptorProto_has_json_name(field_proto)) {
4841 json_name = strviewdup(
4842 ctx, google_protobuf_FieldDescriptorProto_json_name(field_proto));
4843 } else {
4844 json_name = makejsonname(ctx, shortname);
4845 }
4846
4847 field_number = google_protobuf_FieldDescriptorProto_number(field_proto);
4848
4849 if (field_number == 0 || field_number > UPB_MAX_FIELDNUMBER) {
4850 symtab_errf(ctx, "invalid field number (%u)", field_number);
4851 }
4852
4853 if (m) {
4854 /* direct message field. */
4855 upb_value v, field_v, json_v;
4856 size_t json_size;
4857
4858 f = (upb_fielddef*)&m->fields[m->field_count++];
4859 f->msgdef = m;
4860 f->is_extension_ = false;
4861
4862 if (upb_strtable_lookup(&m->ntof, shortname, NULL)) {
4863 symtab_errf(ctx, "duplicate field name (%s)", shortname);
4864 }
4865
4866 if (upb_strtable_lookup(&m->ntof, json_name, NULL)) {
4867 symtab_errf(ctx, "duplicate json_name (%s)", json_name);
4868 }
4869
4870 if (upb_inttable_lookup(&m->itof, field_number, NULL)) {
4871 symtab_errf(ctx, "duplicate field number (%u)", field_number);
4872 }
4873
4874 field_v = pack_def(f, UPB_DEFTYPE_FIELD);
4875 json_v = pack_def(f, UPB_DEFTYPE_FIELD_JSONNAME);
4876 v = upb_value_constptr(f);
4877 json_size = strlen(json_name);
4878
4879 CHK_OOM(
4880 upb_strtable_insert3(&m->ntof, name.data, name.size, field_v, alloc));
4881 CHK_OOM(upb_inttable_insert2(&m->itof, field_number, v, alloc));
4882
4883 if (strcmp(shortname, json_name) != 0) {
4884 upb_strtable_insert3(&m->ntof, json_name, json_size, json_v, alloc);
4885 }
4886
4887 if (ctx->layouts) {
4888 const upb_msglayout_field *fields = m->layout->fields;
4889 int count = m->layout->field_count;
4890 bool found = false;
4891 int i;
4892 for (i = 0; i < count; i++) {
4893 if (fields[i].number == field_number) {
4894 f->layout_index = i;
4895 found = true;
4896 break;
4897 }
4898 }
4899 UPB_ASSERT(found);
4900 }
4901 } else {
4902 /* extension field. */
4903 f = (upb_fielddef*)&ctx->file->exts[ctx->file->ext_count++];
4904 f->is_extension_ = true;
4905 symtab_add(ctx, full_name, pack_def(f, UPB_DEFTYPE_FIELD));
4906 }
4907
4908 f->full_name = full_name;
4909 f->json_name = json_name;
4910 f->file = ctx->file;
4911 f->type_ = (int)google_protobuf_FieldDescriptorProto_type(field_proto);
4912 f->label_ = (int)google_protobuf_FieldDescriptorProto_label(field_proto);
4913 f->number_ = field_number;
4914 f->oneof = NULL;
4915 f->proto3_optional_ =
4916 google_protobuf_FieldDescriptorProto_proto3_optional(field_proto);
4917
4918 /* We can't resolve the subdef or (in the case of extensions) the containing
4919 * message yet, because it may not have been defined yet. We stash a pointer
4920 * to the field_proto until later when we can properly resolve it. */
4921 f->sub.unresolved = field_proto;
4922
4923 if (f->label_ == UPB_LABEL_REQUIRED && f->file->syntax == UPB_SYNTAX_PROTO3) {
4924 symtab_errf(ctx, "proto3 fields cannot be required (%s)", f->full_name);
4925 }
4926
4927 if (google_protobuf_FieldDescriptorProto_has_oneof_index(field_proto)) {
4928 int oneof_index =
4929 google_protobuf_FieldDescriptorProto_oneof_index(field_proto);
4930 upb_oneofdef *oneof;
4931 upb_value v = upb_value_constptr(f);
4932
4933 if (upb_fielddef_label(f) != UPB_LABEL_OPTIONAL) {
4934 symtab_errf(ctx, "fields in oneof must have OPTIONAL label (%s)",
4935 f->full_name);
4936 }
4937
4938 if (!m) {
4939 symtab_errf(ctx, "oneof_index provided for extension field (%s)",
4940 f->full_name);
4941 }
4942
4943 if (oneof_index >= m->oneof_count) {
4944 symtab_errf(ctx, "oneof_index out of range (%s)", f->full_name);
4945 }
4946
4947 oneof = (upb_oneofdef*)&m->oneofs[oneof_index];
4948 f->oneof = oneof;
4949
4950 oneof->field_count++;
4951 if (f->proto3_optional_) {
4952 oneof->synthetic = true;
4953 }
4954 CHK_OOM(upb_inttable_insert2(&oneof->itof, f->number_, v, alloc));
4955 CHK_OOM(upb_strtable_insert3(&oneof->ntof, name.data, name.size, v, alloc));
4956 } else {
4957 f->oneof = NULL;
4958 if (f->proto3_optional_) {
4959 symtab_errf(ctx, "field with proto3_optional was not in a oneof (%s)",
4960 f->full_name);
4961 }
4962 }
4963
4964 options = google_protobuf_FieldDescriptorProto_has_options(field_proto) ?
4965 google_protobuf_FieldDescriptorProto_options(field_proto) : NULL;
4966
4967 if (options && google_protobuf_FieldOptions_has_packed(options)) {
4968 f->packed_ = google_protobuf_FieldOptions_packed(options);
4969 } else {
4970 /* Repeated fields default to packed for proto3 only. */
4971 f->packed_ = upb_fielddef_isprimitive(f) &&
4972 f->label_ == UPB_LABEL_REPEATED && f->file->syntax == UPB_SYNTAX_PROTO3;
4973 }
4974
4975 if (options) {
4976 f->lazy_ = google_protobuf_FieldOptions_lazy(options);
4977 } else {
4978 f->lazy_ = false;
4979 }
4980 }
4981
create_enumdef(symtab_addctx * ctx,const char * prefix,const google_protobuf_EnumDescriptorProto * enum_proto)4982 static void create_enumdef(
4983 symtab_addctx *ctx, const char *prefix,
4984 const google_protobuf_EnumDescriptorProto *enum_proto) {
4985 upb_enumdef *e;
4986 const google_protobuf_EnumValueDescriptorProto *const *values;
4987 upb_strview name;
4988 size_t i, n;
4989
4990 name = google_protobuf_EnumDescriptorProto_name(enum_proto);
4991 check_ident(ctx, name, false);
4992
4993 e = (upb_enumdef*)&ctx->file->enums[ctx->file->enum_count++];
4994 e->full_name = makefullname(ctx, prefix, name);
4995 symtab_add(ctx, e->full_name, pack_def(e, UPB_DEFTYPE_ENUM));
4996
4997 values = google_protobuf_EnumDescriptorProto_value(enum_proto, &n);
4998 CHK_OOM(upb_strtable_init2(&e->ntoi, UPB_CTYPE_INT32, n, ctx->alloc));
4999 CHK_OOM(upb_inttable_init2(&e->iton, UPB_CTYPE_CSTR, ctx->alloc));
5000
5001 e->file = ctx->file;
5002 e->defaultval = 0;
5003
5004 if (n == 0) {
5005 symtab_errf(ctx, "enums must contain at least one value (%s)",
5006 e->full_name);
5007 }
5008
5009 for (i = 0; i < n; i++) {
5010 const google_protobuf_EnumValueDescriptorProto *value = values[i];
5011 upb_strview name = google_protobuf_EnumValueDescriptorProto_name(value);
5012 char *name2 = strviewdup(ctx, name);
5013 int32_t num = google_protobuf_EnumValueDescriptorProto_number(value);
5014 upb_value v = upb_value_int32(num);
5015
5016 if (i == 0 && e->file->syntax == UPB_SYNTAX_PROTO3 && num != 0) {
5017 symtab_errf(ctx, "for proto3, the first enum value must be zero (%s)",
5018 e->full_name);
5019 }
5020
5021 if (upb_strtable_lookup(&e->ntoi, name2, NULL)) {
5022 symtab_errf(ctx, "duplicate enum label '%s'", name2);
5023 }
5024
5025 CHK_OOM(name2)
5026 CHK_OOM(
5027 upb_strtable_insert3(&e->ntoi, name2, strlen(name2), v, ctx->alloc));
5028
5029 if (!upb_inttable_lookup(&e->iton, num, NULL)) {
5030 upb_value v = upb_value_cstr(name2);
5031 CHK_OOM(upb_inttable_insert2(&e->iton, num, v, ctx->alloc));
5032 }
5033 }
5034
5035 upb_inttable_compact2(&e->iton, ctx->alloc);
5036 }
5037
create_msgdef(symtab_addctx * ctx,const char * prefix,const google_protobuf_DescriptorProto * msg_proto)5038 static void create_msgdef(symtab_addctx *ctx, const char *prefix,
5039 const google_protobuf_DescriptorProto *msg_proto) {
5040 upb_msgdef *m;
5041 const google_protobuf_MessageOptions *options;
5042 const google_protobuf_OneofDescriptorProto *const *oneofs;
5043 const google_protobuf_FieldDescriptorProto *const *fields;
5044 const google_protobuf_EnumDescriptorProto *const *enums;
5045 const google_protobuf_DescriptorProto *const *msgs;
5046 size_t i, n_oneof, n_field, n;
5047 upb_strview name;
5048
5049 name = google_protobuf_DescriptorProto_name(msg_proto);
5050 check_ident(ctx, name, false);
5051
5052 m = (upb_msgdef*)&ctx->file->msgs[ctx->file->msg_count++];
5053 m->full_name = makefullname(ctx, prefix, name);
5054 symtab_add(ctx, m->full_name, pack_def(m, UPB_DEFTYPE_MSG));
5055
5056 oneofs = google_protobuf_DescriptorProto_oneof_decl(msg_proto, &n_oneof);
5057 fields = google_protobuf_DescriptorProto_field(msg_proto, &n_field);
5058
5059 CHK_OOM(upb_inttable_init2(&m->itof, UPB_CTYPE_CONSTPTR, ctx->alloc));
5060 CHK_OOM(upb_strtable_init2(&m->ntof, UPB_CTYPE_CONSTPTR, n_oneof + n_field,
5061 ctx->alloc));
5062
5063 m->file = ctx->file;
5064 m->map_entry = false;
5065
5066 options = google_protobuf_DescriptorProto_options(msg_proto);
5067
5068 if (options) {
5069 m->map_entry = google_protobuf_MessageOptions_map_entry(options);
5070 }
5071
5072 if (ctx->layouts) {
5073 m->layout = *ctx->layouts;
5074 ctx->layouts++;
5075 } else {
5076 /* Allocate now (to allow cross-linking), populate later. */
5077 m->layout = symtab_alloc(ctx, sizeof(*m->layout));
5078 }
5079
5080 m->oneof_count = 0;
5081 m->oneofs = symtab_alloc(ctx, sizeof(*m->oneofs) * n_oneof);
5082 for (i = 0; i < n_oneof; i++) {
5083 create_oneofdef(ctx, m, oneofs[i]);
5084 }
5085
5086 m->field_count = 0;
5087 m->fields = symtab_alloc(ctx, sizeof(*m->fields) * n_field);
5088 for (i = 0; i < n_field; i++) {
5089 create_fielddef(ctx, m->full_name, m, fields[i]);
5090 }
5091
5092 assign_msg_indices(ctx, m);
5093 finalize_oneofs(ctx, m);
5094 assign_msg_wellknowntype(m);
5095 upb_inttable_compact2(&m->itof, ctx->alloc);
5096
5097 /* This message is built. Now build nested messages and enums. */
5098
5099 enums = google_protobuf_DescriptorProto_enum_type(msg_proto, &n);
5100 for (i = 0; i < n; i++) {
5101 create_enumdef(ctx, m->full_name, enums[i]);
5102 }
5103
5104 msgs = google_protobuf_DescriptorProto_nested_type(msg_proto, &n);
5105 for (i = 0; i < n; i++) {
5106 create_msgdef(ctx, m->full_name, msgs[i]);
5107 }
5108 }
5109
count_types_in_msg(const google_protobuf_DescriptorProto * msg_proto,upb_filedef * file)5110 static void count_types_in_msg(const google_protobuf_DescriptorProto *msg_proto,
5111 upb_filedef *file) {
5112 const google_protobuf_DescriptorProto *const *msgs;
5113 size_t i, n;
5114
5115 file->msg_count++;
5116
5117 msgs = google_protobuf_DescriptorProto_nested_type(msg_proto, &n);
5118 for (i = 0; i < n; i++) {
5119 count_types_in_msg(msgs[i], file);
5120 }
5121
5122 google_protobuf_DescriptorProto_enum_type(msg_proto, &n);
5123 file->enum_count += n;
5124
5125 google_protobuf_DescriptorProto_extension(msg_proto, &n);
5126 file->ext_count += n;
5127 }
5128
count_types_in_file(const google_protobuf_FileDescriptorProto * file_proto,upb_filedef * file)5129 static void count_types_in_file(
5130 const google_protobuf_FileDescriptorProto *file_proto,
5131 upb_filedef *file) {
5132 const google_protobuf_DescriptorProto *const *msgs;
5133 size_t i, n;
5134
5135 msgs = google_protobuf_FileDescriptorProto_message_type(file_proto, &n);
5136 for (i = 0; i < n; i++) {
5137 count_types_in_msg(msgs[i], file);
5138 }
5139
5140 google_protobuf_FileDescriptorProto_enum_type(file_proto, &n);
5141 file->enum_count += n;
5142
5143 google_protobuf_FileDescriptorProto_extension(file_proto, &n);
5144 file->ext_count += n;
5145 }
5146
resolve_fielddef(symtab_addctx * ctx,const char * prefix,upb_fielddef * f)5147 static void resolve_fielddef(symtab_addctx *ctx, const char *prefix,
5148 upb_fielddef *f) {
5149 upb_strview name;
5150 const google_protobuf_FieldDescriptorProto *field_proto = f->sub.unresolved;
5151
5152 if (f->is_extension_) {
5153 if (!google_protobuf_FieldDescriptorProto_has_extendee(field_proto)) {
5154 symtab_errf(ctx, "extension for field '%s' had no extendee",
5155 f->full_name);
5156 }
5157
5158 name = google_protobuf_FieldDescriptorProto_extendee(field_proto);
5159 f->msgdef = symtab_resolve(ctx, f, prefix, name, UPB_DEFTYPE_MSG);
5160 }
5161
5162 if ((upb_fielddef_issubmsg(f) || f->type_ == UPB_DESCRIPTOR_TYPE_ENUM) &&
5163 !google_protobuf_FieldDescriptorProto_has_type_name(field_proto)) {
5164 symtab_errf(ctx, "field '%s' is missing type name", f->full_name);
5165 }
5166
5167 name = google_protobuf_FieldDescriptorProto_type_name(field_proto);
5168
5169 if (upb_fielddef_issubmsg(f)) {
5170 f->sub.msgdef = symtab_resolve(ctx, f, prefix, name, UPB_DEFTYPE_MSG);
5171 } else if (f->type_ == UPB_DESCRIPTOR_TYPE_ENUM) {
5172 f->sub.enumdef = symtab_resolve(ctx, f, prefix, name, UPB_DEFTYPE_ENUM);
5173 }
5174
5175 /* Have to delay resolving of the default value until now because of the enum
5176 * case, since enum defaults are specified with a label. */
5177 if (google_protobuf_FieldDescriptorProto_has_default_value(field_proto)) {
5178 upb_strview defaultval =
5179 google_protobuf_FieldDescriptorProto_default_value(field_proto);
5180
5181 if (f->file->syntax == UPB_SYNTAX_PROTO3) {
5182 symtab_errf(ctx, "proto3 fields cannot have explicit defaults (%s)",
5183 f->full_name);
5184 }
5185
5186 if (upb_fielddef_issubmsg(f)) {
5187 symtab_errf(ctx, "message fields cannot have explicit defaults (%s)",
5188 f->full_name);
5189 }
5190
5191 parse_default(ctx, defaultval.data, defaultval.size, f);
5192 } else {
5193 set_default_default(ctx, f);
5194 }
5195 }
5196
build_filedef(symtab_addctx * ctx,upb_filedef * file,const google_protobuf_FileDescriptorProto * file_proto)5197 static void build_filedef(
5198 symtab_addctx *ctx, upb_filedef *file,
5199 const google_protobuf_FileDescriptorProto *file_proto) {
5200 const google_protobuf_FileOptions *file_options_proto;
5201 const google_protobuf_DescriptorProto *const *msgs;
5202 const google_protobuf_EnumDescriptorProto *const *enums;
5203 const google_protobuf_FieldDescriptorProto *const *exts;
5204 const upb_strview* strs;
5205 size_t i, n;
5206
5207 count_types_in_file(file_proto, file);
5208
5209 file->msgs = symtab_alloc(ctx, sizeof(*file->msgs) * file->msg_count);
5210 file->enums = symtab_alloc(ctx, sizeof(*file->enums) * file->enum_count);
5211 file->exts = symtab_alloc(ctx, sizeof(*file->exts) * file->ext_count);
5212
5213 /* We increment these as defs are added. */
5214 file->msg_count = 0;
5215 file->enum_count = 0;
5216 file->ext_count = 0;
5217
5218 if (!google_protobuf_FileDescriptorProto_has_name(file_proto)) {
5219 symtab_errf(ctx, "File has no name");
5220 }
5221
5222 file->name =
5223 strviewdup(ctx, google_protobuf_FileDescriptorProto_name(file_proto));
5224 file->phpprefix = NULL;
5225 file->phpnamespace = NULL;
5226
5227 if (google_protobuf_FileDescriptorProto_has_package(file_proto)) {
5228 upb_strview package =
5229 google_protobuf_FileDescriptorProto_package(file_proto);
5230 check_ident(ctx, package, true);
5231 file->package = strviewdup(ctx, package);
5232 } else {
5233 file->package = NULL;
5234 }
5235
5236 if (google_protobuf_FileDescriptorProto_has_syntax(file_proto)) {
5237 upb_strview syntax =
5238 google_protobuf_FileDescriptorProto_syntax(file_proto);
5239
5240 if (streql_view(syntax, "proto2")) {
5241 file->syntax = UPB_SYNTAX_PROTO2;
5242 } else if (streql_view(syntax, "proto3")) {
5243 file->syntax = UPB_SYNTAX_PROTO3;
5244 } else {
5245 symtab_errf(ctx, "Invalid syntax '" UPB_STRVIEW_FORMAT "'",
5246 UPB_STRVIEW_ARGS(syntax));
5247 }
5248 } else {
5249 file->syntax = UPB_SYNTAX_PROTO2;
5250 }
5251
5252 /* Read options. */
5253 file_options_proto = google_protobuf_FileDescriptorProto_options(file_proto);
5254 if (file_options_proto) {
5255 if (google_protobuf_FileOptions_has_php_class_prefix(file_options_proto)) {
5256 file->phpprefix = strviewdup(
5257 ctx,
5258 google_protobuf_FileOptions_php_class_prefix(file_options_proto));
5259 }
5260 if (google_protobuf_FileOptions_has_php_namespace(file_options_proto)) {
5261 file->phpnamespace = strviewdup(
5262 ctx, google_protobuf_FileOptions_php_namespace(file_options_proto));
5263 }
5264 }
5265
5266 /* Verify dependencies. */
5267 strs = google_protobuf_FileDescriptorProto_dependency(file_proto, &n);
5268 file->deps = symtab_alloc(ctx, sizeof(*file->deps) * n);
5269
5270 for (i = 0; i < n; i++) {
5271 upb_strview dep_name = strs[i];
5272 upb_value v;
5273 if (!upb_strtable_lookup2(&ctx->symtab->files, dep_name.data,
5274 dep_name.size, &v)) {
5275 symtab_errf(ctx,
5276 "Depends on file '" UPB_STRVIEW_FORMAT
5277 "', but it has not been loaded",
5278 UPB_STRVIEW_ARGS(dep_name));
5279 }
5280 file->deps[i] = upb_value_getconstptr(v);
5281 }
5282
5283 /* Create messages. */
5284 msgs = google_protobuf_FileDescriptorProto_message_type(file_proto, &n);
5285 for (i = 0; i < n; i++) {
5286 create_msgdef(ctx, file->package, msgs[i]);
5287 }
5288
5289 /* Create enums. */
5290 enums = google_protobuf_FileDescriptorProto_enum_type(file_proto, &n);
5291 for (i = 0; i < n; i++) {
5292 create_enumdef(ctx, file->package, enums[i]);
5293 }
5294
5295 /* Create extensions. */
5296 exts = google_protobuf_FileDescriptorProto_extension(file_proto, &n);
5297 file->exts = symtab_alloc(ctx, sizeof(*file->exts) * n);
5298 for (i = 0; i < n; i++) {
5299 create_fielddef(ctx, file->package, NULL, exts[i]);
5300 }
5301
5302 /* Now that all names are in the table, build layouts and resolve refs. */
5303 for (i = 0; i < (size_t)file->ext_count; i++) {
5304 resolve_fielddef(ctx, file->package, (upb_fielddef*)&file->exts[i]);
5305 }
5306
5307 for (i = 0; i < (size_t)file->msg_count; i++) {
5308 const upb_msgdef *m = &file->msgs[i];
5309 int j;
5310 for (j = 0; j < m->field_count; j++) {
5311 resolve_fielddef(ctx, m->full_name, (upb_fielddef*)&m->fields[j]);
5312 }
5313 }
5314
5315 if (!ctx->layouts) {
5316 for (i = 0; i < (size_t)file->msg_count; i++) {
5317 const upb_msgdef *m = &file->msgs[i];
5318 make_layout(ctx, m);
5319 }
5320 }
5321 }
5322
remove_filedef(upb_symtab * s,upb_filedef * file)5323 static void remove_filedef(upb_symtab *s, upb_filedef *file) {
5324 upb_alloc *alloc = upb_arena_alloc(s->arena);
5325 int i;
5326 for (i = 0; i < file->msg_count; i++) {
5327 const char *name = file->msgs[i].full_name;
5328 upb_strtable_remove3(&s->syms, name, strlen(name), NULL, alloc);
5329 }
5330 for (i = 0; i < file->enum_count; i++) {
5331 const char *name = file->enums[i].full_name;
5332 upb_strtable_remove3(&s->syms, name, strlen(name), NULL, alloc);
5333 }
5334 for (i = 0; i < file->ext_count; i++) {
5335 const char *name = file->exts[i].full_name;
5336 upb_strtable_remove3(&s->syms, name, strlen(name), NULL, alloc);
5337 }
5338 }
5339
_upb_symtab_addfile(upb_symtab * s,const google_protobuf_FileDescriptorProto * file_proto,const upb_msglayout ** layouts,upb_status * status)5340 static const upb_filedef *_upb_symtab_addfile(
5341 upb_symtab *s, const google_protobuf_FileDescriptorProto *file_proto,
5342 const upb_msglayout **layouts, upb_status *status) {
5343 upb_arena *file_arena = upb_arena_new();
5344 upb_filedef *file;
5345 symtab_addctx ctx;
5346
5347 if (!file_arena) return NULL;
5348
5349 file = upb_arena_malloc(file_arena, sizeof(*file));
5350 if (!file) goto done;
5351
5352 ctx.file = file;
5353 ctx.symtab = s;
5354 ctx.file_arena = file_arena;
5355 ctx.alloc = upb_arena_alloc(file_arena);
5356 ctx.layouts = layouts;
5357 ctx.status = status;
5358
5359 file->msg_count = 0;
5360 file->enum_count = 0;
5361 file->ext_count = 0;
5362
5363 if (UPB_UNLIKELY(setjmp(ctx.err))) {
5364 UPB_ASSERT(!upb_ok(status));
5365 remove_filedef(s, file);
5366 file = NULL;
5367 } else {
5368 build_filedef(&ctx, file, file_proto);
5369 upb_strtable_insert3(&s->files, file->name, strlen(file->name),
5370 upb_value_constptr(file), ctx.alloc);
5371 UPB_ASSERT(upb_ok(status));
5372 upb_arena_fuse(s->arena, file_arena);
5373 }
5374
5375 done:
5376 upb_arena_free(file_arena);
5377 return file;
5378 }
5379
upb_symtab_addfile(upb_symtab * s,const google_protobuf_FileDescriptorProto * file_proto,upb_status * status)5380 const upb_filedef *upb_symtab_addfile(
5381 upb_symtab *s, const google_protobuf_FileDescriptorProto *file_proto,
5382 upb_status *status) {
5383 return _upb_symtab_addfile(s, file_proto, NULL, status);
5384 }
5385
5386 /* Include here since we want most of this file to be stdio-free. */
5387 #include <stdio.h>
5388
_upb_symtab_loaddefinit(upb_symtab * s,const upb_def_init * init)5389 bool _upb_symtab_loaddefinit(upb_symtab *s, const upb_def_init *init) {
5390 /* Since this function should never fail (it would indicate a bug in upb) we
5391 * print errors to stderr instead of returning error status to the user. */
5392 upb_def_init **deps = init->deps;
5393 google_protobuf_FileDescriptorProto *file;
5394 upb_arena *arena;
5395 upb_status status;
5396
5397 upb_status_clear(&status);
5398
5399 if (upb_strtable_lookup(&s->files, init->filename, NULL)) {
5400 return true;
5401 }
5402
5403 arena = upb_arena_new();
5404
5405 for (; *deps; deps++) {
5406 if (!_upb_symtab_loaddefinit(s, *deps)) goto err;
5407 }
5408
5409 file = google_protobuf_FileDescriptorProto_parse(
5410 init->descriptor.data, init->descriptor.size, arena);
5411 s->bytes_loaded += init->descriptor.size;
5412
5413 if (!file) {
5414 upb_status_seterrf(
5415 &status,
5416 "Failed to parse compiled-in descriptor for file '%s'. This should "
5417 "never happen.",
5418 init->filename);
5419 goto err;
5420 }
5421
5422 if (!_upb_symtab_addfile(s, file, init->layouts, &status)) goto err;
5423
5424 upb_arena_free(arena);
5425 return true;
5426
5427 err:
5428 fprintf(stderr, "Error loading compiled-in descriptor: %s\n",
5429 upb_status_errmsg(&status));
5430 upb_arena_free(arena);
5431 return false;
5432 }
5433
_upb_symtab_bytesloaded(const upb_symtab * s)5434 size_t _upb_symtab_bytesloaded(const upb_symtab *s) {
5435 return s->bytes_loaded;
5436 }
5437
5438 #undef CHK_OOM
5439
5440
5441 #include <string.h>
5442
5443
get_field_size(const upb_msglayout_field * f)5444 static size_t get_field_size(const upb_msglayout_field *f) {
5445 static unsigned char sizes[] = {
5446 0,/* 0 */
5447 8, /* UPB_DESCRIPTOR_TYPE_DOUBLE */
5448 4, /* UPB_DESCRIPTOR_TYPE_FLOAT */
5449 8, /* UPB_DESCRIPTOR_TYPE_INT64 */
5450 8, /* UPB_DESCRIPTOR_TYPE_UINT64 */
5451 4, /* UPB_DESCRIPTOR_TYPE_INT32 */
5452 8, /* UPB_DESCRIPTOR_TYPE_FIXED64 */
5453 4, /* UPB_DESCRIPTOR_TYPE_FIXED32 */
5454 1, /* UPB_DESCRIPTOR_TYPE_BOOL */
5455 sizeof(upb_strview), /* UPB_DESCRIPTOR_TYPE_STRING */
5456 sizeof(void*), /* UPB_DESCRIPTOR_TYPE_GROUP */
5457 sizeof(void*), /* UPB_DESCRIPTOR_TYPE_MESSAGE */
5458 sizeof(upb_strview), /* UPB_DESCRIPTOR_TYPE_BYTES */
5459 4, /* UPB_DESCRIPTOR_TYPE_UINT32 */
5460 4, /* UPB_DESCRIPTOR_TYPE_ENUM */
5461 4, /* UPB_DESCRIPTOR_TYPE_SFIXED32 */
5462 8, /* UPB_DESCRIPTOR_TYPE_SFIXED64 */
5463 4, /* UPB_DESCRIPTOR_TYPE_SINT32 */
5464 8, /* UPB_DESCRIPTOR_TYPE_SINT64 */
5465 };
5466 return _upb_repeated_or_map(f) ? sizeof(void *) : sizes[f->descriptortype];
5467 }
5468
5469 /* Strings/bytes are special-cased in maps. */
5470 static char _upb_fieldtype_to_mapsize[12] = {
5471 0,
5472 1, /* UPB_TYPE_BOOL */
5473 4, /* UPB_TYPE_FLOAT */
5474 4, /* UPB_TYPE_INT32 */
5475 4, /* UPB_TYPE_UINT32 */
5476 4, /* UPB_TYPE_ENUM */
5477 sizeof(void*), /* UPB_TYPE_MESSAGE */
5478 8, /* UPB_TYPE_DOUBLE */
5479 8, /* UPB_TYPE_INT64 */
5480 8, /* UPB_TYPE_UINT64 */
5481 0, /* UPB_TYPE_STRING */
5482 0, /* UPB_TYPE_BYTES */
5483 };
5484
5485 static const char _upb_fieldtype_to_sizelg2[12] = {
5486 0,
5487 0, /* UPB_TYPE_BOOL */
5488 2, /* UPB_TYPE_FLOAT */
5489 2, /* UPB_TYPE_INT32 */
5490 2, /* UPB_TYPE_UINT32 */
5491 2, /* UPB_TYPE_ENUM */
5492 UPB_SIZE(2, 3), /* UPB_TYPE_MESSAGE */
5493 3, /* UPB_TYPE_DOUBLE */
5494 3, /* UPB_TYPE_INT64 */
5495 3, /* UPB_TYPE_UINT64 */
5496 UPB_SIZE(3, 4), /* UPB_TYPE_STRING */
5497 UPB_SIZE(3, 4), /* UPB_TYPE_BYTES */
5498 };
5499
5500 /** upb_msg *******************************************************************/
5501
upb_msg_new(const upb_msgdef * m,upb_arena * a)5502 upb_msg *upb_msg_new(const upb_msgdef *m, upb_arena *a) {
5503 return _upb_msg_new(upb_msgdef_layout(m), a);
5504 }
5505
in_oneof(const upb_msglayout_field * field)5506 static bool in_oneof(const upb_msglayout_field *field) {
5507 return field->presence < 0;
5508 }
5509
_upb_msg_getraw(const upb_msg * msg,const upb_fielddef * f)5510 static upb_msgval _upb_msg_getraw(const upb_msg *msg, const upb_fielddef *f) {
5511 const upb_msglayout_field *field = upb_fielddef_layout(f);
5512 const char *mem = UPB_PTR_AT(msg, field->offset, char);
5513 upb_msgval val = {0};
5514 memcpy(&val, mem, get_field_size(field));
5515 return val;
5516 }
5517
upb_msg_has(const upb_msg * msg,const upb_fielddef * f)5518 bool upb_msg_has(const upb_msg *msg, const upb_fielddef *f) {
5519 const upb_msglayout_field *field = upb_fielddef_layout(f);
5520 if (in_oneof(field)) {
5521 return _upb_getoneofcase_field(msg, field) == field->number;
5522 } else if (field->presence > 0) {
5523 return _upb_hasbit_field(msg, field);
5524 } else {
5525 UPB_ASSERT(field->descriptortype == UPB_DESCRIPTOR_TYPE_MESSAGE ||
5526 field->descriptortype == UPB_DESCRIPTOR_TYPE_GROUP);
5527 return _upb_msg_getraw(msg, f).msg_val != NULL;
5528 }
5529 }
5530
upb_msg_whichoneof(const upb_msg * msg,const upb_oneofdef * o)5531 const upb_fielddef *upb_msg_whichoneof(const upb_msg *msg,
5532 const upb_oneofdef *o) {
5533 const upb_fielddef *f = upb_oneofdef_field(o, 0);
5534 if (upb_oneofdef_issynthetic(o)) {
5535 UPB_ASSERT(upb_oneofdef_fieldcount(o) == 1);
5536 return upb_msg_has(msg, f) ? f : NULL;
5537 } else {
5538 const upb_msglayout_field *field = upb_fielddef_layout(f);
5539 uint32_t oneof_case = _upb_getoneofcase_field(msg, field);
5540 f = oneof_case ? upb_oneofdef_itof(o, oneof_case) : NULL;
5541 UPB_ASSERT((f != NULL) == (oneof_case != 0));
5542 return f;
5543 }
5544 }
5545
upb_msg_get(const upb_msg * msg,const upb_fielddef * f)5546 upb_msgval upb_msg_get(const upb_msg *msg, const upb_fielddef *f) {
5547 if (!upb_fielddef_haspresence(f) || upb_msg_has(msg, f)) {
5548 return _upb_msg_getraw(msg, f);
5549 } else {
5550 /* TODO(haberman): change upb_fielddef to not require this switch(). */
5551 upb_msgval val = {0};
5552 switch (upb_fielddef_type(f)) {
5553 case UPB_TYPE_INT32:
5554 case UPB_TYPE_ENUM:
5555 val.int32_val = upb_fielddef_defaultint32(f);
5556 break;
5557 case UPB_TYPE_INT64:
5558 val.int64_val = upb_fielddef_defaultint64(f);
5559 break;
5560 case UPB_TYPE_UINT32:
5561 val.uint32_val = upb_fielddef_defaultuint32(f);
5562 break;
5563 case UPB_TYPE_UINT64:
5564 val.uint64_val = upb_fielddef_defaultuint64(f);
5565 break;
5566 case UPB_TYPE_FLOAT:
5567 val.float_val = upb_fielddef_defaultfloat(f);
5568 break;
5569 case UPB_TYPE_DOUBLE:
5570 val.double_val = upb_fielddef_defaultdouble(f);
5571 break;
5572 case UPB_TYPE_BOOL:
5573 val.double_val = upb_fielddef_defaultbool(f);
5574 break;
5575 case UPB_TYPE_STRING:
5576 case UPB_TYPE_BYTES:
5577 val.str_val.data = upb_fielddef_defaultstr(f, &val.str_val.size);
5578 break;
5579 case UPB_TYPE_MESSAGE:
5580 val.msg_val = NULL;
5581 break;
5582 }
5583 return val;
5584 }
5585 }
5586
upb_msg_mutable(upb_msg * msg,const upb_fielddef * f,upb_arena * a)5587 upb_mutmsgval upb_msg_mutable(upb_msg *msg, const upb_fielddef *f,
5588 upb_arena *a) {
5589 const upb_msglayout_field *field = upb_fielddef_layout(f);
5590 upb_mutmsgval ret;
5591 char *mem = UPB_PTR_AT(msg, field->offset, char);
5592 bool wrong_oneof =
5593 in_oneof(field) && _upb_getoneofcase_field(msg, field) != field->number;
5594
5595 memcpy(&ret, mem, sizeof(void*));
5596
5597 if (a && (!ret.msg || wrong_oneof)) {
5598 if (upb_fielddef_ismap(f)) {
5599 const upb_msgdef *entry = upb_fielddef_msgsubdef(f);
5600 const upb_fielddef *key = upb_msgdef_itof(entry, UPB_MAPENTRY_KEY);
5601 const upb_fielddef *value = upb_msgdef_itof(entry, UPB_MAPENTRY_VALUE);
5602 ret.map = upb_map_new(a, upb_fielddef_type(key), upb_fielddef_type(value));
5603 } else if (upb_fielddef_isseq(f)) {
5604 ret.array = upb_array_new(a, upb_fielddef_type(f));
5605 } else {
5606 UPB_ASSERT(upb_fielddef_issubmsg(f));
5607 ret.msg = upb_msg_new(upb_fielddef_msgsubdef(f), a);
5608 }
5609
5610 memcpy(mem, &ret, sizeof(void*));
5611
5612 if (wrong_oneof) {
5613 *_upb_oneofcase_field(msg, field) = field->number;
5614 } else if (field->presence > 0) {
5615 _upb_sethas_field(msg, field);
5616 }
5617 }
5618 return ret;
5619 }
5620
upb_msg_set(upb_msg * msg,const upb_fielddef * f,upb_msgval val,upb_arena * a)5621 void upb_msg_set(upb_msg *msg, const upb_fielddef *f, upb_msgval val,
5622 upb_arena *a) {
5623 const upb_msglayout_field *field = upb_fielddef_layout(f);
5624 char *mem = UPB_PTR_AT(msg, field->offset, char);
5625 UPB_UNUSED(a); /* We reserve the right to make set insert into a map. */
5626 memcpy(mem, &val, get_field_size(field));
5627 if (field->presence > 0) {
5628 _upb_sethas_field(msg, field);
5629 } else if (in_oneof(field)) {
5630 *_upb_oneofcase_field(msg, field) = field->number;
5631 }
5632 }
5633
upb_msg_clearfield(upb_msg * msg,const upb_fielddef * f)5634 void upb_msg_clearfield(upb_msg *msg, const upb_fielddef *f) {
5635 const upb_msglayout_field *field = upb_fielddef_layout(f);
5636 char *mem = UPB_PTR_AT(msg, field->offset, char);
5637
5638 if (field->presence > 0) {
5639 _upb_clearhas_field(msg, field);
5640 } else if (in_oneof(field)) {
5641 uint32_t *oneof_case = _upb_oneofcase_field(msg, field);
5642 if (*oneof_case != field->number) return;
5643 *oneof_case = 0;
5644 }
5645
5646 memset(mem, 0, get_field_size(field));
5647 }
5648
upb_msg_clear(upb_msg * msg,const upb_msgdef * m)5649 void upb_msg_clear(upb_msg *msg, const upb_msgdef *m) {
5650 _upb_msg_clear(msg, upb_msgdef_layout(m));
5651 }
5652
upb_msg_next(const upb_msg * msg,const upb_msgdef * m,const upb_symtab * ext_pool,const upb_fielddef ** out_f,upb_msgval * out_val,size_t * iter)5653 bool upb_msg_next(const upb_msg *msg, const upb_msgdef *m,
5654 const upb_symtab *ext_pool, const upb_fielddef **out_f,
5655 upb_msgval *out_val, size_t *iter) {
5656 int i = *iter;
5657 int n = upb_msgdef_fieldcount(m);
5658 const upb_msgval zero = {0};
5659 UPB_UNUSED(ext_pool);
5660 while (++i < n) {
5661 const upb_fielddef *f = upb_msgdef_field(m, i);
5662 upb_msgval val = _upb_msg_getraw(msg, f);
5663
5664 /* Skip field if unset or empty. */
5665 if (upb_fielddef_haspresence(f)) {
5666 if (!upb_msg_has(msg, f)) continue;
5667 } else {
5668 upb_msgval test = val;
5669 if (upb_fielddef_isstring(f) && !upb_fielddef_isseq(f)) {
5670 /* Clear string pointer, only size matters (ptr could be non-NULL). */
5671 test.str_val.data = NULL;
5672 }
5673 /* Continue if NULL or 0. */
5674 if (memcmp(&test, &zero, sizeof(test)) == 0) continue;
5675
5676 /* Continue on empty array or map. */
5677 if (upb_fielddef_ismap(f)) {
5678 if (upb_map_size(test.map_val) == 0) continue;
5679 } else if (upb_fielddef_isseq(f)) {
5680 if (upb_array_size(test.array_val) == 0) continue;
5681 }
5682 }
5683
5684 *out_val = val;
5685 *out_f = f;
5686 *iter = i;
5687 return true;
5688 }
5689 *iter = i;
5690 return false;
5691 }
5692
_upb_msg_discardunknown(upb_msg * msg,const upb_msgdef * m,int depth)5693 bool _upb_msg_discardunknown(upb_msg *msg, const upb_msgdef *m, int depth) {
5694 size_t iter = UPB_MSG_BEGIN;
5695 const upb_fielddef *f;
5696 upb_msgval val;
5697 bool ret = true;
5698
5699 if (--depth == 0) return false;
5700
5701 _upb_msg_discardunknown_shallow(msg);
5702
5703 while (upb_msg_next(msg, m, NULL /*ext_pool*/, &f, &val, &iter)) {
5704 const upb_msgdef *subm = upb_fielddef_msgsubdef(f);
5705 if (!subm) continue;
5706 if (upb_fielddef_ismap(f)) {
5707 const upb_fielddef *val_f = upb_msgdef_itof(subm, 2);
5708 const upb_msgdef *val_m = upb_fielddef_msgsubdef(val_f);
5709 upb_map *map = (upb_map*)val.map_val;
5710 size_t iter = UPB_MAP_BEGIN;
5711
5712 if (!val_m) continue;
5713
5714 while (upb_mapiter_next(map, &iter)) {
5715 upb_msgval map_val = upb_mapiter_value(map, iter);
5716 if (!_upb_msg_discardunknown((upb_msg*)map_val.msg_val, val_m, depth)) {
5717 ret = false;
5718 }
5719 }
5720 } else if (upb_fielddef_isseq(f)) {
5721 const upb_array *arr = val.array_val;
5722 size_t i, n = upb_array_size(arr);
5723 for (i = 0; i < n; i++) {
5724 upb_msgval elem = upb_array_get(arr, i);
5725 if (!_upb_msg_discardunknown((upb_msg*)elem.msg_val, subm, depth)) {
5726 ret = false;
5727 }
5728 }
5729 } else {
5730 if (!_upb_msg_discardunknown((upb_msg*)val.msg_val, subm, depth)) {
5731 ret = false;
5732 }
5733 }
5734 }
5735
5736 return ret;
5737 }
5738
upb_msg_discardunknown(upb_msg * msg,const upb_msgdef * m,int maxdepth)5739 bool upb_msg_discardunknown(upb_msg *msg, const upb_msgdef *m, int maxdepth) {
5740 return _upb_msg_discardunknown(msg, m, maxdepth);
5741 }
5742
5743 /** upb_array *****************************************************************/
5744
upb_array_new(upb_arena * a,upb_fieldtype_t type)5745 upb_array *upb_array_new(upb_arena *a, upb_fieldtype_t type) {
5746 return _upb_array_new(a, 4, _upb_fieldtype_to_sizelg2[type]);
5747 }
5748
upb_array_size(const upb_array * arr)5749 size_t upb_array_size(const upb_array *arr) {
5750 return arr->len;
5751 }
5752
upb_array_get(const upb_array * arr,size_t i)5753 upb_msgval upb_array_get(const upb_array *arr, size_t i) {
5754 upb_msgval ret;
5755 const char* data = _upb_array_constptr(arr);
5756 int lg2 = arr->data & 7;
5757 UPB_ASSERT(i < arr->len);
5758 memcpy(&ret, data + (i << lg2), 1 << lg2);
5759 return ret;
5760 }
5761
upb_array_set(upb_array * arr,size_t i,upb_msgval val)5762 void upb_array_set(upb_array *arr, size_t i, upb_msgval val) {
5763 char* data = _upb_array_ptr(arr);
5764 int lg2 = arr->data & 7;
5765 UPB_ASSERT(i < arr->len);
5766 memcpy(data + (i << lg2), &val, 1 << lg2);
5767 }
5768
upb_array_append(upb_array * arr,upb_msgval val,upb_arena * arena)5769 bool upb_array_append(upb_array *arr, upb_msgval val, upb_arena *arena) {
5770 if (!_upb_array_realloc(arr, arr->len + 1, arena)) {
5771 return false;
5772 }
5773 arr->len++;
5774 upb_array_set(arr, arr->len - 1, val);
5775 return true;
5776 }
5777
upb_array_resize(upb_array * arr,size_t size,upb_arena * arena)5778 bool upb_array_resize(upb_array *arr, size_t size, upb_arena *arena) {
5779 return _upb_array_resize(arr, size, arena);
5780 }
5781
5782 /** upb_map *******************************************************************/
5783
upb_map_new(upb_arena * a,upb_fieldtype_t key_type,upb_fieldtype_t value_type)5784 upb_map *upb_map_new(upb_arena *a, upb_fieldtype_t key_type,
5785 upb_fieldtype_t value_type) {
5786 return _upb_map_new(a, _upb_fieldtype_to_mapsize[key_type],
5787 _upb_fieldtype_to_mapsize[value_type]);
5788 }
5789
upb_map_size(const upb_map * map)5790 size_t upb_map_size(const upb_map *map) {
5791 return _upb_map_size(map);
5792 }
5793
upb_map_get(const upb_map * map,upb_msgval key,upb_msgval * val)5794 bool upb_map_get(const upb_map *map, upb_msgval key, upb_msgval *val) {
5795 return _upb_map_get(map, &key, map->key_size, val, map->val_size);
5796 }
5797
upb_map_set(upb_map * map,upb_msgval key,upb_msgval val,upb_arena * arena)5798 bool upb_map_set(upb_map *map, upb_msgval key, upb_msgval val,
5799 upb_arena *arena) {
5800 return _upb_map_set(map, &key, map->key_size, &val, map->val_size, arena);
5801 }
5802
upb_map_delete(upb_map * map,upb_msgval key)5803 bool upb_map_delete(upb_map *map, upb_msgval key) {
5804 return _upb_map_delete(map, &key, map->key_size);
5805 }
5806
upb_mapiter_next(const upb_map * map,size_t * iter)5807 bool upb_mapiter_next(const upb_map *map, size_t *iter) {
5808 return _upb_map_next(map, iter);
5809 }
5810
upb_mapiter_done(const upb_map * map,size_t iter)5811 bool upb_mapiter_done(const upb_map *map, size_t iter) {
5812 upb_strtable_iter i;
5813 UPB_ASSERT(iter != UPB_MAP_BEGIN);
5814 i.t = &map->table;
5815 i.index = iter;
5816 return upb_strtable_done(&i);
5817 }
5818
5819 /* Returns the key and value for this entry of the map. */
upb_mapiter_key(const upb_map * map,size_t iter)5820 upb_msgval upb_mapiter_key(const upb_map *map, size_t iter) {
5821 upb_strtable_iter i;
5822 upb_msgval ret;
5823 i.t = &map->table;
5824 i.index = iter;
5825 _upb_map_fromkey(upb_strtable_iter_key(&i), &ret, map->key_size);
5826 return ret;
5827 }
5828
upb_mapiter_value(const upb_map * map,size_t iter)5829 upb_msgval upb_mapiter_value(const upb_map *map, size_t iter) {
5830 upb_strtable_iter i;
5831 upb_msgval ret;
5832 i.t = &map->table;
5833 i.index = iter;
5834 _upb_map_fromvalue(upb_strtable_iter_value(&i), &ret, map->val_size);
5835 return ret;
5836 }
5837
5838 /* void upb_mapiter_setvalue(upb_map *map, size_t iter, upb_msgval value); */
5839
5840
5841 #ifdef UPB_MSVC_VSNPRINTF
5842 /* Visual C++ earlier than 2015 doesn't have standard C99 snprintf and
5843 * vsnprintf. To support them, missing functions are manually implemented
5844 * using the existing secure functions. */
msvc_vsnprintf(char * s,size_t n,const char * format,va_list arg)5845 int msvc_vsnprintf(char* s, size_t n, const char* format, va_list arg) {
5846 if (!s) {
5847 return _vscprintf(format, arg);
5848 }
5849 int ret = _vsnprintf_s(s, n, _TRUNCATE, format, arg);
5850 if (ret < 0) {
5851 ret = _vscprintf(format, arg);
5852 }
5853 return ret;
5854 }
5855
msvc_snprintf(char * s,size_t n,const char * format,...)5856 int msvc_snprintf(char* s, size_t n, const char* format, ...) {
5857 va_list arg;
5858 va_start(arg, format);
5859 int ret = msvc_vsnprintf(s, n, format, arg);
5860 va_end(arg);
5861 return ret;
5862 }
5863 #endif
5864
5865
5866 #include <errno.h>
5867 #include <float.h>
5868 #include <inttypes.h>
5869 #include <limits.h>
5870 #include <math.h>
5871 #include <setjmp.h>
5872 #include <stdlib.h>
5873 #include <string.h>
5874
5875
5876 /* Special header, must be included last. */
5877
5878 typedef struct {
5879 const char *ptr, *end;
5880 upb_arena *arena; /* TODO: should we have a tmp arena for tmp data? */
5881 const upb_symtab *any_pool;
5882 int depth;
5883 upb_status *status;
5884 jmp_buf err;
5885 int line;
5886 const char *line_begin;
5887 bool is_first;
5888 int options;
5889 const upb_fielddef *debug_field;
5890 } jsondec;
5891
5892 enum { JD_OBJECT, JD_ARRAY, JD_STRING, JD_NUMBER, JD_TRUE, JD_FALSE, JD_NULL };
5893
5894 /* Forward declarations of mutually-recursive functions. */
5895 static void jsondec_wellknown(jsondec *d, upb_msg *msg, const upb_msgdef *m);
5896 static upb_msgval jsondec_value(jsondec *d, const upb_fielddef *f);
5897 static void jsondec_wellknownvalue(jsondec *d, upb_msg *msg,
5898 const upb_msgdef *m);
5899 static void jsondec_object(jsondec *d, upb_msg *msg, const upb_msgdef *m);
5900
jsondec_streql(upb_strview str,const char * lit)5901 static bool jsondec_streql(upb_strview str, const char *lit) {
5902 return str.size == strlen(lit) && memcmp(str.data, lit, str.size) == 0;
5903 }
5904
jsondec_isnullvalue(const upb_fielddef * f)5905 static bool jsondec_isnullvalue(const upb_fielddef *f) {
5906 return upb_fielddef_type(f) == UPB_TYPE_ENUM &&
5907 strcmp(upb_enumdef_fullname(upb_fielddef_enumsubdef(f)),
5908 "google.protobuf.NullValue") == 0;
5909 }
5910
jsondec_isvalue(const upb_fielddef * f)5911 static bool jsondec_isvalue(const upb_fielddef *f) {
5912 return (upb_fielddef_type(f) == UPB_TYPE_MESSAGE &&
5913 upb_msgdef_wellknowntype(upb_fielddef_msgsubdef(f)) ==
5914 UPB_WELLKNOWN_VALUE) ||
5915 jsondec_isnullvalue(f);
5916 }
5917
jsondec_err(jsondec * d,const char * msg)5918 UPB_NORETURN static void jsondec_err(jsondec *d, const char *msg) {
5919 upb_status_seterrf(d->status, "Error parsing JSON @%d:%d: %s", d->line,
5920 (int)(d->ptr - d->line_begin), msg);
5921 longjmp(d->err, 1);
5922 }
5923
jsondec_errf(jsondec * d,const char * fmt,...)5924 UPB_NORETURN static void jsondec_errf(jsondec *d, const char *fmt, ...) {
5925 va_list argp;
5926 upb_status_seterrf(d->status, "Error parsing JSON @%d:%d: ", d->line,
5927 (int)(d->ptr - d->line_begin));
5928 va_start(argp, fmt);
5929 upb_status_vappenderrf(d->status, fmt, argp);
5930 va_end(argp);
5931 longjmp(d->err, 1);
5932 }
5933
jsondec_skipws(jsondec * d)5934 static void jsondec_skipws(jsondec *d) {
5935 while (d->ptr != d->end) {
5936 switch (*d->ptr) {
5937 case '\n':
5938 d->line++;
5939 d->line_begin = d->ptr;
5940 /* Fallthrough. */
5941 case '\r':
5942 case '\t':
5943 case ' ':
5944 d->ptr++;
5945 break;
5946 default:
5947 return;
5948 }
5949 }
5950 jsondec_err(d, "Unexpected EOF");
5951 }
5952
jsondec_tryparsech(jsondec * d,char ch)5953 static bool jsondec_tryparsech(jsondec *d, char ch) {
5954 if (d->ptr == d->end || *d->ptr != ch) return false;
5955 d->ptr++;
5956 return true;
5957 }
5958
jsondec_parselit(jsondec * d,const char * lit)5959 static void jsondec_parselit(jsondec *d, const char *lit) {
5960 size_t avail = d->end - d->ptr;
5961 size_t len = strlen(lit);
5962 if (avail < len || memcmp(d->ptr, lit, len) != 0) {
5963 jsondec_errf(d, "Expected: '%s'", lit);
5964 }
5965 d->ptr += len;
5966 }
5967
jsondec_wsch(jsondec * d,char ch)5968 static void jsondec_wsch(jsondec *d, char ch) {
5969 jsondec_skipws(d);
5970 if (!jsondec_tryparsech(d, ch)) {
5971 jsondec_errf(d, "Expected: '%c'", ch);
5972 }
5973 }
5974
jsondec_true(jsondec * d)5975 static void jsondec_true(jsondec *d) { jsondec_parselit(d, "true"); }
jsondec_false(jsondec * d)5976 static void jsondec_false(jsondec *d) { jsondec_parselit(d, "false"); }
jsondec_null(jsondec * d)5977 static void jsondec_null(jsondec *d) { jsondec_parselit(d, "null"); }
5978
jsondec_entrysep(jsondec * d)5979 static void jsondec_entrysep(jsondec *d) {
5980 jsondec_skipws(d);
5981 jsondec_parselit(d, ":");
5982 }
5983
jsondec_rawpeek(jsondec * d)5984 static int jsondec_rawpeek(jsondec *d) {
5985 switch (*d->ptr) {
5986 case '{':
5987 return JD_OBJECT;
5988 case '[':
5989 return JD_ARRAY;
5990 case '"':
5991 return JD_STRING;
5992 case '-':
5993 case '0':
5994 case '1':
5995 case '2':
5996 case '3':
5997 case '4':
5998 case '5':
5999 case '6':
6000 case '7':
6001 case '8':
6002 case '9':
6003 return JD_NUMBER;
6004 case 't':
6005 return JD_TRUE;
6006 case 'f':
6007 return JD_FALSE;
6008 case 'n':
6009 return JD_NULL;
6010 default:
6011 jsondec_errf(d, "Unexpected character: '%c'", *d->ptr);
6012 }
6013 }
6014
6015 /* JSON object/array **********************************************************/
6016
6017 /* These are used like so:
6018 *
6019 * jsondec_objstart(d);
6020 * while (jsondec_objnext(d)) {
6021 * ...
6022 * }
6023 * jsondec_objend(d) */
6024
jsondec_peek(jsondec * d)6025 static int jsondec_peek(jsondec *d) {
6026 jsondec_skipws(d);
6027 return jsondec_rawpeek(d);
6028 }
6029
jsondec_push(jsondec * d)6030 static void jsondec_push(jsondec *d) {
6031 if (--d->depth < 0) {
6032 jsondec_err(d, "Recursion limit exceeded");
6033 }
6034 d->is_first = true;
6035 }
6036
jsondec_seqnext(jsondec * d,char end_ch)6037 static bool jsondec_seqnext(jsondec *d, char end_ch) {
6038 bool is_first = d->is_first;
6039 d->is_first = false;
6040 jsondec_skipws(d);
6041 if (*d->ptr == end_ch) return false;
6042 if (!is_first) jsondec_parselit(d, ",");
6043 return true;
6044 }
6045
jsondec_arrstart(jsondec * d)6046 static void jsondec_arrstart(jsondec *d) {
6047 jsondec_push(d);
6048 jsondec_wsch(d, '[');
6049 }
6050
jsondec_arrend(jsondec * d)6051 static void jsondec_arrend(jsondec *d) {
6052 d->depth++;
6053 jsondec_wsch(d, ']');
6054 }
6055
jsondec_arrnext(jsondec * d)6056 static bool jsondec_arrnext(jsondec *d) {
6057 return jsondec_seqnext(d, ']');
6058 }
6059
jsondec_objstart(jsondec * d)6060 static void jsondec_objstart(jsondec *d) {
6061 jsondec_push(d);
6062 jsondec_wsch(d, '{');
6063 }
6064
jsondec_objend(jsondec * d)6065 static void jsondec_objend(jsondec *d) {
6066 d->depth++;
6067 jsondec_wsch(d, '}');
6068 }
6069
jsondec_objnext(jsondec * d)6070 static bool jsondec_objnext(jsondec *d) {
6071 if (!jsondec_seqnext(d, '}')) return false;
6072 if (jsondec_peek(d) != JD_STRING) {
6073 jsondec_err(d, "Object must start with string");
6074 }
6075 return true;
6076 }
6077
6078 /* JSON number ****************************************************************/
6079
jsondec_tryskipdigits(jsondec * d)6080 static bool jsondec_tryskipdigits(jsondec *d) {
6081 const char *start = d->ptr;
6082
6083 while (d->ptr < d->end) {
6084 if (*d->ptr < '0' || *d->ptr > '9') {
6085 break;
6086 }
6087 d->ptr++;
6088 }
6089
6090 return d->ptr != start;
6091 }
6092
jsondec_skipdigits(jsondec * d)6093 static void jsondec_skipdigits(jsondec *d) {
6094 if (!jsondec_tryskipdigits(d)) {
6095 jsondec_err(d, "Expected one or more digits");
6096 }
6097 }
6098
jsondec_number(jsondec * d)6099 static double jsondec_number(jsondec *d) {
6100 const char *start = d->ptr;
6101
6102 assert(jsondec_rawpeek(d) == JD_NUMBER);
6103
6104 /* Skip over the syntax of a number, as specified by JSON. */
6105 if (*d->ptr == '-') d->ptr++;
6106
6107 if (jsondec_tryparsech(d, '0')) {
6108 if (jsondec_tryskipdigits(d)) {
6109 jsondec_err(d, "number cannot have leading zero");
6110 }
6111 } else {
6112 jsondec_skipdigits(d);
6113 }
6114
6115 if (d->ptr == d->end) goto parse;
6116 if (jsondec_tryparsech(d, '.')) {
6117 jsondec_skipdigits(d);
6118 }
6119 if (d->ptr == d->end) goto parse;
6120
6121 if (*d->ptr == 'e' || *d->ptr == 'E') {
6122 d->ptr++;
6123 if (d->ptr == d->end) {
6124 jsondec_err(d, "Unexpected EOF in number");
6125 }
6126 if (*d->ptr == '+' || *d->ptr == '-') {
6127 d->ptr++;
6128 }
6129 jsondec_skipdigits(d);
6130 }
6131
6132 parse:
6133 /* Having verified the syntax of a JSON number, use strtod() to parse
6134 * (strtod() accepts a superset of JSON syntax). */
6135 errno = 0;
6136 {
6137 char* end;
6138 double val = strtod(start, &end);
6139 assert(end == d->ptr);
6140
6141 /* Currently the min/max-val conformance tests fail if we check this. Does
6142 * this mean the conformance tests are wrong or strtod() is wrong, or
6143 * something else? Investigate further. */
6144 /*
6145 if (errno == ERANGE) {
6146 jsondec_err(d, "Number out of range");
6147 }
6148 */
6149
6150 if (val > DBL_MAX || val < -DBL_MAX) {
6151 jsondec_err(d, "Number out of range");
6152 }
6153
6154 return val;
6155 }
6156 }
6157
6158 /* JSON string ****************************************************************/
6159
jsondec_escape(jsondec * d)6160 static char jsondec_escape(jsondec *d) {
6161 switch (*d->ptr++) {
6162 case '"':
6163 return '\"';
6164 case '\\':
6165 return '\\';
6166 case '/':
6167 return '/';
6168 case 'b':
6169 return '\b';
6170 case 'f':
6171 return '\f';
6172 case 'n':
6173 return '\n';
6174 case 'r':
6175 return '\r';
6176 case 't':
6177 return '\t';
6178 default:
6179 jsondec_err(d, "Invalid escape char");
6180 }
6181 }
6182
jsondec_codepoint(jsondec * d)6183 static uint32_t jsondec_codepoint(jsondec *d) {
6184 uint32_t cp = 0;
6185 const char *end;
6186
6187 if (d->end - d->ptr < 4) {
6188 jsondec_err(d, "EOF inside string");
6189 }
6190
6191 end = d->ptr + 4;
6192 while (d->ptr < end) {
6193 char ch = *d->ptr++;
6194 if (ch >= '0' && ch <= '9') {
6195 ch -= '0';
6196 } else if (ch >= 'a' && ch <= 'f') {
6197 ch = ch - 'a' + 10;
6198 } else if (ch >= 'A' && ch <= 'F') {
6199 ch = ch - 'A' + 10;
6200 } else {
6201 jsondec_err(d, "Invalid hex digit");
6202 }
6203 cp = (cp << 4) | ch;
6204 }
6205
6206 return cp;
6207 }
6208
6209 /* Parses a \uXXXX unicode escape (possibly a surrogate pair). */
jsondec_unicode(jsondec * d,char * out)6210 static size_t jsondec_unicode(jsondec *d, char* out) {
6211 uint32_t cp = jsondec_codepoint(d);
6212 if (cp >= 0xd800 && cp <= 0xdbff) {
6213 /* Surrogate pair: two 16-bit codepoints become a 32-bit codepoint. */
6214 uint32_t high = cp;
6215 uint32_t low;
6216 jsondec_parselit(d, "\\u");
6217 low = jsondec_codepoint(d);
6218 if (low < 0xdc00 || low > 0xdfff) {
6219 jsondec_err(d, "Invalid low surrogate");
6220 }
6221 cp = (high & 0x3ff) << 10;
6222 cp |= (low & 0x3ff);
6223 cp += 0x10000;
6224 } else if (cp >= 0xdc00 && cp <= 0xdfff) {
6225 jsondec_err(d, "Unpaired low surrogate");
6226 }
6227
6228 /* Write to UTF-8 */
6229 if (cp <= 0x7f) {
6230 out[0] = cp;
6231 return 1;
6232 } else if (cp <= 0x07FF) {
6233 out[0] = ((cp >> 6) & 0x1F) | 0xC0;
6234 out[1] = ((cp >> 0) & 0x3F) | 0x80;
6235 return 2;
6236 } else if (cp <= 0xFFFF) {
6237 out[0] = ((cp >> 12) & 0x0F) | 0xE0;
6238 out[1] = ((cp >> 6) & 0x3F) | 0x80;
6239 out[2] = ((cp >> 0) & 0x3F) | 0x80;
6240 return 3;
6241 } else if (cp < 0x10FFFF) {
6242 out[0] = ((cp >> 18) & 0x07) | 0xF0;
6243 out[1] = ((cp >> 12) & 0x3f) | 0x80;
6244 out[2] = ((cp >> 6) & 0x3f) | 0x80;
6245 out[3] = ((cp >> 0) & 0x3f) | 0x80;
6246 return 4;
6247 } else {
6248 jsondec_err(d, "Invalid codepoint");
6249 }
6250 }
6251
jsondec_resize(jsondec * d,char ** buf,char ** end,char ** buf_end)6252 static void jsondec_resize(jsondec *d, char **buf, char **end, char **buf_end) {
6253 size_t oldsize = *buf_end - *buf;
6254 size_t len = *end - *buf;
6255 size_t size = UPB_MAX(8, 2 * oldsize);
6256
6257 *buf = upb_arena_realloc(d->arena, *buf, len, size);
6258 if (!*buf) jsondec_err(d, "Out of memory");
6259
6260 *end = *buf + len;
6261 *buf_end = *buf + size;
6262 }
6263
jsondec_string(jsondec * d)6264 static upb_strview jsondec_string(jsondec *d) {
6265 char *buf = NULL;
6266 char *end = NULL;
6267 char *buf_end = NULL;
6268
6269 jsondec_skipws(d);
6270
6271 if (*d->ptr++ != '"') {
6272 jsondec_err(d, "Expected string");
6273 }
6274
6275 while (d->ptr < d->end) {
6276 char ch = *d->ptr++;
6277
6278 if (end == buf_end) {
6279 jsondec_resize(d, &buf, &end, &buf_end);
6280 }
6281
6282 switch (ch) {
6283 case '"': {
6284 upb_strview ret;
6285 ret.data = buf;
6286 ret.size = end - buf;
6287 *end = '\0'; /* Needed for possible strtod(). */
6288 return ret;
6289 }
6290 case '\\':
6291 if (d->ptr == d->end) goto eof;
6292 if (*d->ptr == 'u') {
6293 d->ptr++;
6294 if (buf_end - end < 4) {
6295 /* Allow space for maximum-sized code point (4 bytes). */
6296 jsondec_resize(d, &buf, &end, &buf_end);
6297 }
6298 end += jsondec_unicode(d, end);
6299 } else {
6300 *end++ = jsondec_escape(d);
6301 }
6302 break;
6303 default:
6304 if ((unsigned char)*d->ptr < 0x20) {
6305 jsondec_err(d, "Invalid char in JSON string");
6306 }
6307 *end++ = ch;
6308 break;
6309 }
6310 }
6311
6312 eof:
6313 jsondec_err(d, "EOF inside string");
6314 }
6315
jsondec_skipval(jsondec * d)6316 static void jsondec_skipval(jsondec *d) {
6317 switch (jsondec_peek(d)) {
6318 case JD_OBJECT:
6319 jsondec_objstart(d);
6320 while (jsondec_objnext(d)) {
6321 jsondec_string(d);
6322 jsondec_entrysep(d);
6323 jsondec_skipval(d);
6324 }
6325 jsondec_objend(d);
6326 break;
6327 case JD_ARRAY:
6328 jsondec_arrstart(d);
6329 while (jsondec_arrnext(d)) {
6330 jsondec_skipval(d);
6331 }
6332 jsondec_arrend(d);
6333 break;
6334 case JD_TRUE:
6335 jsondec_true(d);
6336 break;
6337 case JD_FALSE:
6338 jsondec_false(d);
6339 break;
6340 case JD_NULL:
6341 jsondec_null(d);
6342 break;
6343 case JD_STRING:
6344 jsondec_string(d);
6345 break;
6346 case JD_NUMBER:
6347 jsondec_number(d);
6348 break;
6349 }
6350 }
6351
6352 /* Base64 decoding for bytes fields. ******************************************/
6353
jsondec_base64_tablelookup(const char ch)6354 static unsigned int jsondec_base64_tablelookup(const char ch) {
6355 /* Table includes the normal base64 chars plus the URL-safe variant. */
6356 const signed char table[256] = {
6357 -1, -1, -1, -1, -1, -1, -1,
6358 -1, -1, -1, -1, -1, -1, -1,
6359 -1, -1, -1, -1, -1, -1, -1,
6360 -1, -1, -1, -1, -1, -1, -1,
6361 -1, -1, -1, -1, -1, -1, -1,
6362 -1, -1, -1, -1, -1, -1, -1,
6363 -1, 62 /*+*/, -1, 62 /*-*/, -1, 63 /*/ */, 52 /*0*/,
6364 53 /*1*/, 54 /*2*/, 55 /*3*/, 56 /*4*/, 57 /*5*/, 58 /*6*/, 59 /*7*/,
6365 60 /*8*/, 61 /*9*/, -1, -1, -1, -1, -1,
6366 -1, -1, 0 /*A*/, 1 /*B*/, 2 /*C*/, 3 /*D*/, 4 /*E*/,
6367 5 /*F*/, 6 /*G*/, 07 /*H*/, 8 /*I*/, 9 /*J*/, 10 /*K*/, 11 /*L*/,
6368 12 /*M*/, 13 /*N*/, 14 /*O*/, 15 /*P*/, 16 /*Q*/, 17 /*R*/, 18 /*S*/,
6369 19 /*T*/, 20 /*U*/, 21 /*V*/, 22 /*W*/, 23 /*X*/, 24 /*Y*/, 25 /*Z*/,
6370 -1, -1, -1, -1, 63 /*_*/, -1, 26 /*a*/,
6371 27 /*b*/, 28 /*c*/, 29 /*d*/, 30 /*e*/, 31 /*f*/, 32 /*g*/, 33 /*h*/,
6372 34 /*i*/, 35 /*j*/, 36 /*k*/, 37 /*l*/, 38 /*m*/, 39 /*n*/, 40 /*o*/,
6373 41 /*p*/, 42 /*q*/, 43 /*r*/, 44 /*s*/, 45 /*t*/, 46 /*u*/, 47 /*v*/,
6374 48 /*w*/, 49 /*x*/, 50 /*y*/, 51 /*z*/, -1, -1, -1,
6375 -1, -1, -1, -1, -1, -1, -1,
6376 -1, -1, -1, -1, -1, -1, -1,
6377 -1, -1, -1, -1, -1, -1, -1,
6378 -1, -1, -1, -1, -1, -1, -1,
6379 -1, -1, -1, -1, -1, -1, -1,
6380 -1, -1, -1, -1, -1, -1, -1,
6381 -1, -1, -1, -1, -1, -1, -1,
6382 -1, -1, -1, -1, -1, -1, -1,
6383 -1, -1, -1, -1, -1, -1, -1,
6384 -1, -1, -1, -1, -1, -1, -1,
6385 -1, -1, -1, -1, -1, -1, -1,
6386 -1, -1, -1, -1, -1, -1, -1,
6387 -1, -1, -1, -1, -1, -1, -1,
6388 -1, -1, -1, -1, -1, -1, -1,
6389 -1, -1, -1, -1, -1, -1, -1,
6390 -1, -1, -1, -1, -1, -1, -1,
6391 -1, -1, -1, -1, -1, -1, -1,
6392 -1, -1, -1, -1, -1, -1, -1,
6393 -1, -1, -1, -1};
6394
6395 /* Sign-extend return value so high bit will be set on any unexpected char. */
6396 return table[(unsigned)ch];
6397 }
6398
jsondec_partialbase64(jsondec * d,const char * ptr,const char * end,char * out)6399 static char *jsondec_partialbase64(jsondec *d, const char *ptr, const char *end,
6400 char *out) {
6401 int32_t val = -1;
6402
6403 switch (end - ptr) {
6404 case 2:
6405 val = jsondec_base64_tablelookup(ptr[0]) << 18 |
6406 jsondec_base64_tablelookup(ptr[1]) << 12;
6407 out[0] = val >> 16;
6408 out += 1;
6409 break;
6410 case 3:
6411 val = jsondec_base64_tablelookup(ptr[0]) << 18 |
6412 jsondec_base64_tablelookup(ptr[1]) << 12 |
6413 jsondec_base64_tablelookup(ptr[2]) << 6;
6414 out[0] = val >> 16;
6415 out[1] = (val >> 8) & 0xff;
6416 out += 2;
6417 break;
6418 }
6419
6420 if (val < 0) {
6421 jsondec_err(d, "Corrupt base64");
6422 }
6423
6424 return out;
6425 }
6426
jsondec_base64(jsondec * d,upb_strview str)6427 static size_t jsondec_base64(jsondec *d, upb_strview str) {
6428 /* We decode in place. This is safe because this is a new buffer (not
6429 * aliasing the input) and because base64 decoding shrinks 4 bytes into 3. */
6430 char *out = (char*)str.data;
6431 const char *ptr = str.data;
6432 const char *end = ptr + str.size;
6433 const char *end4 = ptr + (str.size & -4); /* Round down to multiple of 4. */
6434
6435 for (; ptr < end4; ptr += 4, out += 3) {
6436 int val = jsondec_base64_tablelookup(ptr[0]) << 18 |
6437 jsondec_base64_tablelookup(ptr[1]) << 12 |
6438 jsondec_base64_tablelookup(ptr[2]) << 6 |
6439 jsondec_base64_tablelookup(ptr[3]) << 0;
6440
6441 if (val < 0) {
6442 /* Junk chars or padding. Remove trailing padding, if any. */
6443 if (end - ptr == 4 && ptr[3] == '=') {
6444 if (ptr[2] == '=') {
6445 end -= 2;
6446 } else {
6447 end -= 1;
6448 }
6449 }
6450 break;
6451 }
6452
6453 out[0] = val >> 16;
6454 out[1] = (val >> 8) & 0xff;
6455 out[2] = val & 0xff;
6456 }
6457
6458 if (ptr < end) {
6459 /* Process remaining chars. We do not require padding. */
6460 out = jsondec_partialbase64(d, ptr, end, out);
6461 }
6462
6463 return out - str.data;
6464 }
6465
6466 /* Low-level integer parsing **************************************************/
6467
6468 /* We use these hand-written routines instead of strto[u]l() because the "long
6469 * long" variants aren't in c89. Also our version allows setting a ptr limit. */
6470
jsondec_buftouint64(jsondec * d,const char * ptr,const char * end,uint64_t * val)6471 static const char *jsondec_buftouint64(jsondec *d, const char *ptr,
6472 const char *end, uint64_t *val) {
6473 uint64_t u64 = 0;
6474 while (ptr < end) {
6475 unsigned ch = *ptr - '0';
6476 if (ch >= 10) break;
6477 if (u64 > UINT64_MAX / 10 || u64 * 10 > UINT64_MAX - ch) {
6478 jsondec_err(d, "Integer overflow");
6479 }
6480 u64 *= 10;
6481 u64 += ch;
6482 ptr++;
6483 }
6484
6485 *val = u64;
6486 return ptr;
6487 }
6488
jsondec_buftoint64(jsondec * d,const char * ptr,const char * end,int64_t * val)6489 static const char *jsondec_buftoint64(jsondec *d, const char *ptr,
6490 const char *end, int64_t *val) {
6491 bool neg = false;
6492 uint64_t u64;
6493
6494 if (ptr != end && *ptr == '-') {
6495 ptr++;
6496 neg = true;
6497 }
6498
6499 ptr = jsondec_buftouint64(d, ptr, end, &u64);
6500 if (u64 > (uint64_t)INT64_MAX + neg) {
6501 jsondec_err(d, "Integer overflow");
6502 }
6503
6504 *val = neg ? -u64 : u64;
6505 return ptr;
6506 }
6507
jsondec_strtouint64(jsondec * d,upb_strview str)6508 static uint64_t jsondec_strtouint64(jsondec *d, upb_strview str) {
6509 const char *end = str.data + str.size;
6510 uint64_t ret;
6511 if (jsondec_buftouint64(d, str.data, end, &ret) != end) {
6512 jsondec_err(d, "Non-number characters in quoted integer");
6513 }
6514 return ret;
6515 }
6516
jsondec_strtoint64(jsondec * d,upb_strview str)6517 static int64_t jsondec_strtoint64(jsondec *d, upb_strview str) {
6518 const char *end = str.data + str.size;
6519 int64_t ret;
6520 if (jsondec_buftoint64(d, str.data, end, &ret) != end) {
6521 jsondec_err(d, "Non-number characters in quoted integer");
6522 }
6523 return ret;
6524 }
6525
6526 /* Primitive value types ******************************************************/
6527
6528 /* Parse INT32 or INT64 value. */
jsondec_int(jsondec * d,const upb_fielddef * f)6529 static upb_msgval jsondec_int(jsondec *d, const upb_fielddef *f) {
6530 upb_msgval val;
6531
6532 switch (jsondec_peek(d)) {
6533 case JD_NUMBER: {
6534 double dbl = jsondec_number(d);
6535 if (dbl > 9223372036854774784.0 || dbl < -9223372036854775808.0) {
6536 jsondec_err(d, "JSON number is out of range.");
6537 }
6538 val.int64_val = dbl; /* must be guarded, overflow here is UB */
6539 if (val.int64_val != dbl) {
6540 jsondec_errf(d, "JSON number was not integral (%d != %" PRId64 ")", dbl,
6541 val.int64_val);
6542 }
6543 break;
6544 }
6545 case JD_STRING: {
6546 upb_strview str = jsondec_string(d);
6547 val.int64_val = jsondec_strtoint64(d, str);
6548 break;
6549 }
6550 default:
6551 jsondec_err(d, "Expected number or string");
6552 }
6553
6554 if (upb_fielddef_type(f) == UPB_TYPE_INT32) {
6555 if (val.int64_val > INT32_MAX || val.int64_val < INT32_MIN) {
6556 jsondec_err(d, "Integer out of range.");
6557 }
6558 val.int32_val = (int32_t)val.int64_val;
6559 }
6560
6561 return val;
6562 }
6563
6564 /* Parse UINT32 or UINT64 value. */
jsondec_uint(jsondec * d,const upb_fielddef * f)6565 static upb_msgval jsondec_uint(jsondec *d, const upb_fielddef *f) {
6566 upb_msgval val;
6567
6568 switch (jsondec_peek(d)) {
6569 case JD_NUMBER: {
6570 double dbl = jsondec_number(d);
6571 if (dbl > 18446744073709549568.0 || dbl < 0) {
6572 jsondec_err(d, "JSON number is out of range.");
6573 }
6574 val.uint64_val = dbl; /* must be guarded, overflow here is UB */
6575 if (val.uint64_val != dbl) {
6576 jsondec_errf(d, "JSON number was not integral (%d != %" PRIu64 ")", dbl,
6577 val.uint64_val);
6578 }
6579 break;
6580 }
6581 case JD_STRING: {
6582 upb_strview str = jsondec_string(d);
6583 val.uint64_val = jsondec_strtouint64(d, str);
6584 break;
6585 }
6586 default:
6587 jsondec_err(d, "Expected number or string");
6588 }
6589
6590 if (upb_fielddef_type(f) == UPB_TYPE_UINT32) {
6591 if (val.uint64_val > UINT32_MAX) {
6592 jsondec_err(d, "Integer out of range.");
6593 }
6594 val.uint32_val = (uint32_t)val.uint64_val;
6595 }
6596
6597 return val;
6598 }
6599
6600 /* Parse DOUBLE or FLOAT value. */
jsondec_double(jsondec * d,const upb_fielddef * f)6601 static upb_msgval jsondec_double(jsondec *d, const upb_fielddef *f) {
6602 upb_strview str;
6603 upb_msgval val;
6604
6605 switch (jsondec_peek(d)) {
6606 case JD_NUMBER:
6607 val.double_val = jsondec_number(d);
6608 break;
6609 case JD_STRING:
6610 str = jsondec_string(d);
6611 if (jsondec_streql(str, "NaN")) {
6612 val.double_val = NAN;
6613 } else if (jsondec_streql(str, "Infinity")) {
6614 val.double_val = INFINITY;
6615 } else if (jsondec_streql(str, "-Infinity")) {
6616 val.double_val = -INFINITY;
6617 } else {
6618 val.double_val = strtod(str.data, NULL);
6619 }
6620 break;
6621 default:
6622 jsondec_err(d, "Expected number or string");
6623 }
6624
6625 if (upb_fielddef_type(f) == UPB_TYPE_FLOAT) {
6626 if (val.double_val != INFINITY && val.double_val != -INFINITY &&
6627 (val.double_val > FLT_MAX || val.double_val < -FLT_MAX)) {
6628 jsondec_err(d, "Float out of range");
6629 }
6630 val.float_val = val.double_val;
6631 }
6632
6633 return val;
6634 }
6635
6636 /* Parse STRING or BYTES value. */
jsondec_strfield(jsondec * d,const upb_fielddef * f)6637 static upb_msgval jsondec_strfield(jsondec *d, const upb_fielddef *f) {
6638 upb_msgval val;
6639 val.str_val = jsondec_string(d);
6640 if (upb_fielddef_type(f) == UPB_TYPE_BYTES) {
6641 val.str_val.size = jsondec_base64(d, val.str_val);
6642 }
6643 return val;
6644 }
6645
jsondec_enum(jsondec * d,const upb_fielddef * f)6646 static upb_msgval jsondec_enum(jsondec *d, const upb_fielddef *f) {
6647 switch (jsondec_peek(d)) {
6648 case JD_STRING: {
6649 const upb_enumdef *e = upb_fielddef_enumsubdef(f);
6650 upb_strview str = jsondec_string(d);
6651 upb_msgval val;
6652 if (!upb_enumdef_ntoi(e, str.data, str.size, &val.int32_val)) {
6653 if (d->options & UPB_JSONDEC_IGNOREUNKNOWN) {
6654 val.int32_val = 0;
6655 } else {
6656 jsondec_errf(d, "Unknown enumerator: '" UPB_STRVIEW_FORMAT "'",
6657 UPB_STRVIEW_ARGS(str));
6658 }
6659 }
6660 return val;
6661 }
6662 case JD_NULL: {
6663 if (jsondec_isnullvalue(f)) {
6664 upb_msgval val;
6665 jsondec_null(d);
6666 val.int32_val = 0;
6667 return val;
6668 }
6669 }
6670 /* Fallthrough. */
6671 default:
6672 return jsondec_int(d, f);
6673 }
6674 }
6675
jsondec_bool(jsondec * d,const upb_fielddef * f)6676 static upb_msgval jsondec_bool(jsondec *d, const upb_fielddef *f) {
6677 bool is_map_key = upb_fielddef_number(f) == 1 &&
6678 upb_msgdef_mapentry(upb_fielddef_containingtype(f));
6679 upb_msgval val;
6680
6681 if (is_map_key) {
6682 upb_strview str = jsondec_string(d);
6683 if (jsondec_streql(str, "true")) {
6684 val.bool_val = true;
6685 } else if (jsondec_streql(str, "false")) {
6686 val.bool_val = false;
6687 } else {
6688 jsondec_err(d, "Invalid boolean map key");
6689 }
6690 } else {
6691 switch (jsondec_peek(d)) {
6692 case JD_TRUE:
6693 val.bool_val = true;
6694 jsondec_true(d);
6695 break;
6696 case JD_FALSE:
6697 val.bool_val = false;
6698 jsondec_false(d);
6699 break;
6700 default:
6701 jsondec_err(d, "Expected true or false");
6702 }
6703 }
6704
6705 return val;
6706 }
6707
6708 /* Composite types (array/message/map) ****************************************/
6709
jsondec_array(jsondec * d,upb_msg * msg,const upb_fielddef * f)6710 static void jsondec_array(jsondec *d, upb_msg *msg, const upb_fielddef *f) {
6711 upb_array *arr = upb_msg_mutable(msg, f, d->arena).array;
6712
6713 jsondec_arrstart(d);
6714 while (jsondec_arrnext(d)) {
6715 upb_msgval elem = jsondec_value(d, f);
6716 upb_array_append(arr, elem, d->arena);
6717 }
6718 jsondec_arrend(d);
6719 }
6720
jsondec_map(jsondec * d,upb_msg * msg,const upb_fielddef * f)6721 static void jsondec_map(jsondec *d, upb_msg *msg, const upb_fielddef *f) {
6722 upb_map *map = upb_msg_mutable(msg, f, d->arena).map;
6723 const upb_msgdef *entry = upb_fielddef_msgsubdef(f);
6724 const upb_fielddef *key_f = upb_msgdef_itof(entry, 1);
6725 const upb_fielddef *val_f = upb_msgdef_itof(entry, 2);
6726
6727 jsondec_objstart(d);
6728 while (jsondec_objnext(d)) {
6729 upb_msgval key, val;
6730 key = jsondec_value(d, key_f);
6731 jsondec_entrysep(d);
6732 val = jsondec_value(d, val_f);
6733 upb_map_set(map, key, val, d->arena);
6734 }
6735 jsondec_objend(d);
6736 }
6737
jsondec_tomsg(jsondec * d,upb_msg * msg,const upb_msgdef * m)6738 static void jsondec_tomsg(jsondec *d, upb_msg *msg, const upb_msgdef *m) {
6739 if (upb_msgdef_wellknowntype(m) == UPB_WELLKNOWN_UNSPECIFIED) {
6740 jsondec_object(d, msg, m);
6741 } else {
6742 jsondec_wellknown(d, msg, m);
6743 }
6744 }
6745
jsondec_msg(jsondec * d,const upb_fielddef * f)6746 static upb_msgval jsondec_msg(jsondec *d, const upb_fielddef *f) {
6747 const upb_msgdef *m = upb_fielddef_msgsubdef(f);
6748 upb_msg *msg = upb_msg_new(m, d->arena);
6749 upb_msgval val;
6750
6751 jsondec_tomsg(d, msg, m);
6752 val.msg_val = msg;
6753 return val;
6754 }
6755
jsondec_field(jsondec * d,upb_msg * msg,const upb_msgdef * m)6756 static void jsondec_field(jsondec *d, upb_msg *msg, const upb_msgdef *m) {
6757 upb_strview name;
6758 const upb_fielddef *f;
6759 const upb_fielddef *preserved;
6760
6761 name = jsondec_string(d);
6762 jsondec_entrysep(d);
6763 f = upb_msgdef_lookupjsonname(m, name.data, name.size);
6764
6765 if (!f) {
6766 if ((d->options & UPB_JSONDEC_IGNOREUNKNOWN) == 0) {
6767 jsondec_errf(d, "Unknown field: '" UPB_STRVIEW_FORMAT "'",
6768 UPB_STRVIEW_ARGS(name));
6769 }
6770 jsondec_skipval(d);
6771 return;
6772 }
6773
6774 if (upb_fielddef_realcontainingoneof(f) &&
6775 upb_msg_whichoneof(msg, upb_fielddef_containingoneof(f))) {
6776 jsondec_err(d, "More than one field for this oneof.");
6777 }
6778
6779 if (jsondec_peek(d) == JD_NULL && !jsondec_isvalue(f)) {
6780 /* JSON "null" indicates a default value, so no need to set anything. */
6781 jsondec_null(d);
6782 return;
6783 }
6784
6785 preserved = d->debug_field;
6786 d->debug_field = f;
6787
6788 if (upb_fielddef_ismap(f)) {
6789 jsondec_map(d, msg, f);
6790 } else if (upb_fielddef_isseq(f)) {
6791 jsondec_array(d, msg, f);
6792 } else if (upb_fielddef_issubmsg(f)) {
6793 upb_msg *submsg = upb_msg_mutable(msg, f, d->arena).msg;
6794 const upb_msgdef *subm = upb_fielddef_msgsubdef(f);
6795 jsondec_tomsg(d, submsg, subm);
6796 } else {
6797 upb_msgval val = jsondec_value(d, f);
6798 upb_msg_set(msg, f, val, d->arena);
6799 }
6800
6801 d->debug_field = preserved;
6802 }
6803
jsondec_object(jsondec * d,upb_msg * msg,const upb_msgdef * m)6804 static void jsondec_object(jsondec *d, upb_msg *msg, const upb_msgdef *m) {
6805 jsondec_objstart(d);
6806 while (jsondec_objnext(d)) {
6807 jsondec_field(d, msg, m);
6808 }
6809 jsondec_objend(d);
6810 }
6811
jsondec_value(jsondec * d,const upb_fielddef * f)6812 static upb_msgval jsondec_value(jsondec *d, const upb_fielddef *f) {
6813 switch (upb_fielddef_type(f)) {
6814 case UPB_TYPE_BOOL:
6815 return jsondec_bool(d, f);
6816 case UPB_TYPE_FLOAT:
6817 case UPB_TYPE_DOUBLE:
6818 return jsondec_double(d, f);
6819 case UPB_TYPE_UINT32:
6820 case UPB_TYPE_UINT64:
6821 return jsondec_uint(d, f);
6822 case UPB_TYPE_INT32:
6823 case UPB_TYPE_INT64:
6824 return jsondec_int(d, f);
6825 case UPB_TYPE_STRING:
6826 case UPB_TYPE_BYTES:
6827 return jsondec_strfield(d, f);
6828 case UPB_TYPE_ENUM:
6829 return jsondec_enum(d, f);
6830 case UPB_TYPE_MESSAGE:
6831 return jsondec_msg(d, f);
6832 default:
6833 UPB_UNREACHABLE();
6834 }
6835 }
6836
6837 /* Well-known types ***********************************************************/
6838
jsondec_tsdigits(jsondec * d,const char ** ptr,size_t digits,const char * after)6839 static int jsondec_tsdigits(jsondec *d, const char **ptr, size_t digits,
6840 const char *after) {
6841 uint64_t val;
6842 const char *p = *ptr;
6843 const char *end = p + digits;
6844 size_t after_len = after ? strlen(after) : 0;
6845
6846 UPB_ASSERT(digits <= 9); /* int can't overflow. */
6847
6848 if (jsondec_buftouint64(d, p, end, &val) != end ||
6849 (after_len && memcmp(end, after, after_len) != 0)) {
6850 jsondec_err(d, "Malformed timestamp");
6851 }
6852
6853 UPB_ASSERT(val < INT_MAX);
6854
6855 *ptr = end + after_len;
6856 return (int)val;
6857 }
6858
jsondec_nanos(jsondec * d,const char ** ptr,const char * end)6859 static int jsondec_nanos(jsondec *d, const char **ptr, const char *end) {
6860 uint64_t nanos = 0;
6861 const char *p = *ptr;
6862
6863 if (p != end && *p == '.') {
6864 const char *nano_end = jsondec_buftouint64(d, p + 1, end, &nanos);
6865 int digits = (int)(nano_end - p - 1);
6866 int exp_lg10 = 9 - digits;
6867 if (digits > 9) {
6868 jsondec_err(d, "Too many digits for partial seconds");
6869 }
6870 while (exp_lg10--) nanos *= 10;
6871 *ptr = nano_end;
6872 }
6873
6874 UPB_ASSERT(nanos < INT_MAX);
6875
6876 return (int)nanos;
6877 }
6878
6879 /* jsondec_epochdays(1970, 1, 1) == 1970-01-01 == 0. */
jsondec_epochdays(int y,int m,int d)6880 int jsondec_epochdays(int y, int m, int d) {
6881 const uint32_t year_base = 4800; /* Before min year, multiple of 400. */
6882 const uint32_t m_adj = m - 3; /* March-based month. */
6883 const uint32_t carry = m_adj > (uint32_t)m ? 1 : 0;
6884 const uint32_t adjust = carry ? 12 : 0;
6885 const uint32_t y_adj = y + year_base - carry;
6886 const uint32_t month_days = ((m_adj + adjust) * 62719 + 769) / 2048;
6887 const uint32_t leap_days = y_adj / 4 - y_adj / 100 + y_adj / 400;
6888 return y_adj * 365 + leap_days + month_days + (d - 1) - 2472632;
6889 }
6890
jsondec_unixtime(int y,int m,int d,int h,int min,int s)6891 static int64_t jsondec_unixtime(int y, int m, int d, int h, int min, int s) {
6892 return (int64_t)jsondec_epochdays(y, m, d) * 86400 + h * 3600 + min * 60 + s;
6893 }
6894
jsondec_timestamp(jsondec * d,upb_msg * msg,const upb_msgdef * m)6895 static void jsondec_timestamp(jsondec *d, upb_msg *msg, const upb_msgdef *m) {
6896 upb_msgval seconds;
6897 upb_msgval nanos;
6898 upb_strview str = jsondec_string(d);
6899 const char *ptr = str.data;
6900 const char *end = ptr + str.size;
6901
6902 if (str.size < 20) goto malformed;
6903
6904 {
6905 /* 1972-01-01T01:00:00 */
6906 int year = jsondec_tsdigits(d, &ptr, 4, "-");
6907 int mon = jsondec_tsdigits(d, &ptr, 2, "-");
6908 int day = jsondec_tsdigits(d, &ptr, 2, "T");
6909 int hour = jsondec_tsdigits(d, &ptr, 2, ":");
6910 int min = jsondec_tsdigits(d, &ptr, 2, ":");
6911 int sec = jsondec_tsdigits(d, &ptr, 2, NULL);
6912
6913 seconds.int64_val = jsondec_unixtime(year, mon, day, hour, min, sec);
6914 }
6915
6916 nanos.int32_val = jsondec_nanos(d, &ptr, end);
6917
6918 {
6919 /* [+-]08:00 or Z */
6920 int ofs = 0;
6921 bool neg = false;
6922
6923 if (ptr == end) goto malformed;
6924
6925 switch (*ptr++) {
6926 case '-':
6927 neg = true;
6928 /* fallthrough */
6929 case '+':
6930 if ((end - ptr) != 5) goto malformed;
6931 ofs = jsondec_tsdigits(d, &ptr, 2, ":00");
6932 ofs *= 60 * 60;
6933 seconds.int64_val += (neg ? ofs : -ofs);
6934 break;
6935 case 'Z':
6936 if (ptr != end) goto malformed;
6937 break;
6938 default:
6939 goto malformed;
6940 }
6941 }
6942
6943 if (seconds.int64_val < -62135596800) {
6944 jsondec_err(d, "Timestamp out of range");
6945 }
6946
6947 upb_msg_set(msg, upb_msgdef_itof(m, 1), seconds, d->arena);
6948 upb_msg_set(msg, upb_msgdef_itof(m, 2), nanos, d->arena);
6949 return;
6950
6951 malformed:
6952 jsondec_err(d, "Malformed timestamp");
6953 }
6954
jsondec_duration(jsondec * d,upb_msg * msg,const upb_msgdef * m)6955 static void jsondec_duration(jsondec *d, upb_msg *msg, const upb_msgdef *m) {
6956 upb_msgval seconds;
6957 upb_msgval nanos;
6958 upb_strview str = jsondec_string(d);
6959 const char *ptr = str.data;
6960 const char *end = ptr + str.size;
6961 const int64_t max = (uint64_t)3652500 * 86400;
6962
6963 /* "3.000000001s", "3s", etc. */
6964 ptr = jsondec_buftoint64(d, ptr, end, &seconds.int64_val);
6965 nanos.int32_val = jsondec_nanos(d, &ptr, end);
6966
6967 if (end - ptr != 1 || *ptr != 's') {
6968 jsondec_err(d, "Malformed duration");
6969 }
6970
6971 if (seconds.int64_val < -max || seconds.int64_val > max) {
6972 jsondec_err(d, "Duration out of range");
6973 }
6974
6975 if (seconds.int64_val < 0) {
6976 nanos.int32_val = - nanos.int32_val;
6977 }
6978
6979 upb_msg_set(msg, upb_msgdef_itof(m, 1), seconds, d->arena);
6980 upb_msg_set(msg, upb_msgdef_itof(m, 2), nanos, d->arena);
6981 }
6982
jsondec_listvalue(jsondec * d,upb_msg * msg,const upb_msgdef * m)6983 static void jsondec_listvalue(jsondec *d, upb_msg *msg, const upb_msgdef *m) {
6984 const upb_fielddef *values_f = upb_msgdef_itof(m, 1);
6985 const upb_msgdef *value_m = upb_fielddef_msgsubdef(values_f);
6986 upb_array *values = upb_msg_mutable(msg, values_f, d->arena).array;
6987
6988 jsondec_arrstart(d);
6989 while (jsondec_arrnext(d)) {
6990 upb_msg *value_msg = upb_msg_new(value_m, d->arena);
6991 upb_msgval value;
6992 value.msg_val = value_msg;
6993 upb_array_append(values, value, d->arena);
6994 jsondec_wellknownvalue(d, value_msg, value_m);
6995 }
6996 jsondec_arrend(d);
6997 }
6998
jsondec_struct(jsondec * d,upb_msg * msg,const upb_msgdef * m)6999 static void jsondec_struct(jsondec *d, upb_msg *msg, const upb_msgdef *m) {
7000 const upb_fielddef *fields_f = upb_msgdef_itof(m, 1);
7001 const upb_msgdef *entry_m = upb_fielddef_msgsubdef(fields_f);
7002 const upb_fielddef *value_f = upb_msgdef_itof(entry_m, 2);
7003 const upb_msgdef *value_m = upb_fielddef_msgsubdef(value_f);
7004 upb_map *fields = upb_msg_mutable(msg, fields_f, d->arena).map;
7005
7006 jsondec_objstart(d);
7007 while (jsondec_objnext(d)) {
7008 upb_msgval key, value;
7009 upb_msg *value_msg = upb_msg_new(value_m, d->arena);
7010 key.str_val = jsondec_string(d);
7011 value.msg_val = value_msg;
7012 upb_map_set(fields, key, value, d->arena);
7013 jsondec_entrysep(d);
7014 jsondec_wellknownvalue(d, value_msg, value_m);
7015 }
7016 jsondec_objend(d);
7017 }
7018
jsondec_wellknownvalue(jsondec * d,upb_msg * msg,const upb_msgdef * m)7019 static void jsondec_wellknownvalue(jsondec *d, upb_msg *msg,
7020 const upb_msgdef *m) {
7021 upb_msgval val;
7022 const upb_fielddef *f;
7023 upb_msg *submsg;
7024
7025 switch (jsondec_peek(d)) {
7026 case JD_NUMBER:
7027 /* double number_value = 2; */
7028 f = upb_msgdef_itof(m, 2);
7029 val.double_val = jsondec_number(d);
7030 break;
7031 case JD_STRING:
7032 /* string string_value = 3; */
7033 f = upb_msgdef_itof(m, 3);
7034 val.str_val = jsondec_string(d);
7035 break;
7036 case JD_FALSE:
7037 /* bool bool_value = 4; */
7038 f = upb_msgdef_itof(m, 4);
7039 val.bool_val = false;
7040 jsondec_false(d);
7041 break;
7042 case JD_TRUE:
7043 /* bool bool_value = 4; */
7044 f = upb_msgdef_itof(m, 4);
7045 val.bool_val = true;
7046 jsondec_true(d);
7047 break;
7048 case JD_NULL:
7049 /* NullValue null_value = 1; */
7050 f = upb_msgdef_itof(m, 1);
7051 val.int32_val = 0;
7052 jsondec_null(d);
7053 break;
7054 /* Note: these cases return, because upb_msg_mutable() is enough. */
7055 case JD_OBJECT:
7056 /* Struct struct_value = 5; */
7057 f = upb_msgdef_itof(m, 5);
7058 submsg = upb_msg_mutable(msg, f, d->arena).msg;
7059 jsondec_struct(d, submsg, upb_fielddef_msgsubdef(f));
7060 return;
7061 case JD_ARRAY:
7062 /* ListValue list_value = 6; */
7063 f = upb_msgdef_itof(m, 6);
7064 submsg = upb_msg_mutable(msg, f, d->arena).msg;
7065 jsondec_listvalue(d, submsg, upb_fielddef_msgsubdef(f));
7066 return;
7067 default:
7068 UPB_UNREACHABLE();
7069 }
7070
7071 upb_msg_set(msg, f, val, d->arena);
7072 }
7073
jsondec_mask(jsondec * d,const char * buf,const char * end)7074 static upb_strview jsondec_mask(jsondec *d, const char *buf, const char *end) {
7075 /* FieldMask fields grow due to inserted '_' characters, so we can't do the
7076 * transform in place. */
7077 const char *ptr = buf;
7078 upb_strview ret;
7079 char *out;
7080
7081 ret.size = end - ptr;
7082 while (ptr < end) {
7083 ret.size += (*ptr >= 'A' && *ptr <= 'Z');
7084 ptr++;
7085 }
7086
7087 out = upb_arena_malloc(d->arena, ret.size);
7088 ptr = buf;
7089 ret.data = out;
7090
7091 while (ptr < end) {
7092 char ch = *ptr++;
7093 if (ch >= 'A' && ch <= 'Z') {
7094 *out++ = '_';
7095 *out++ = ch + 32;
7096 } else if (ch == '_') {
7097 jsondec_err(d, "field mask may not contain '_'");
7098 } else {
7099 *out++ = ch;
7100 }
7101 }
7102
7103 return ret;
7104 }
7105
jsondec_fieldmask(jsondec * d,upb_msg * msg,const upb_msgdef * m)7106 static void jsondec_fieldmask(jsondec *d, upb_msg *msg, const upb_msgdef *m) {
7107 /* repeated string paths = 1; */
7108 const upb_fielddef *paths_f = upb_msgdef_itof(m, 1);
7109 upb_array *arr = upb_msg_mutable(msg, paths_f, d->arena).array;
7110 upb_strview str = jsondec_string(d);
7111 const char *ptr = str.data;
7112 const char *end = ptr + str.size;
7113 upb_msgval val;
7114
7115 while (ptr < end) {
7116 const char *elem_end = memchr(ptr, ',', end - ptr);
7117 if (elem_end) {
7118 val.str_val = jsondec_mask(d, ptr, elem_end);
7119 ptr = elem_end + 1;
7120 } else {
7121 val.str_val = jsondec_mask(d, ptr, end);
7122 ptr = end;
7123 }
7124 upb_array_append(arr, val, d->arena);
7125 }
7126 }
7127
jsondec_anyfield(jsondec * d,upb_msg * msg,const upb_msgdef * m)7128 static void jsondec_anyfield(jsondec *d, upb_msg *msg, const upb_msgdef *m) {
7129 if (upb_msgdef_wellknowntype(m) == UPB_WELLKNOWN_UNSPECIFIED) {
7130 /* For regular types: {"@type": "[user type]", "f1": <V1>, "f2": <V2>}
7131 * where f1, f2, etc. are the normal fields of this type. */
7132 jsondec_field(d, msg, m);
7133 } else {
7134 /* For well-known types: {"@type": "[well-known type]", "value": <X>}
7135 * where <X> is whatever encoding the WKT normally uses. */
7136 upb_strview str = jsondec_string(d);
7137 jsondec_entrysep(d);
7138 if (!jsondec_streql(str, "value")) {
7139 jsondec_err(d, "Key for well-known type must be 'value'");
7140 }
7141 jsondec_wellknown(d, msg, m);
7142 }
7143 }
7144
jsondec_typeurl(jsondec * d,upb_msg * msg,const upb_msgdef * m)7145 static const upb_msgdef *jsondec_typeurl(jsondec *d, upb_msg *msg,
7146 const upb_msgdef *m) {
7147 const upb_fielddef *type_url_f = upb_msgdef_itof(m, 1);
7148 const upb_msgdef *type_m;
7149 upb_strview type_url = jsondec_string(d);
7150 const char *end = type_url.data + type_url.size;
7151 const char *ptr = end;
7152 upb_msgval val;
7153
7154 val.str_val = type_url;
7155 upb_msg_set(msg, type_url_f, val, d->arena);
7156
7157 /* Find message name after the last '/' */
7158 while (ptr > type_url.data && *--ptr != '/') {}
7159
7160 if (ptr == type_url.data || ptr == end) {
7161 jsondec_err(d, "Type url must have at least one '/' and non-empty host");
7162 }
7163
7164 ptr++;
7165 type_m = upb_symtab_lookupmsg2(d->any_pool, ptr, end - ptr);
7166
7167 if (!type_m) {
7168 jsondec_err(d, "Type was not found");
7169 }
7170
7171 return type_m;
7172 }
7173
jsondec_any(jsondec * d,upb_msg * msg,const upb_msgdef * m)7174 static void jsondec_any(jsondec *d, upb_msg *msg, const upb_msgdef *m) {
7175 /* string type_url = 1;
7176 * bytes value = 2; */
7177 const upb_fielddef *value_f = upb_msgdef_itof(m, 2);
7178 upb_msg *any_msg;
7179 const upb_msgdef *any_m = NULL;
7180 const char *pre_type_data = NULL;
7181 const char *pre_type_end = NULL;
7182 upb_msgval encoded;
7183
7184 jsondec_objstart(d);
7185
7186 /* Scan looking for "@type", which is not necessarily first. */
7187 while (!any_m && jsondec_objnext(d)) {
7188 const char *start = d->ptr;
7189 upb_strview name = jsondec_string(d);
7190 jsondec_entrysep(d);
7191 if (jsondec_streql(name, "@type")) {
7192 any_m = jsondec_typeurl(d, msg, m);
7193 if (pre_type_data) {
7194 pre_type_end = start;
7195 while (*pre_type_end != ',') pre_type_end--;
7196 }
7197 } else {
7198 if (!pre_type_data) pre_type_data = start;
7199 jsondec_skipval(d);
7200 }
7201 }
7202
7203 if (!any_m) {
7204 jsondec_err(d, "Any object didn't contain a '@type' field");
7205 }
7206
7207 any_msg = upb_msg_new(any_m, d->arena);
7208
7209 if (pre_type_data) {
7210 size_t len = pre_type_end - pre_type_data + 1;
7211 char *tmp = upb_arena_malloc(d->arena, len);
7212 const char *saved_ptr = d->ptr;
7213 const char *saved_end = d->end;
7214 memcpy(tmp, pre_type_data, len - 1);
7215 tmp[len - 1] = '}';
7216 d->ptr = tmp;
7217 d->end = tmp + len;
7218 d->is_first = true;
7219 while (jsondec_objnext(d)) {
7220 jsondec_anyfield(d, any_msg, any_m);
7221 }
7222 d->ptr = saved_ptr;
7223 d->end = saved_end;
7224 }
7225
7226 while (jsondec_objnext(d)) {
7227 jsondec_anyfield(d, any_msg, any_m);
7228 }
7229
7230 jsondec_objend(d);
7231
7232 encoded.str_val.data = upb_encode(any_msg, upb_msgdef_layout(any_m), d->arena,
7233 &encoded.str_val.size);
7234 upb_msg_set(msg, value_f, encoded, d->arena);
7235 }
7236
jsondec_wrapper(jsondec * d,upb_msg * msg,const upb_msgdef * m)7237 static void jsondec_wrapper(jsondec *d, upb_msg *msg, const upb_msgdef *m) {
7238 const upb_fielddef *value_f = upb_msgdef_itof(m, 1);
7239 upb_msgval val = jsondec_value(d, value_f);
7240 upb_msg_set(msg, value_f, val, d->arena);
7241 }
7242
jsondec_wellknown(jsondec * d,upb_msg * msg,const upb_msgdef * m)7243 static void jsondec_wellknown(jsondec *d, upb_msg *msg, const upb_msgdef *m) {
7244 switch (upb_msgdef_wellknowntype(m)) {
7245 case UPB_WELLKNOWN_ANY:
7246 jsondec_any(d, msg, m);
7247 break;
7248 case UPB_WELLKNOWN_FIELDMASK:
7249 jsondec_fieldmask(d, msg, m);
7250 break;
7251 case UPB_WELLKNOWN_DURATION:
7252 jsondec_duration(d, msg, m);
7253 break;
7254 case UPB_WELLKNOWN_TIMESTAMP:
7255 jsondec_timestamp(d, msg, m);
7256 break;
7257 case UPB_WELLKNOWN_VALUE:
7258 jsondec_wellknownvalue(d, msg, m);
7259 break;
7260 case UPB_WELLKNOWN_LISTVALUE:
7261 jsondec_listvalue(d, msg, m);
7262 break;
7263 case UPB_WELLKNOWN_STRUCT:
7264 jsondec_struct(d, msg, m);
7265 break;
7266 case UPB_WELLKNOWN_DOUBLEVALUE:
7267 case UPB_WELLKNOWN_FLOATVALUE:
7268 case UPB_WELLKNOWN_INT64VALUE:
7269 case UPB_WELLKNOWN_UINT64VALUE:
7270 case UPB_WELLKNOWN_INT32VALUE:
7271 case UPB_WELLKNOWN_UINT32VALUE:
7272 case UPB_WELLKNOWN_STRINGVALUE:
7273 case UPB_WELLKNOWN_BYTESVALUE:
7274 case UPB_WELLKNOWN_BOOLVALUE:
7275 jsondec_wrapper(d, msg, m);
7276 break;
7277 default:
7278 UPB_UNREACHABLE();
7279 }
7280 }
7281
upb_json_decode(const char * buf,size_t size,upb_msg * msg,const upb_msgdef * m,const upb_symtab * any_pool,int options,upb_arena * arena,upb_status * status)7282 bool upb_json_decode(const char *buf, size_t size, upb_msg *msg,
7283 const upb_msgdef *m, const upb_symtab *any_pool,
7284 int options, upb_arena *arena, upb_status *status) {
7285 jsondec d;
7286 d.ptr = buf;
7287 d.end = buf + size;
7288 d.arena = arena;
7289 d.any_pool = any_pool;
7290 d.status = status;
7291 d.options = options;
7292 d.depth = 64;
7293 d.line = 1;
7294 d.line_begin = d.ptr;
7295 d.debug_field = NULL;
7296 d.is_first = false;
7297
7298 if (setjmp(d.err)) return false;
7299
7300 jsondec_tomsg(&d, msg, m);
7301 return true;
7302 }
7303
7304
7305 #include <ctype.h>
7306 #include <float.h>
7307 #include <inttypes.h>
7308 #include <math.h>
7309 #include <setjmp.h>
7310 #include <stdarg.h>
7311 #include <stdio.h>
7312 #include <string.h>
7313
7314
7315 /* Must be last. */
7316
7317 typedef struct {
7318 char *buf, *ptr, *end;
7319 size_t overflow;
7320 int indent_depth;
7321 int options;
7322 const upb_symtab *ext_pool;
7323 jmp_buf err;
7324 upb_status *status;
7325 upb_arena *arena;
7326 } jsonenc;
7327
7328 static void jsonenc_msg(jsonenc *e, const upb_msg *msg, const upb_msgdef *m);
7329 static void jsonenc_scalar(jsonenc *e, upb_msgval val, const upb_fielddef *f);
7330 static void jsonenc_msgfield(jsonenc *e, const upb_msg *msg,
7331 const upb_msgdef *m);
7332 static void jsonenc_msgfields(jsonenc *e, const upb_msg *msg,
7333 const upb_msgdef *m);
7334 static void jsonenc_value(jsonenc *e, const upb_msg *msg, const upb_msgdef *m);
7335
jsonenc_err(jsonenc * e,const char * msg)7336 UPB_NORETURN static void jsonenc_err(jsonenc *e, const char *msg) {
7337 upb_status_seterrmsg(e->status, msg);
7338 longjmp(e->err, 1);
7339 }
7340
jsonenc_errf(jsonenc * e,const char * fmt,...)7341 UPB_NORETURN static void jsonenc_errf(jsonenc *e, const char *fmt, ...) {
7342 va_list argp;
7343 va_start(argp, fmt);
7344 upb_status_vseterrf(e->status, fmt, argp);
7345 va_end(argp);
7346 longjmp(e->err, 1);
7347 }
7348
jsonenc_arena(jsonenc * e)7349 static upb_arena *jsonenc_arena(jsonenc *e) {
7350 /* Create lazily, since it's only needed for Any */
7351 if (!e->arena) {
7352 e->arena = upb_arena_new();
7353 }
7354 return e->arena;
7355 }
7356
jsonenc_putbytes(jsonenc * e,const void * data,size_t len)7357 static void jsonenc_putbytes(jsonenc *e, const void *data, size_t len) {
7358 size_t have = e->end - e->ptr;
7359 if (UPB_LIKELY(have >= len)) {
7360 memcpy(e->ptr, data, len);
7361 e->ptr += len;
7362 } else {
7363 if (have) memcpy(e->ptr, data, have);
7364 e->ptr += have;
7365 e->overflow += (len - have);
7366 }
7367 }
7368
jsonenc_putstr(jsonenc * e,const char * str)7369 static void jsonenc_putstr(jsonenc *e, const char *str) {
7370 jsonenc_putbytes(e, str, strlen(str));
7371 }
7372
jsonenc_printf(jsonenc * e,const char * fmt,...)7373 static void jsonenc_printf(jsonenc *e, const char *fmt, ...) {
7374 size_t n;
7375 size_t have = e->end - e->ptr;
7376 va_list args;
7377
7378 va_start(args, fmt);
7379 n = vsnprintf(e->ptr, have, fmt, args);
7380 va_end(args);
7381
7382 if (UPB_LIKELY(have > n)) {
7383 e->ptr += n;
7384 } else {
7385 e->ptr += have;
7386 e->overflow += (n - have);
7387 }
7388 }
7389
jsonenc_nanos(jsonenc * e,int32_t nanos)7390 static void jsonenc_nanos(jsonenc *e, int32_t nanos) {
7391 int digits = 9;
7392
7393 if (nanos == 0) return;
7394 if (nanos < 0 || nanos >= 1000000000) {
7395 jsonenc_err(e, "error formatting timestamp as JSON: invalid nanos");
7396 }
7397
7398 while (nanos % 1000 == 0) {
7399 nanos /= 1000;
7400 digits -= 3;
7401 }
7402
7403 jsonenc_printf(e, ".%0.*" PRId32, digits, nanos);
7404 }
7405
jsonenc_timestamp(jsonenc * e,const upb_msg * msg,const upb_msgdef * m)7406 static void jsonenc_timestamp(jsonenc *e, const upb_msg *msg,
7407 const upb_msgdef *m) {
7408 const upb_fielddef *seconds_f = upb_msgdef_itof(m, 1);
7409 const upb_fielddef *nanos_f = upb_msgdef_itof(m, 2);
7410 int64_t seconds = upb_msg_get(msg, seconds_f).int64_val;
7411 int32_t nanos = upb_msg_get(msg, nanos_f).int32_val;
7412 int L, N, I, J, K, hour, min, sec;
7413
7414 if (seconds < -62135596800) {
7415 jsonenc_err(e,
7416 "error formatting timestamp as JSON: minimum acceptable value "
7417 "is 0001-01-01T00:00:00Z");
7418 } else if (seconds > 253402300799) {
7419 jsonenc_err(e,
7420 "error formatting timestamp as JSON: maximum acceptable value "
7421 "is 9999-12-31T23:59:59Z");
7422 }
7423
7424 /* Julian Day -> Y/M/D, Algorithm from:
7425 * Fliegel, H. F., and Van Flandern, T. C., "A Machine Algorithm for
7426 * Processing Calendar Dates," Communications of the Association of
7427 * Computing Machines, vol. 11 (1968), p. 657. */
7428 L = (int)(seconds / 86400) + 68569 + 2440588;
7429 N = 4 * L / 146097;
7430 L = L - (146097 * N + 3) / 4;
7431 I = 4000 * (L + 1) / 1461001;
7432 L = L - 1461 * I / 4 + 31;
7433 J = 80 * L / 2447;
7434 K = L - 2447 * J / 80;
7435 L = J / 11;
7436 J = J + 2 - 12 * L;
7437 I = 100 * (N - 49) + I + L;
7438
7439 sec = seconds % 60;
7440 min = (seconds / 60) % 60;
7441 hour = (seconds / 3600) % 24;
7442
7443 jsonenc_printf(e, "\"%04d-%02d-%02dT%02d:%02d:%02d", I, J, K, hour, min, sec);
7444 jsonenc_nanos(e, nanos);
7445 jsonenc_putstr(e, "Z\"");
7446 }
7447
jsonenc_duration(jsonenc * e,const upb_msg * msg,const upb_msgdef * m)7448 static void jsonenc_duration(jsonenc *e, const upb_msg *msg, const upb_msgdef *m) {
7449 const upb_fielddef *seconds_f = upb_msgdef_itof(m, 1);
7450 const upb_fielddef *nanos_f = upb_msgdef_itof(m, 2);
7451 int64_t seconds = upb_msg_get(msg, seconds_f).int64_val;
7452 int32_t nanos = upb_msg_get(msg, nanos_f).int32_val;
7453
7454 if (seconds > 315576000000 || seconds < -315576000000 ||
7455 (seconds < 0) != (nanos < 0)) {
7456 jsonenc_err(e, "bad duration");
7457 }
7458
7459 if (nanos < 0) {
7460 nanos = -nanos;
7461 }
7462
7463 jsonenc_printf(e, "\"%" PRId64, seconds);
7464 jsonenc_nanos(e, nanos);
7465 jsonenc_putstr(e, "s\"");
7466 }
7467
jsonenc_enum(int32_t val,const upb_fielddef * f,jsonenc * e)7468 static void jsonenc_enum(int32_t val, const upb_fielddef *f, jsonenc *e) {
7469 const upb_enumdef *e_def = upb_fielddef_enumsubdef(f);
7470
7471 if (strcmp(upb_enumdef_fullname(e_def), "google.protobuf.NullValue") == 0) {
7472 jsonenc_putstr(e, "null");
7473 } else {
7474 const char *name = upb_enumdef_iton(e_def, val);
7475
7476 if (name) {
7477 jsonenc_printf(e, "\"%s\"", name);
7478 } else {
7479 jsonenc_printf(e, "%" PRId32, val);
7480 }
7481 }
7482 }
7483
jsonenc_bytes(jsonenc * e,upb_strview str)7484 static void jsonenc_bytes(jsonenc *e, upb_strview str) {
7485 /* This is the regular base64, not the "web-safe" version. */
7486 static const char base64[] =
7487 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
7488 const unsigned char *ptr = (unsigned char*)str.data;
7489 const unsigned char *end = ptr + str.size;
7490 char buf[4];
7491
7492 jsonenc_putstr(e, "\"");
7493
7494 while (end - ptr >= 3) {
7495 buf[0] = base64[ptr[0] >> 2];
7496 buf[1] = base64[((ptr[0] & 0x3) << 4) | (ptr[1] >> 4)];
7497 buf[2] = base64[((ptr[1] & 0xf) << 2) | (ptr[2] >> 6)];
7498 buf[3] = base64[ptr[2] & 0x3f];
7499 jsonenc_putbytes(e, buf, 4);
7500 ptr += 3;
7501 }
7502
7503 switch (end - ptr) {
7504 case 2:
7505 buf[0] = base64[ptr[0] >> 2];
7506 buf[1] = base64[((ptr[0] & 0x3) << 4) | (ptr[1] >> 4)];
7507 buf[2] = base64[(ptr[1] & 0xf) << 2];
7508 buf[3] = '=';
7509 jsonenc_putbytes(e, buf, 4);
7510 break;
7511 case 1:
7512 buf[0] = base64[ptr[0] >> 2];
7513 buf[1] = base64[((ptr[0] & 0x3) << 4)];
7514 buf[2] = '=';
7515 buf[3] = '=';
7516 jsonenc_putbytes(e, buf, 4);
7517 break;
7518 }
7519
7520 jsonenc_putstr(e, "\"");
7521 }
7522
jsonenc_stringbody(jsonenc * e,upb_strview str)7523 static void jsonenc_stringbody(jsonenc *e, upb_strview str) {
7524 const char *ptr = str.data;
7525 const char *end = ptr + str.size;
7526
7527 while (ptr < end) {
7528 switch (*ptr) {
7529 case '\n':
7530 jsonenc_putstr(e, "\\n");
7531 break;
7532 case '\r':
7533 jsonenc_putstr(e, "\\r");
7534 break;
7535 case '\t':
7536 jsonenc_putstr(e, "\\t");
7537 break;
7538 case '\"':
7539 jsonenc_putstr(e, "\\\"");
7540 break;
7541 case '\f':
7542 jsonenc_putstr(e, "\\f");
7543 break;
7544 case '\b':
7545 jsonenc_putstr(e, "\\b");
7546 break;
7547 case '\\':
7548 jsonenc_putstr(e, "\\\\");
7549 break;
7550 default:
7551 if ((uint8_t)*ptr < 0x20) {
7552 jsonenc_printf(e, "\\u%04x", (int)(uint8_t)*ptr);
7553 } else {
7554 /* This could be a non-ASCII byte. We rely on the string being valid
7555 * UTF-8. */
7556 jsonenc_putbytes(e, ptr, 1);
7557 }
7558 break;
7559 }
7560 ptr++;
7561 }
7562 }
7563
jsonenc_string(jsonenc * e,upb_strview str)7564 static void jsonenc_string(jsonenc *e, upb_strview str) {
7565 jsonenc_putstr(e, "\"");
7566 jsonenc_stringbody(e, str);
7567 jsonenc_putstr(e, "\"");
7568 }
7569
jsonenc_double(jsonenc * e,const char * fmt,double val)7570 static void jsonenc_double(jsonenc *e, const char *fmt, double val) {
7571 if (val == INFINITY) {
7572 jsonenc_putstr(e, "\"Infinity\"");
7573 } else if (val == -INFINITY) {
7574 jsonenc_putstr(e, "\"-Infinity\"");
7575 } else if (val != val) {
7576 jsonenc_putstr(e, "\"NaN\"");
7577 } else {
7578 jsonenc_printf(e, fmt, val);
7579 }
7580 }
7581
jsonenc_wrapper(jsonenc * e,const upb_msg * msg,const upb_msgdef * m)7582 static void jsonenc_wrapper(jsonenc *e, const upb_msg *msg,
7583 const upb_msgdef *m) {
7584 const upb_fielddef *val_f = upb_msgdef_itof(m, 1);
7585 upb_msgval val = upb_msg_get(msg, val_f);
7586 jsonenc_scalar(e, val, val_f);
7587 }
7588
jsonenc_getanymsg(jsonenc * e,upb_strview type_url)7589 static const upb_msgdef *jsonenc_getanymsg(jsonenc *e, upb_strview type_url) {
7590 /* Find last '/', if any. */
7591 const char *end = type_url.data + type_url.size;
7592 const char *ptr = end;
7593 const upb_msgdef *ret;
7594
7595 if (!e->ext_pool) {
7596 jsonenc_err(e, "Tried to encode Any, but no symtab was provided");
7597 }
7598
7599 if (type_url.size == 0) goto badurl;
7600
7601 while (true) {
7602 if (--ptr == type_url.data) {
7603 /* Type URL must contain at least one '/', with host before. */
7604 goto badurl;
7605 }
7606 if (*ptr == '/') {
7607 ptr++;
7608 break;
7609 }
7610 }
7611
7612 ret = upb_symtab_lookupmsg2(e->ext_pool, ptr, end - ptr);
7613
7614 if (!ret) {
7615 jsonenc_errf(e, "Couldn't find Any type: %.*s", (int)(end - ptr), ptr);
7616 }
7617
7618 return ret;
7619
7620 badurl:
7621 jsonenc_errf(
7622 e, "Bad type URL: " UPB_STRVIEW_FORMAT, UPB_STRVIEW_ARGS(type_url));
7623 }
7624
jsonenc_any(jsonenc * e,const upb_msg * msg,const upb_msgdef * m)7625 static void jsonenc_any(jsonenc *e, const upb_msg *msg, const upb_msgdef *m) {
7626 const upb_fielddef *type_url_f = upb_msgdef_itof(m, 1);
7627 const upb_fielddef *value_f = upb_msgdef_itof(m, 2);
7628 upb_strview type_url = upb_msg_get(msg, type_url_f).str_val;
7629 upb_strview value = upb_msg_get(msg, value_f).str_val;
7630 const upb_msgdef *any_m = jsonenc_getanymsg(e, type_url);
7631 const upb_msglayout *any_layout = upb_msgdef_layout(any_m);
7632 upb_arena *arena = jsonenc_arena(e);
7633 upb_msg *any = upb_msg_new(any_m, arena);
7634
7635 if (!upb_decode(value.data, value.size, any, any_layout, arena)) {
7636 jsonenc_err(e, "Error decoding message in Any");
7637 }
7638
7639 jsonenc_putstr(e, "{\"@type\":");
7640 jsonenc_string(e, type_url);
7641 jsonenc_putstr(e, ",");
7642
7643 if (upb_msgdef_wellknowntype(any_m) == UPB_WELLKNOWN_UNSPECIFIED) {
7644 /* Regular messages: {"@type": "...","foo": 1, "bar": 2} */
7645 jsonenc_msgfields(e, any, any_m);
7646 } else {
7647 /* Well-known type: {"@type": "...","value": <well-known encoding>} */
7648 jsonenc_putstr(e, "\"value\":");
7649 jsonenc_msgfield(e, any, any_m);
7650 }
7651
7652 jsonenc_putstr(e, "}");
7653 }
7654
jsonenc_putsep(jsonenc * e,const char * str,bool * first)7655 static void jsonenc_putsep(jsonenc *e, const char *str, bool *first) {
7656 if (*first) {
7657 *first = false;
7658 } else {
7659 jsonenc_putstr(e, str);
7660 }
7661 }
7662
jsonenc_fieldpath(jsonenc * e,upb_strview path)7663 static void jsonenc_fieldpath(jsonenc *e, upb_strview path) {
7664 const char *ptr = path.data;
7665 const char *end = ptr + path.size;
7666
7667 while (ptr < end) {
7668 char ch = *ptr;
7669
7670 if (ch >= 'A' && ch <= 'Z') {
7671 jsonenc_err(e, "Field mask element may not have upper-case letter.");
7672 } else if (ch == '_') {
7673 if (ptr == end - 1 || *(ptr + 1) < 'a' || *(ptr + 1) > 'z') {
7674 jsonenc_err(e, "Underscore must be followed by a lowercase letter.");
7675 }
7676 ch = *++ptr - 32;
7677 }
7678
7679 jsonenc_putbytes(e, &ch, 1);
7680 ptr++;
7681 }
7682 }
7683
jsonenc_fieldmask(jsonenc * e,const upb_msg * msg,const upb_msgdef * m)7684 static void jsonenc_fieldmask(jsonenc *e, const upb_msg *msg,
7685 const upb_msgdef *m) {
7686 const upb_fielddef *paths_f = upb_msgdef_itof(m, 1);
7687 const upb_array *paths = upb_msg_get(msg, paths_f).array_val;
7688 bool first = true;
7689 size_t i, n = 0;
7690
7691 if (paths) n = upb_array_size(paths);
7692
7693 jsonenc_putstr(e, "\"");
7694
7695 for (i = 0; i < n; i++) {
7696 jsonenc_putsep(e, ",", &first);
7697 jsonenc_fieldpath(e, upb_array_get(paths, i).str_val);
7698 }
7699
7700 jsonenc_putstr(e, "\"");
7701 }
7702
jsonenc_struct(jsonenc * e,const upb_msg * msg,const upb_msgdef * m)7703 static void jsonenc_struct(jsonenc *e, const upb_msg *msg,
7704 const upb_msgdef *m) {
7705 const upb_fielddef *fields_f = upb_msgdef_itof(m, 1);
7706 const upb_map *fields = upb_msg_get(msg, fields_f).map_val;
7707 const upb_msgdef *entry_m = upb_fielddef_msgsubdef(fields_f);
7708 const upb_fielddef *value_f = upb_msgdef_itof(entry_m, 2);
7709 size_t iter = UPB_MAP_BEGIN;
7710 bool first = true;
7711
7712 jsonenc_putstr(e, "{");
7713
7714 if (fields) {
7715 while (upb_mapiter_next(fields, &iter)) {
7716 upb_msgval key = upb_mapiter_key(fields, iter);
7717 upb_msgval val = upb_mapiter_value(fields, iter);
7718
7719 jsonenc_putsep(e, ",", &first);
7720 jsonenc_string(e, key.str_val);
7721 jsonenc_putstr(e, ":");
7722 jsonenc_value(e, val.msg_val, upb_fielddef_msgsubdef(value_f));
7723 }
7724 }
7725
7726 jsonenc_putstr(e, "}");
7727 }
7728
jsonenc_listvalue(jsonenc * e,const upb_msg * msg,const upb_msgdef * m)7729 static void jsonenc_listvalue(jsonenc *e, const upb_msg *msg,
7730 const upb_msgdef *m) {
7731 const upb_fielddef *values_f = upb_msgdef_itof(m, 1);
7732 const upb_msgdef *values_m = upb_fielddef_msgsubdef(values_f);
7733 const upb_array *values = upb_msg_get(msg, values_f).array_val;
7734 size_t i;
7735 bool first = true;
7736
7737 jsonenc_putstr(e, "[");
7738
7739 if (values) {
7740 const size_t size = upb_array_size(values);
7741 for (i = 0; i < size; i++) {
7742 upb_msgval elem = upb_array_get(values, i);
7743
7744 jsonenc_putsep(e, ",", &first);
7745 jsonenc_value(e, elem.msg_val, values_m);
7746 }
7747 }
7748
7749 jsonenc_putstr(e, "]");
7750 }
7751
jsonenc_value(jsonenc * e,const upb_msg * msg,const upb_msgdef * m)7752 static void jsonenc_value(jsonenc *e, const upb_msg *msg, const upb_msgdef *m) {
7753 /* TODO(haberman): do we want a reflection method to get oneof case? */
7754 size_t iter = UPB_MSG_BEGIN;
7755 const upb_fielddef *f;
7756 upb_msgval val;
7757
7758 if (!upb_msg_next(msg, m, NULL, &f, &val, &iter)) {
7759 jsonenc_err(e, "No value set in Value proto");
7760 }
7761
7762 switch (upb_fielddef_number(f)) {
7763 case 1:
7764 jsonenc_putstr(e, "null");
7765 break;
7766 case 2:
7767 jsonenc_double(e, "%.17g", val.double_val);
7768 break;
7769 case 3:
7770 jsonenc_string(e, val.str_val);
7771 break;
7772 case 4:
7773 jsonenc_putstr(e, val.bool_val ? "true" : "false");
7774 break;
7775 case 5:
7776 jsonenc_struct(e, val.msg_val, upb_fielddef_msgsubdef(f));
7777 break;
7778 case 6:
7779 jsonenc_listvalue(e, val.msg_val, upb_fielddef_msgsubdef(f));
7780 break;
7781 }
7782 }
7783
jsonenc_msgfield(jsonenc * e,const upb_msg * msg,const upb_msgdef * m)7784 static void jsonenc_msgfield(jsonenc *e, const upb_msg *msg,
7785 const upb_msgdef *m) {
7786 switch (upb_msgdef_wellknowntype(m)) {
7787 case UPB_WELLKNOWN_UNSPECIFIED:
7788 jsonenc_msg(e, msg, m);
7789 break;
7790 case UPB_WELLKNOWN_ANY:
7791 jsonenc_any(e, msg, m);
7792 break;
7793 case UPB_WELLKNOWN_FIELDMASK:
7794 jsonenc_fieldmask(e, msg, m);
7795 break;
7796 case UPB_WELLKNOWN_DURATION:
7797 jsonenc_duration(e, msg, m);
7798 break;
7799 case UPB_WELLKNOWN_TIMESTAMP:
7800 jsonenc_timestamp(e, msg, m);
7801 break;
7802 case UPB_WELLKNOWN_DOUBLEVALUE:
7803 case UPB_WELLKNOWN_FLOATVALUE:
7804 case UPB_WELLKNOWN_INT64VALUE:
7805 case UPB_WELLKNOWN_UINT64VALUE:
7806 case UPB_WELLKNOWN_INT32VALUE:
7807 case UPB_WELLKNOWN_UINT32VALUE:
7808 case UPB_WELLKNOWN_STRINGVALUE:
7809 case UPB_WELLKNOWN_BYTESVALUE:
7810 case UPB_WELLKNOWN_BOOLVALUE:
7811 jsonenc_wrapper(e, msg, m);
7812 break;
7813 case UPB_WELLKNOWN_VALUE:
7814 jsonenc_value(e, msg, m);
7815 break;
7816 case UPB_WELLKNOWN_LISTVALUE:
7817 jsonenc_listvalue(e, msg, m);
7818 break;
7819 case UPB_WELLKNOWN_STRUCT:
7820 jsonenc_struct(e, msg, m);
7821 break;
7822 }
7823 }
7824
jsonenc_scalar(jsonenc * e,upb_msgval val,const upb_fielddef * f)7825 static void jsonenc_scalar(jsonenc *e, upb_msgval val, const upb_fielddef *f) {
7826 switch (upb_fielddef_type(f)) {
7827 case UPB_TYPE_BOOL:
7828 jsonenc_putstr(e, val.bool_val ? "true" : "false");
7829 break;
7830 case UPB_TYPE_FLOAT:
7831 jsonenc_double(e, "%.9g", val.float_val);
7832 break;
7833 case UPB_TYPE_DOUBLE:
7834 jsonenc_double(e, "%.17g", val.double_val);
7835 break;
7836 case UPB_TYPE_INT32:
7837 jsonenc_printf(e, "%" PRId32, val.int32_val);
7838 break;
7839 case UPB_TYPE_UINT32:
7840 jsonenc_printf(e, "%" PRIu32, val.uint32_val);
7841 break;
7842 case UPB_TYPE_INT64:
7843 jsonenc_printf(e, "\"%" PRId64 "\"", val.int64_val);
7844 break;
7845 case UPB_TYPE_UINT64:
7846 jsonenc_printf(e, "\"%" PRIu64 "\"", val.uint64_val);
7847 break;
7848 case UPB_TYPE_STRING:
7849 jsonenc_string(e, val.str_val);
7850 break;
7851 case UPB_TYPE_BYTES:
7852 jsonenc_bytes(e, val.str_val);
7853 break;
7854 case UPB_TYPE_ENUM:
7855 jsonenc_enum(val.int32_val, f, e);
7856 break;
7857 case UPB_TYPE_MESSAGE:
7858 jsonenc_msgfield(e, val.msg_val, upb_fielddef_msgsubdef(f));
7859 break;
7860 }
7861 }
7862
jsonenc_mapkey(jsonenc * e,upb_msgval val,const upb_fielddef * f)7863 static void jsonenc_mapkey(jsonenc *e, upb_msgval val, const upb_fielddef *f) {
7864 jsonenc_putstr(e, "\"");
7865
7866 switch (upb_fielddef_type(f)) {
7867 case UPB_TYPE_BOOL:
7868 jsonenc_putstr(e, val.bool_val ? "true" : "false");
7869 break;
7870 case UPB_TYPE_INT32:
7871 jsonenc_printf(e, "%" PRId32, val.int32_val);
7872 break;
7873 case UPB_TYPE_UINT32:
7874 jsonenc_printf(e, "%" PRIu32, val.uint32_val);
7875 break;
7876 case UPB_TYPE_INT64:
7877 jsonenc_printf(e, "%" PRId64, val.int64_val);
7878 break;
7879 case UPB_TYPE_UINT64:
7880 jsonenc_printf(e, "%" PRIu64, val.uint64_val);
7881 break;
7882 case UPB_TYPE_STRING:
7883 jsonenc_stringbody(e, val.str_val);
7884 break;
7885 default:
7886 UPB_UNREACHABLE();
7887 }
7888
7889 jsonenc_putstr(e, "\":");
7890 }
7891
jsonenc_array(jsonenc * e,const upb_array * arr,const upb_fielddef * f)7892 static void jsonenc_array(jsonenc *e, const upb_array *arr,
7893 const upb_fielddef *f) {
7894 size_t i;
7895 size_t size = upb_array_size(arr);
7896 bool first = true;
7897
7898 jsonenc_putstr(e, "[");
7899
7900 for (i = 0; i < size; i++) {
7901 jsonenc_putsep(e, ",", &first);
7902 jsonenc_scalar(e, upb_array_get(arr, i), f);
7903 }
7904
7905 jsonenc_putstr(e, "]");
7906 }
7907
jsonenc_map(jsonenc * e,const upb_map * map,const upb_fielddef * f)7908 static void jsonenc_map(jsonenc *e, const upb_map *map, const upb_fielddef *f) {
7909 const upb_msgdef *entry = upb_fielddef_msgsubdef(f);
7910 const upb_fielddef *key_f = upb_msgdef_itof(entry, 1);
7911 const upb_fielddef *val_f = upb_msgdef_itof(entry, 2);
7912 size_t iter = UPB_MAP_BEGIN;
7913 bool first = true;
7914
7915 jsonenc_putstr(e, "{");
7916
7917 while (upb_mapiter_next(map, &iter)) {
7918 jsonenc_putsep(e, ",", &first);
7919 jsonenc_mapkey(e, upb_mapiter_key(map, iter), key_f);
7920 jsonenc_scalar(e, upb_mapiter_value(map, iter), val_f);
7921 }
7922
7923 jsonenc_putstr(e, "}");
7924 }
7925
jsonenc_fieldval(jsonenc * e,const upb_fielddef * f,upb_msgval val,bool * first)7926 static void jsonenc_fieldval(jsonenc *e, const upb_fielddef *f,
7927 upb_msgval val, bool *first) {
7928 const char *name;
7929
7930 if (e->options & UPB_JSONENC_PROTONAMES) {
7931 name = upb_fielddef_name(f);
7932 } else {
7933 name = upb_fielddef_jsonname(f);
7934 }
7935
7936 jsonenc_putsep(e, ",", first);
7937 jsonenc_printf(e, "\"%s\":", name);
7938
7939 if (upb_fielddef_ismap(f)) {
7940 jsonenc_map(e, val.map_val, f);
7941 } else if (upb_fielddef_isseq(f)) {
7942 jsonenc_array(e, val.array_val, f);
7943 } else {
7944 jsonenc_scalar(e, val, f);
7945 }
7946 }
7947
jsonenc_msgfields(jsonenc * e,const upb_msg * msg,const upb_msgdef * m)7948 static void jsonenc_msgfields(jsonenc *e, const upb_msg *msg,
7949 const upb_msgdef *m) {
7950 upb_msgval val;
7951 const upb_fielddef *f;
7952 bool first = true;
7953
7954 if (e->options & UPB_JSONENC_EMITDEFAULTS) {
7955 /* Iterate over all fields. */
7956 int i = 0;
7957 int n = upb_msgdef_fieldcount(m);
7958 for (i = 0; i < n; i++) {
7959 f = upb_msgdef_field(m, i);
7960 jsonenc_fieldval(e, f, upb_msg_get(msg, f), &first);
7961 }
7962 } else {
7963 /* Iterate over non-empty fields. */
7964 size_t iter = UPB_MSG_BEGIN;
7965 while (upb_msg_next(msg, m, e->ext_pool, &f, &val, &iter)) {
7966 jsonenc_fieldval(e, f, val, &first);
7967 }
7968 }
7969 }
7970
jsonenc_msg(jsonenc * e,const upb_msg * msg,const upb_msgdef * m)7971 static void jsonenc_msg(jsonenc *e, const upb_msg *msg, const upb_msgdef *m) {
7972 jsonenc_putstr(e, "{");
7973 jsonenc_msgfields(e, msg, m);
7974 jsonenc_putstr(e, "}");
7975 }
7976
jsonenc_nullz(jsonenc * e,size_t size)7977 static size_t jsonenc_nullz(jsonenc *e, size_t size) {
7978 size_t ret = e->ptr - e->buf + e->overflow;
7979
7980 if (size > 0) {
7981 if (e->ptr == e->end) e->ptr--;
7982 *e->ptr = '\0';
7983 }
7984
7985 return ret;
7986 }
7987
upb_json_encode(const upb_msg * msg,const upb_msgdef * m,const upb_symtab * ext_pool,int options,char * buf,size_t size,upb_status * status)7988 size_t upb_json_encode(const upb_msg *msg, const upb_msgdef *m,
7989 const upb_symtab *ext_pool, int options, char *buf,
7990 size_t size, upb_status *status) {
7991 jsonenc e;
7992
7993 e.buf = buf;
7994 e.ptr = buf;
7995 e.end = buf + size;
7996 e.overflow = 0;
7997 e.options = options;
7998 e.ext_pool = ext_pool;
7999 e.status = status;
8000 e.arena = NULL;
8001
8002 if (setjmp(e.err)) return -1;
8003
8004 jsonenc_msgfield(&e, msg, m);
8005 if (e.arena) upb_arena_free(e.arena);
8006 return jsonenc_nullz(&e, size);
8007 }
8008 /* See port_def.inc. This should #undef all macros #defined there. */
8009
8010 #undef UPB_MAPTYPE_STRING
8011 #undef UPB_SIZE
8012 #undef UPB_PTR_AT
8013 #undef UPB_READ_ONEOF
8014 #undef UPB_WRITE_ONEOF
8015 #undef UPB_INLINE
8016 #undef UPB_ALIGN_UP
8017 #undef UPB_ALIGN_DOWN
8018 #undef UPB_ALIGN_MALLOC
8019 #undef UPB_ALIGN_OF
8020 #undef UPB_FORCEINLINE
8021 #undef UPB_NOINLINE
8022 #undef UPB_NORETURN
8023 #undef UPB_MAX
8024 #undef UPB_MIN
8025 #undef UPB_UNUSED
8026 #undef UPB_ASSUME
8027 #undef UPB_ASSERT
8028 #undef UPB_UNREACHABLE
8029 #undef UPB_POISON_MEMORY_REGION
8030 #undef UPB_UNPOISON_MEMORY_REGION
8031 #undef UPB_ASAN
8032