• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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