• 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 #include <stdint.h>
26 #include <stddef.h>
27 
28 #if UINTPTR_MAX == 0xffffffff
29 #define UPB_SIZE(size32, size64) size32
30 #else
31 #define UPB_SIZE(size32, size64) size64
32 #endif
33 
34 /* If we always read/write as a consistent type to each address, this shouldn't
35  * violate aliasing.
36  */
37 #define UPB_PTR_AT(msg, ofs, type) ((type*)((char*)(msg) + (ofs)))
38 
39 #define UPB_READ_ONEOF(msg, fieldtype, offset, case_offset, case_val, default) \
40   *UPB_PTR_AT(msg, case_offset, int) == case_val                              \
41       ? *UPB_PTR_AT(msg, offset, fieldtype)                                   \
42       : default
43 
44 #define UPB_WRITE_ONEOF(msg, fieldtype, offset, value, case_offset, case_val) \
45   *UPB_PTR_AT(msg, case_offset, int) = case_val;                             \
46   *UPB_PTR_AT(msg, offset, fieldtype) = value;
47 
48 #define UPB_MAPTYPE_STRING 0
49 
50 /* UPB_INLINE: inline if possible, emit standalone code if required. */
51 #ifdef __cplusplus
52 #define UPB_INLINE inline
53 #elif defined (__GNUC__) || defined(__clang__)
54 #define UPB_INLINE static __inline__
55 #else
56 #define UPB_INLINE static
57 #endif
58 
59 #define UPB_ALIGN_UP(size, align) (((size) + (align) - 1) / (align) * (align))
60 #define UPB_ALIGN_DOWN(size, align) ((size) / (align) * (align))
61 #define UPB_ALIGN_MALLOC(size) UPB_ALIGN_UP(size, 16)
62 #define UPB_ALIGN_OF(type) offsetof (struct { char c; type member; }, member)
63 
64 /* Hints to the compiler about likely/unlikely branches. */
65 #if defined (__GNUC__) || defined(__clang__)
66 #define UPB_LIKELY(x) __builtin_expect((x),1)
67 #define UPB_UNLIKELY(x) __builtin_expect((x),0)
68 #else
69 #define UPB_LIKELY(x) (x)
70 #define UPB_UNLIKELY(x) (x)
71 #endif
72 
73 /* Define UPB_BIG_ENDIAN manually if you're on big endian and your compiler
74  * doesn't provide these preprocessor symbols. */
75 #if defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)
76 #define UPB_BIG_ENDIAN
77 #endif
78 
79 /* Macros for function attributes on compilers that support them. */
80 #ifdef __GNUC__
81 #define UPB_FORCEINLINE __inline__ __attribute__((always_inline))
82 #define UPB_NOINLINE __attribute__((noinline))
83 #define UPB_NORETURN __attribute__((__noreturn__))
84 #else  /* !defined(__GNUC__) */
85 #define UPB_FORCEINLINE
86 #define UPB_NOINLINE
87 #define UPB_NORETURN
88 #endif
89 
90 #if __STDC_VERSION__ >= 199901L || __cplusplus >= 201103L
91 /* C99/C++11 versions. */
92 #include <stdio.h>
93 #define _upb_snprintf snprintf
94 #define _upb_vsnprintf vsnprintf
95 #define _upb_va_copy(a, b) va_copy(a, b)
96 #elif defined(_MSC_VER)
97 /* Microsoft C/C++ versions. */
98 #include <stdarg.h>
99 #include <stdio.h>
100 #if _MSC_VER < 1900
101 int msvc_snprintf(char* s, size_t n, const char* format, ...);
102 int msvc_vsnprintf(char* s, size_t n, const char* format, va_list arg);
103 #define UPB_MSVC_VSNPRINTF
104 #define _upb_snprintf msvc_snprintf
105 #define _upb_vsnprintf msvc_vsnprintf
106 #else
107 #define _upb_snprintf snprintf
108 #define _upb_vsnprintf vsnprintf
109 #endif
110 #define _upb_va_copy(a, b) va_copy(a, b)
111 #elif defined __GNUC__
112 /* A few hacky workarounds for functions not in C89.
113  * For internal use only!
114  * TODO(haberman): fix these by including our own implementations, or finding
115  * another workaround.
116  */
117 #define _upb_snprintf __builtin_snprintf
118 #define _upb_vsnprintf __builtin_vsnprintf
119 #define _upb_va_copy(a, b) __va_copy(a, b)
120 #else
121 #error Need implementations of [v]snprintf and va_copy
122 #endif
123 
124 #ifdef __cplusplus
125 #if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__) || \
126     (defined(_MSC_VER) && _MSC_VER >= 1900)
127 /* C++11 is present */
128 #else
129 #error upb requires C++11 for C++ support
130 #endif
131 #endif
132 
133 #define UPB_MAX(x, y) ((x) > (y) ? (x) : (y))
134 #define UPB_MIN(x, y) ((x) < (y) ? (x) : (y))
135 
136 #define UPB_UNUSED(var) (void)var
137 
138 /* UPB_ASSUME(): in release mode, we tell the compiler to assume this is true.
139  */
140 #ifdef NDEBUG
141 #ifdef __GNUC__
142 #define UPB_ASSUME(expr) if (!(expr)) __builtin_unreachable()
143 #elif defined _MSC_VER
144 #define UPB_ASSUME(expr) if (!(expr)) __assume(0)
145 #else
146 #define UPB_ASSUME(expr) do {} if (false && (expr))
147 #endif
148 #else
149 #define UPB_ASSUME(expr) assert(expr)
150 #endif
151 
152 /* UPB_ASSERT(): in release mode, we use the expression without letting it be
153  * evaluated.  This prevents "unused variable" warnings. */
154 #ifdef NDEBUG
155 #define UPB_ASSERT(expr) do {} while (false && (expr))
156 #else
157 #define UPB_ASSERT(expr) assert(expr)
158 #endif
159 
160 /* UPB_ASSERT_DEBUGVAR(): assert that uses functions or variables that only
161  * exist in debug mode.  This turns into regular assert. */
162 #define UPB_ASSERT_DEBUGVAR(expr) assert(expr)
163 
164 #if defined(__GNUC__) || defined(__clang__)
165 #define UPB_UNREACHABLE() do { assert(0); __builtin_unreachable(); } while(0)
166 #else
167 #define UPB_UNREACHABLE() do { assert(0); } while(0)
168 #endif
169 
170 /* UPB_INFINITY representing floating-point positive infinity. */
171 #include <math.h>
172 #ifdef INFINITY
173 #define UPB_INFINITY INFINITY
174 #else
175 #define UPB_INFINITY (1.0 / 0.0)
176 #endif
177 #ifdef NAN
178 #define UPB_NAN NAN
179 #else
180 #define UPB_NAN (0.0 / 0.0)
181 #endif
182 
183 #include <setjmp.h>
184 #include <string.h>
185 
186 
187 
188 /* Maps descriptor type -> upb field type.  */
189 static const uint8_t desctype_to_fieldtype[] = {
190     -1,               /* invalid descriptor type */
191     UPB_TYPE_DOUBLE,  /* DOUBLE */
192     UPB_TYPE_FLOAT,   /* FLOAT */
193     UPB_TYPE_INT64,   /* INT64 */
194     UPB_TYPE_UINT64,  /* UINT64 */
195     UPB_TYPE_INT32,   /* INT32 */
196     UPB_TYPE_UINT64,  /* FIXED64 */
197     UPB_TYPE_UINT32,  /* FIXED32 */
198     UPB_TYPE_BOOL,    /* BOOL */
199     UPB_TYPE_STRING,  /* STRING */
200     UPB_TYPE_MESSAGE, /* GROUP */
201     UPB_TYPE_MESSAGE, /* MESSAGE */
202     UPB_TYPE_BYTES,   /* BYTES */
203     UPB_TYPE_UINT32,  /* UINT32 */
204     UPB_TYPE_ENUM,    /* ENUM */
205     UPB_TYPE_INT32,   /* SFIXED32 */
206     UPB_TYPE_INT64,   /* SFIXED64 */
207     UPB_TYPE_INT32,   /* SINT32 */
208     UPB_TYPE_INT64,   /* SINT64 */
209 };
210 
211 /* Maps descriptor type -> upb map size.  */
212 static const uint8_t desctype_to_mapsize[] = {
213     -1,                 /* invalid descriptor type */
214     8,                  /* DOUBLE */
215     4,                  /* FLOAT */
216     8,                  /* INT64 */
217     8,                  /* UINT64 */
218     4,                  /* INT32 */
219     8,                  /* FIXED64 */
220     4,                  /* FIXED32 */
221     1,                  /* BOOL */
222     UPB_MAPTYPE_STRING, /* STRING */
223     sizeof(void *),     /* GROUP */
224     sizeof(void *),     /* MESSAGE */
225     UPB_MAPTYPE_STRING, /* BYTES */
226     4,                  /* UINT32 */
227     4,                  /* ENUM */
228     4,                  /* SFIXED32 */
229     8,                  /* SFIXED64 */
230     4,                  /* SINT32 */
231     8,                  /* SINT64 */
232 };
233 
234 static const unsigned fixed32_ok = (1 << UPB_DTYPE_FLOAT) |
235                                    (1 << UPB_DTYPE_FIXED32) |
236                                    (1 << UPB_DTYPE_SFIXED32);
237 
238 static const unsigned fixed64_ok = (1 << UPB_DTYPE_DOUBLE) |
239                                    (1 << UPB_DTYPE_FIXED64) |
240                                    (1 << UPB_DTYPE_SFIXED64);
241 
242 /* Op: an action to be performed for a wire-type/field-type combination. */
243 #define OP_SCALAR_LG2(n) (n)      /* n in [0, 2, 3] => op in [0, 2, 3] */
244 #define OP_STRING 4
245 #define OP_BYTES 5
246 #define OP_SUBMSG 6
247 /* Ops above are scalar-only. Repeated fields can use any op.  */
248 #define OP_FIXPCK_LG2(n) (n + 5)  /* n in [2, 3] => op in [7, 8] */
249 #define OP_VARPCK_LG2(n) (n + 9)  /* n in [0, 2, 3] => op in [9, 11, 12] */
250 
251 static const int8_t varint_ops[19] = {
252     -1,               /* field not found */
253     -1,               /* DOUBLE */
254     -1,               /* FLOAT */
255     OP_SCALAR_LG2(3), /* INT64 */
256     OP_SCALAR_LG2(3), /* UINT64 */
257     OP_SCALAR_LG2(2), /* INT32 */
258     -1,               /* FIXED64 */
259     -1,               /* FIXED32 */
260     OP_SCALAR_LG2(0), /* BOOL */
261     -1,               /* STRING */
262     -1,               /* GROUP */
263     -1,               /* MESSAGE */
264     -1,               /* BYTES */
265     OP_SCALAR_LG2(2), /* UINT32 */
266     OP_SCALAR_LG2(2), /* ENUM */
267     -1,               /* SFIXED32 */
268     -1,               /* SFIXED64 */
269     OP_SCALAR_LG2(2), /* SINT32 */
270     OP_SCALAR_LG2(3), /* SINT64 */
271 };
272 
273 static const int8_t delim_ops[37] = {
274     /* For non-repeated field type. */
275     -1,        /* field not found */
276     -1,        /* DOUBLE */
277     -1,        /* FLOAT */
278     -1,        /* INT64 */
279     -1,        /* UINT64 */
280     -1,        /* INT32 */
281     -1,        /* FIXED64 */
282     -1,        /* FIXED32 */
283     -1,        /* BOOL */
284     OP_STRING, /* STRING */
285     -1,        /* GROUP */
286     OP_SUBMSG, /* MESSAGE */
287     OP_BYTES,  /* BYTES */
288     -1,        /* UINT32 */
289     -1,        /* ENUM */
290     -1,        /* SFIXED32 */
291     -1,        /* SFIXED64 */
292     -1,        /* SINT32 */
293     -1,        /* SINT64 */
294     /* For repeated field type. */
295     OP_FIXPCK_LG2(3), /* REPEATED DOUBLE */
296     OP_FIXPCK_LG2(2), /* REPEATED FLOAT */
297     OP_VARPCK_LG2(3), /* REPEATED INT64 */
298     OP_VARPCK_LG2(3), /* REPEATED UINT64 */
299     OP_VARPCK_LG2(2), /* REPEATED INT32 */
300     OP_FIXPCK_LG2(3), /* REPEATED FIXED64 */
301     OP_FIXPCK_LG2(2), /* REPEATED FIXED32 */
302     OP_VARPCK_LG2(0), /* REPEATED BOOL */
303     OP_STRING,        /* REPEATED STRING */
304     OP_SUBMSG,        /* REPEATED GROUP */
305     OP_SUBMSG,        /* REPEATED MESSAGE */
306     OP_BYTES,         /* REPEATED BYTES */
307     OP_VARPCK_LG2(2), /* REPEATED UINT32 */
308     OP_VARPCK_LG2(2), /* REPEATED ENUM */
309     OP_FIXPCK_LG2(2), /* REPEATED SFIXED32 */
310     OP_FIXPCK_LG2(3), /* REPEATED SFIXED64 */
311     OP_VARPCK_LG2(2), /* REPEATED SINT32 */
312     OP_VARPCK_LG2(3), /* REPEATED SINT64 */
313 };
314 
315 /* Data pertaining to the parse. */
316 typedef struct {
317   const char *limit;       /* End of delimited region or end of buffer. */
318   upb_arena *arena;
319   int depth;
320   uint32_t end_group; /* Set to field number of END_GROUP tag, if any. */
321   jmp_buf err;
322 } upb_decstate;
323 
324 typedef union {
325   bool bool_val;
326   int32_t int32_val;
327   int64_t int64_val;
328   uint32_t uint32_val;
329   uint64_t uint64_val;
330   upb_strview str_val;
331 } wireval;
332 
333 static const char *decode_msg(upb_decstate *d, const char *ptr, upb_msg *msg,
334                               const upb_msglayout *layout);
335 
decode_err(upb_decstate * d)336 UPB_NORETURN static void decode_err(upb_decstate *d) { longjmp(d->err, 1); }
337 
decode_verifyutf8(upb_decstate * d,const char * buf,int len)338 void decode_verifyutf8(upb_decstate *d, const char *buf, int len) {
339   static const uint8_t utf8_offset[] = {
340       1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
341       1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
342       1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
343       1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
344       1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
345       1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
346       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
347       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
348       2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
349       2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
350       4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0,
351   };
352 
353   int i, j;
354   uint8_t offset;
355 
356   i = 0;
357   while (i < len) {
358     offset = utf8_offset[(uint8_t)buf[i]];
359     if (offset == 0 || i + offset > len) {
360       decode_err(d);
361     }
362     for (j = i + 1; j < i + offset; j++) {
363       if ((buf[j] & 0xc0) != 0x80) {
364         decode_err(d);
365       }
366     }
367     i += offset;
368   }
369   if (i != len) decode_err(d);
370 }
371 
decode_reserve(upb_decstate * d,upb_array * arr,size_t elem)372 static bool decode_reserve(upb_decstate *d, upb_array *arr, size_t elem) {
373   bool need_realloc = arr->size - arr->len < elem;
374   if (need_realloc && !_upb_array_realloc(arr, arr->len + elem, d->arena)) {
375     decode_err(d);
376   }
377   return need_realloc;
378 }
379 
380 UPB_NOINLINE
decode_longvarint64(upb_decstate * d,const char * ptr,const char * limit,uint64_t * val)381 static const char *decode_longvarint64(upb_decstate *d, const char *ptr,
382                                        const char *limit, uint64_t *val) {
383   uint8_t byte;
384   int bitpos = 0;
385   uint64_t out = 0;
386 
387   do {
388     if (bitpos >= 70 || ptr == limit) decode_err(d);
389     byte = *ptr;
390     out |= (uint64_t)(byte & 0x7F) << bitpos;
391     ptr++;
392     bitpos += 7;
393   } while (byte & 0x80);
394 
395   *val = out;
396   return ptr;
397 }
398 
399 UPB_FORCEINLINE
decode_varint64(upb_decstate * d,const char * ptr,const char * limit,uint64_t * val)400 static const char *decode_varint64(upb_decstate *d, const char *ptr,
401                                    const char *limit, uint64_t *val) {
402   if (UPB_LIKELY(ptr < limit && (*ptr & 0x80) == 0)) {
403     *val = (uint8_t)*ptr;
404     return ptr + 1;
405   } else {
406     return decode_longvarint64(d, ptr, limit, val);
407   }
408 }
409 
decode_varint32(upb_decstate * d,const char * ptr,const char * limit,uint32_t * val)410 static const char *decode_varint32(upb_decstate *d, const char *ptr,
411                                    const char *limit, uint32_t *val) {
412   uint64_t u64;
413   ptr = decode_varint64(d, ptr, limit, &u64);
414   if (u64 > UINT32_MAX) decode_err(d);
415   *val = (uint32_t)u64;
416   return ptr;
417 }
418 
decode_munge(int type,wireval * val)419 static void decode_munge(int type, wireval *val) {
420   switch (type) {
421     case UPB_DESCRIPTOR_TYPE_BOOL:
422       val->bool_val = val->uint64_val != 0;
423       break;
424     case UPB_DESCRIPTOR_TYPE_SINT32: {
425       uint32_t n = val->uint32_val;
426       val->int32_val = (n >> 1) ^ -(int32_t)(n & 1);
427       break;
428     }
429     case UPB_DESCRIPTOR_TYPE_SINT64: {
430       uint64_t n = val->uint64_val;
431       val->int64_val = (n >> 1) ^ -(int64_t)(n & 1);
432       break;
433     }
434   }
435 }
436 
upb_find_field(const upb_msglayout * l,uint32_t field_number)437 static const upb_msglayout_field *upb_find_field(const upb_msglayout *l,
438                                                  uint32_t field_number) {
439   static upb_msglayout_field none = {0, 0, 0, 0, 0, 0};
440 
441   /* Lots of optimization opportunities here. */
442   int i;
443   if (l == NULL) return &none;
444   for (i = 0; i < l->field_count; i++) {
445     if (l->fields[i].number == field_number) {
446       return &l->fields[i];
447     }
448   }
449 
450   return &none; /* Unknown field. */
451 }
452 
decode_newsubmsg(upb_decstate * d,const upb_msglayout * layout,const upb_msglayout_field * field)453 static upb_msg *decode_newsubmsg(upb_decstate *d, const upb_msglayout *layout,
454                                  const upb_msglayout_field *field) {
455   const upb_msglayout *subl = layout->submsgs[field->submsg_index];
456   return _upb_msg_new(subl, d->arena);
457 }
458 
decode_tosubmsg(upb_decstate * d,upb_msg * submsg,const upb_msglayout * layout,const upb_msglayout_field * field,upb_strview val)459 static void decode_tosubmsg(upb_decstate *d, upb_msg *submsg,
460                             const upb_msglayout *layout,
461                             const upb_msglayout_field *field, upb_strview val) {
462   const upb_msglayout *subl = layout->submsgs[field->submsg_index];
463   const char *saved_limit = d->limit;
464   if (--d->depth < 0) decode_err(d);
465   d->limit = val.data + val.size;
466   decode_msg(d, val.data, submsg, subl);
467   d->limit = saved_limit;
468   if (d->end_group != 0) decode_err(d);
469   d->depth++;
470 }
471 
decode_group(upb_decstate * d,const char * ptr,upb_msg * submsg,const upb_msglayout * subl,uint32_t number)472 static const char *decode_group(upb_decstate *d, const char *ptr,
473                                 upb_msg *submsg, const upb_msglayout *subl,
474                                 uint32_t number) {
475   if (--d->depth < 0) decode_err(d);
476   ptr = decode_msg(d, ptr, submsg, subl);
477   if (d->end_group != number) decode_err(d);
478   d->end_group = 0;
479   d->depth++;
480   return ptr;
481 }
482 
decode_togroup(upb_decstate * d,const char * ptr,upb_msg * submsg,const upb_msglayout * layout,const upb_msglayout_field * field)483 static const char *decode_togroup(upb_decstate *d, const char *ptr,
484                                   upb_msg *submsg, const upb_msglayout *layout,
485                                   const upb_msglayout_field *field) {
486   const upb_msglayout *subl = layout->submsgs[field->submsg_index];
487   return decode_group(d, ptr, submsg, subl, field->number);
488 }
489 
decode_toarray(upb_decstate * d,const char * ptr,upb_msg * msg,const upb_msglayout * layout,const upb_msglayout_field * field,wireval val,int op)490 static const char *decode_toarray(upb_decstate *d, const char *ptr,
491                                   upb_msg *msg, const upb_msglayout *layout,
492                                   const upb_msglayout_field *field, wireval val,
493                                   int op) {
494   upb_array **arrp = UPB_PTR_AT(msg, field->offset, void);
495   upb_array *arr = *arrp;
496   void *mem;
497 
498   if (!arr) {
499     upb_fieldtype_t type = desctype_to_fieldtype[field->descriptortype];
500     arr = _upb_array_new(d->arena, type);
501     if (!arr) decode_err(d);
502     *arrp = arr;
503   }
504 
505   decode_reserve(d, arr, 1);
506 
507   switch (op) {
508     case OP_SCALAR_LG2(0):
509     case OP_SCALAR_LG2(2):
510     case OP_SCALAR_LG2(3):
511       /* Append scalar value. */
512       mem = UPB_PTR_AT(_upb_array_ptr(arr), arr->len << op, void);
513       arr->len++;
514       memcpy(mem, &val, 1 << op);
515       return ptr;
516     case OP_STRING:
517       decode_verifyutf8(d, val.str_val.data, val.str_val.size);
518       /* Fallthrough. */
519     case OP_BYTES:
520       /* Append bytes. */
521       mem =
522           UPB_PTR_AT(_upb_array_ptr(arr), arr->len * sizeof(upb_strview), void);
523       arr->len++;
524       memcpy(mem, &val, sizeof(upb_strview));
525       return ptr;
526     case OP_SUBMSG: {
527       /* Append submessage / group. */
528       upb_msg *submsg = decode_newsubmsg(d, layout, field);
529       *UPB_PTR_AT(_upb_array_ptr(arr), arr->len * sizeof(void *), upb_msg *) =
530           submsg;
531       arr->len++;
532       if (UPB_UNLIKELY(field->descriptortype == UPB_DTYPE_GROUP)) {
533         ptr = decode_togroup(d, ptr, submsg, layout, field);
534       } else {
535         decode_tosubmsg(d, submsg, layout, field, val.str_val);
536       }
537       return ptr;
538     }
539     case OP_FIXPCK_LG2(2):
540     case OP_FIXPCK_LG2(3): {
541       /* Fixed packed. */
542       int lg2 = op - OP_FIXPCK_LG2(0);
543       int mask = (1 << lg2) - 1;
544       size_t count = val.str_val.size >> lg2;
545       if ((val.str_val.size & mask) != 0) {
546         decode_err(d); /* Length isn't a round multiple of elem size. */
547       }
548       decode_reserve(d, arr, count);
549       mem = UPB_PTR_AT(_upb_array_ptr(arr), arr->len << lg2, void);
550       arr->len += count;
551       memcpy(mem, val.str_val.data, val.str_val.size);
552       return ptr;
553     }
554     case OP_VARPCK_LG2(0):
555     case OP_VARPCK_LG2(2):
556     case OP_VARPCK_LG2(3): {
557       /* Varint packed. */
558       int lg2 = op - OP_VARPCK_LG2(0);
559       int scale = 1 << lg2;
560       const char *ptr = val.str_val.data;
561       const char *end = ptr + val.str_val.size;
562       char *out = UPB_PTR_AT(_upb_array_ptr(arr), arr->len << lg2, void);
563       while (ptr < end) {
564         wireval elem;
565         ptr = decode_varint64(d, ptr, end, &elem.uint64_val);
566         decode_munge(field->descriptortype, &elem);
567         if (decode_reserve(d, arr, 1)) {
568           out = UPB_PTR_AT(_upb_array_ptr(arr), arr->len << lg2, void);
569         }
570         arr->len++;
571         memcpy(out, &elem, scale);
572         out += scale;
573       }
574       if (ptr != end) decode_err(d);
575       return ptr;
576     }
577     default:
578       UPB_UNREACHABLE();
579   }
580 }
581 
decode_tomap(upb_decstate * d,upb_msg * msg,const upb_msglayout * layout,const upb_msglayout_field * field,wireval val)582 static void decode_tomap(upb_decstate *d, upb_msg *msg,
583                          const upb_msglayout *layout,
584                          const upb_msglayout_field *field, wireval val) {
585   upb_map **map_p = UPB_PTR_AT(msg, field->offset, upb_map *);
586   upb_map *map = *map_p;
587   upb_map_entry ent;
588   const upb_msglayout *entry = layout->submsgs[field->submsg_index];
589 
590   if (!map) {
591     /* Lazily create map. */
592     const upb_msglayout *entry = layout->submsgs[field->submsg_index];
593     const upb_msglayout_field *key_field = &entry->fields[0];
594     const upb_msglayout_field *val_field = &entry->fields[1];
595     char key_size = desctype_to_mapsize[key_field->descriptortype];
596     char val_size = desctype_to_mapsize[val_field->descriptortype];
597     UPB_ASSERT(key_field->offset == 0);
598     UPB_ASSERT(val_field->offset == sizeof(upb_strview));
599     map = _upb_map_new(d->arena, key_size, val_size);
600     *map_p = map;
601   }
602 
603   /* Parse map entry. */
604   memset(&ent, 0, sizeof(ent));
605 
606   if (entry->fields[1].descriptortype == UPB_DESCRIPTOR_TYPE_MESSAGE ||
607       entry->fields[1].descriptortype == UPB_DESCRIPTOR_TYPE_GROUP) {
608     /* Create proactively to handle the case where it doesn't appear. */
609     ent.v.val.val = (uint64_t)_upb_msg_new(entry->submsgs[0], d->arena);
610   }
611 
612   decode_tosubmsg(d, &ent.k, layout, field, val.str_val);
613 
614   /* Insert into map. */
615   _upb_map_set(map, &ent.k, map->key_size, &ent.v, map->val_size, d->arena);
616 }
617 
decode_tomsg(upb_decstate * d,const char * ptr,upb_msg * msg,const upb_msglayout * layout,const upb_msglayout_field * field,wireval val,int op)618 static const char *decode_tomsg(upb_decstate *d, const char *ptr, upb_msg *msg,
619                                 const upb_msglayout *layout,
620                                 const upb_msglayout_field *field, wireval val,
621                                 int op) {
622   void *mem = UPB_PTR_AT(msg, field->offset, void);
623   int type = field->descriptortype;
624 
625   /* Set presence if necessary. */
626   if (field->presence < 0) {
627     /* Oneof case */
628     uint32_t *oneof_case = _upb_oneofcase_field(msg, field);
629     if (op == OP_SUBMSG && *oneof_case != field->number) {
630       memset(mem, 0, sizeof(void*));
631     }
632     *oneof_case = field->number;
633   } else if (field->presence > 0) {
634     _upb_sethas_field(msg, field);
635   }
636 
637   /* Store into message. */
638   switch (op) {
639     case OP_SUBMSG: {
640       upb_msg **submsgp = mem;
641       upb_msg *submsg = *submsgp;
642       if (!submsg) {
643         submsg = decode_newsubmsg(d, layout, field);
644         *submsgp = submsg;
645       }
646       if (UPB_UNLIKELY(type == UPB_DTYPE_GROUP)) {
647         ptr = decode_togroup(d, ptr, submsg, layout, field);
648       } else {
649         decode_tosubmsg(d, submsg, layout, field, val.str_val);
650       }
651       break;
652     }
653     case OP_STRING:
654       decode_verifyutf8(d, val.str_val.data, val.str_val.size);
655       /* Fallthrough. */
656     case OP_BYTES:
657       memcpy(mem, &val, sizeof(upb_strview));
658       break;
659     case OP_SCALAR_LG2(3):
660       memcpy(mem, &val, 8);
661       break;
662     case OP_SCALAR_LG2(2):
663       memcpy(mem, &val, 4);
664       break;
665     case OP_SCALAR_LG2(0):
666       memcpy(mem, &val, 1);
667       break;
668     default:
669       UPB_UNREACHABLE();
670   }
671 
672   return ptr;
673 }
674 
decode_msg(upb_decstate * d,const char * ptr,upb_msg * msg,const upb_msglayout * layout)675 static const char *decode_msg(upb_decstate *d, const char *ptr, upb_msg *msg,
676                               const upb_msglayout *layout) {
677   while (ptr < d->limit) {
678     uint32_t tag;
679     const upb_msglayout_field *field;
680     int field_number;
681     int wire_type;
682     const char *field_start = ptr;
683     wireval val;
684     int op;
685 
686     ptr = decode_varint32(d, ptr, d->limit, &tag);
687     field_number = tag >> 3;
688     wire_type = tag & 7;
689 
690     field = upb_find_field(layout, field_number);
691 
692     switch (wire_type) {
693       case UPB_WIRE_TYPE_VARINT:
694         ptr = decode_varint64(d, ptr, d->limit, &val.uint64_val);
695         op = varint_ops[field->descriptortype];
696         decode_munge(field->descriptortype, &val);
697         break;
698       case UPB_WIRE_TYPE_32BIT:
699         if (d->limit - ptr < 4) decode_err(d);
700         memcpy(&val, ptr, 4);
701         ptr += 4;
702         op = OP_SCALAR_LG2(2);
703         if (((1 << field->descriptortype) & fixed32_ok) == 0) goto unknown;
704         break;
705       case UPB_WIRE_TYPE_64BIT:
706         if (d->limit - ptr < 8) decode_err(d);
707         memcpy(&val, ptr, 8);
708         ptr += 8;
709         op = OP_SCALAR_LG2(3);
710         if (((1 << field->descriptortype) & fixed64_ok) == 0) goto unknown;
711         break;
712       case UPB_WIRE_TYPE_DELIMITED: {
713         uint32_t size;
714         int ndx = field->descriptortype;
715         if (_upb_isrepeated(field)) ndx += 18;
716         ptr = decode_varint32(d, ptr, d->limit, &size);
717         if (size >= INT32_MAX || (size_t)(d->limit - ptr) < size) {
718           decode_err(d); /* Length overflow. */
719         }
720         val.str_val.data = ptr;
721         val.str_val.size = size;
722         ptr += size;
723         op = delim_ops[ndx];
724         break;
725       }
726       case UPB_WIRE_TYPE_START_GROUP:
727         val.int32_val = field_number;
728         op = OP_SUBMSG;
729         if (field->descriptortype != UPB_DTYPE_GROUP) goto unknown;
730         break;
731       case UPB_WIRE_TYPE_END_GROUP:
732         d->end_group = field_number;
733         return ptr;
734       default:
735         decode_err(d);
736     }
737 
738     if (op >= 0) {
739       /* Parse, using op for dispatch. */
740       switch (field->label) {
741         case UPB_LABEL_REPEATED:
742         case _UPB_LABEL_PACKED:
743           ptr = decode_toarray(d, ptr, msg, layout, field, val, op);
744           break;
745         case _UPB_LABEL_MAP:
746           decode_tomap(d, msg, layout, field, val);
747           break;
748         default:
749           ptr = decode_tomsg(d, ptr, msg, layout, field, val, op);
750           break;
751       }
752     } else {
753     unknown:
754       /* Skip unknown field. */
755       if (field_number == 0) decode_err(d);
756       if (wire_type == UPB_WIRE_TYPE_START_GROUP) {
757         ptr = decode_group(d, ptr, NULL, NULL, field_number);
758       }
759       if (msg) {
760         if (!_upb_msg_addunknown(msg, field_start, ptr - field_start,
761                                  d->arena)) {
762           decode_err(d);
763         }
764       }
765     }
766   }
767 
768   if (ptr != d->limit) decode_err(d);
769   return ptr;
770 }
771 
upb_decode(const char * buf,size_t size,void * msg,const upb_msglayout * l,upb_arena * arena)772 bool upb_decode(const char *buf, size_t size, void *msg, const upb_msglayout *l,
773                 upb_arena *arena) {
774   upb_decstate state;
775   state.limit = buf + size;
776   state.arena = arena;
777   state.depth = 64;
778   state.end_group = 0;
779 
780   if (setjmp(state.err)) return false;
781 
782   if (size == 0) return true;
783   decode_msg(&state, buf, msg, l);
784 
785   return state.end_group == 0;
786 }
787 
788 #undef OP_SCALAR_LG2
789 #undef OP_FIXPCK_LG2
790 #undef OP_VARPCK_LG2
791 #undef OP_STRING
792 #undef OP_SUBMSG
793 /* We encode backwards, to avoid pre-computing lengths (one-pass encode). */
794 
795 
796 #include <string.h>
797 
798 
799 
800 #define UPB_PB_VARINT_MAX_LEN 10
801 #define CHK(x) do { if (!(x)) { return false; } } while(0)
802 
upb_encode_varint(uint64_t val,char * buf)803 static size_t upb_encode_varint(uint64_t val, char *buf) {
804   size_t i;
805   if (val < 128) { buf[0] = val; return 1; }
806   i = 0;
807   while (val) {
808     uint8_t byte = val & 0x7fU;
809     val >>= 7;
810     if (val) byte |= 0x80U;
811     buf[i++] = byte;
812   }
813   return i;
814 }
815 
upb_zzencode_32(int32_t n)816 static uint32_t upb_zzencode_32(int32_t n) { return ((uint32_t)n << 1) ^ (n >> 31); }
upb_zzencode_64(int64_t n)817 static uint64_t upb_zzencode_64(int64_t n) { return ((uint64_t)n << 1) ^ (n >> 63); }
818 
819 typedef struct {
820   upb_alloc *alloc;
821   char *buf, *ptr, *limit;
822 } upb_encstate;
823 
upb_roundup_pow2(size_t bytes)824 static size_t upb_roundup_pow2(size_t bytes) {
825   size_t ret = 128;
826   while (ret < bytes) {
827     ret *= 2;
828   }
829   return ret;
830 }
831 
upb_encode_growbuffer(upb_encstate * e,size_t bytes)832 static bool upb_encode_growbuffer(upb_encstate *e, size_t bytes) {
833   size_t old_size = e->limit - e->buf;
834   size_t new_size = upb_roundup_pow2(bytes + (e->limit - e->ptr));
835   char *new_buf = upb_realloc(e->alloc, e->buf, old_size, new_size);
836   CHK(new_buf);
837 
838   /* We want previous data at the end, realloc() put it at the beginning. */
839   if (old_size > 0) {
840     memmove(new_buf + new_size - old_size, e->buf, old_size);
841   }
842 
843   e->ptr = new_buf + new_size - (e->limit - e->ptr);
844   e->limit = new_buf + new_size;
845   e->buf = new_buf;
846   return true;
847 }
848 
849 /* Call to ensure that at least "bytes" bytes are available for writing at
850  * e->ptr.  Returns false if the bytes could not be allocated. */
upb_encode_reserve(upb_encstate * e,size_t bytes)851 static bool upb_encode_reserve(upb_encstate *e, size_t bytes) {
852   CHK(UPB_LIKELY((size_t)(e->ptr - e->buf) >= bytes) ||
853       upb_encode_growbuffer(e, bytes));
854 
855   e->ptr -= bytes;
856   return true;
857 }
858 
859 /* Writes the given bytes to the buffer, handling reserve/advance. */
upb_put_bytes(upb_encstate * e,const void * data,size_t len)860 static bool upb_put_bytes(upb_encstate *e, const void *data, size_t len) {
861   if (len == 0) return true;
862   CHK(upb_encode_reserve(e, len));
863   memcpy(e->ptr, data, len);
864   return true;
865 }
866 
upb_put_fixed64(upb_encstate * e,uint64_t val)867 static bool upb_put_fixed64(upb_encstate *e, uint64_t val) {
868   /* TODO(haberman): byte-swap for big endian. */
869   return upb_put_bytes(e, &val, sizeof(uint64_t));
870 }
871 
upb_put_fixed32(upb_encstate * e,uint32_t val)872 static bool upb_put_fixed32(upb_encstate *e, uint32_t val) {
873   /* TODO(haberman): byte-swap for big endian. */
874   return upb_put_bytes(e, &val, sizeof(uint32_t));
875 }
876 
upb_put_varint(upb_encstate * e,uint64_t val)877 static bool upb_put_varint(upb_encstate *e, uint64_t val) {
878   size_t len;
879   char *start;
880   CHK(upb_encode_reserve(e, UPB_PB_VARINT_MAX_LEN));
881   len = upb_encode_varint(val, e->ptr);
882   start = e->ptr + UPB_PB_VARINT_MAX_LEN - len;
883   memmove(start, e->ptr, len);
884   e->ptr = start;
885   return true;
886 }
887 
upb_put_double(upb_encstate * e,double d)888 static bool upb_put_double(upb_encstate *e, double d) {
889   uint64_t u64;
890   UPB_ASSERT(sizeof(double) == sizeof(uint64_t));
891   memcpy(&u64, &d, sizeof(uint64_t));
892   return upb_put_fixed64(e, u64);
893 }
894 
upb_put_float(upb_encstate * e,float d)895 static bool upb_put_float(upb_encstate *e, float d) {
896   uint32_t u32;
897   UPB_ASSERT(sizeof(float) == sizeof(uint32_t));
898   memcpy(&u32, &d, sizeof(uint32_t));
899   return upb_put_fixed32(e, u32);
900 }
901 
upb_put_tag(upb_encstate * e,int field_number,int wire_type)902 static bool upb_put_tag(upb_encstate *e, int field_number, int wire_type) {
903   return upb_put_varint(e, (field_number << 3) | wire_type);
904 }
905 
upb_put_fixedarray(upb_encstate * e,const upb_array * arr,size_t elem_size,uint32_t tag)906 static bool upb_put_fixedarray(upb_encstate *e, const upb_array *arr,
907                                size_t elem_size, uint32_t tag) {
908   size_t bytes = arr->len * elem_size;
909   const char* data = _upb_array_constptr(arr);
910   const char* ptr = data + bytes - elem_size;
911   if (tag) {
912     while (true) {
913       CHK(upb_put_bytes(e, ptr, elem_size) && upb_put_varint(e, tag));
914       if (ptr == data) break;
915       ptr -= elem_size;
916     }
917     return true;
918   } else {
919     return upb_put_bytes(e, data, bytes) && upb_put_varint(e, bytes);
920   }
921 }
922 
923 bool upb_encode_message(upb_encstate *e, const char *msg,
924                         const upb_msglayout *m, size_t *size);
925 
upb_encode_scalarfield(upb_encstate * e,const void * _field_mem,const upb_msglayout * m,const upb_msglayout_field * f,bool skip_zero_value)926 static bool upb_encode_scalarfield(upb_encstate *e, const void *_field_mem,
927                                    const upb_msglayout *m,
928                                    const upb_msglayout_field *f,
929                                    bool skip_zero_value) {
930   const char *field_mem = _field_mem;
931 #define CASE(ctype, type, wire_type, encodeval) do { \
932   ctype val = *(ctype*)field_mem; \
933   if (skip_zero_value && val == 0) { \
934     return true; \
935   } \
936   return upb_put_ ## type(e, encodeval) && \
937       upb_put_tag(e, f->number, wire_type); \
938 } while(0)
939 
940   switch (f->descriptortype) {
941     case UPB_DESCRIPTOR_TYPE_DOUBLE:
942       CASE(double, double, UPB_WIRE_TYPE_64BIT, val);
943     case UPB_DESCRIPTOR_TYPE_FLOAT:
944       CASE(float, float, UPB_WIRE_TYPE_32BIT, val);
945     case UPB_DESCRIPTOR_TYPE_INT64:
946     case UPB_DESCRIPTOR_TYPE_UINT64:
947       CASE(uint64_t, varint, UPB_WIRE_TYPE_VARINT, val);
948     case UPB_DESCRIPTOR_TYPE_UINT32:
949       CASE(uint32_t, varint, UPB_WIRE_TYPE_VARINT, val);
950     case UPB_DESCRIPTOR_TYPE_INT32:
951     case UPB_DESCRIPTOR_TYPE_ENUM:
952       CASE(int32_t, varint, UPB_WIRE_TYPE_VARINT, (int64_t)val);
953     case UPB_DESCRIPTOR_TYPE_SFIXED64:
954     case UPB_DESCRIPTOR_TYPE_FIXED64:
955       CASE(uint64_t, fixed64, UPB_WIRE_TYPE_64BIT, val);
956     case UPB_DESCRIPTOR_TYPE_FIXED32:
957     case UPB_DESCRIPTOR_TYPE_SFIXED32:
958       CASE(uint32_t, fixed32, UPB_WIRE_TYPE_32BIT, val);
959     case UPB_DESCRIPTOR_TYPE_BOOL:
960       CASE(bool, varint, UPB_WIRE_TYPE_VARINT, val);
961     case UPB_DESCRIPTOR_TYPE_SINT32:
962       CASE(int32_t, varint, UPB_WIRE_TYPE_VARINT, upb_zzencode_32(val));
963     case UPB_DESCRIPTOR_TYPE_SINT64:
964       CASE(int64_t, varint, UPB_WIRE_TYPE_VARINT, upb_zzencode_64(val));
965     case UPB_DESCRIPTOR_TYPE_STRING:
966     case UPB_DESCRIPTOR_TYPE_BYTES: {
967       upb_strview view = *(upb_strview*)field_mem;
968       if (skip_zero_value && view.size == 0) {
969         return true;
970       }
971       return upb_put_bytes(e, view.data, view.size) &&
972           upb_put_varint(e, view.size) &&
973           upb_put_tag(e, f->number, UPB_WIRE_TYPE_DELIMITED);
974     }
975     case UPB_DESCRIPTOR_TYPE_GROUP: {
976       size_t size;
977       void *submsg = *(void **)field_mem;
978       const upb_msglayout *subm = m->submsgs[f->submsg_index];
979       if (submsg == NULL) {
980         return true;
981       }
982       return upb_put_tag(e, f->number, UPB_WIRE_TYPE_END_GROUP) &&
983           upb_encode_message(e, submsg, subm, &size) &&
984           upb_put_tag(e, f->number, UPB_WIRE_TYPE_START_GROUP);
985     }
986     case UPB_DESCRIPTOR_TYPE_MESSAGE: {
987       size_t size;
988       void *submsg = *(void **)field_mem;
989       const upb_msglayout *subm = m->submsgs[f->submsg_index];
990       if (submsg == NULL) {
991         return true;
992       }
993       return upb_encode_message(e, submsg, subm, &size) &&
994           upb_put_varint(e, size) &&
995           upb_put_tag(e, f->number, UPB_WIRE_TYPE_DELIMITED);
996     }
997   }
998 #undef CASE
999   UPB_UNREACHABLE();
1000 }
1001 
upb_encode_array(upb_encstate * e,const char * field_mem,const upb_msglayout * m,const upb_msglayout_field * f)1002 static bool upb_encode_array(upb_encstate *e, const char *field_mem,
1003                              const upb_msglayout *m,
1004                              const upb_msglayout_field *f) {
1005   const upb_array *arr = *(const upb_array**)field_mem;
1006   bool packed = f->label == _UPB_LABEL_PACKED;
1007 
1008   if (arr == NULL || arr->len == 0) {
1009     return true;
1010   }
1011 
1012 #define VARINT_CASE(ctype, encode)                                       \
1013   {                                                                      \
1014     const ctype *start = _upb_array_constptr(arr);                       \
1015     const ctype *ptr = start + arr->len;                                 \
1016     size_t pre_len = e->limit - e->ptr;                                  \
1017     uint32_t tag = packed ? 0 : (f->number << 3) | UPB_WIRE_TYPE_VARINT; \
1018     do {                                                                 \
1019       ptr--;                                                             \
1020       CHK(upb_put_varint(e, encode));                                    \
1021       if (tag) CHK(upb_put_varint(e, tag));                              \
1022     } while (ptr != start);                                              \
1023     if (!tag) CHK(upb_put_varint(e, e->limit - e->ptr - pre_len));       \
1024   }                                                                      \
1025   break;                                                                 \
1026   do {                                                                   \
1027     ;                                                                    \
1028   } while (0)
1029 
1030 #define TAG(wire_type) (packed ? 0 : (f->number << 3 | wire_type))
1031 
1032   switch (f->descriptortype) {
1033     case UPB_DESCRIPTOR_TYPE_DOUBLE:
1034       CHK(upb_put_fixedarray(e, arr, sizeof(double), TAG(UPB_WIRE_TYPE_64BIT)));
1035       break;
1036     case UPB_DESCRIPTOR_TYPE_FLOAT:
1037       CHK(upb_put_fixedarray(e, arr, sizeof(float), TAG(UPB_WIRE_TYPE_32BIT)));
1038       break;
1039     case UPB_DESCRIPTOR_TYPE_SFIXED64:
1040     case UPB_DESCRIPTOR_TYPE_FIXED64:
1041       CHK(upb_put_fixedarray(e, arr, sizeof(uint64_t), TAG(UPB_WIRE_TYPE_64BIT)));
1042       break;
1043     case UPB_DESCRIPTOR_TYPE_FIXED32:
1044     case UPB_DESCRIPTOR_TYPE_SFIXED32:
1045       CHK(upb_put_fixedarray(e, arr, sizeof(uint32_t), TAG(UPB_WIRE_TYPE_32BIT)));
1046       break;
1047     case UPB_DESCRIPTOR_TYPE_INT64:
1048     case UPB_DESCRIPTOR_TYPE_UINT64:
1049       VARINT_CASE(uint64_t, *ptr);
1050     case UPB_DESCRIPTOR_TYPE_UINT32:
1051       VARINT_CASE(uint32_t, *ptr);
1052     case UPB_DESCRIPTOR_TYPE_INT32:
1053     case UPB_DESCRIPTOR_TYPE_ENUM:
1054       VARINT_CASE(int32_t, (int64_t)*ptr);
1055     case UPB_DESCRIPTOR_TYPE_BOOL:
1056       VARINT_CASE(bool, *ptr);
1057     case UPB_DESCRIPTOR_TYPE_SINT32:
1058       VARINT_CASE(int32_t, upb_zzencode_32(*ptr));
1059     case UPB_DESCRIPTOR_TYPE_SINT64:
1060       VARINT_CASE(int64_t, upb_zzencode_64(*ptr));
1061     case UPB_DESCRIPTOR_TYPE_STRING:
1062     case UPB_DESCRIPTOR_TYPE_BYTES: {
1063       const upb_strview *start = _upb_array_constptr(arr);
1064       const upb_strview *ptr = start + arr->len;
1065       do {
1066         ptr--;
1067         CHK(upb_put_bytes(e, ptr->data, ptr->size) &&
1068             upb_put_varint(e, ptr->size) &&
1069             upb_put_tag(e, f->number, UPB_WIRE_TYPE_DELIMITED));
1070       } while (ptr != start);
1071       return true;
1072     }
1073     case UPB_DESCRIPTOR_TYPE_GROUP: {
1074       const void *const*start = _upb_array_constptr(arr);
1075       const void *const*ptr = start + arr->len;
1076       const upb_msglayout *subm = m->submsgs[f->submsg_index];
1077       do {
1078         size_t size;
1079         ptr--;
1080         CHK(upb_put_tag(e, f->number, UPB_WIRE_TYPE_END_GROUP) &&
1081             upb_encode_message(e, *ptr, subm, &size) &&
1082             upb_put_tag(e, f->number, UPB_WIRE_TYPE_START_GROUP));
1083       } while (ptr != start);
1084       return true;
1085     }
1086     case UPB_DESCRIPTOR_TYPE_MESSAGE: {
1087       const void *const*start = _upb_array_constptr(arr);
1088       const void *const*ptr = start + arr->len;
1089       const upb_msglayout *subm = m->submsgs[f->submsg_index];
1090       do {
1091         size_t size;
1092         ptr--;
1093         CHK(upb_encode_message(e, *ptr, subm, &size) &&
1094             upb_put_varint(e, size) &&
1095             upb_put_tag(e, f->number, UPB_WIRE_TYPE_DELIMITED));
1096       } while (ptr != start);
1097       return true;
1098     }
1099   }
1100 #undef VARINT_CASE
1101 
1102   if (packed) {
1103     CHK(upb_put_tag(e, f->number, UPB_WIRE_TYPE_DELIMITED));
1104   }
1105   return true;
1106 }
1107 
upb_encode_map(upb_encstate * e,const char * field_mem,const upb_msglayout * m,const upb_msglayout_field * f)1108 static bool upb_encode_map(upb_encstate *e, const char *field_mem,
1109                            const upb_msglayout *m,
1110                            const upb_msglayout_field *f) {
1111   const upb_map *map = *(const upb_map**)field_mem;
1112   const upb_msglayout *entry = m->submsgs[f->submsg_index];
1113   const upb_msglayout_field *key_field = &entry->fields[0];
1114   const upb_msglayout_field *val_field = &entry->fields[1];
1115   upb_strtable_iter i;
1116   if (map == NULL) {
1117     return true;
1118   }
1119 
1120   upb_strtable_begin(&i, &map->table);
1121   for(; !upb_strtable_done(&i); upb_strtable_next(&i)) {
1122     size_t pre_len = e->limit - e->ptr;
1123     size_t size;
1124     upb_strview key = upb_strtable_iter_key(&i);
1125     const upb_value val = upb_strtable_iter_value(&i);
1126     upb_map_entry ent;
1127     _upb_map_fromkey(key, &ent.k, map->key_size);
1128     _upb_map_fromvalue(val, &ent.v, map->val_size);
1129     CHK(upb_encode_scalarfield(e, &ent.v, entry, val_field, false));
1130     CHK(upb_encode_scalarfield(e, &ent.k, entry, key_field, false));
1131     size = (e->limit - e->ptr) - pre_len;
1132     CHK(upb_put_varint(e, size));
1133     CHK(upb_put_tag(e, f->number, UPB_WIRE_TYPE_DELIMITED));
1134   }
1135 
1136   return true;
1137 }
1138 
1139 
upb_encode_message(upb_encstate * e,const char * msg,const upb_msglayout * m,size_t * size)1140 bool upb_encode_message(upb_encstate *e, const char *msg,
1141                         const upb_msglayout *m, size_t *size) {
1142   int i;
1143   size_t pre_len = e->limit - e->ptr;
1144   const char *unknown;
1145   size_t unknown_size;
1146 
1147   unknown = upb_msg_getunknown(msg, &unknown_size);
1148 
1149   if (unknown) {
1150     upb_put_bytes(e, unknown, unknown_size);
1151   }
1152 
1153   for (i = m->field_count - 1; i >= 0; i--) {
1154     const upb_msglayout_field *f = &m->fields[i];
1155 
1156     if (_upb_isrepeated(f)) {
1157       CHK(upb_encode_array(e, msg + f->offset, m, f));
1158     } else if (f->label == _UPB_LABEL_MAP) {
1159       CHK(upb_encode_map(e, msg + f->offset, m, f));
1160     } else {
1161       bool skip_empty = false;
1162       if (f->presence == 0) {
1163         /* Proto3 presence. */
1164         skip_empty = true;
1165       } else if (f->presence > 0) {
1166         /* Proto2 presence: hasbit. */
1167         if (!_upb_hasbit_field(msg, f)) {
1168           continue;
1169         }
1170       } else {
1171         /* Field is in a oneof. */
1172         if (_upb_getoneofcase_field(msg, f) != f->number) {
1173           continue;
1174         }
1175       }
1176       CHK(upb_encode_scalarfield(e, msg + f->offset, m, f, skip_empty));
1177     }
1178   }
1179 
1180   *size = (e->limit - e->ptr) - pre_len;
1181   return true;
1182 }
1183 
upb_encode(const void * msg,const upb_msglayout * m,upb_arena * arena,size_t * size)1184 char *upb_encode(const void *msg, const upb_msglayout *m, upb_arena *arena,
1185                  size_t *size) {
1186   upb_encstate e;
1187   e.alloc = upb_arena_alloc(arena);
1188   e.buf = NULL;
1189   e.limit = NULL;
1190   e.ptr = NULL;
1191 
1192   if (!upb_encode_message(&e, msg, m, size)) {
1193     *size = 0;
1194     return NULL;
1195   }
1196 
1197   *size = e.limit - e.ptr;
1198 
1199   if (*size == 0) {
1200     static char ch;
1201     return &ch;
1202   } else {
1203     UPB_ASSERT(e.ptr);
1204     return e.ptr;
1205   }
1206 }
1207 
1208 #undef CHK
1209 
1210 
1211 
1212 
1213 /** upb_msg *******************************************************************/
1214 
1215 static const char _upb_fieldtype_to_sizelg2[12] = {
1216   0,
1217   0,  /* UPB_TYPE_BOOL */
1218   2,  /* UPB_TYPE_FLOAT */
1219   2,  /* UPB_TYPE_INT32 */
1220   2,  /* UPB_TYPE_UINT32 */
1221   2,  /* UPB_TYPE_ENUM */
1222   UPB_SIZE(2, 3),  /* UPB_TYPE_MESSAGE */
1223   3,  /* UPB_TYPE_DOUBLE */
1224   3,  /* UPB_TYPE_INT64 */
1225   3,  /* UPB_TYPE_UINT64 */
1226   UPB_SIZE(3, 4),  /* UPB_TYPE_STRING */
1227   UPB_SIZE(3, 4),  /* UPB_TYPE_BYTES */
1228 };
1229 
tag_arrptr(void * ptr,int elem_size_lg2)1230 static uintptr_t tag_arrptr(void* ptr, int elem_size_lg2) {
1231   UPB_ASSERT(elem_size_lg2 <= 4);
1232   return (uintptr_t)ptr | elem_size_lg2;
1233 }
1234 
upb_msg_internalsize(const upb_msglayout * l)1235 static int upb_msg_internalsize(const upb_msglayout *l) {
1236   return sizeof(upb_msg_internal) - l->extendable * sizeof(void *);
1237 }
1238 
upb_msg_sizeof(const upb_msglayout * l)1239 static size_t upb_msg_sizeof(const upb_msglayout *l) {
1240   return l->size + upb_msg_internalsize(l);
1241 }
1242 
upb_msg_getinternal_const(const upb_msg * msg)1243 static const upb_msg_internal *upb_msg_getinternal_const(const upb_msg *msg) {
1244   ptrdiff_t size = sizeof(upb_msg_internal);
1245   return UPB_PTR_AT(msg, -size, upb_msg_internal);
1246 }
1247 
upb_msg_getinternal(upb_msg * msg)1248 static upb_msg_internal *upb_msg_getinternal(upb_msg *msg) {
1249   return (upb_msg_internal*)upb_msg_getinternal_const(msg);
1250 }
1251 
_upb_msg_clear(upb_msg * msg,const upb_msglayout * l)1252 void _upb_msg_clear(upb_msg *msg, const upb_msglayout *l) {
1253   ptrdiff_t internal = upb_msg_internalsize(l);
1254   void *mem = UPB_PTR_AT(msg, -internal, char);
1255   memset(mem, 0, l->size + internal);
1256 }
1257 
_upb_msg_new(const upb_msglayout * l,upb_arena * a)1258 upb_msg *_upb_msg_new(const upb_msglayout *l, upb_arena *a) {
1259   void *mem = upb_arena_malloc(a, upb_msg_sizeof(l));
1260   upb_msg *msg;
1261 
1262   if (!mem) {
1263     return NULL;
1264   }
1265 
1266   msg = UPB_PTR_AT(mem, upb_msg_internalsize(l), upb_msg);
1267   _upb_msg_clear(msg, l);
1268   return msg;
1269 }
1270 
_upb_msg_addunknown(upb_msg * msg,const char * data,size_t len,upb_arena * arena)1271 bool _upb_msg_addunknown(upb_msg *msg, const char *data, size_t len,
1272                          upb_arena *arena) {
1273   upb_msg_internal *in = upb_msg_getinternal(msg);
1274   if (len > in->unknown_size - in->unknown_len) {
1275     upb_alloc *alloc = upb_arena_alloc(arena);
1276     size_t need = in->unknown_size + len;
1277     size_t newsize = UPB_MAX(in->unknown_size * 2, need);
1278     void *mem = upb_realloc(alloc, in->unknown, in->unknown_size, newsize);
1279     if (!mem) return false;
1280     in->unknown = mem;
1281     in->unknown_size = newsize;
1282   }
1283   memcpy(in->unknown + in->unknown_len, data, len);
1284   in->unknown_len += len;
1285   return true;
1286 }
1287 
_upb_msg_discardunknown_shallow(upb_msg * msg)1288 void _upb_msg_discardunknown_shallow(upb_msg *msg) {
1289   upb_msg_internal *in = upb_msg_getinternal(msg);
1290   in->unknown_len = 0;
1291 }
1292 
upb_msg_getunknown(const upb_msg * msg,size_t * len)1293 const char *upb_msg_getunknown(const upb_msg *msg, size_t *len) {
1294   const upb_msg_internal *in = upb_msg_getinternal_const(msg);
1295   *len = in->unknown_len;
1296   return in->unknown;
1297 }
1298 
1299 /** upb_array *****************************************************************/
1300 
_upb_array_new(upb_arena * a,upb_fieldtype_t type)1301 upb_array *_upb_array_new(upb_arena *a, upb_fieldtype_t type) {
1302   upb_array *arr = upb_arena_malloc(a, sizeof(upb_array));
1303 
1304   if (!arr) {
1305     return NULL;
1306   }
1307 
1308   arr->data = tag_arrptr(NULL, _upb_fieldtype_to_sizelg2[type]);
1309   arr->len = 0;
1310   arr->size = 0;
1311 
1312   return arr;
1313 }
1314 
_upb_array_realloc(upb_array * arr,size_t min_size,upb_arena * arena)1315 bool _upb_array_realloc(upb_array *arr, size_t min_size, upb_arena *arena) {
1316   size_t new_size = UPB_MAX(arr->size, 4);
1317   int elem_size_lg2 = arr->data & 7;
1318   size_t old_bytes = arr->size << elem_size_lg2;
1319   size_t new_bytes;
1320   void* ptr = _upb_array_ptr(arr);
1321 
1322   /* Log2 ceiling of size. */
1323   while (new_size < min_size) new_size *= 2;
1324 
1325   new_bytes = new_size << elem_size_lg2;
1326   ptr = upb_arena_realloc(arena, ptr, old_bytes, new_bytes);
1327 
1328   if (!ptr) {
1329     return false;
1330   }
1331 
1332   arr->data = tag_arrptr(ptr, elem_size_lg2);
1333   arr->size = new_size;
1334   return true;
1335 }
1336 
getorcreate_array(upb_array ** arr_ptr,upb_fieldtype_t type,upb_arena * arena)1337 static upb_array *getorcreate_array(upb_array **arr_ptr, upb_fieldtype_t type,
1338                                     upb_arena *arena) {
1339   upb_array *arr = *arr_ptr;
1340   if (!arr) {
1341     arr = _upb_array_new(arena, type);
1342     if (!arr) return NULL;
1343     *arr_ptr = arr;
1344   }
1345   return arr;
1346 }
1347 
_upb_array_resize_fallback(upb_array ** arr_ptr,size_t size,upb_fieldtype_t type,upb_arena * arena)1348 void *_upb_array_resize_fallback(upb_array **arr_ptr, size_t size,
1349                                  upb_fieldtype_t type, upb_arena *arena) {
1350   upb_array *arr = getorcreate_array(arr_ptr, type, arena);
1351   return arr && _upb_array_resize(arr, size, arena) ? _upb_array_ptr(arr) : NULL;
1352 }
1353 
_upb_array_append_fallback(upb_array ** arr_ptr,const void * value,upb_fieldtype_t type,upb_arena * arena)1354 bool _upb_array_append_fallback(upb_array **arr_ptr, const void *value,
1355                                 upb_fieldtype_t type, upb_arena *arena) {
1356   upb_array *arr = getorcreate_array(arr_ptr, type, arena);
1357   size_t elem = arr->len;
1358   int lg2 = _upb_fieldtype_to_sizelg2[type];
1359   char *data;
1360 
1361   if (!arr || !_upb_array_resize(arr, elem + 1, arena)) return false;
1362 
1363   data = _upb_array_ptr(arr);
1364   memcpy(data + (elem << lg2), value, 1 << lg2);
1365   return true;
1366 }
1367 
1368 /** upb_map *******************************************************************/
1369 
_upb_map_new(upb_arena * a,size_t key_size,size_t value_size)1370 upb_map *_upb_map_new(upb_arena *a, size_t key_size, size_t value_size) {
1371   upb_map *map = upb_arena_malloc(a, sizeof(upb_map));
1372 
1373   if (!map) {
1374     return NULL;
1375   }
1376 
1377   upb_strtable_init2(&map->table, UPB_CTYPE_INT32, upb_arena_alloc(a));
1378   map->key_size = key_size;
1379   map->val_size = value_size;
1380 
1381   return map;
1382 }
1383 /*
1384 ** upb_table Implementation
1385 **
1386 ** Implementation is heavily inspired by Lua's ltable.c.
1387 */
1388 
1389 
1390 #include <string.h>
1391 
1392 
1393 #define UPB_MAXARRSIZE 16  /* 64k. */
1394 
1395 /* From Chromium. */
1396 #define ARRAY_SIZE(x) \
1397     ((sizeof(x)/sizeof(0[x])) / ((size_t)(!(sizeof(x) % sizeof(0[x])))))
1398 
1399 static const double MAX_LOAD = 0.85;
1400 
1401 /* The minimum utilization of the array part of a mixed hash/array table.  This
1402  * is a speed/memory-usage tradeoff (though it's not straightforward because of
1403  * cache effects).  The lower this is, the more memory we'll use. */
1404 static const double MIN_DENSITY = 0.1;
1405 
is_pow2(uint64_t v)1406 bool is_pow2(uint64_t v) { return v == 0 || (v & (v - 1)) == 0; }
1407 
log2ceil(uint64_t v)1408 int log2ceil(uint64_t v) {
1409   int ret = 0;
1410   bool pow2 = is_pow2(v);
1411   while (v >>= 1) ret++;
1412   ret = pow2 ? ret : ret + 1;  /* Ceiling. */
1413   return UPB_MIN(UPB_MAXARRSIZE, ret);
1414 }
1415 
upb_strdup(const char * s,upb_alloc * a)1416 char *upb_strdup(const char *s, upb_alloc *a) {
1417   return upb_strdup2(s, strlen(s), a);
1418 }
1419 
upb_strdup2(const char * s,size_t len,upb_alloc * a)1420 char *upb_strdup2(const char *s, size_t len, upb_alloc *a) {
1421   size_t n;
1422   char *p;
1423 
1424   /* Prevent overflow errors. */
1425   if (len == SIZE_MAX) return NULL;
1426   /* Always null-terminate, even if binary data; but don't rely on the input to
1427    * have a null-terminating byte since it may be a raw binary buffer. */
1428   n = len + 1;
1429   p = upb_malloc(a, n);
1430   if (p) {
1431     memcpy(p, s, len);
1432     p[len] = 0;
1433   }
1434   return p;
1435 }
1436 
1437 /* A type to represent the lookup key of either a strtable or an inttable. */
1438 typedef union {
1439   uintptr_t num;
1440   struct {
1441     const char *str;
1442     size_t len;
1443   } str;
1444 } lookupkey_t;
1445 
strkey2(const char * str,size_t len)1446 static lookupkey_t strkey2(const char *str, size_t len) {
1447   lookupkey_t k;
1448   k.str.str = str;
1449   k.str.len = len;
1450   return k;
1451 }
1452 
intkey(uintptr_t key)1453 static lookupkey_t intkey(uintptr_t key) {
1454   lookupkey_t k;
1455   k.num = key;
1456   return k;
1457 }
1458 
1459 typedef uint32_t hashfunc_t(upb_tabkey key);
1460 typedef bool eqlfunc_t(upb_tabkey k1, lookupkey_t k2);
1461 
1462 /* Base table (shared code) ***************************************************/
1463 
1464 /* For when we need to cast away const. */
mutable_entries(upb_table * t)1465 static upb_tabent *mutable_entries(upb_table *t) {
1466   return (upb_tabent*)t->entries;
1467 }
1468 
isfull(upb_table * t)1469 static bool isfull(upb_table *t) {
1470   if (upb_table_size(t) == 0) {
1471     return true;
1472   } else {
1473     return ((double)(t->count + 1) / upb_table_size(t)) > MAX_LOAD;
1474   }
1475 }
1476 
init(upb_table * t,uint8_t size_lg2,upb_alloc * a)1477 static bool init(upb_table *t, uint8_t size_lg2, upb_alloc *a) {
1478   size_t bytes;
1479 
1480   t->count = 0;
1481   t->size_lg2 = size_lg2;
1482   t->mask = upb_table_size(t) ? upb_table_size(t) - 1 : 0;
1483   bytes = upb_table_size(t) * sizeof(upb_tabent);
1484   if (bytes > 0) {
1485     t->entries = upb_malloc(a, bytes);
1486     if (!t->entries) return false;
1487     memset(mutable_entries(t), 0, bytes);
1488   } else {
1489     t->entries = NULL;
1490   }
1491   return true;
1492 }
1493 
uninit(upb_table * t,upb_alloc * a)1494 static void uninit(upb_table *t, upb_alloc *a) {
1495   upb_free(a, mutable_entries(t));
1496 }
1497 
emptyent(upb_table * t)1498 static upb_tabent *emptyent(upb_table *t) {
1499   upb_tabent *e = mutable_entries(t) + upb_table_size(t);
1500   while (1) { if (upb_tabent_isempty(--e)) return e; UPB_ASSERT(e > t->entries); }
1501 }
1502 
getentry_mutable(upb_table * t,uint32_t hash)1503 static upb_tabent *getentry_mutable(upb_table *t, uint32_t hash) {
1504   return (upb_tabent*)upb_getentry(t, hash);
1505 }
1506 
findentry(const upb_table * t,lookupkey_t key,uint32_t hash,eqlfunc_t * eql)1507 static const upb_tabent *findentry(const upb_table *t, lookupkey_t key,
1508                                    uint32_t hash, eqlfunc_t *eql) {
1509   const upb_tabent *e;
1510 
1511   if (t->size_lg2 == 0) return NULL;
1512   e = upb_getentry(t, hash);
1513   if (upb_tabent_isempty(e)) return NULL;
1514   while (1) {
1515     if (eql(e->key, key)) return e;
1516     if ((e = e->next) == NULL) return NULL;
1517   }
1518 }
1519 
findentry_mutable(upb_table * t,lookupkey_t key,uint32_t hash,eqlfunc_t * eql)1520 static upb_tabent *findentry_mutable(upb_table *t, lookupkey_t key,
1521                                      uint32_t hash, eqlfunc_t *eql) {
1522   return (upb_tabent*)findentry(t, key, hash, eql);
1523 }
1524 
lookup(const upb_table * t,lookupkey_t key,upb_value * v,uint32_t hash,eqlfunc_t * eql)1525 static bool lookup(const upb_table *t, lookupkey_t key, upb_value *v,
1526                    uint32_t hash, eqlfunc_t *eql) {
1527   const upb_tabent *e = findentry(t, key, hash, eql);
1528   if (e) {
1529     if (v) {
1530       _upb_value_setval(v, e->val.val);
1531     }
1532     return true;
1533   } else {
1534     return false;
1535   }
1536 }
1537 
1538 /* 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)1539 static void insert(upb_table *t, lookupkey_t key, upb_tabkey tabkey,
1540                    upb_value val, uint32_t hash,
1541                    hashfunc_t *hashfunc, eqlfunc_t *eql) {
1542   upb_tabent *mainpos_e;
1543   upb_tabent *our_e;
1544 
1545   UPB_ASSERT(findentry(t, key, hash, eql) == NULL);
1546 
1547   t->count++;
1548   mainpos_e = getentry_mutable(t, hash);
1549   our_e = mainpos_e;
1550 
1551   if (upb_tabent_isempty(mainpos_e)) {
1552     /* Our main position is empty; use it. */
1553     our_e->next = NULL;
1554   } else {
1555     /* Collision. */
1556     upb_tabent *new_e = emptyent(t);
1557     /* Head of collider's chain. */
1558     upb_tabent *chain = getentry_mutable(t, hashfunc(mainpos_e->key));
1559     if (chain == mainpos_e) {
1560       /* Existing ent is in its main posisiton (it has the same hash as us, and
1561        * is the head of our chain).  Insert to new ent and append to this chain. */
1562       new_e->next = mainpos_e->next;
1563       mainpos_e->next = new_e;
1564       our_e = new_e;
1565     } else {
1566       /* Existing ent is not in its main position (it is a node in some other
1567        * chain).  This implies that no existing ent in the table has our hash.
1568        * Evict it (updating its chain) and use its ent for head of our chain. */
1569       *new_e = *mainpos_e;  /* copies next. */
1570       while (chain->next != mainpos_e) {
1571         chain = (upb_tabent*)chain->next;
1572         UPB_ASSERT(chain);
1573       }
1574       chain->next = new_e;
1575       our_e = mainpos_e;
1576       our_e->next = NULL;
1577     }
1578   }
1579   our_e->key = tabkey;
1580   our_e->val.val = val.val;
1581   UPB_ASSERT(findentry(t, key, hash, eql) == our_e);
1582 }
1583 
rm(upb_table * t,lookupkey_t key,upb_value * val,upb_tabkey * removed,uint32_t hash,eqlfunc_t * eql)1584 static bool rm(upb_table *t, lookupkey_t key, upb_value *val,
1585                upb_tabkey *removed, uint32_t hash, eqlfunc_t *eql) {
1586   upb_tabent *chain = getentry_mutable(t, hash);
1587   if (upb_tabent_isempty(chain)) return false;
1588   if (eql(chain->key, key)) {
1589     /* Element to remove is at the head of its chain. */
1590     t->count--;
1591     if (val) _upb_value_setval(val, chain->val.val);
1592     if (removed) *removed = chain->key;
1593     if (chain->next) {
1594       upb_tabent *move = (upb_tabent*)chain->next;
1595       *chain = *move;
1596       move->key = 0;  /* Make the slot empty. */
1597     } else {
1598       chain->key = 0;  /* Make the slot empty. */
1599     }
1600     return true;
1601   } else {
1602     /* Element to remove is either in a non-head position or not in the
1603      * table. */
1604     while (chain->next && !eql(chain->next->key, key)) {
1605       chain = (upb_tabent*)chain->next;
1606     }
1607     if (chain->next) {
1608       /* Found element to remove. */
1609       upb_tabent *rm = (upb_tabent*)chain->next;
1610       t->count--;
1611       if (val) _upb_value_setval(val, chain->next->val.val);
1612       if (removed) *removed = rm->key;
1613       rm->key = 0;  /* Make the slot empty. */
1614       chain->next = rm->next;
1615       return true;
1616     } else {
1617       /* Element to remove is not in the table. */
1618       return false;
1619     }
1620   }
1621 }
1622 
next(const upb_table * t,size_t i)1623 static size_t next(const upb_table *t, size_t i) {
1624   do {
1625     if (++i >= upb_table_size(t))
1626       return SIZE_MAX - 1;  /* Distinct from -1. */
1627   } while(upb_tabent_isempty(&t->entries[i]));
1628 
1629   return i;
1630 }
1631 
begin(const upb_table * t)1632 static size_t begin(const upb_table *t) {
1633   return next(t, -1);
1634 }
1635 
1636 
1637 /* upb_strtable ***************************************************************/
1638 
1639 /* A simple "subclass" of upb_table that only adds a hash function for strings. */
1640 
strcopy(lookupkey_t k2,upb_alloc * a)1641 static upb_tabkey strcopy(lookupkey_t k2, upb_alloc *a) {
1642   uint32_t len = (uint32_t) k2.str.len;
1643   char *str = upb_malloc(a, k2.str.len + sizeof(uint32_t) + 1);
1644   if (str == NULL) return 0;
1645   memcpy(str, &len, sizeof(uint32_t));
1646   if (k2.str.len) memcpy(str + sizeof(uint32_t), k2.str.str, k2.str.len);
1647   str[sizeof(uint32_t) + k2.str.len] = '\0';
1648   return (uintptr_t)str;
1649 }
1650 
strhash(upb_tabkey key)1651 static uint32_t strhash(upb_tabkey key) {
1652   uint32_t len;
1653   char *str = upb_tabstr(key, &len);
1654   return upb_murmur_hash2(str, len, 0);
1655 }
1656 
streql(upb_tabkey k1,lookupkey_t k2)1657 static bool streql(upb_tabkey k1, lookupkey_t k2) {
1658   uint32_t len;
1659   char *str = upb_tabstr(k1, &len);
1660   return len == k2.str.len && (len == 0 || memcmp(str, k2.str.str, len) == 0);
1661 }
1662 
upb_strtable_init2(upb_strtable * t,upb_ctype_t ctype,upb_alloc * a)1663 bool upb_strtable_init2(upb_strtable *t, upb_ctype_t ctype, upb_alloc *a) {
1664   UPB_UNUSED(ctype);  /* TODO(haberman): rm */
1665   return init(&t->t, 2, a);
1666 }
1667 
upb_strtable_clear(upb_strtable * t)1668 void upb_strtable_clear(upb_strtable *t) {
1669   size_t bytes = upb_table_size(&t->t) * sizeof(upb_tabent);
1670   t->t.count = 0;
1671   memset((char*)t->t.entries, 0, bytes);
1672 }
1673 
upb_strtable_uninit2(upb_strtable * t,upb_alloc * a)1674 void upb_strtable_uninit2(upb_strtable *t, upb_alloc *a) {
1675   size_t i;
1676   for (i = 0; i < upb_table_size(&t->t); i++)
1677     upb_free(a, (void*)t->t.entries[i].key);
1678   uninit(&t->t, a);
1679 }
1680 
upb_strtable_resize(upb_strtable * t,size_t size_lg2,upb_alloc * a)1681 bool upb_strtable_resize(upb_strtable *t, size_t size_lg2, upb_alloc *a) {
1682   upb_strtable new_table;
1683   upb_strtable_iter i;
1684 
1685   if (!init(&new_table.t, size_lg2, a))
1686     return false;
1687   upb_strtable_begin(&i, t);
1688   for ( ; !upb_strtable_done(&i); upb_strtable_next(&i)) {
1689     upb_strview key = upb_strtable_iter_key(&i);
1690     upb_strtable_insert3(
1691         &new_table, key.data, key.size,
1692         upb_strtable_iter_value(&i), a);
1693   }
1694   upb_strtable_uninit2(t, a);
1695   *t = new_table;
1696   return true;
1697 }
1698 
upb_strtable_insert3(upb_strtable * t,const char * k,size_t len,upb_value v,upb_alloc * a)1699 bool upb_strtable_insert3(upb_strtable *t, const char *k, size_t len,
1700                           upb_value v, upb_alloc *a) {
1701   lookupkey_t key;
1702   upb_tabkey tabkey;
1703   uint32_t hash;
1704 
1705   if (isfull(&t->t)) {
1706     /* Need to resize.  New table of double the size, add old elements to it. */
1707     if (!upb_strtable_resize(t, t->t.size_lg2 + 1, a)) {
1708       return false;
1709     }
1710   }
1711 
1712   key = strkey2(k, len);
1713   tabkey = strcopy(key, a);
1714   if (tabkey == 0) return false;
1715 
1716   hash = upb_murmur_hash2(key.str.str, key.str.len, 0);
1717   insert(&t->t, key, tabkey, v, hash, &strhash, &streql);
1718   return true;
1719 }
1720 
upb_strtable_lookup2(const upb_strtable * t,const char * key,size_t len,upb_value * v)1721 bool upb_strtable_lookup2(const upb_strtable *t, const char *key, size_t len,
1722                           upb_value *v) {
1723   uint32_t hash = upb_murmur_hash2(key, len, 0);
1724   return lookup(&t->t, strkey2(key, len), v, hash, &streql);
1725 }
1726 
upb_strtable_remove3(upb_strtable * t,const char * key,size_t len,upb_value * val,upb_alloc * alloc)1727 bool upb_strtable_remove3(upb_strtable *t, const char *key, size_t len,
1728                          upb_value *val, upb_alloc *alloc) {
1729   uint32_t hash = upb_murmur_hash2(key, len, 0);
1730   upb_tabkey tabkey;
1731   if (rm(&t->t, strkey2(key, len), val, &tabkey, hash, &streql)) {
1732     if (alloc) {
1733       /* Arena-based allocs don't need to free and won't pass this. */
1734       upb_free(alloc, (void*)tabkey);
1735     }
1736     return true;
1737   } else {
1738     return false;
1739   }
1740 }
1741 
1742 /* Iteration */
1743 
upb_strtable_begin(upb_strtable_iter * i,const upb_strtable * t)1744 void upb_strtable_begin(upb_strtable_iter *i, const upb_strtable *t) {
1745   i->t = t;
1746   i->index = begin(&t->t);
1747 }
1748 
upb_strtable_next(upb_strtable_iter * i)1749 void upb_strtable_next(upb_strtable_iter *i) {
1750   i->index = next(&i->t->t, i->index);
1751 }
1752 
upb_strtable_done(const upb_strtable_iter * i)1753 bool upb_strtable_done(const upb_strtable_iter *i) {
1754   if (!i->t) return true;
1755   return i->index >= upb_table_size(&i->t->t) ||
1756          upb_tabent_isempty(str_tabent(i));
1757 }
1758 
upb_strtable_iter_key(const upb_strtable_iter * i)1759 upb_strview upb_strtable_iter_key(const upb_strtable_iter *i) {
1760   upb_strview key;
1761   uint32_t len;
1762   UPB_ASSERT(!upb_strtable_done(i));
1763   key.data = upb_tabstr(str_tabent(i)->key, &len);
1764   key.size = len;
1765   return key;
1766 }
1767 
upb_strtable_iter_value(const upb_strtable_iter * i)1768 upb_value upb_strtable_iter_value(const upb_strtable_iter *i) {
1769   UPB_ASSERT(!upb_strtable_done(i));
1770   return _upb_value_val(str_tabent(i)->val.val);
1771 }
1772 
upb_strtable_iter_setdone(upb_strtable_iter * i)1773 void upb_strtable_iter_setdone(upb_strtable_iter *i) {
1774   i->t = NULL;
1775   i->index = SIZE_MAX;
1776 }
1777 
upb_strtable_iter_isequal(const upb_strtable_iter * i1,const upb_strtable_iter * i2)1778 bool upb_strtable_iter_isequal(const upb_strtable_iter *i1,
1779                                const upb_strtable_iter *i2) {
1780   if (upb_strtable_done(i1) && upb_strtable_done(i2))
1781     return true;
1782   return i1->t == i2->t && i1->index == i2->index;
1783 }
1784 
1785 
1786 /* upb_inttable ***************************************************************/
1787 
1788 /* For inttables we use a hybrid structure where small keys are kept in an
1789  * array and large keys are put in the hash table. */
1790 
inthash(upb_tabkey key)1791 static uint32_t inthash(upb_tabkey key) { return upb_inthash(key); }
1792 
inteql(upb_tabkey k1,lookupkey_t k2)1793 static bool inteql(upb_tabkey k1, lookupkey_t k2) {
1794   return k1 == k2.num;
1795 }
1796 
mutable_array(upb_inttable * t)1797 static upb_tabval *mutable_array(upb_inttable *t) {
1798   return (upb_tabval*)t->array;
1799 }
1800 
inttable_val(upb_inttable * t,uintptr_t key)1801 static upb_tabval *inttable_val(upb_inttable *t, uintptr_t key) {
1802   if (key < t->array_size) {
1803     return upb_arrhas(t->array[key]) ? &(mutable_array(t)[key]) : NULL;
1804   } else {
1805     upb_tabent *e =
1806         findentry_mutable(&t->t, intkey(key), upb_inthash(key), &inteql);
1807     return e ? &e->val : NULL;
1808   }
1809 }
1810 
inttable_val_const(const upb_inttable * t,uintptr_t key)1811 static const upb_tabval *inttable_val_const(const upb_inttable *t,
1812                                             uintptr_t key) {
1813   return inttable_val((upb_inttable*)t, key);
1814 }
1815 
upb_inttable_count(const upb_inttable * t)1816 size_t upb_inttable_count(const upb_inttable *t) {
1817   return t->t.count + t->array_count;
1818 }
1819 
check(upb_inttable * t)1820 static void check(upb_inttable *t) {
1821   UPB_UNUSED(t);
1822 #if defined(UPB_DEBUG_TABLE) && !defined(NDEBUG)
1823   {
1824     /* This check is very expensive (makes inserts/deletes O(N)). */
1825     size_t count = 0;
1826     upb_inttable_iter i;
1827     upb_inttable_begin(&i, t);
1828     for(; !upb_inttable_done(&i); upb_inttable_next(&i), count++) {
1829       UPB_ASSERT(upb_inttable_lookup(t, upb_inttable_iter_key(&i), NULL));
1830     }
1831     UPB_ASSERT(count == upb_inttable_count(t));
1832   }
1833 #endif
1834 }
1835 
upb_inttable_sizedinit(upb_inttable * t,size_t asize,int hsize_lg2,upb_alloc * a)1836 bool upb_inttable_sizedinit(upb_inttable *t, size_t asize, int hsize_lg2,
1837                             upb_alloc *a) {
1838   size_t array_bytes;
1839 
1840   if (!init(&t->t, hsize_lg2, a)) return false;
1841   /* Always make the array part at least 1 long, so that we know key 0
1842    * won't be in the hash part, which simplifies things. */
1843   t->array_size = UPB_MAX(1, asize);
1844   t->array_count = 0;
1845   array_bytes = t->array_size * sizeof(upb_value);
1846   t->array = upb_malloc(a, array_bytes);
1847   if (!t->array) {
1848     uninit(&t->t, a);
1849     return false;
1850   }
1851   memset(mutable_array(t), 0xff, array_bytes);
1852   check(t);
1853   return true;
1854 }
1855 
upb_inttable_init2(upb_inttable * t,upb_ctype_t ctype,upb_alloc * a)1856 bool upb_inttable_init2(upb_inttable *t, upb_ctype_t ctype, upb_alloc *a) {
1857   UPB_UNUSED(ctype);  /* TODO(haberman): rm */
1858   return upb_inttable_sizedinit(t, 0, 4, a);
1859 }
1860 
upb_inttable_uninit2(upb_inttable * t,upb_alloc * a)1861 void upb_inttable_uninit2(upb_inttable *t, upb_alloc *a) {
1862   uninit(&t->t, a);
1863   upb_free(a, mutable_array(t));
1864 }
1865 
upb_inttable_insert2(upb_inttable * t,uintptr_t key,upb_value val,upb_alloc * a)1866 bool upb_inttable_insert2(upb_inttable *t, uintptr_t key, upb_value val,
1867                           upb_alloc *a) {
1868   upb_tabval tabval;
1869   tabval.val = val.val;
1870   UPB_ASSERT(upb_arrhas(tabval));  /* This will reject (uint64_t)-1.  Fix this. */
1871 
1872   if (key < t->array_size) {
1873     UPB_ASSERT(!upb_arrhas(t->array[key]));
1874     t->array_count++;
1875     mutable_array(t)[key].val = val.val;
1876   } else {
1877     if (isfull(&t->t)) {
1878       /* Need to resize the hash part, but we re-use the array part. */
1879       size_t i;
1880       upb_table new_table;
1881 
1882       if (!init(&new_table, t->t.size_lg2 + 1, a)) {
1883         return false;
1884       }
1885 
1886       for (i = begin(&t->t); i < upb_table_size(&t->t); i = next(&t->t, i)) {
1887         const upb_tabent *e = &t->t.entries[i];
1888         uint32_t hash;
1889         upb_value v;
1890 
1891         _upb_value_setval(&v, e->val.val);
1892         hash = upb_inthash(e->key);
1893         insert(&new_table, intkey(e->key), e->key, v, hash, &inthash, &inteql);
1894       }
1895 
1896       UPB_ASSERT(t->t.count == new_table.count);
1897 
1898       uninit(&t->t, a);
1899       t->t = new_table;
1900     }
1901     insert(&t->t, intkey(key), key, val, upb_inthash(key), &inthash, &inteql);
1902   }
1903   check(t);
1904   return true;
1905 }
1906 
upb_inttable_lookup(const upb_inttable * t,uintptr_t key,upb_value * v)1907 bool upb_inttable_lookup(const upb_inttable *t, uintptr_t key, upb_value *v) {
1908   const upb_tabval *table_v = inttable_val_const(t, key);
1909   if (!table_v) return false;
1910   if (v) _upb_value_setval(v, table_v->val);
1911   return true;
1912 }
1913 
upb_inttable_replace(upb_inttable * t,uintptr_t key,upb_value val)1914 bool upb_inttable_replace(upb_inttable *t, uintptr_t key, upb_value val) {
1915   upb_tabval *table_v = inttable_val(t, key);
1916   if (!table_v) return false;
1917   table_v->val = val.val;
1918   return true;
1919 }
1920 
upb_inttable_remove(upb_inttable * t,uintptr_t key,upb_value * val)1921 bool upb_inttable_remove(upb_inttable *t, uintptr_t key, upb_value *val) {
1922   bool success;
1923   if (key < t->array_size) {
1924     if (upb_arrhas(t->array[key])) {
1925       upb_tabval empty = UPB_TABVALUE_EMPTY_INIT;
1926       t->array_count--;
1927       if (val) {
1928         _upb_value_setval(val, t->array[key].val);
1929       }
1930       mutable_array(t)[key] = empty;
1931       success = true;
1932     } else {
1933       success = false;
1934     }
1935   } else {
1936     success = rm(&t->t, intkey(key), val, NULL, upb_inthash(key), &inteql);
1937   }
1938   check(t);
1939   return success;
1940 }
1941 
upb_inttable_insertptr2(upb_inttable * t,const void * key,upb_value val,upb_alloc * a)1942 bool upb_inttable_insertptr2(upb_inttable *t, const void *key, upb_value val,
1943                              upb_alloc *a) {
1944   return upb_inttable_insert2(t, (uintptr_t)key, val, a);
1945 }
1946 
upb_inttable_lookupptr(const upb_inttable * t,const void * key,upb_value * v)1947 bool upb_inttable_lookupptr(const upb_inttable *t, const void *key,
1948                             upb_value *v) {
1949   return upb_inttable_lookup(t, (uintptr_t)key, v);
1950 }
1951 
upb_inttable_removeptr(upb_inttable * t,const void * key,upb_value * val)1952 bool upb_inttable_removeptr(upb_inttable *t, const void *key, upb_value *val) {
1953   return upb_inttable_remove(t, (uintptr_t)key, val);
1954 }
1955 
upb_inttable_compact2(upb_inttable * t,upb_alloc * a)1956 void upb_inttable_compact2(upb_inttable *t, upb_alloc *a) {
1957   /* A power-of-two histogram of the table keys. */
1958   size_t counts[UPB_MAXARRSIZE + 1] = {0};
1959 
1960   /* The max key in each bucket. */
1961   uintptr_t max[UPB_MAXARRSIZE + 1] = {0};
1962 
1963   upb_inttable_iter i;
1964   size_t arr_count;
1965   int size_lg2;
1966   upb_inttable new_t;
1967 
1968   upb_inttable_begin(&i, t);
1969   for (; !upb_inttable_done(&i); upb_inttable_next(&i)) {
1970     uintptr_t key = upb_inttable_iter_key(&i);
1971     int bucket = log2ceil(key);
1972     max[bucket] = UPB_MAX(max[bucket], key);
1973     counts[bucket]++;
1974   }
1975 
1976   /* Find the largest power of two that satisfies the MIN_DENSITY
1977    * definition (while actually having some keys). */
1978   arr_count = upb_inttable_count(t);
1979 
1980   for (size_lg2 = ARRAY_SIZE(counts) - 1; size_lg2 > 0; size_lg2--) {
1981     if (counts[size_lg2] == 0) {
1982       /* We can halve again without losing any entries. */
1983       continue;
1984     } else if (arr_count >= (1 << size_lg2) * MIN_DENSITY) {
1985       break;
1986     }
1987 
1988     arr_count -= counts[size_lg2];
1989   }
1990 
1991   UPB_ASSERT(arr_count <= upb_inttable_count(t));
1992 
1993   {
1994     /* Insert all elements into new, perfectly-sized table. */
1995     size_t arr_size = max[size_lg2] + 1;  /* +1 so arr[max] will fit. */
1996     size_t hash_count = upb_inttable_count(t) - arr_count;
1997     size_t hash_size = hash_count ? (hash_count / MAX_LOAD) + 1 : 0;
1998     int hashsize_lg2 = log2ceil(hash_size);
1999 
2000     upb_inttable_sizedinit(&new_t, arr_size, hashsize_lg2, a);
2001     upb_inttable_begin(&i, t);
2002     for (; !upb_inttable_done(&i); upb_inttable_next(&i)) {
2003       uintptr_t k = upb_inttable_iter_key(&i);
2004       upb_inttable_insert2(&new_t, k, upb_inttable_iter_value(&i), a);
2005     }
2006     UPB_ASSERT(new_t.array_size == arr_size);
2007     UPB_ASSERT(new_t.t.size_lg2 == hashsize_lg2);
2008   }
2009   upb_inttable_uninit2(t, a);
2010   *t = new_t;
2011 }
2012 
2013 /* Iteration. */
2014 
int_tabent(const upb_inttable_iter * i)2015 static const upb_tabent *int_tabent(const upb_inttable_iter *i) {
2016   UPB_ASSERT(!i->array_part);
2017   return &i->t->t.entries[i->index];
2018 }
2019 
int_arrent(const upb_inttable_iter * i)2020 static upb_tabval int_arrent(const upb_inttable_iter *i) {
2021   UPB_ASSERT(i->array_part);
2022   return i->t->array[i->index];
2023 }
2024 
upb_inttable_begin(upb_inttable_iter * i,const upb_inttable * t)2025 void upb_inttable_begin(upb_inttable_iter *i, const upb_inttable *t) {
2026   i->t = t;
2027   i->index = -1;
2028   i->array_part = true;
2029   upb_inttable_next(i);
2030 }
2031 
upb_inttable_next(upb_inttable_iter * iter)2032 void upb_inttable_next(upb_inttable_iter *iter) {
2033   const upb_inttable *t = iter->t;
2034   if (iter->array_part) {
2035     while (++iter->index < t->array_size) {
2036       if (upb_arrhas(int_arrent(iter))) {
2037         return;
2038       }
2039     }
2040     iter->array_part = false;
2041     iter->index = begin(&t->t);
2042   } else {
2043     iter->index = next(&t->t, iter->index);
2044   }
2045 }
2046 
upb_inttable_done(const upb_inttable_iter * i)2047 bool upb_inttable_done(const upb_inttable_iter *i) {
2048   if (!i->t) return true;
2049   if (i->array_part) {
2050     return i->index >= i->t->array_size ||
2051            !upb_arrhas(int_arrent(i));
2052   } else {
2053     return i->index >= upb_table_size(&i->t->t) ||
2054            upb_tabent_isempty(int_tabent(i));
2055   }
2056 }
2057 
upb_inttable_iter_key(const upb_inttable_iter * i)2058 uintptr_t upb_inttable_iter_key(const upb_inttable_iter *i) {
2059   UPB_ASSERT(!upb_inttable_done(i));
2060   return i->array_part ? i->index : int_tabent(i)->key;
2061 }
2062 
upb_inttable_iter_value(const upb_inttable_iter * i)2063 upb_value upb_inttable_iter_value(const upb_inttable_iter *i) {
2064   UPB_ASSERT(!upb_inttable_done(i));
2065   return _upb_value_val(
2066       i->array_part ? i->t->array[i->index].val : int_tabent(i)->val.val);
2067 }
2068 
upb_inttable_iter_setdone(upb_inttable_iter * i)2069 void upb_inttable_iter_setdone(upb_inttable_iter *i) {
2070   i->t = NULL;
2071   i->index = SIZE_MAX;
2072   i->array_part = false;
2073 }
2074 
upb_inttable_iter_isequal(const upb_inttable_iter * i1,const upb_inttable_iter * i2)2075 bool upb_inttable_iter_isequal(const upb_inttable_iter *i1,
2076                                           const upb_inttable_iter *i2) {
2077   if (upb_inttable_done(i1) && upb_inttable_done(i2))
2078     return true;
2079   return i1->t == i2->t && i1->index == i2->index &&
2080          i1->array_part == i2->array_part;
2081 }
2082 
2083 #if defined(UPB_UNALIGNED_READS_OK) || defined(__s390x__)
2084 /* -----------------------------------------------------------------------------
2085  * MurmurHash2, by Austin Appleby (released as public domain).
2086  * Reformatted and C99-ified by Joshua Haberman.
2087  * Note - This code makes a few assumptions about how your machine behaves -
2088  *   1. We can read a 4-byte value from any address without crashing
2089  *   2. sizeof(int) == 4 (in upb this limitation is removed by using uint32_t
2090  * And it has a few limitations -
2091  *   1. It will not work incrementally.
2092  *   2. It will not produce the same results on little-endian and big-endian
2093  *      machines. */
upb_murmur_hash2(const void * key,size_t len,uint32_t seed)2094 uint32_t upb_murmur_hash2(const void *key, size_t len, uint32_t seed) {
2095   /* 'm' and 'r' are mixing constants generated offline.
2096    * They're not really 'magic', they just happen to work well. */
2097   const uint32_t m = 0x5bd1e995;
2098   const int32_t r = 24;
2099 
2100   /* Initialize the hash to a 'random' value */
2101   uint32_t h = seed ^ len;
2102 
2103   /* Mix 4 bytes at a time into the hash */
2104   const uint8_t * data = (const uint8_t *)key;
2105   while(len >= 4) {
2106     uint32_t k;
2107     memcpy(&k, data, sizeof(k));
2108 
2109     k *= m;
2110     k ^= k >> r;
2111     k *= m;
2112 
2113     h *= m;
2114     h ^= k;
2115 
2116     data += 4;
2117     len -= 4;
2118   }
2119 
2120   /* Handle the last few bytes of the input array */
2121   switch(len) {
2122     case 3: h ^= data[2] << 16;
2123     case 2: h ^= data[1] << 8;
2124     case 1: h ^= data[0]; h *= m;
2125   };
2126 
2127   /* Do a few final mixes of the hash to ensure the last few
2128    * bytes are well-incorporated. */
2129   h ^= h >> 13;
2130   h *= m;
2131   h ^= h >> 15;
2132 
2133   return h;
2134 }
2135 
2136 #else /* !UPB_UNALIGNED_READS_OK */
2137 
2138 /* -----------------------------------------------------------------------------
2139  * MurmurHashAligned2, by Austin Appleby
2140  * Same algorithm as MurmurHash2, but only does aligned reads - should be safer
2141  * on certain platforms.
2142  * Performance will be lower than MurmurHash2 */
2143 
2144 #define MIX(h,k,m) { k *= m; k ^= k >> r; k *= m; h *= m; h ^= k; }
2145 
upb_murmur_hash2(const void * key,size_t len,uint32_t seed)2146 uint32_t upb_murmur_hash2(const void * key, size_t len, uint32_t seed) {
2147   const uint32_t m = 0x5bd1e995;
2148   const int32_t r = 24;
2149   const uint8_t * data = (const uint8_t *)key;
2150   uint32_t h = (uint32_t)(seed ^ len);
2151   uint8_t align = (uintptr_t)data & 3;
2152 
2153   if(align && (len >= 4)) {
2154     /* Pre-load the temp registers */
2155     uint32_t t = 0, d = 0;
2156     int32_t sl;
2157     int32_t sr;
2158 
2159     switch(align) {
2160       case 1: t |= data[2] << 16;  /* fallthrough */
2161       case 2: t |= data[1] << 8;   /* fallthrough */
2162       case 3: t |= data[0];
2163     }
2164 
2165     t <<= (8 * align);
2166 
2167     data += 4-align;
2168     len -= 4-align;
2169 
2170     sl = 8 * (4-align);
2171     sr = 8 * align;
2172 
2173     /* Mix */
2174 
2175     while(len >= 4) {
2176       uint32_t k;
2177 
2178       d = *(uint32_t *)data;
2179       t = (t >> sr) | (d << sl);
2180 
2181       k = t;
2182 
2183       MIX(h,k,m);
2184 
2185       t = d;
2186 
2187       data += 4;
2188       len -= 4;
2189     }
2190 
2191     /* Handle leftover data in temp registers */
2192 
2193     d = 0;
2194 
2195     if(len >= align) {
2196       uint32_t k;
2197 
2198       switch(align) {
2199         case 3: d |= data[2] << 16;  /* fallthrough */
2200         case 2: d |= data[1] << 8;   /* fallthrough */
2201         case 1: d |= data[0];        /* fallthrough */
2202       }
2203 
2204       k = (t >> sr) | (d << sl);
2205       MIX(h,k,m);
2206 
2207       data += align;
2208       len -= align;
2209 
2210       /* ----------
2211        * Handle tail bytes */
2212 
2213       switch(len) {
2214         case 3: h ^= data[2] << 16;    /* fallthrough */
2215         case 2: h ^= data[1] << 8;     /* fallthrough */
2216         case 1: h ^= data[0]; h *= m;  /* fallthrough */
2217       };
2218     } else {
2219       switch(len) {
2220         case 3: d |= data[2] << 16;  /* fallthrough */
2221         case 2: d |= data[1] << 8;   /* fallthrough */
2222         case 1: d |= data[0];        /* fallthrough */
2223         case 0: h ^= (t >> sr) | (d << sl); h *= m;
2224       }
2225     }
2226 
2227     h ^= h >> 13;
2228     h *= m;
2229     h ^= h >> 15;
2230 
2231     return h;
2232   } else {
2233     while(len >= 4) {
2234       uint32_t k = *(uint32_t *)data;
2235 
2236       MIX(h,k,m);
2237 
2238       data += 4;
2239       len -= 4;
2240     }
2241 
2242     /* ----------
2243      * Handle tail bytes */
2244 
2245     switch(len) {
2246       case 3: h ^= data[2] << 16; /* fallthrough */
2247       case 2: h ^= data[1] << 8;  /* fallthrough */
2248       case 1: h ^= data[0]; h *= m;
2249     };
2250 
2251     h ^= h >> 13;
2252     h *= m;
2253     h ^= h >> 15;
2254 
2255     return h;
2256   }
2257 }
2258 #undef MIX
2259 
2260 #endif /* UPB_UNALIGNED_READS_OK */
2261 
2262 
2263 #include <errno.h>
2264 #include <stdarg.h>
2265 #include <stddef.h>
2266 #include <stdint.h>
2267 #include <stdio.h>
2268 #include <stdlib.h>
2269 #include <string.h>
2270 
2271 
2272 /* upb_status *****************************************************************/
2273 
upb_status_clear(upb_status * status)2274 void upb_status_clear(upb_status *status) {
2275   if (!status) return;
2276   status->ok = true;
2277   status->msg[0] = '\0';
2278 }
2279 
upb_ok(const upb_status * status)2280 bool upb_ok(const upb_status *status) { return status->ok; }
2281 
upb_status_errmsg(const upb_status * status)2282 const char *upb_status_errmsg(const upb_status *status) { return status->msg; }
2283 
upb_status_seterrmsg(upb_status * status,const char * msg)2284 void upb_status_seterrmsg(upb_status *status, const char *msg) {
2285   if (!status) return;
2286   status->ok = false;
2287   strncpy(status->msg, msg, UPB_STATUS_MAX_MESSAGE - 1);
2288   status->msg[UPB_STATUS_MAX_MESSAGE - 1] = '\0';
2289 }
2290 
upb_status_seterrf(upb_status * status,const char * fmt,...)2291 void upb_status_seterrf(upb_status *status, const char *fmt, ...) {
2292   va_list args;
2293   va_start(args, fmt);
2294   upb_status_vseterrf(status, fmt, args);
2295   va_end(args);
2296 }
2297 
upb_status_vseterrf(upb_status * status,const char * fmt,va_list args)2298 void upb_status_vseterrf(upb_status *status, const char *fmt, va_list args) {
2299   if (!status) return;
2300   status->ok = false;
2301   _upb_vsnprintf(status->msg, sizeof(status->msg), fmt, args);
2302   status->msg[UPB_STATUS_MAX_MESSAGE - 1] = '\0';
2303 }
2304 
upb_status_vappenderrf(upb_status * status,const char * fmt,va_list args)2305 void upb_status_vappenderrf(upb_status *status, const char *fmt, va_list args) {
2306   size_t len;
2307   if (!status) return;
2308   status->ok = false;
2309   len = strlen(status->msg);
2310   _upb_vsnprintf(status->msg + len, sizeof(status->msg) - len, fmt, args);
2311   status->msg[UPB_STATUS_MAX_MESSAGE - 1] = '\0';
2312 }
2313 
2314 /* upb_alloc ******************************************************************/
2315 
upb_global_allocfunc(upb_alloc * alloc,void * ptr,size_t oldsize,size_t size)2316 static void *upb_global_allocfunc(upb_alloc *alloc, void *ptr, size_t oldsize,
2317                                   size_t size) {
2318   UPB_UNUSED(alloc);
2319   UPB_UNUSED(oldsize);
2320   if (size == 0) {
2321     free(ptr);
2322     return NULL;
2323   } else {
2324     return realloc(ptr, size);
2325   }
2326 }
2327 
2328 upb_alloc upb_alloc_global = {&upb_global_allocfunc};
2329 
2330 /* upb_arena ******************************************************************/
2331 
2332 /* Be conservative and choose 16 in case anyone is using SSE. */
2333 
2334 typedef struct mem_block {
2335   struct mem_block *next;
2336   uint32_t size;
2337   uint32_t cleanups;
2338   /* Data follows. */
2339 } mem_block;
2340 
2341 typedef struct cleanup_ent {
2342   upb_cleanup_func *cleanup;
2343   void *ud;
2344 } cleanup_ent;
2345 
2346 struct upb_arena {
2347   _upb_arena_head head;
2348   uint32_t *cleanups;
2349 
2350   /* Allocator to allocate arena blocks.  We are responsible for freeing these
2351    * when we are destroyed. */
2352   upb_alloc *block_alloc;
2353   uint32_t last_size;
2354 
2355   /* When multiple arenas are fused together, each arena points to a parent
2356    * arena (root points to itself). The root tracks how many live arenas
2357    * reference it. */
2358   uint32_t refcount;  /* Only used when a->parent == a */
2359   struct upb_arena *parent;
2360 
2361   /* Linked list of blocks to free/cleanup. */
2362   mem_block *freelist, *freelist_tail;
2363 };
2364 
2365 static const size_t memblock_reserve = UPB_ALIGN_UP(sizeof(mem_block), 16);
2366 
arena_findroot(upb_arena * a)2367 static upb_arena *arena_findroot(upb_arena *a) {
2368   /* Path splitting keeps time complexity down, see:
2369    *   https://en.wikipedia.org/wiki/Disjoint-set_data_structure */
2370   while (a->parent != a) {
2371     upb_arena *next = a->parent;
2372     a->parent = next->parent;
2373     a = next;
2374   }
2375   return a;
2376 }
2377 
upb_arena_addblock(upb_arena * a,void * ptr,size_t size)2378 static void upb_arena_addblock(upb_arena *a, void *ptr, size_t size) {
2379   mem_block *block = ptr;
2380   upb_arena *root = arena_findroot(a);
2381 
2382   /* The block is for arena |a|, but should appear in the freelist of |root|. */
2383   block->next = root->freelist;
2384   block->size = (uint32_t)size;
2385   block->cleanups = 0;
2386   root->freelist = block;
2387   a->last_size = block->size;
2388   if (!root->freelist_tail) root->freelist_tail = block;
2389 
2390   a->head.ptr = UPB_PTR_AT(block, memblock_reserve, char);
2391   a->head.end = UPB_PTR_AT(block, size, char);
2392   a->cleanups = &block->cleanups;
2393 
2394   /* TODO(haberman): ASAN poison. */
2395 }
2396 
upb_arena_allocblock(upb_arena * a,size_t size)2397 static bool upb_arena_allocblock(upb_arena *a, size_t size) {
2398   size_t block_size = UPB_MAX(size, a->last_size * 2) + memblock_reserve;
2399   mem_block *block = upb_malloc(a->block_alloc, block_size);
2400 
2401   if (!block) return false;
2402   upb_arena_addblock(a, block, block_size);
2403   return true;
2404 }
2405 
arena_has(upb_arena * a,size_t size)2406 static bool arena_has(upb_arena *a, size_t size) {
2407   _upb_arena_head *h = (_upb_arena_head*)a;
2408   return (size_t)(h->end - h->ptr) >= size;
2409 }
2410 
_upb_arena_slowmalloc(upb_arena * a,size_t size)2411 void *_upb_arena_slowmalloc(upb_arena *a, size_t size) {
2412   if (!upb_arena_allocblock(a, size)) return NULL;  /* Out of memory. */
2413   UPB_ASSERT(arena_has(a, size));
2414   return upb_arena_malloc(a, size);
2415 }
2416 
upb_arena_doalloc(upb_alloc * alloc,void * ptr,size_t oldsize,size_t size)2417 static void *upb_arena_doalloc(upb_alloc *alloc, void *ptr, size_t oldsize,
2418                                size_t size) {
2419   upb_arena *a = (upb_arena*)alloc;  /* upb_alloc is initial member. */
2420   return upb_arena_realloc(a, ptr, oldsize, size);
2421 }
2422 
2423 /* Public Arena API ***********************************************************/
2424 
arena_initslow(void * mem,size_t n,upb_alloc * alloc)2425 upb_arena *arena_initslow(void *mem, size_t n, upb_alloc *alloc) {
2426   const size_t first_block_overhead = sizeof(upb_arena) + memblock_reserve;
2427   upb_arena *a;
2428 
2429   /* We need to malloc the initial block. */
2430   n = first_block_overhead + 256;
2431   if (!alloc || !(mem = upb_malloc(alloc, n))) {
2432     return NULL;
2433   }
2434 
2435   a = UPB_PTR_AT(mem, n - sizeof(*a), upb_arena);
2436   n -= sizeof(*a);
2437 
2438   a->head.alloc.func = &upb_arena_doalloc;
2439   a->block_alloc = alloc;
2440   a->parent = a;
2441   a->refcount = 1;
2442   a->freelist = NULL;
2443   a->freelist_tail = NULL;
2444 
2445   upb_arena_addblock(a, mem, n);
2446 
2447   return a;
2448 }
2449 
upb_arena_init(void * mem,size_t n,upb_alloc * alloc)2450 upb_arena *upb_arena_init(void *mem, size_t n, upb_alloc *alloc) {
2451   upb_arena *a;
2452 
2453   /* Round block size down to alignof(*a) since we will allocate the arena
2454    * itself at the end. */
2455   n = UPB_ALIGN_DOWN(n, UPB_ALIGN_OF(upb_arena));
2456 
2457   if (UPB_UNLIKELY(n < sizeof(upb_arena))) {
2458     return arena_initslow(mem, n, alloc);
2459   }
2460 
2461   a = UPB_PTR_AT(mem, n - sizeof(*a), upb_arena);
2462   n -= sizeof(*a);
2463 
2464   a->head.alloc.func = &upb_arena_doalloc;
2465   a->block_alloc = alloc;
2466   a->parent = a;
2467   a->refcount = 1;
2468   a->last_size = 128;
2469   a->head.ptr = mem;
2470   a->head.end = UPB_PTR_AT(mem, n, char);
2471   a->freelist = NULL;
2472   a->cleanups = NULL;
2473 
2474   return a;
2475 }
2476 
arena_dofree(upb_arena * a)2477 static void arena_dofree(upb_arena *a) {
2478   mem_block *block = a->freelist;
2479   UPB_ASSERT(a->parent == a);
2480   UPB_ASSERT(a->refcount == 0);
2481 
2482   while (block) {
2483     /* Load first since we are deleting block. */
2484     mem_block *next = block->next;
2485 
2486     if (block->cleanups > 0) {
2487       cleanup_ent *end = UPB_PTR_AT(block, block->size, void);
2488       cleanup_ent *ptr = end - block->cleanups;
2489 
2490       for (; ptr < end; ptr++) {
2491         ptr->cleanup(ptr->ud);
2492       }
2493     }
2494 
2495     upb_free(a->block_alloc, block);
2496     block = next;
2497   }
2498 }
2499 
upb_arena_free(upb_arena * a)2500 void upb_arena_free(upb_arena *a) {
2501   a = arena_findroot(a);
2502   if (--a->refcount == 0) arena_dofree(a);
2503 }
2504 
upb_arena_addcleanup(upb_arena * a,void * ud,upb_cleanup_func * func)2505 bool upb_arena_addcleanup(upb_arena *a, void *ud, upb_cleanup_func *func) {
2506   cleanup_ent *ent;
2507 
2508   if (!a->cleanups || !arena_has(a, sizeof(cleanup_ent))) {
2509     if (!upb_arena_allocblock(a, 128)) return false;  /* Out of memory. */
2510     UPB_ASSERT(arena_has(a, sizeof(cleanup_ent)));
2511   }
2512 
2513   a->head.end -= sizeof(cleanup_ent);
2514   ent = (cleanup_ent*)a->head.end;
2515   (*a->cleanups)++;
2516 
2517   ent->cleanup = func;
2518   ent->ud = ud;
2519 
2520   return true;
2521 }
2522 
upb_arena_fuse(upb_arena * a1,upb_arena * a2)2523 void upb_arena_fuse(upb_arena *a1, upb_arena *a2) {
2524   upb_arena *r1 = arena_findroot(a1);
2525   upb_arena *r2 = arena_findroot(a2);
2526 
2527   if (r1 == r2) return;  /* Already fused. */
2528 
2529   /* We want to join the smaller tree to the larger tree.
2530    * So swap first if they are backwards. */
2531   if (r1->refcount < r2->refcount) {
2532     upb_arena *tmp = r1;
2533     r1 = r2;
2534     r2 = tmp;
2535   }
2536 
2537   /* r1 takes over r2's freelist and refcount. */
2538   r1->refcount += r2->refcount;
2539   if (r2->freelist_tail) {
2540     UPB_ASSERT(r2->freelist_tail->next == NULL);
2541     r2->freelist_tail->next = r1->freelist;
2542     r1->freelist = r2->freelist;
2543   }
2544   r2->parent = r1;
2545 }
2546 /* This file was generated by upbc (the upb compiler) from the input
2547  * file:
2548  *
2549  *     google/protobuf/descriptor.proto
2550  *
2551  * Do not edit -- your changes will be discarded when the file is
2552  * regenerated. */
2553 
2554 #include <stddef.h>
2555 
2556 
2557 static const upb_msglayout *const google_protobuf_FileDescriptorSet_submsgs[1] = {
2558   &google_protobuf_FileDescriptorProto_msginit,
2559 };
2560 
2561 static const upb_msglayout_field google_protobuf_FileDescriptorSet__fields[1] = {
2562   {1, UPB_SIZE(0, 0), 0, 0, 11, 3},
2563 };
2564 
2565 const upb_msglayout google_protobuf_FileDescriptorSet_msginit = {
2566   &google_protobuf_FileDescriptorSet_submsgs[0],
2567   &google_protobuf_FileDescriptorSet__fields[0],
2568   UPB_SIZE(4, 8), 1, false,
2569 };
2570 
2571 static const upb_msglayout *const google_protobuf_FileDescriptorProto_submsgs[6] = {
2572   &google_protobuf_DescriptorProto_msginit,
2573   &google_protobuf_EnumDescriptorProto_msginit,
2574   &google_protobuf_FieldDescriptorProto_msginit,
2575   &google_protobuf_FileOptions_msginit,
2576   &google_protobuf_ServiceDescriptorProto_msginit,
2577   &google_protobuf_SourceCodeInfo_msginit,
2578 };
2579 
2580 static const upb_msglayout_field google_protobuf_FileDescriptorProto__fields[12] = {
2581   {1, UPB_SIZE(4, 8), 1, 0, 12, 1},
2582   {2, UPB_SIZE(12, 24), 2, 0, 12, 1},
2583   {3, UPB_SIZE(36, 72), 0, 0, 12, 3},
2584   {4, UPB_SIZE(40, 80), 0, 0, 11, 3},
2585   {5, UPB_SIZE(44, 88), 0, 1, 11, 3},
2586   {6, UPB_SIZE(48, 96), 0, 4, 11, 3},
2587   {7, UPB_SIZE(52, 104), 0, 2, 11, 3},
2588   {8, UPB_SIZE(28, 56), 4, 3, 11, 1},
2589   {9, UPB_SIZE(32, 64), 5, 5, 11, 1},
2590   {10, UPB_SIZE(56, 112), 0, 0, 5, 3},
2591   {11, UPB_SIZE(60, 120), 0, 0, 5, 3},
2592   {12, UPB_SIZE(20, 40), 3, 0, 12, 1},
2593 };
2594 
2595 const upb_msglayout google_protobuf_FileDescriptorProto_msginit = {
2596   &google_protobuf_FileDescriptorProto_submsgs[0],
2597   &google_protobuf_FileDescriptorProto__fields[0],
2598   UPB_SIZE(64, 128), 12, false,
2599 };
2600 
2601 static const upb_msglayout *const google_protobuf_DescriptorProto_submsgs[8] = {
2602   &google_protobuf_DescriptorProto_msginit,
2603   &google_protobuf_DescriptorProto_ExtensionRange_msginit,
2604   &google_protobuf_DescriptorProto_ReservedRange_msginit,
2605   &google_protobuf_EnumDescriptorProto_msginit,
2606   &google_protobuf_FieldDescriptorProto_msginit,
2607   &google_protobuf_MessageOptions_msginit,
2608   &google_protobuf_OneofDescriptorProto_msginit,
2609 };
2610 
2611 static const upb_msglayout_field google_protobuf_DescriptorProto__fields[10] = {
2612   {1, UPB_SIZE(4, 8), 1, 0, 12, 1},
2613   {2, UPB_SIZE(16, 32), 0, 4, 11, 3},
2614   {3, UPB_SIZE(20, 40), 0, 0, 11, 3},
2615   {4, UPB_SIZE(24, 48), 0, 3, 11, 3},
2616   {5, UPB_SIZE(28, 56), 0, 1, 11, 3},
2617   {6, UPB_SIZE(32, 64), 0, 4, 11, 3},
2618   {7, UPB_SIZE(12, 24), 2, 5, 11, 1},
2619   {8, UPB_SIZE(36, 72), 0, 6, 11, 3},
2620   {9, UPB_SIZE(40, 80), 0, 2, 11, 3},
2621   {10, UPB_SIZE(44, 88), 0, 0, 12, 3},
2622 };
2623 
2624 const upb_msglayout google_protobuf_DescriptorProto_msginit = {
2625   &google_protobuf_DescriptorProto_submsgs[0],
2626   &google_protobuf_DescriptorProto__fields[0],
2627   UPB_SIZE(48, 96), 10, false,
2628 };
2629 
2630 static const upb_msglayout *const google_protobuf_DescriptorProto_ExtensionRange_submsgs[1] = {
2631   &google_protobuf_ExtensionRangeOptions_msginit,
2632 };
2633 
2634 static const upb_msglayout_field google_protobuf_DescriptorProto_ExtensionRange__fields[3] = {
2635   {1, UPB_SIZE(4, 4), 1, 0, 5, 1},
2636   {2, UPB_SIZE(8, 8), 2, 0, 5, 1},
2637   {3, UPB_SIZE(12, 16), 3, 0, 11, 1},
2638 };
2639 
2640 const upb_msglayout google_protobuf_DescriptorProto_ExtensionRange_msginit = {
2641   &google_protobuf_DescriptorProto_ExtensionRange_submsgs[0],
2642   &google_protobuf_DescriptorProto_ExtensionRange__fields[0],
2643   UPB_SIZE(16, 24), 3, false,
2644 };
2645 
2646 static const upb_msglayout_field google_protobuf_DescriptorProto_ReservedRange__fields[2] = {
2647   {1, UPB_SIZE(4, 4), 1, 0, 5, 1},
2648   {2, UPB_SIZE(8, 8), 2, 0, 5, 1},
2649 };
2650 
2651 const upb_msglayout google_protobuf_DescriptorProto_ReservedRange_msginit = {
2652   NULL,
2653   &google_protobuf_DescriptorProto_ReservedRange__fields[0],
2654   UPB_SIZE(12, 12), 2, false,
2655 };
2656 
2657 static const upb_msglayout *const google_protobuf_ExtensionRangeOptions_submsgs[1] = {
2658   &google_protobuf_UninterpretedOption_msginit,
2659 };
2660 
2661 static const upb_msglayout_field google_protobuf_ExtensionRangeOptions__fields[1] = {
2662   {999, UPB_SIZE(0, 0), 0, 0, 11, 3},
2663 };
2664 
2665 const upb_msglayout google_protobuf_ExtensionRangeOptions_msginit = {
2666   &google_protobuf_ExtensionRangeOptions_submsgs[0],
2667   &google_protobuf_ExtensionRangeOptions__fields[0],
2668   UPB_SIZE(4, 8), 1, false,
2669 };
2670 
2671 static const upb_msglayout *const google_protobuf_FieldDescriptorProto_submsgs[1] = {
2672   &google_protobuf_FieldOptions_msginit,
2673 };
2674 
2675 static const upb_msglayout_field google_protobuf_FieldDescriptorProto__fields[11] = {
2676   {1, UPB_SIZE(36, 40), 6, 0, 12, 1},
2677   {2, UPB_SIZE(44, 56), 7, 0, 12, 1},
2678   {3, UPB_SIZE(24, 24), 3, 0, 5, 1},
2679   {4, UPB_SIZE(8, 8), 1, 0, 14, 1},
2680   {5, UPB_SIZE(16, 16), 2, 0, 14, 1},
2681   {6, UPB_SIZE(52, 72), 8, 0, 12, 1},
2682   {7, UPB_SIZE(60, 88), 9, 0, 12, 1},
2683   {8, UPB_SIZE(76, 120), 11, 0, 11, 1},
2684   {9, UPB_SIZE(28, 28), 4, 0, 5, 1},
2685   {10, UPB_SIZE(68, 104), 10, 0, 12, 1},
2686   {17, UPB_SIZE(32, 32), 5, 0, 8, 1},
2687 };
2688 
2689 const upb_msglayout google_protobuf_FieldDescriptorProto_msginit = {
2690   &google_protobuf_FieldDescriptorProto_submsgs[0],
2691   &google_protobuf_FieldDescriptorProto__fields[0],
2692   UPB_SIZE(80, 128), 11, false,
2693 };
2694 
2695 static const upb_msglayout *const google_protobuf_OneofDescriptorProto_submsgs[1] = {
2696   &google_protobuf_OneofOptions_msginit,
2697 };
2698 
2699 static const upb_msglayout_field google_protobuf_OneofDescriptorProto__fields[2] = {
2700   {1, UPB_SIZE(4, 8), 1, 0, 12, 1},
2701   {2, UPB_SIZE(12, 24), 2, 0, 11, 1},
2702 };
2703 
2704 const upb_msglayout google_protobuf_OneofDescriptorProto_msginit = {
2705   &google_protobuf_OneofDescriptorProto_submsgs[0],
2706   &google_protobuf_OneofDescriptorProto__fields[0],
2707   UPB_SIZE(16, 32), 2, false,
2708 };
2709 
2710 static const upb_msglayout *const google_protobuf_EnumDescriptorProto_submsgs[3] = {
2711   &google_protobuf_EnumDescriptorProto_EnumReservedRange_msginit,
2712   &google_protobuf_EnumOptions_msginit,
2713   &google_protobuf_EnumValueDescriptorProto_msginit,
2714 };
2715 
2716 static const upb_msglayout_field google_protobuf_EnumDescriptorProto__fields[5] = {
2717   {1, UPB_SIZE(4, 8), 1, 0, 12, 1},
2718   {2, UPB_SIZE(16, 32), 0, 2, 11, 3},
2719   {3, UPB_SIZE(12, 24), 2, 1, 11, 1},
2720   {4, UPB_SIZE(20, 40), 0, 0, 11, 3},
2721   {5, UPB_SIZE(24, 48), 0, 0, 12, 3},
2722 };
2723 
2724 const upb_msglayout google_protobuf_EnumDescriptorProto_msginit = {
2725   &google_protobuf_EnumDescriptorProto_submsgs[0],
2726   &google_protobuf_EnumDescriptorProto__fields[0],
2727   UPB_SIZE(32, 64), 5, false,
2728 };
2729 
2730 static const upb_msglayout_field google_protobuf_EnumDescriptorProto_EnumReservedRange__fields[2] = {
2731   {1, UPB_SIZE(4, 4), 1, 0, 5, 1},
2732   {2, UPB_SIZE(8, 8), 2, 0, 5, 1},
2733 };
2734 
2735 const upb_msglayout google_protobuf_EnumDescriptorProto_EnumReservedRange_msginit = {
2736   NULL,
2737   &google_protobuf_EnumDescriptorProto_EnumReservedRange__fields[0],
2738   UPB_SIZE(12, 12), 2, false,
2739 };
2740 
2741 static const upb_msglayout *const google_protobuf_EnumValueDescriptorProto_submsgs[1] = {
2742   &google_protobuf_EnumValueOptions_msginit,
2743 };
2744 
2745 static const upb_msglayout_field google_protobuf_EnumValueDescriptorProto__fields[3] = {
2746   {1, UPB_SIZE(8, 8), 2, 0, 12, 1},
2747   {2, UPB_SIZE(4, 4), 1, 0, 5, 1},
2748   {3, UPB_SIZE(16, 24), 3, 0, 11, 1},
2749 };
2750 
2751 const upb_msglayout google_protobuf_EnumValueDescriptorProto_msginit = {
2752   &google_protobuf_EnumValueDescriptorProto_submsgs[0],
2753   &google_protobuf_EnumValueDescriptorProto__fields[0],
2754   UPB_SIZE(24, 32), 3, false,
2755 };
2756 
2757 static const upb_msglayout *const google_protobuf_ServiceDescriptorProto_submsgs[2] = {
2758   &google_protobuf_MethodDescriptorProto_msginit,
2759   &google_protobuf_ServiceOptions_msginit,
2760 };
2761 
2762 static const upb_msglayout_field google_protobuf_ServiceDescriptorProto__fields[3] = {
2763   {1, UPB_SIZE(4, 8), 1, 0, 12, 1},
2764   {2, UPB_SIZE(16, 32), 0, 0, 11, 3},
2765   {3, UPB_SIZE(12, 24), 2, 1, 11, 1},
2766 };
2767 
2768 const upb_msglayout google_protobuf_ServiceDescriptorProto_msginit = {
2769   &google_protobuf_ServiceDescriptorProto_submsgs[0],
2770   &google_protobuf_ServiceDescriptorProto__fields[0],
2771   UPB_SIZE(24, 48), 3, false,
2772 };
2773 
2774 static const upb_msglayout *const google_protobuf_MethodDescriptorProto_submsgs[1] = {
2775   &google_protobuf_MethodOptions_msginit,
2776 };
2777 
2778 static const upb_msglayout_field google_protobuf_MethodDescriptorProto__fields[6] = {
2779   {1, UPB_SIZE(4, 8), 3, 0, 12, 1},
2780   {2, UPB_SIZE(12, 24), 4, 0, 12, 1},
2781   {3, UPB_SIZE(20, 40), 5, 0, 12, 1},
2782   {4, UPB_SIZE(28, 56), 6, 0, 11, 1},
2783   {5, UPB_SIZE(1, 1), 1, 0, 8, 1},
2784   {6, UPB_SIZE(2, 2), 2, 0, 8, 1},
2785 };
2786 
2787 const upb_msglayout google_protobuf_MethodDescriptorProto_msginit = {
2788   &google_protobuf_MethodDescriptorProto_submsgs[0],
2789   &google_protobuf_MethodDescriptorProto__fields[0],
2790   UPB_SIZE(32, 64), 6, false,
2791 };
2792 
2793 static const upb_msglayout *const google_protobuf_FileOptions_submsgs[1] = {
2794   &google_protobuf_UninterpretedOption_msginit,
2795 };
2796 
2797 static const upb_msglayout_field google_protobuf_FileOptions__fields[21] = {
2798   {1, UPB_SIZE(28, 32), 11, 0, 12, 1},
2799   {8, UPB_SIZE(36, 48), 12, 0, 12, 1},
2800   {9, UPB_SIZE(8, 8), 1, 0, 14, 1},
2801   {10, UPB_SIZE(16, 16), 2, 0, 8, 1},
2802   {11, UPB_SIZE(44, 64), 13, 0, 12, 1},
2803   {16, UPB_SIZE(17, 17), 3, 0, 8, 1},
2804   {17, UPB_SIZE(18, 18), 4, 0, 8, 1},
2805   {18, UPB_SIZE(19, 19), 5, 0, 8, 1},
2806   {20, UPB_SIZE(20, 20), 6, 0, 8, 1},
2807   {23, UPB_SIZE(21, 21), 7, 0, 8, 1},
2808   {27, UPB_SIZE(22, 22), 8, 0, 8, 1},
2809   {31, UPB_SIZE(23, 23), 9, 0, 8, 1},
2810   {36, UPB_SIZE(52, 80), 14, 0, 12, 1},
2811   {37, UPB_SIZE(60, 96), 15, 0, 12, 1},
2812   {39, UPB_SIZE(68, 112), 16, 0, 12, 1},
2813   {40, UPB_SIZE(76, 128), 17, 0, 12, 1},
2814   {41, UPB_SIZE(84, 144), 18, 0, 12, 1},
2815   {42, UPB_SIZE(24, 24), 10, 0, 8, 1},
2816   {44, UPB_SIZE(92, 160), 19, 0, 12, 1},
2817   {45, UPB_SIZE(100, 176), 20, 0, 12, 1},
2818   {999, UPB_SIZE(108, 192), 0, 0, 11, 3},
2819 };
2820 
2821 const upb_msglayout google_protobuf_FileOptions_msginit = {
2822   &google_protobuf_FileOptions_submsgs[0],
2823   &google_protobuf_FileOptions__fields[0],
2824   UPB_SIZE(112, 208), 21, false,
2825 };
2826 
2827 static const upb_msglayout *const google_protobuf_MessageOptions_submsgs[1] = {
2828   &google_protobuf_UninterpretedOption_msginit,
2829 };
2830 
2831 static const upb_msglayout_field google_protobuf_MessageOptions__fields[5] = {
2832   {1, UPB_SIZE(1, 1), 1, 0, 8, 1},
2833   {2, UPB_SIZE(2, 2), 2, 0, 8, 1},
2834   {3, UPB_SIZE(3, 3), 3, 0, 8, 1},
2835   {7, UPB_SIZE(4, 4), 4, 0, 8, 1},
2836   {999, UPB_SIZE(8, 8), 0, 0, 11, 3},
2837 };
2838 
2839 const upb_msglayout google_protobuf_MessageOptions_msginit = {
2840   &google_protobuf_MessageOptions_submsgs[0],
2841   &google_protobuf_MessageOptions__fields[0],
2842   UPB_SIZE(12, 16), 5, false,
2843 };
2844 
2845 static const upb_msglayout *const google_protobuf_FieldOptions_submsgs[1] = {
2846   &google_protobuf_UninterpretedOption_msginit,
2847 };
2848 
2849 static const upb_msglayout_field google_protobuf_FieldOptions__fields[7] = {
2850   {1, UPB_SIZE(8, 8), 1, 0, 14, 1},
2851   {2, UPB_SIZE(24, 24), 3, 0, 8, 1},
2852   {3, UPB_SIZE(25, 25), 4, 0, 8, 1},
2853   {5, UPB_SIZE(26, 26), 5, 0, 8, 1},
2854   {6, UPB_SIZE(16, 16), 2, 0, 14, 1},
2855   {10, UPB_SIZE(27, 27), 6, 0, 8, 1},
2856   {999, UPB_SIZE(28, 32), 0, 0, 11, 3},
2857 };
2858 
2859 const upb_msglayout google_protobuf_FieldOptions_msginit = {
2860   &google_protobuf_FieldOptions_submsgs[0],
2861   &google_protobuf_FieldOptions__fields[0],
2862   UPB_SIZE(32, 40), 7, false,
2863 };
2864 
2865 static const upb_msglayout *const google_protobuf_OneofOptions_submsgs[1] = {
2866   &google_protobuf_UninterpretedOption_msginit,
2867 };
2868 
2869 static const upb_msglayout_field google_protobuf_OneofOptions__fields[1] = {
2870   {999, UPB_SIZE(0, 0), 0, 0, 11, 3},
2871 };
2872 
2873 const upb_msglayout google_protobuf_OneofOptions_msginit = {
2874   &google_protobuf_OneofOptions_submsgs[0],
2875   &google_protobuf_OneofOptions__fields[0],
2876   UPB_SIZE(4, 8), 1, false,
2877 };
2878 
2879 static const upb_msglayout *const google_protobuf_EnumOptions_submsgs[1] = {
2880   &google_protobuf_UninterpretedOption_msginit,
2881 };
2882 
2883 static const upb_msglayout_field google_protobuf_EnumOptions__fields[3] = {
2884   {2, UPB_SIZE(1, 1), 1, 0, 8, 1},
2885   {3, UPB_SIZE(2, 2), 2, 0, 8, 1},
2886   {999, UPB_SIZE(4, 8), 0, 0, 11, 3},
2887 };
2888 
2889 const upb_msglayout google_protobuf_EnumOptions_msginit = {
2890   &google_protobuf_EnumOptions_submsgs[0],
2891   &google_protobuf_EnumOptions__fields[0],
2892   UPB_SIZE(8, 16), 3, false,
2893 };
2894 
2895 static const upb_msglayout *const google_protobuf_EnumValueOptions_submsgs[1] = {
2896   &google_protobuf_UninterpretedOption_msginit,
2897 };
2898 
2899 static const upb_msglayout_field google_protobuf_EnumValueOptions__fields[2] = {
2900   {1, UPB_SIZE(1, 1), 1, 0, 8, 1},
2901   {999, UPB_SIZE(4, 8), 0, 0, 11, 3},
2902 };
2903 
2904 const upb_msglayout google_protobuf_EnumValueOptions_msginit = {
2905   &google_protobuf_EnumValueOptions_submsgs[0],
2906   &google_protobuf_EnumValueOptions__fields[0],
2907   UPB_SIZE(8, 16), 2, false,
2908 };
2909 
2910 static const upb_msglayout *const google_protobuf_ServiceOptions_submsgs[1] = {
2911   &google_protobuf_UninterpretedOption_msginit,
2912 };
2913 
2914 static const upb_msglayout_field google_protobuf_ServiceOptions__fields[2] = {
2915   {33, UPB_SIZE(1, 1), 1, 0, 8, 1},
2916   {999, UPB_SIZE(4, 8), 0, 0, 11, 3},
2917 };
2918 
2919 const upb_msglayout google_protobuf_ServiceOptions_msginit = {
2920   &google_protobuf_ServiceOptions_submsgs[0],
2921   &google_protobuf_ServiceOptions__fields[0],
2922   UPB_SIZE(8, 16), 2, false,
2923 };
2924 
2925 static const upb_msglayout *const google_protobuf_MethodOptions_submsgs[1] = {
2926   &google_protobuf_UninterpretedOption_msginit,
2927 };
2928 
2929 static const upb_msglayout_field google_protobuf_MethodOptions__fields[3] = {
2930   {33, UPB_SIZE(16, 16), 2, 0, 8, 1},
2931   {34, UPB_SIZE(8, 8), 1, 0, 14, 1},
2932   {999, UPB_SIZE(20, 24), 0, 0, 11, 3},
2933 };
2934 
2935 const upb_msglayout google_protobuf_MethodOptions_msginit = {
2936   &google_protobuf_MethodOptions_submsgs[0],
2937   &google_protobuf_MethodOptions__fields[0],
2938   UPB_SIZE(24, 32), 3, false,
2939 };
2940 
2941 static const upb_msglayout *const google_protobuf_UninterpretedOption_submsgs[1] = {
2942   &google_protobuf_UninterpretedOption_NamePart_msginit,
2943 };
2944 
2945 static const upb_msglayout_field google_protobuf_UninterpretedOption__fields[7] = {
2946   {2, UPB_SIZE(56, 80), 0, 0, 11, 3},
2947   {3, UPB_SIZE(32, 32), 4, 0, 12, 1},
2948   {4, UPB_SIZE(8, 8), 1, 0, 4, 1},
2949   {5, UPB_SIZE(16, 16), 2, 0, 3, 1},
2950   {6, UPB_SIZE(24, 24), 3, 0, 1, 1},
2951   {7, UPB_SIZE(40, 48), 5, 0, 12, 1},
2952   {8, UPB_SIZE(48, 64), 6, 0, 12, 1},
2953 };
2954 
2955 const upb_msglayout google_protobuf_UninterpretedOption_msginit = {
2956   &google_protobuf_UninterpretedOption_submsgs[0],
2957   &google_protobuf_UninterpretedOption__fields[0],
2958   UPB_SIZE(64, 96), 7, false,
2959 };
2960 
2961 static const upb_msglayout_field google_protobuf_UninterpretedOption_NamePart__fields[2] = {
2962   {1, UPB_SIZE(4, 8), 2, 0, 12, 2},
2963   {2, UPB_SIZE(1, 1), 1, 0, 8, 2},
2964 };
2965 
2966 const upb_msglayout google_protobuf_UninterpretedOption_NamePart_msginit = {
2967   NULL,
2968   &google_protobuf_UninterpretedOption_NamePart__fields[0],
2969   UPB_SIZE(16, 32), 2, false,
2970 };
2971 
2972 static const upb_msglayout *const google_protobuf_SourceCodeInfo_submsgs[1] = {
2973   &google_protobuf_SourceCodeInfo_Location_msginit,
2974 };
2975 
2976 static const upb_msglayout_field google_protobuf_SourceCodeInfo__fields[1] = {
2977   {1, UPB_SIZE(0, 0), 0, 0, 11, 3},
2978 };
2979 
2980 const upb_msglayout google_protobuf_SourceCodeInfo_msginit = {
2981   &google_protobuf_SourceCodeInfo_submsgs[0],
2982   &google_protobuf_SourceCodeInfo__fields[0],
2983   UPB_SIZE(4, 8), 1, false,
2984 };
2985 
2986 static const upb_msglayout_field google_protobuf_SourceCodeInfo_Location__fields[5] = {
2987   {1, UPB_SIZE(20, 40), 0, 0, 5, _UPB_LABEL_PACKED},
2988   {2, UPB_SIZE(24, 48), 0, 0, 5, _UPB_LABEL_PACKED},
2989   {3, UPB_SIZE(4, 8), 1, 0, 12, 1},
2990   {4, UPB_SIZE(12, 24), 2, 0, 12, 1},
2991   {6, UPB_SIZE(28, 56), 0, 0, 12, 3},
2992 };
2993 
2994 const upb_msglayout google_protobuf_SourceCodeInfo_Location_msginit = {
2995   NULL,
2996   &google_protobuf_SourceCodeInfo_Location__fields[0],
2997   UPB_SIZE(32, 64), 5, false,
2998 };
2999 
3000 static const upb_msglayout *const google_protobuf_GeneratedCodeInfo_submsgs[1] = {
3001   &google_protobuf_GeneratedCodeInfo_Annotation_msginit,
3002 };
3003 
3004 static const upb_msglayout_field google_protobuf_GeneratedCodeInfo__fields[1] = {
3005   {1, UPB_SIZE(0, 0), 0, 0, 11, 3},
3006 };
3007 
3008 const upb_msglayout google_protobuf_GeneratedCodeInfo_msginit = {
3009   &google_protobuf_GeneratedCodeInfo_submsgs[0],
3010   &google_protobuf_GeneratedCodeInfo__fields[0],
3011   UPB_SIZE(4, 8), 1, false,
3012 };
3013 
3014 static const upb_msglayout_field google_protobuf_GeneratedCodeInfo_Annotation__fields[4] = {
3015   {1, UPB_SIZE(20, 32), 0, 0, 5, _UPB_LABEL_PACKED},
3016   {2, UPB_SIZE(12, 16), 3, 0, 12, 1},
3017   {3, UPB_SIZE(4, 4), 1, 0, 5, 1},
3018   {4, UPB_SIZE(8, 8), 2, 0, 5, 1},
3019 };
3020 
3021 const upb_msglayout google_protobuf_GeneratedCodeInfo_Annotation_msginit = {
3022   NULL,
3023   &google_protobuf_GeneratedCodeInfo_Annotation__fields[0],
3024   UPB_SIZE(24, 48), 4, false,
3025 };
3026 
3027 
3028 /* This file was generated by upbc (the upb compiler) from the input
3029  * file:
3030  *
3031  *     google/protobuf/descriptor.proto
3032  *
3033  * Do not edit -- your changes will be discarded when the file is
3034  * regenerated. */
3035 
3036 
3037 extern const upb_msglayout google_protobuf_FileDescriptorSet_msginit;
3038 extern const upb_msglayout google_protobuf_FileDescriptorProto_msginit;
3039 extern const upb_msglayout google_protobuf_DescriptorProto_msginit;
3040 extern const upb_msglayout google_protobuf_DescriptorProto_ExtensionRange_msginit;
3041 extern const upb_msglayout google_protobuf_DescriptorProto_ReservedRange_msginit;
3042 extern const upb_msglayout google_protobuf_ExtensionRangeOptions_msginit;
3043 extern const upb_msglayout google_protobuf_FieldDescriptorProto_msginit;
3044 extern const upb_msglayout google_protobuf_OneofDescriptorProto_msginit;
3045 extern const upb_msglayout google_protobuf_EnumDescriptorProto_msginit;
3046 extern const upb_msglayout google_protobuf_EnumDescriptorProto_EnumReservedRange_msginit;
3047 extern const upb_msglayout google_protobuf_EnumValueDescriptorProto_msginit;
3048 extern const upb_msglayout google_protobuf_ServiceDescriptorProto_msginit;
3049 extern const upb_msglayout google_protobuf_MethodDescriptorProto_msginit;
3050 extern const upb_msglayout google_protobuf_FileOptions_msginit;
3051 extern const upb_msglayout google_protobuf_MessageOptions_msginit;
3052 extern const upb_msglayout google_protobuf_FieldOptions_msginit;
3053 extern const upb_msglayout google_protobuf_OneofOptions_msginit;
3054 extern const upb_msglayout google_protobuf_EnumOptions_msginit;
3055 extern const upb_msglayout google_protobuf_EnumValueOptions_msginit;
3056 extern const upb_msglayout google_protobuf_ServiceOptions_msginit;
3057 extern const upb_msglayout google_protobuf_MethodOptions_msginit;
3058 extern const upb_msglayout google_protobuf_UninterpretedOption_msginit;
3059 extern const upb_msglayout google_protobuf_UninterpretedOption_NamePart_msginit;
3060 extern const upb_msglayout google_protobuf_SourceCodeInfo_msginit;
3061 extern const upb_msglayout google_protobuf_SourceCodeInfo_Location_msginit;
3062 extern const upb_msglayout google_protobuf_GeneratedCodeInfo_msginit;
3063 extern const upb_msglayout google_protobuf_GeneratedCodeInfo_Annotation_msginit;
3064 
3065 static const upb_msglayout *layouts[27] = {
3066   &google_protobuf_FileDescriptorSet_msginit,
3067   &google_protobuf_FileDescriptorProto_msginit,
3068   &google_protobuf_DescriptorProto_msginit,
3069   &google_protobuf_DescriptorProto_ExtensionRange_msginit,
3070   &google_protobuf_DescriptorProto_ReservedRange_msginit,
3071   &google_protobuf_ExtensionRangeOptions_msginit,
3072   &google_protobuf_FieldDescriptorProto_msginit,
3073   &google_protobuf_OneofDescriptorProto_msginit,
3074   &google_protobuf_EnumDescriptorProto_msginit,
3075   &google_protobuf_EnumDescriptorProto_EnumReservedRange_msginit,
3076   &google_protobuf_EnumValueDescriptorProto_msginit,
3077   &google_protobuf_ServiceDescriptorProto_msginit,
3078   &google_protobuf_MethodDescriptorProto_msginit,
3079   &google_protobuf_FileOptions_msginit,
3080   &google_protobuf_MessageOptions_msginit,
3081   &google_protobuf_FieldOptions_msginit,
3082   &google_protobuf_OneofOptions_msginit,
3083   &google_protobuf_EnumOptions_msginit,
3084   &google_protobuf_EnumValueOptions_msginit,
3085   &google_protobuf_ServiceOptions_msginit,
3086   &google_protobuf_MethodOptions_msginit,
3087   &google_protobuf_UninterpretedOption_msginit,
3088   &google_protobuf_UninterpretedOption_NamePart_msginit,
3089   &google_protobuf_SourceCodeInfo_msginit,
3090   &google_protobuf_SourceCodeInfo_Location_msginit,
3091   &google_protobuf_GeneratedCodeInfo_msginit,
3092   &google_protobuf_GeneratedCodeInfo_Annotation_msginit,
3093 };
3094 
3095 static const char descriptor[7619] = {'\n', ' ', 'g', 'o', 'o', 'g', 'l', 'e', '/', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '/', 'd', 'e', 's', 'c', 'r', 'i', 'p',
3096 't', 'o', 'r', '.', 'p', 'r', 'o', 't', 'o', '\022', '\017', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u',
3097 'f', '\"', 'M', '\n', '\021', 'F', 'i', 'l', 'e', 'D', 'e', 's', 'c', 'r', 'i', 'p', 't', 'o', 'r', 'S', 'e', 't', '\022', '8', '\n',
3098 '\004', 'f', 'i', 'l', 'e', '\030', '\001', ' ', '\003', '(', '\013', '2', '$', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't',
3099 'o', 'b', 'u', 'f', '.', 'F', 'i', 'l', 'e', 'D', 'e', 's', 'c', 'r', 'i', 'p', 't', 'o', 'r', 'P', 'r', 'o', 't', 'o', 'R',
3100 '\004', 'f', 'i', 'l', 'e', '\"', '\344', '\004', '\n', '\023', 'F', 'i', 'l', 'e', 'D', 'e', 's', 'c', 'r', 'i', 'p', 't', 'o', 'r', 'P',
3101 'r', 'o', 't', 'o', '\022', '\022', '\n', '\004', 'n', 'a', 'm', 'e', '\030', '\001', ' ', '\001', '(', '\t', 'R', '\004', 'n', 'a', 'm', 'e', '\022',
3102 '\030', '\n', '\007', 'p', 'a', 'c', 'k', 'a', 'g', 'e', '\030', '\002', ' ', '\001', '(', '\t', 'R', '\007', 'p', 'a', 'c', 'k', 'a', 'g', 'e',
3103 '\022', '\036', '\n', '\n', 'd', 'e', 'p', 'e', 'n', 'd', 'e', 'n', 'c', 'y', '\030', '\003', ' ', '\003', '(', '\t', 'R', '\n', 'd', 'e', 'p',
3104 'e', 'n', 'd', 'e', 'n', 'c', 'y', '\022', '+', '\n', '\021', 'p', 'u', 'b', 'l', 'i', 'c', '_', 'd', 'e', 'p', 'e', 'n', 'd', 'e',
3105 'n', 'c', 'y', '\030', '\n', ' ', '\003', '(', '\005', 'R', '\020', 'p', 'u', 'b', 'l', 'i', 'c', 'D', 'e', 'p', 'e', 'n', 'd', 'e', 'n',
3106 'c', 'y', '\022', '\'', '\n', '\017', 'w', 'e', 'a', 'k', '_', 'd', 'e', 'p', 'e', 'n', 'd', 'e', 'n', 'c', 'y', '\030', '\013', ' ', '\003',
3107 '(', '\005', 'R', '\016', 'w', 'e', 'a', 'k', 'D', 'e', 'p', 'e', 'n', 'd', 'e', 'n', 'c', 'y', '\022', 'C', '\n', '\014', 'm', 'e', 's',
3108 's', 'a', 'g', 'e', '_', 't', 'y', 'p', 'e', '\030', '\004', ' ', '\003', '(', '\013', '2', ' ', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.',
3109 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'D', 'e', 's', 'c', 'r', 'i', 'p', 't', 'o', 'r', 'P', 'r', 'o', 't', 'o', 'R',
3110 '\013', 'm', 'e', 's', 's', 'a', 'g', 'e', 'T', 'y', 'p', 'e', '\022', 'A', '\n', '\t', 'e', 'n', 'u', 'm', '_', 't', 'y', 'p', 'e',
3111 '\030', '\005', ' ', '\003', '(', '\013', '2', '$', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.',
3112 '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',
3113 'T', 'y', 'p', 'e', '\022', 'A', '\n', '\007', 's', 'e', 'r', 'v', 'i', 'c', 'e', '\030', '\006', ' ', '\003', '(', '\013', '2', '\'', '.', 'g',
3114 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'S', 'e', 'r', 'v', 'i', 'c', 'e', 'D', 'e', 's',
3115 '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',
3116 'e', 'x', 't', 'e', 'n', 's', 'i', 'o', 'n', '\030', '\007', ' ', '\003', '(', '\013', '2', '%', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.',
3117 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'F', 'i', 'e', 'l', 'd', 'D', 'e', 's', 'c', 'r', 'i', 'p', 't', 'o', 'r', 'P',
3118 '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',
3119 's', '\030', '\010', ' ', '\001', '(', '\013', '2', '\034', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f',
3120 '.', 'F', 'i', 'l', 'e', 'O', 'p', 't', 'i', 'o', 'n', 's', 'R', '\007', 'o', 'p', 't', 'i', 'o', 'n', 's', '\022', 'I', '\n', '\020',
3121 's', 'o', 'u', 'r', 'c', 'e', '_', 'c', 'o', 'd', 'e', '_', 'i', 'n', 'f', 'o', '\030', '\t', ' ', '\001', '(', '\013', '2', '\037', '.',
3122 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'S', 'o', 'u', 'r', 'c', 'e', 'C', 'o', 'd',
3123 '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',
3124 's', 'y', 'n', 't', 'a', 'x', '\030', '\014', ' ', '\001', '(', '\t', 'R', '\006', 's', 'y', 'n', 't', 'a', 'x', '\"', '\271', '\006', '\n', '\017',
3125 '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',
3126 ' ', '\001', '(', '\t', 'R', '\004', 'n', 'a', 'm', 'e', '\022', ';', '\n', '\005', 'f', 'i', 'e', 'l', 'd', '\030', '\002', ' ', '\003', '(', '\013',
3127 '2', '%', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'F', 'i', 'e', 'l', 'd', 'D',
3128 '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',
3129 'e', 'x', 't', 'e', 'n', 's', 'i', 'o', 'n', '\030', '\006', ' ', '\003', '(', '\013', '2', '%', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.',
3130 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'F', 'i', 'e', 'l', 'd', 'D', 'e', 's', 'c', 'r', 'i', 'p', 't', 'o', 'r', 'P',
3131 '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',
3132 '_', 't', 'y', 'p', 'e', '\030', '\003', ' ', '\003', '(', '\013', '2', ' ', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't',
3133 'o', 'b', 'u', 'f', '.', 'D', 'e', 's', 'c', 'r', 'i', 'p', 't', 'o', 'r', 'P', 'r', 'o', 't', 'o', 'R', '\n', 'n', 'e', 's',
3134 't', 'e', 'd', 'T', 'y', 'p', 'e', '\022', 'A', '\n', '\t', 'e', 'n', 'u', 'm', '_', 't', 'y', 'p', 'e', '\030', '\004', ' ', '\003', '(',
3135 '\013', '2', '$', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'E', 'n', 'u', 'm', 'D',
3136 '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',
3137 'X', '\n', '\017', 'e', 'x', 't', 'e', 'n', 's', 'i', 'o', 'n', '_', 'r', 'a', 'n', 'g', 'e', '\030', '\005', ' ', '\003', '(', '\013', '2',
3138 '/', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'D', 'e', 's', 'c', 'r', 'i', 'p',
3139 't', 'o', 'r', 'P', 'r', 'o', 't', 'o', '.', 'E', 'x', 't', 'e', 'n', 's', 'i', 'o', 'n', 'R', 'a', 'n', 'g', 'e', 'R', '\016',
3140 'e', 'x', 't', 'e', 'n', 's', 'i', 'o', 'n', 'R', 'a', 'n', 'g', 'e', '\022', 'D', '\n', '\n', 'o', 'n', 'e', 'o', 'f', '_', 'd',
3141 'e', 'c', 'l', '\030', '\010', ' ', '\003', '(', '\013', '2', '%', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b',
3142 'u', 'f', '.', 'O', 'n', 'e', 'o', 'f', 'D', 'e', 's', 'c', 'r', 'i', 'p', 't', 'o', 'r', 'P', 'r', 'o', 't', 'o', 'R', '\t',
3143 'o', 'n', 'e', 'o', 'f', 'D', 'e', 'c', 'l', '\022', '9', '\n', '\007', 'o', 'p', 't', 'i', 'o', 'n', 's', '\030', '\007', ' ', '\001', '(',
3144 '\013', '2', '\037', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'M', 'e', 's', 's', 'a',
3145 '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',
3146 'e', 'r', 'v', 'e', 'd', '_', 'r', 'a', 'n', 'g', 'e', '\030', '\t', ' ', '\003', '(', '\013', '2', '.', '.', 'g', 'o', 'o', 'g', 'l',
3147 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'D', 'e', 's', 'c', 'r', 'i', 'p', 't', 'o', 'r', 'P', 'r', 'o', 't',
3148 'o', '.', 'R', 'e', 's', 'e', 'r', 'v', 'e', 'd', 'R', 'a', 'n', 'g', 'e', 'R', '\r', 'r', 'e', 's', 'e', 'r', 'v', 'e', 'd',
3149 'R', 'a', 'n', 'g', 'e', '\022', '#', '\n', '\r', 'r', 'e', 's', 'e', 'r', 'v', 'e', 'd', '_', 'n', 'a', 'm', 'e', '\030', '\n', ' ',
3150 '\003', '(', '\t', 'R', '\014', 'r', 'e', 's', 'e', 'r', 'v', 'e', 'd', 'N', 'a', 'm', 'e', '\032', 'z', '\n', '\016', 'E', 'x', 't', 'e',
3151 'n', 's', 'i', 'o', 'n', 'R', 'a', 'n', 'g', 'e', '\022', '\024', '\n', '\005', 's', 't', 'a', 'r', 't', '\030', '\001', ' ', '\001', '(', '\005',
3152 'R', '\005', 's', 't', 'a', 'r', 't', '\022', '\020', '\n', '\003', 'e', 'n', 'd', '\030', '\002', ' ', '\001', '(', '\005', 'R', '\003', 'e', 'n', 'd',
3153 '\022', '@', '\n', '\007', 'o', 'p', 't', 'i', 'o', 'n', 's', '\030', '\003', ' ', '\001', '(', '\013', '2', '&', '.', 'g', 'o', 'o', 'g', 'l',
3154 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'E', 'x', 't', 'e', 'n', 's', 'i', 'o', 'n', 'R', 'a', 'n', 'g', 'e',
3155 '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',
3156 'v', 'e', 'd', 'R', 'a', 'n', 'g', 'e', '\022', '\024', '\n', '\005', 's', 't', 'a', 'r', 't', '\030', '\001', ' ', '\001', '(', '\005', 'R', '\005',
3157 's', 't', 'a', 'r', 't', '\022', '\020', '\n', '\003', 'e', 'n', 'd', '\030', '\002', ' ', '\001', '(', '\005', 'R', '\003', 'e', 'n', 'd', '\"', '|',
3158 '\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',
3159 '\n', '\024', 'u', 'n', 'i', 'n', 't', 'e', 'r', 'p', 'r', 'e', 't', 'e', 'd', '_', 'o', 'p', 't', 'i', 'o', 'n', '\030', '\347', '\007',
3160 ' ', '\003', '(', '\013', '2', '$', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'U', 'n',
3161 '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',
3162 'r', 'p', 'r', 'e', 't', 'e', 'd', 'O', 'p', 't', 'i', 'o', 'n', '*', '\t', '\010', '\350', '\007', '\020', '\200', '\200', '\200', '\200', '\002', '\"',
3163 '\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',
3164 '\022', '\n', '\004', 'n', 'a', 'm', 'e', '\030', '\001', ' ', '\001', '(', '\t', 'R', '\004', 'n', 'a', 'm', 'e', '\022', '\026', '\n', '\006', 'n', 'u',
3165 'm', 'b', 'e', 'r', '\030', '\003', ' ', '\001', '(', '\005', 'R', '\006', 'n', 'u', 'm', 'b', 'e', 'r', '\022', 'A', '\n', '\005', 'l', 'a', 'b',
3166 'e', 'l', '\030', '\004', ' ', '\001', '(', '\016', '2', '+', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u',
3167 'f', '.', 'F', 'i', 'e', 'l', 'd', 'D', 'e', 's', 'c', 'r', 'i', 'p', 't', 'o', 'r', 'P', 'r', 'o', 't', 'o', '.', 'L', 'a',
3168 'b', 'e', 'l', 'R', '\005', 'l', 'a', 'b', 'e', 'l', '\022', '>', '\n', '\004', 't', 'y', 'p', 'e', '\030', '\005', ' ', '\001', '(', '\016', '2',
3169 '*', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'F', 'i', 'e', 'l', 'd', 'D', 'e',
3170 's', 'c', 'r', 'i', 'p', 't', 'o', 'r', 'P', 'r', 'o', 't', 'o', '.', 'T', 'y', 'p', 'e', 'R', '\004', 't', 'y', 'p', 'e', '\022',
3171 '\033', '\n', '\t', 't', 'y', 'p', 'e', '_', 'n', 'a', 'm', 'e', '\030', '\006', ' ', '\001', '(', '\t', 'R', '\010', 't', 'y', 'p', 'e', 'N',
3172 'a', 'm', 'e', '\022', '\032', '\n', '\010', 'e', 'x', 't', 'e', 'n', 'd', 'e', 'e', '\030', '\002', ' ', '\001', '(', '\t', 'R', '\010', 'e', 'x',
3173 't', 'e', 'n', 'd', 'e', 'e', '\022', '#', '\n', '\r', 'd', 'e', 'f', 'a', 'u', 'l', 't', '_', 'v', 'a', 'l', 'u', 'e', '\030', '\007',
3174 ' ', '\001', '(', '\t', 'R', '\014', 'd', 'e', 'f', 'a', 'u', 'l', 't', 'V', 'a', 'l', 'u', 'e', '\022', '\037', '\n', '\013', 'o', 'n', 'e',
3175 'o', 'f', '_', 'i', 'n', 'd', 'e', 'x', '\030', '\t', ' ', '\001', '(', '\005', 'R', '\n', 'o', 'n', 'e', 'o', 'f', 'I', 'n', 'd', 'e',
3176 'x', '\022', '\033', '\n', '\t', 'j', 's', 'o', 'n', '_', 'n', 'a', 'm', 'e', '\030', '\n', ' ', '\001', '(', '\t', 'R', '\010', 'j', 's', 'o',
3177 'n', 'N', 'a', 'm', 'e', '\022', '7', '\n', '\007', 'o', 'p', 't', 'i', 'o', 'n', 's', '\030', '\010', ' ', '\001', '(', '\013', '2', '\035', '.',
3178 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'F', 'i', 'e', 'l', 'd', 'O', 'p', 't', 'i',
3179 'o', 'n', 's', 'R', '\007', 'o', 'p', 't', 'i', 'o', 'n', 's', '\022', '\'', '\n', '\017', 'p', 'r', 'o', 't', 'o', '3', '_', 'o', 'p',
3180 't', 'i', 'o', 'n', 'a', 'l', '\030', '\021', ' ', '\001', '(', '\010', 'R', '\016', 'p', 'r', 'o', 't', 'o', '3', 'O', 'p', 't', 'i', 'o',
3181 'n', 'a', 'l', '\"', '\266', '\002', '\n', '\004', 'T', 'y', 'p', 'e', '\022', '\017', '\n', '\013', 'T', 'Y', 'P', 'E', '_', 'D', 'O', 'U', 'B',
3182 'L', 'E', '\020', '\001', '\022', '\016', '\n', '\n', 'T', 'Y', 'P', 'E', '_', 'F', 'L', 'O', 'A', 'T', '\020', '\002', '\022', '\016', '\n', '\n', 'T',
3183 'Y', 'P', 'E', '_', 'I', 'N', 'T', '6', '4', '\020', '\003', '\022', '\017', '\n', '\013', 'T', 'Y', 'P', 'E', '_', 'U', 'I', 'N', 'T', '6',
3184 '4', '\020', '\004', '\022', '\016', '\n', '\n', 'T', 'Y', 'P', 'E', '_', 'I', 'N', 'T', '3', '2', '\020', '\005', '\022', '\020', '\n', '\014', 'T', 'Y',
3185 'P', 'E', '_', 'F', 'I', 'X', 'E', 'D', '6', '4', '\020', '\006', '\022', '\020', '\n', '\014', 'T', 'Y', 'P', 'E', '_', 'F', 'I', 'X', 'E',
3186 'D', '3', '2', '\020', '\007', '\022', '\r', '\n', '\t', 'T', 'Y', 'P', 'E', '_', 'B', 'O', 'O', 'L', '\020', '\010', '\022', '\017', '\n', '\013', 'T',
3187 'Y', 'P', 'E', '_', 'S', 'T', 'R', 'I', 'N', 'G', '\020', '\t', '\022', '\016', '\n', '\n', 'T', 'Y', 'P', 'E', '_', 'G', 'R', 'O', 'U',
3188 'P', '\020', '\n', '\022', '\020', '\n', '\014', 'T', 'Y', 'P', 'E', '_', 'M', 'E', 'S', 'S', 'A', 'G', 'E', '\020', '\013', '\022', '\016', '\n', '\n',
3189 'T', 'Y', 'P', 'E', '_', 'B', 'Y', 'T', 'E', 'S', '\020', '\014', '\022', '\017', '\n', '\013', 'T', 'Y', 'P', 'E', '_', 'U', 'I', 'N', 'T',
3190 '3', '2', '\020', '\r', '\022', '\r', '\n', '\t', 'T', 'Y', 'P', 'E', '_', 'E', 'N', 'U', 'M', '\020', '\016', '\022', '\021', '\n', '\r', 'T', 'Y',
3191 'P', 'E', '_', 'S', 'F', 'I', 'X', 'E', 'D', '3', '2', '\020', '\017', '\022', '\021', '\n', '\r', 'T', 'Y', 'P', 'E', '_', 'S', 'F', 'I',
3192 'X', 'E', 'D', '6', '4', '\020', '\020', '\022', '\017', '\n', '\013', 'T', 'Y', 'P', 'E', '_', 'S', 'I', 'N', 'T', '3', '2', '\020', '\021', '\022',
3193 '\017', '\n', '\013', 'T', 'Y', 'P', 'E', '_', 'S', 'I', 'N', 'T', '6', '4', '\020', '\022', '\"', 'C', '\n', '\005', 'L', 'a', 'b', 'e', 'l',
3194 '\022', '\022', '\n', '\016', 'L', 'A', 'B', 'E', 'L', '_', 'O', 'P', 'T', 'I', 'O', 'N', 'A', 'L', '\020', '\001', '\022', '\022', '\n', '\016', 'L',
3195 'A', 'B', 'E', 'L', '_', 'R', 'E', 'Q', 'U', 'I', 'R', 'E', 'D', '\020', '\002', '\022', '\022', '\n', '\016', 'L', 'A', 'B', 'E', 'L', '_',
3196 'R', 'E', 'P', 'E', 'A', 'T', 'E', 'D', '\020', '\003', '\"', 'c', '\n', '\024', 'O', 'n', 'e', 'o', 'f', 'D', 'e', 's', 'c', 'r', 'i',
3197 'p', 't', 'o', 'r', 'P', 'r', 'o', 't', 'o', '\022', '\022', '\n', '\004', 'n', 'a', 'm', 'e', '\030', '\001', ' ', '\001', '(', '\t', 'R', '\004',
3198 'n', 'a', 'm', 'e', '\022', '7', '\n', '\007', 'o', 'p', 't', 'i', 'o', 'n', 's', '\030', '\002', ' ', '\001', '(', '\013', '2', '\035', '.', 'g',
3199 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'O', 'n', 'e', 'o', 'f', 'O', 'p', 't', 'i', 'o',
3200 'n', 's', 'R', '\007', 'o', 'p', 't', 'i', 'o', 'n', 's', '\"', '\343', '\002', '\n', '\023', 'E', 'n', 'u', 'm', 'D', 'e', 's', 'c', 'r',
3201 'i', 'p', 't', 'o', 'r', 'P', 'r', 'o', 't', 'o', '\022', '\022', '\n', '\004', 'n', 'a', 'm', 'e', '\030', '\001', ' ', '\001', '(', '\t', 'R',
3202 '\004', 'n', 'a', 'm', 'e', '\022', '?', '\n', '\005', 'v', 'a', 'l', 'u', 'e', '\030', '\002', ' ', '\003', '(', '\013', '2', ')', '.', 'g', 'o',
3203 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'E', 'n', 'u', 'm', 'V', 'a', 'l', 'u', 'e', 'D', 'e',
3204 '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',
3205 'p', 't', 'i', 'o', 'n', 's', '\030', '\003', ' ', '\001', '(', '\013', '2', '\034', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o',
3206 't', 'o', 'b', 'u', 'f', '.', 'E', 'n', 'u', 'm', 'O', 'p', 't', 'i', 'o', 'n', 's', 'R', '\007', 'o', 'p', 't', 'i', 'o', 'n',
3207 's', '\022', ']', '\n', '\016', 'r', 'e', 's', 'e', 'r', 'v', 'e', 'd', '_', 'r', 'a', 'n', 'g', 'e', '\030', '\004', ' ', '\003', '(', '\013',
3208 '2', '6', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'E', 'n', 'u', 'm', 'D', 'e',
3209 's', 'c', 'r', 'i', 'p', 't', 'o', 'r', 'P', 'r', 'o', 't', 'o', '.', 'E', 'n', 'u', 'm', 'R', 'e', 's', 'e', 'r', 'v', 'e',
3210 'd', 'R', 'a', 'n', 'g', 'e', 'R', '\r', 'r', 'e', 's', 'e', 'r', 'v', 'e', 'd', 'R', 'a', 'n', 'g', 'e', '\022', '#', '\n', '\r',
3211 'r', 'e', 's', 'e', 'r', 'v', 'e', 'd', '_', 'n', 'a', 'm', 'e', '\030', '\005', ' ', '\003', '(', '\t', 'R', '\014', 'r', 'e', 's', 'e',
3212 'r', 'v', 'e', 'd', 'N', 'a', 'm', 'e', '\032', ';', '\n', '\021', 'E', 'n', 'u', 'm', 'R', 'e', 's', 'e', 'r', 'v', 'e', 'd', 'R',
3213 'a', 'n', 'g', 'e', '\022', '\024', '\n', '\005', 's', 't', 'a', 'r', 't', '\030', '\001', ' ', '\001', '(', '\005', 'R', '\005', 's', 't', 'a', 'r',
3214 't', '\022', '\020', '\n', '\003', 'e', 'n', 'd', '\030', '\002', ' ', '\001', '(', '\005', 'R', '\003', 'e', 'n', 'd', '\"', '\203', '\001', '\n', '\030', 'E',
3215 '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',
3216 '\n', '\004', 'n', 'a', 'm', 'e', '\030', '\001', ' ', '\001', '(', '\t', 'R', '\004', 'n', 'a', 'm', 'e', '\022', '\026', '\n', '\006', 'n', 'u', 'm',
3217 'b', 'e', 'r', '\030', '\002', ' ', '\001', '(', '\005', 'R', '\006', 'n', 'u', 'm', 'b', 'e', 'r', '\022', ';', '\n', '\007', 'o', 'p', 't', 'i',
3218 'o', 'n', 's', '\030', '\003', ' ', '\001', '(', '\013', '2', '!', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b',
3219 'u', 'f', '.', 'E', 'n', 'u', 'm', 'V', 'a', 'l', 'u', 'e', 'O', 'p', 't', 'i', 'o', 'n', 's', 'R', '\007', 'o', 'p', 't', 'i',
3220 'o', 'n', 's', '\"', '\247', '\001', '\n', '\026', 'S', 'e', 'r', 'v', 'i', 'c', 'e', 'D', 'e', 's', 'c', 'r', 'i', 'p', 't', 'o', 'r',
3221 'P', 'r', 'o', 't', 'o', '\022', '\022', '\n', '\004', 'n', 'a', 'm', 'e', '\030', '\001', ' ', '\001', '(', '\t', 'R', '\004', 'n', 'a', 'm', 'e',
3222 '\022', '>', '\n', '\006', 'm', 'e', 't', 'h', 'o', 'd', '\030', '\002', ' ', '\003', '(', '\013', '2', '&', '.', 'g', 'o', 'o', 'g', 'l', 'e',
3223 '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'M', 'e', 't', 'h', 'o', 'd', 'D', 'e', 's', 'c', 'r', 'i', 'p', 't', 'o',
3224 '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',
3225 '\030', '\003', ' ', '\001', '(', '\013', '2', '\037', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.',
3226 'S', 'e', 'r', 'v', 'i', 'c', 'e', 'O', 'p', 't', 'i', 'o', 'n', 's', 'R', '\007', 'o', 'p', 't', 'i', 'o', 'n', 's', '\"', '\211',
3227 '\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',
3228 '\022', '\n', '\004', 'n', 'a', 'm', 'e', '\030', '\001', ' ', '\001', '(', '\t', 'R', '\004', 'n', 'a', 'm', 'e', '\022', '\035', '\n', '\n', 'i', 'n',
3229 'p', 'u', 't', '_', 't', 'y', 'p', 'e', '\030', '\002', ' ', '\001', '(', '\t', 'R', '\t', 'i', 'n', 'p', 'u', 't', 'T', 'y', 'p', 'e',
3230 '\022', '\037', '\n', '\013', 'o', 'u', 't', 'p', 'u', 't', '_', 't', 'y', 'p', 'e', '\030', '\003', ' ', '\001', '(', '\t', 'R', '\n', 'o', 'u',
3231 't', 'p', 'u', 't', 'T', 'y', 'p', 'e', '\022', '8', '\n', '\007', 'o', 'p', 't', 'i', 'o', 'n', 's', '\030', '\004', ' ', '\001', '(', '\013',
3232 '2', '\036', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'M', 'e', 't', 'h', 'o', 'd',
3233 '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',
3234 't', '_', 's', 't', 'r', 'e', 'a', 'm', 'i', 'n', 'g', '\030', '\005', ' ', '\001', '(', '\010', ':', '\005', 'f', 'a', 'l', 's', 'e', 'R',
3235 '\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',
3236 'r', '_', 's', 't', 'r', 'e', 'a', 'm', 'i', 'n', 'g', '\030', '\006', ' ', '\001', '(', '\010', ':', '\005', 'f', 'a', 'l', 's', 'e', 'R',
3237 '\017', 's', 'e', 'r', 'v', 'e', 'r', 'S', 't', 'r', 'e', 'a', 'm', 'i', 'n', 'g', '\"', '\221', '\t', '\n', '\013', 'F', 'i', 'l', 'e',
3238 'O', 'p', 't', 'i', 'o', 'n', 's', '\022', '!', '\n', '\014', 'j', 'a', 'v', 'a', '_', 'p', 'a', 'c', 'k', 'a', 'g', 'e', '\030', '\001',
3239 ' ', '\001', '(', '\t', 'R', '\013', 'j', 'a', 'v', 'a', 'P', 'a', 'c', 'k', 'a', 'g', 'e', '\022', '0', '\n', '\024', 'j', 'a', 'v', 'a',
3240 '_', 'o', 'u', 't', 'e', 'r', '_', 'c', 'l', 'a', 's', 's', 'n', 'a', 'm', 'e', '\030', '\010', ' ', '\001', '(', '\t', 'R', '\022', 'j',
3241 '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',
3242 '_', 'm', 'u', 'l', 't', 'i', 'p', 'l', 'e', '_', 'f', 'i', 'l', 'e', 's', '\030', '\n', ' ', '\001', '(', '\010', ':', '\005', 'f', 'a',
3243 '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',
3244 '\035', 'j', 'a', 'v', 'a', '_', 'g', 'e', 'n', 'e', 'r', 'a', 't', 'e', '_', 'e', 'q', 'u', 'a', 'l', 's', '_', 'a', 'n', 'd',
3245 '_', 'h', 'a', 's', 'h', '\030', '\024', ' ', '\001', '(', '\010', 'B', '\002', '\030', '\001', 'R', '\031', 'j', 'a', 'v', 'a', 'G', 'e', 'n', 'e',
3246 'r', 'a', 't', 'e', 'E', 'q', 'u', 'a', 'l', 's', 'A', 'n', 'd', 'H', 'a', 's', 'h', '\022', ':', '\n', '\026', 'j', 'a', 'v', 'a',
3247 '_', 's', 't', 'r', 'i', 'n', 'g', '_', 'c', 'h', 'e', 'c', 'k', '_', 'u', 't', 'f', '8', '\030', '\033', ' ', '\001', '(', '\010', ':',
3248 '\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',
3249 'f', '8', '\022', 'S', '\n', '\014', 'o', 'p', 't', 'i', 'm', 'i', 'z', 'e', '_', 'f', 'o', 'r', '\030', '\t', ' ', '\001', '(', '\016', '2',
3250 ')', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'F', 'i', 'l', 'e', 'O', 'p', 't',
3251 'i', 'o', 'n', 's', '.', 'O', 'p', 't', 'i', 'm', 'i', 'z', 'e', 'M', 'o', 'd', 'e', ':', '\005', 'S', 'P', 'E', 'E', 'D', 'R',
3252 '\013', 'o', 'p', 't', 'i', 'm', 'i', 'z', 'e', 'F', 'o', 'r', '\022', '\035', '\n', '\n', 'g', 'o', '_', 'p', 'a', 'c', 'k', 'a', 'g',
3253 'e', '\030', '\013', ' ', '\001', '(', '\t', 'R', '\t', 'g', 'o', 'P', 'a', 'c', 'k', 'a', 'g', 'e', '\022', '5', '\n', '\023', 'c', 'c', '_',
3254 'g', 'e', 'n', 'e', 'r', 'i', 'c', '_', 's', 'e', 'r', 'v', 'i', 'c', 'e', 's', '\030', '\020', ' ', '\001', '(', '\010', ':', '\005', 'f',
3255 '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',
3256 '\n', '\025', 'j', 'a', 'v', 'a', '_', 'g', 'e', 'n', 'e', 'r', 'i', 'c', '_', 's', 'e', 'r', 'v', 'i', 'c', 'e', 's', '\030', '\021',
3257 ' ', '\001', '(', '\010', ':', '\005', 'f', 'a', 'l', 's', 'e', 'R', '\023', 'j', 'a', 'v', 'a', 'G', 'e', 'n', 'e', 'r', 'i', 'c', 'S',
3258 'e', 'r', 'v', 'i', 'c', 'e', 's', '\022', '5', '\n', '\023', 'p', 'y', '_', 'g', 'e', 'n', 'e', 'r', 'i', 'c', '_', 's', 'e', 'r',
3259 'v', 'i', 'c', 'e', 's', '\030', '\022', ' ', '\001', '(', '\010', ':', '\005', 'f', 'a', 'l', 's', 'e', 'R', '\021', 'p', 'y', 'G', 'e', 'n',
3260 'e', 'r', 'i', 'c', 'S', 'e', 'r', 'v', 'i', 'c', 'e', 's', '\022', '7', '\n', '\024', 'p', 'h', 'p', '_', 'g', 'e', 'n', 'e', 'r',
3261 'i', 'c', '_', 's', 'e', 'r', 'v', 'i', 'c', 'e', 's', '\030', '*', ' ', '\001', '(', '\010', ':', '\005', 'f', 'a', 'l', 's', 'e', 'R',
3262 '\022', 'p', 'h', 'p', 'G', 'e', 'n', 'e', 'r', 'i', 'c', 'S', 'e', 'r', 'v', 'i', 'c', 'e', 's', '\022', '%', '\n', '\n', 'd', 'e',
3263 'p', 'r', 'e', 'c', 'a', 't', 'e', 'd', '\030', '\027', ' ', '\001', '(', '\010', ':', '\005', 'f', 'a', 'l', 's', 'e', 'R', '\n', 'd', 'e',
3264 'p', 'r', 'e', 'c', 'a', 't', 'e', 'd', '\022', '.', '\n', '\020', 'c', 'c', '_', 'e', 'n', 'a', 'b', 'l', 'e', '_', 'a', 'r', 'e',
3265 'n', 'a', 's', '\030', '\037', ' ', '\001', '(', '\010', ':', '\004', 't', 'r', 'u', 'e', 'R', '\016', 'c', 'c', 'E', 'n', 'a', 'b', 'l', 'e',
3266 'A', 'r', 'e', 'n', 'a', 's', '\022', '*', '\n', '\021', 'o', 'b', 'j', 'c', '_', 'c', 'l', 'a', 's', 's', '_', 'p', 'r', 'e', 'f',
3267 'i', 'x', '\030', '$', ' ', '\001', '(', '\t', 'R', '\017', 'o', 'b', 'j', 'c', 'C', 'l', 'a', 's', 's', 'P', 'r', 'e', 'f', 'i', 'x',
3268 '\022', ')', '\n', '\020', 'c', 's', 'h', 'a', 'r', 'p', '_', 'n', 'a', 'm', 'e', 's', 'p', 'a', 'c', 'e', '\030', '%', ' ', '\001', '(',
3269 '\t', 'R', '\017', 'c', 's', 'h', 'a', 'r', 'p', 'N', 'a', 'm', 'e', 's', 'p', 'a', 'c', 'e', '\022', '!', '\n', '\014', 's', 'w', 'i',
3270 'f', 't', '_', 'p', 'r', 'e', 'f', 'i', 'x', '\030', '\'', ' ', '\001', '(', '\t', 'R', '\013', 's', 'w', 'i', 'f', 't', 'P', 'r', 'e',
3271 'f', 'i', 'x', '\022', '(', '\n', '\020', 'p', 'h', 'p', '_', 'c', 'l', 'a', 's', 's', '_', 'p', 'r', 'e', 'f', 'i', 'x', '\030', '(',
3272 ' ', '\001', '(', '\t', 'R', '\016', 'p', 'h', 'p', 'C', 'l', 'a', 's', 's', 'P', 'r', 'e', 'f', 'i', 'x', '\022', '#', '\n', '\r', 'p',
3273 'h', 'p', '_', 'n', 'a', 'm', 'e', 's', 'p', 'a', 'c', 'e', '\030', ')', ' ', '\001', '(', '\t', 'R', '\014', 'p', 'h', 'p', 'N', 'a',
3274 'm', 'e', 's', 'p', 'a', 'c', 'e', '\022', '4', '\n', '\026', 'p', 'h', 'p', '_', 'm', 'e', 't', 'a', 'd', 'a', 't', 'a', '_', 'n',
3275 'a', 'm', 'e', 's', 'p', 'a', 'c', 'e', '\030', ',', ' ', '\001', '(', '\t', 'R', '\024', 'p', 'h', 'p', 'M', 'e', 't', 'a', 'd', 'a',
3276 't', 'a', 'N', 'a', 'm', 'e', 's', 'p', 'a', 'c', 'e', '\022', '!', '\n', '\014', 'r', 'u', 'b', 'y', '_', 'p', 'a', 'c', 'k', 'a',
3277 'g', 'e', '\030', '-', ' ', '\001', '(', '\t', 'R', '\013', 'r', 'u', 'b', 'y', 'P', 'a', 'c', 'k', 'a', 'g', 'e', '\022', 'X', '\n', '\024',
3278 'u', 'n', 'i', 'n', 't', 'e', 'r', 'p', 'r', 'e', 't', 'e', 'd', '_', 'o', 'p', 't', 'i', 'o', 'n', '\030', '\347', '\007', ' ', '\003',
3279 '(', '\013', '2', '$', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'U', 'n', 'i', 'n',
3280 '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',
3281 'r', 'e', 't', 'e', 'd', 'O', 'p', 't', 'i', 'o', 'n', '\"', ':', '\n', '\014', 'O', 'p', 't', 'i', 'm', 'i', 'z', 'e', 'M', 'o',
3282 'd', 'e', '\022', '\t', '\n', '\005', 'S', 'P', 'E', 'E', 'D', '\020', '\001', '\022', '\r', '\n', '\t', 'C', 'O', 'D', 'E', '_', 'S', 'I', 'Z',
3283 'E', '\020', '\002', '\022', '\020', '\n', '\014', 'L', 'I', 'T', 'E', '_', 'R', 'U', 'N', 'T', 'I', 'M', 'E', '\020', '\003', '*', '\t', '\010', '\350',
3284 '\007', '\020', '\200', '\200', '\200', '\200', '\002', 'J', '\004', '\010', '&', '\020', '\'', '\"', '\321', '\002', '\n', '\016', 'M', 'e', 's', 's', 'a', 'g', 'e',
3285 'O', 'p', 't', 'i', 'o', 'n', 's', '\022', '<', '\n', '\027', 'm', 'e', 's', 's', 'a', 'g', 'e', '_', 's', 'e', 't', '_', 'w', 'i',
3286 'r', 'e', '_', 'f', 'o', 'r', 'm', 'a', 't', '\030', '\001', ' ', '\001', '(', '\010', ':', '\005', 'f', 'a', 'l', 's', 'e', 'R', '\024', 'm',
3287 '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',
3288 '_', 's', 't', 'a', 'n', 'd', 'a', 'r', 'd', '_', 'd', 'e', 's', 'c', 'r', 'i', 'p', 't', 'o', 'r', '_', 'a', 'c', 'c', 'e',
3289 's', 's', 'o', 'r', '\030', '\002', ' ', '\001', '(', '\010', ':', '\005', 'f', 'a', 'l', 's', 'e', 'R', '\034', 'n', 'o', 'S', 't', 'a', 'n',
3290 'd', 'a', 'r', 'd', 'D', 'e', 's', 'c', 'r', 'i', 'p', 't', 'o', 'r', 'A', 'c', 'c', 'e', 's', 's', 'o', 'r', '\022', '%', '\n',
3291 '\n', 'd', 'e', 'p', 'r', 'e', 'c', 'a', 't', 'e', 'd', '\030', '\003', ' ', '\001', '(', '\010', ':', '\005', 'f', 'a', 'l', 's', 'e', 'R',
3292 '\n', 'd', 'e', 'p', 'r', 'e', 'c', 'a', 't', 'e', 'd', '\022', '\033', '\n', '\t', 'm', 'a', 'p', '_', 'e', 'n', 't', 'r', 'y', '\030',
3293 '\007', ' ', '\001', '(', '\010', 'R', '\010', 'm', 'a', 'p', 'E', 'n', 't', 'r', 'y', '\022', 'X', '\n', '\024', 'u', 'n', 'i', 'n', 't', 'e',
3294 'r', 'p', 'r', 'e', 't', 'e', 'd', '_', 'o', 'p', 't', 'i', 'o', 'n', '\030', '\347', '\007', ' ', '\003', '(', '\013', '2', '$', '.', 'g',
3295 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'U', 'n', 'i', 'n', 't', 'e', 'r', 'p', 'r', 'e',
3296 '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',
3297 'p', 't', 'i', 'o', 'n', '*', '\t', '\010', '\350', '\007', '\020', '\200', '\200', '\200', '\200', '\002', 'J', '\004', '\010', '\010', '\020', '\t', 'J', '\004', '\010',
3298 '\t', '\020', '\n', '\"', '\342', '\003', '\n', '\014', 'F', 'i', 'e', 'l', 'd', 'O', 'p', 't', 'i', 'o', 'n', 's', '\022', 'A', '\n', '\005', 'c',
3299 't', 'y', 'p', 'e', '\030', '\001', ' ', '\001', '(', '\016', '2', '#', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o',
3300 'b', 'u', 'f', '.', 'F', 'i', 'e', 'l', 'd', 'O', 'p', 't', 'i', 'o', 'n', 's', '.', 'C', 'T', 'y', 'p', 'e', ':', '\006', 'S',
3301 'T', 'R', 'I', 'N', 'G', 'R', '\005', 'c', 't', 'y', 'p', 'e', '\022', '\026', '\n', '\006', 'p', 'a', 'c', 'k', 'e', 'd', '\030', '\002', ' ',
3302 '\001', '(', '\010', 'R', '\006', 'p', 'a', 'c', 'k', 'e', 'd', '\022', 'G', '\n', '\006', 'j', 's', 't', 'y', 'p', 'e', '\030', '\006', ' ', '\001',
3303 '(', '\016', '2', '$', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'F', 'i', 'e', 'l',
3304 'd', 'O', 'p', 't', 'i', 'o', 'n', 's', '.', 'J', 'S', 'T', 'y', 'p', 'e', ':', '\t', 'J', 'S', '_', 'N', 'O', 'R', 'M', 'A',
3305 'L', 'R', '\006', 'j', 's', 't', 'y', 'p', 'e', '\022', '\031', '\n', '\004', 'l', 'a', 'z', 'y', '\030', '\005', ' ', '\001', '(', '\010', ':', '\005',
3306 'f', 'a', 'l', 's', 'e', 'R', '\004', 'l', 'a', 'z', 'y', '\022', '%', '\n', '\n', 'd', 'e', 'p', 'r', 'e', 'c', 'a', 't', 'e', 'd',
3307 '\030', '\003', ' ', '\001', '(', '\010', ':', '\005', 'f', 'a', 'l', 's', 'e', 'R', '\n', 'd', 'e', 'p', 'r', 'e', 'c', 'a', 't', 'e', 'd',
3308 '\022', '\031', '\n', '\004', 'w', 'e', 'a', 'k', '\030', '\n', ' ', '\001', '(', '\010', ':', '\005', 'f', 'a', 'l', 's', 'e', 'R', '\004', 'w', 'e',
3309 'a', 'k', '\022', 'X', '\n', '\024', 'u', 'n', 'i', 'n', 't', 'e', 'r', 'p', 'r', 'e', 't', 'e', 'd', '_', 'o', 'p', 't', 'i', 'o',
3310 'n', '\030', '\347', '\007', ' ', '\003', '(', '\013', '2', '$', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u',
3311 'f', '.', 'U', 'n', 'i', 'n', 't', 'e', 'r', 'p', 'r', 'e', 't', 'e', 'd', 'O', 'p', 't', 'i', 'o', 'n', 'R', '\023', 'u', 'n',
3312 'i', 'n', 't', 'e', 'r', 'p', 'r', 'e', 't', 'e', 'd', 'O', 'p', 't', 'i', 'o', 'n', '\"', '/', '\n', '\005', 'C', 'T', 'y', 'p',
3313 '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',
3314 '\n', '\014', 'S', 'T', 'R', 'I', 'N', 'G', '_', 'P', 'I', 'E', 'C', 'E', '\020', '\002', '\"', '5', '\n', '\006', 'J', 'S', 'T', 'y', 'p',
3315 'e', '\022', '\r', '\n', '\t', 'J', 'S', '_', 'N', 'O', 'R', 'M', 'A', 'L', '\020', '\000', '\022', '\r', '\n', '\t', 'J', 'S', '_', 'S', 'T',
3316 'R', 'I', 'N', 'G', '\020', '\001', '\022', '\r', '\n', '\t', 'J', 'S', '_', 'N', 'U', 'M', 'B', 'E', 'R', '\020', '\002', '*', '\t', '\010', '\350',
3317 '\007', '\020', '\200', '\200', '\200', '\200', '\002', 'J', '\004', '\010', '\004', '\020', '\005', '\"', 's', '\n', '\014', 'O', 'n', 'e', 'o', 'f', 'O', 'p', 't',
3318 'i', 'o', 'n', 's', '\022', 'X', '\n', '\024', 'u', 'n', 'i', 'n', 't', 'e', 'r', 'p', 'r', 'e', 't', 'e', 'd', '_', 'o', 'p', 't',
3319 'i', 'o', 'n', '\030', '\347', '\007', ' ', '\003', '(', '\013', '2', '$', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o',
3320 'b', 'u', 'f', '.', 'U', 'n', 'i', 'n', 't', 'e', 'r', 'p', 'r', 'e', 't', 'e', 'd', 'O', 'p', 't', 'i', 'o', 'n', 'R', '\023',
3321 'u', 'n', 'i', 'n', 't', 'e', 'r', 'p', 'r', 'e', 't', 'e', 'd', 'O', 'p', 't', 'i', 'o', 'n', '*', '\t', '\010', '\350', '\007', '\020',
3322 '\200', '\200', '\200', '\200', '\002', '\"', '\300', '\001', '\n', '\013', 'E', 'n', 'u', 'm', 'O', 'p', 't', 'i', 'o', 'n', 's', '\022', '\037', '\n', '\013',
3323 'a', 'l', 'l', 'o', 'w', '_', 'a', 'l', 'i', 'a', 's', '\030', '\002', ' ', '\001', '(', '\010', 'R', '\n', 'a', 'l', 'l', 'o', 'w', 'A',
3324 'l', 'i', 'a', 's', '\022', '%', '\n', '\n', 'd', 'e', 'p', 'r', 'e', 'c', 'a', 't', 'e', 'd', '\030', '\003', ' ', '\001', '(', '\010', ':',
3325 '\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',
3326 'n', 't', 'e', 'r', 'p', 'r', 'e', 't', 'e', 'd', '_', 'o', 'p', 't', 'i', 'o', 'n', '\030', '\347', '\007', ' ', '\003', '(', '\013', '2',
3327 '$', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'U', 'n', 'i', 'n', 't', 'e', 'r',
3328 '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',
3329 'e', 'd', 'O', 'p', 't', 'i', 'o', 'n', '*', '\t', '\010', '\350', '\007', '\020', '\200', '\200', '\200', '\200', '\002', 'J', '\004', '\010', '\005', '\020', '\006',
3330 '\"', '\236', '\001', '\n', '\020', 'E', 'n', 'u', 'm', 'V', 'a', 'l', 'u', 'e', 'O', 'p', 't', 'i', 'o', 'n', 's', '\022', '%', '\n', '\n',
3331 'd', 'e', 'p', 'r', 'e', 'c', 'a', 't', 'e', 'd', '\030', '\001', ' ', '\001', '(', '\010', ':', '\005', 'f', 'a', 'l', 's', 'e', 'R', '\n',
3332 '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',
3333 'e', 'd', '_', 'o', 'p', 't', 'i', 'o', 'n', '\030', '\347', '\007', ' ', '\003', '(', '\013', '2', '$', '.', 'g', 'o', 'o', 'g', 'l', 'e',
3334 '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'U', 'n', 'i', 'n', 't', 'e', 'r', 'p', 'r', 'e', 't', 'e', 'd', 'O', 'p',
3335 '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',
3336 '*', '\t', '\010', '\350', '\007', '\020', '\200', '\200', '\200', '\200', '\002', '\"', '\234', '\001', '\n', '\016', 'S', 'e', 'r', 'v', 'i', 'c', 'e', 'O', 'p',
3337 't', 'i', 'o', 'n', 's', '\022', '%', '\n', '\n', 'd', 'e', 'p', 'r', 'e', 'c', 'a', 't', 'e', 'd', '\030', '!', ' ', '\001', '(', '\010',
3338 ':', '\005', 'f', 'a', 'l', 's', 'e', 'R', '\n', 'd', 'e', 'p', 'r', 'e', 'c', 'a', 't', 'e', 'd', '\022', 'X', '\n', '\024', 'u', 'n',
3339 'i', 'n', 't', 'e', 'r', 'p', 'r', 'e', 't', 'e', 'd', '_', 'o', 'p', 't', 'i', 'o', 'n', '\030', '\347', '\007', ' ', '\003', '(', '\013',
3340 '2', '$', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'U', 'n', 'i', 'n', 't', 'e',
3341 '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',
3342 't', 'e', 'd', 'O', 'p', 't', 'i', 'o', 'n', '*', '\t', '\010', '\350', '\007', '\020', '\200', '\200', '\200', '\200', '\002', '\"', '\340', '\002', '\n', '\r',
3343 'M', 'e', 't', 'h', 'o', 'd', 'O', 'p', 't', 'i', 'o', 'n', 's', '\022', '%', '\n', '\n', 'd', 'e', 'p', 'r', 'e', 'c', 'a', 't',
3344 'e', 'd', '\030', '!', ' ', '\001', '(', '\010', ':', '\005', 'f', 'a', 'l', 's', 'e', 'R', '\n', 'd', 'e', 'p', 'r', 'e', 'c', 'a', 't',
3345 'e', 'd', '\022', 'q', '\n', '\021', 'i', 'd', 'e', 'm', 'p', 'o', 't', 'e', 'n', 'c', 'y', '_', 'l', 'e', 'v', 'e', 'l', '\030', '\"',
3346 ' ', '\001', '(', '\016', '2', '/', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'M', 'e',
3347 't', 'h', 'o', 'd', 'O', 'p', 't', 'i', 'o', 'n', 's', '.', 'I', 'd', 'e', 'm', 'p', 'o', 't', 'e', 'n', 'c', 'y', 'L', 'e',
3348 'v', 'e', 'l', ':', '\023', 'I', 'D', 'E', 'M', 'P', 'O', 'T', 'E', 'N', 'C', 'Y', '_', 'U', 'N', 'K', 'N', 'O', 'W', 'N', 'R',
3349 '\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',
3350 't', 'e', 'r', 'p', 'r', 'e', 't', 'e', 'd', '_', 'o', 'p', 't', 'i', 'o', 'n', '\030', '\347', '\007', ' ', '\003', '(', '\013', '2', '$',
3351 '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'U', 'n', 'i', 'n', 't', 'e', 'r', 'p',
3352 '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',
3353 'd', 'O', 'p', 't', 'i', 'o', 'n', '\"', 'P', '\n', '\020', 'I', 'd', 'e', 'm', 'p', 'o', 't', 'e', 'n', 'c', 'y', 'L', 'e', 'v',
3354 'e', 'l', '\022', '\027', '\n', '\023', 'I', 'D', 'E', 'M', 'P', 'O', 'T', 'E', 'N', 'C', 'Y', '_', 'U', 'N', 'K', 'N', 'O', 'W', 'N',
3355 '\020', '\000', '\022', '\023', '\n', '\017', 'N', 'O', '_', 'S', 'I', 'D', 'E', '_', 'E', 'F', 'F', 'E', 'C', 'T', 'S', '\020', '\001', '\022', '\016',
3356 '\n', '\n', 'I', 'D', 'E', 'M', 'P', 'O', 'T', 'E', 'N', 'T', '\020', '\002', '*', '\t', '\010', '\350', '\007', '\020', '\200', '\200', '\200', '\200', '\002',
3357 '\"', '\232', '\003', '\n', '\023', 'U', 'n', 'i', 'n', 't', 'e', 'r', 'p', 'r', 'e', 't', 'e', 'd', 'O', 'p', 't', 'i', 'o', 'n', '\022',
3358 'A', '\n', '\004', 'n', 'a', 'm', 'e', '\030', '\002', ' ', '\003', '(', '\013', '2', '-', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r',
3359 'o', 't', 'o', 'b', 'u', 'f', '.', 'U', 'n', 'i', 'n', 't', 'e', 'r', 'p', 'r', 'e', 't', 'e', 'd', 'O', 'p', 't', 'i', 'o',
3360 'n', '.', 'N', 'a', 'm', 'e', 'P', 'a', 'r', 't', 'R', '\004', 'n', 'a', 'm', 'e', '\022', ')', '\n', '\020', 'i', 'd', 'e', 'n', 't',
3361 'i', 'f', 'i', 'e', 'r', '_', 'v', 'a', 'l', 'u', 'e', '\030', '\003', ' ', '\001', '(', '\t', 'R', '\017', 'i', 'd', 'e', 'n', 't', 'i',
3362 'f', 'i', 'e', 'r', 'V', 'a', 'l', 'u', 'e', '\022', ',', '\n', '\022', 'p', 'o', 's', 'i', 't', 'i', 'v', 'e', '_', 'i', 'n', 't',
3363 '_', 'v', 'a', 'l', 'u', 'e', '\030', '\004', ' ', '\001', '(', '\004', 'R', '\020', 'p', 'o', 's', 'i', 't', 'i', 'v', 'e', 'I', 'n', 't',
3364 'V', 'a', 'l', 'u', 'e', '\022', ',', '\n', '\022', 'n', 'e', 'g', 'a', 't', 'i', 'v', 'e', '_', 'i', 'n', 't', '_', 'v', 'a', 'l',
3365 'u', 'e', '\030', '\005', ' ', '\001', '(', '\003', 'R', '\020', 'n', 'e', 'g', 'a', 't', 'i', 'v', 'e', 'I', 'n', 't', 'V', 'a', 'l', 'u',
3366 'e', '\022', '!', '\n', '\014', 'd', 'o', 'u', 'b', 'l', 'e', '_', 'v', 'a', 'l', 'u', 'e', '\030', '\006', ' ', '\001', '(', '\001', 'R', '\013',
3367 'd', 'o', 'u', 'b', 'l', 'e', 'V', 'a', 'l', 'u', 'e', '\022', '!', '\n', '\014', 's', 't', 'r', 'i', 'n', 'g', '_', 'v', 'a', 'l',
3368 'u', 'e', '\030', '\007', ' ', '\001', '(', '\014', 'R', '\013', 's', 't', 'r', 'i', 'n', 'g', 'V', 'a', 'l', 'u', 'e', '\022', '\'', '\n', '\017',
3369 'a', 'g', 'g', 'r', 'e', 'g', 'a', 't', 'e', '_', 'v', 'a', 'l', 'u', 'e', '\030', '\010', ' ', '\001', '(', '\t', 'R', '\016', 'a', 'g',
3370 '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',
3371 '\033', '\n', '\t', 'n', 'a', 'm', 'e', '_', 'p', 'a', 'r', 't', '\030', '\001', ' ', '\002', '(', '\t', 'R', '\010', 'n', 'a', 'm', 'e', 'P',
3372 'a', 'r', 't', '\022', '!', '\n', '\014', 'i', 's', '_', 'e', 'x', 't', 'e', 'n', 's', 'i', 'o', 'n', '\030', '\002', ' ', '\002', '(', '\010',
3373 'R', '\013', 'i', 's', 'E', 'x', 't', 'e', 'n', 's', 'i', 'o', 'n', '\"', '\247', '\002', '\n', '\016', 'S', 'o', 'u', 'r', 'c', 'e', 'C',
3374 'o', 'd', 'e', 'I', 'n', 'f', 'o', '\022', 'D', '\n', '\010', 'l', 'o', 'c', 'a', 't', 'i', 'o', 'n', '\030', '\001', ' ', '\003', '(', '\013',
3375 '2', '(', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'S', 'o', 'u', 'r', 'c', 'e',
3376 'C', 'o', 'd', 'e', 'I', 'n', 'f', 'o', '.', 'L', 'o', 'c', 'a', 't', 'i', 'o', 'n', 'R', '\010', 'l', 'o', 'c', 'a', 't', 'i',
3377 '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',
3378 ' ', '\003', '(', '\005', 'B', '\002', '\020', '\001', 'R', '\004', 'p', 'a', 't', 'h', '\022', '\026', '\n', '\004', 's', 'p', 'a', 'n', '\030', '\002', ' ',
3379 '\003', '(', '\005', 'B', '\002', '\020', '\001', 'R', '\004', 's', 'p', 'a', 'n', '\022', ')', '\n', '\020', 'l', 'e', 'a', 'd', 'i', 'n', 'g', '_',
3380 'c', 'o', 'm', 'm', 'e', 'n', 't', 's', '\030', '\003', ' ', '\001', '(', '\t', 'R', '\017', 'l', 'e', 'a', 'd', 'i', 'n', 'g', 'C', 'o',
3381 'm', 'm', 'e', 'n', 't', 's', '\022', '+', '\n', '\021', 't', 'r', 'a', 'i', 'l', 'i', 'n', 'g', '_', 'c', 'o', 'm', 'm', 'e', 'n',
3382 't', 's', '\030', '\004', ' ', '\001', '(', '\t', 'R', '\020', 't', 'r', 'a', 'i', 'l', 'i', 'n', 'g', 'C', 'o', 'm', 'm', 'e', 'n', 't',
3383 's', '\022', ':', '\n', '\031', 'l', 'e', 'a', 'd', 'i', 'n', 'g', '_', 'd', 'e', 't', 'a', 'c', 'h', 'e', 'd', '_', 'c', 'o', 'm',
3384 'm', 'e', 'n', 't', 's', '\030', '\006', ' ', '\003', '(', '\t', 'R', '\027', 'l', 'e', 'a', 'd', 'i', 'n', 'g', 'D', 'e', 't', 'a', 'c',
3385 'h', 'e', 'd', 'C', 'o', 'm', 'm', 'e', 'n', 't', 's', '\"', '\321', '\001', '\n', '\021', 'G', 'e', 'n', 'e', 'r', 'a', 't', 'e', 'd',
3386 'C', 'o', 'd', 'e', 'I', 'n', 'f', 'o', '\022', 'M', '\n', '\n', 'a', 'n', 'n', 'o', 't', 'a', 't', 'i', 'o', 'n', '\030', '\001', ' ',
3387 '\003', '(', '\013', '2', '-', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'G', 'e', 'n',
3388 'e', 'r', 'a', 't', 'e', 'd', 'C', 'o', 'd', 'e', 'I', 'n', 'f', 'o', '.', 'A', 'n', 'n', 'o', 't', 'a', 't', 'i', 'o', 'n',
3389 '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',
3390 'n', '\022', '\026', '\n', '\004', 'p', 'a', 't', 'h', '\030', '\001', ' ', '\003', '(', '\005', 'B', '\002', '\020', '\001', 'R', '\004', 'p', 'a', 't', 'h',
3391 '\022', '\037', '\n', '\013', 's', 'o', 'u', 'r', 'c', 'e', '_', 'f', 'i', 'l', 'e', '\030', '\002', ' ', '\001', '(', '\t', 'R', '\n', 's', 'o',
3392 'u', 'r', 'c', 'e', 'F', 'i', 'l', 'e', '\022', '\024', '\n', '\005', 'b', 'e', 'g', 'i', 'n', '\030', '\003', ' ', '\001', '(', '\005', 'R', '\005',
3393 'b', 'e', 'g', 'i', 'n', '\022', '\020', '\n', '\003', 'e', 'n', 'd', '\030', '\004', ' ', '\001', '(', '\005', 'R', '\003', 'e', 'n', 'd', 'B', '\217',
3394 '\001', '\n', '\023', 'c', 'o', 'm', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', 'B', '\020', 'D',
3395 'e', 's', 'c', 'r', 'i', 'p', 't', 'o', 'r', 'P', 'r', 'o', 't', 'o', 's', 'H', '\001', 'Z', '>', 'g', 'i', 't', 'h', 'u', 'b',
3396 '.', 'c', 'o', 'm', '/', 'g', 'o', 'l', 'a', 'n', 'g', '/', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '/', 'p', 'r', 'o', 't',
3397 'o', 'c', '-', 'g', 'e', 'n', '-', 'g', 'o', '/', 'd', 'e', 's', 'c', 'r', 'i', 'p', 't', 'o', 'r', ';', 'd', 'e', 's', 'c',
3398 'r', 'i', 'p', 't', 'o', 'r', '\370', '\001', '\001', '\242', '\002', '\003', 'G', 'P', 'B', '\252', '\002', '\032', 'G', 'o', 'o', 'g', 'l', 'e', '.',
3399 'P', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'R', 'e', 'f', 'l', 'e', 'c', 't', 'i', 'o', 'n',
3400 };
3401 
3402 static upb_def_init *deps[1] = {
3403   NULL
3404 };
3405 
3406 upb_def_init google_protobuf_descriptor_proto_upbdefinit = {
3407   deps,
3408   layouts,
3409   "google/protobuf/descriptor.proto",
3410   UPB_STRVIEW_INIT(descriptor, 7619)
3411 };
3412 
3413 
3414 #include <ctype.h>
3415 #include <errno.h>
3416 #include <stdlib.h>
3417 #include <string.h>
3418 
3419 
3420 typedef struct {
3421   size_t len;
3422   char str[1];  /* Null-terminated string data follows. */
3423 } str_t;
3424 
newstr(upb_alloc * alloc,const char * data,size_t len)3425 static str_t *newstr(upb_alloc *alloc, const char *data, size_t len) {
3426   str_t *ret = upb_malloc(alloc, sizeof(*ret) + len);
3427   if (!ret) return NULL;
3428   ret->len = len;
3429   if (len) memcpy(ret->str, data, len);
3430   ret->str[len] = '\0';
3431   return ret;
3432 }
3433 
3434 struct upb_fielddef {
3435   const upb_filedef *file;
3436   const upb_msgdef *msgdef;
3437   const char *full_name;
3438   const char *json_name;
3439   union {
3440     int64_t sint;
3441     uint64_t uint;
3442     double dbl;
3443     float flt;
3444     bool boolean;
3445     str_t *str;
3446   } defaultval;
3447   const upb_oneofdef *oneof;
3448   union {
3449     const upb_msgdef *msgdef;
3450     const upb_enumdef *enumdef;
3451     const google_protobuf_FieldDescriptorProto *unresolved;
3452   } sub;
3453   uint32_t number_;
3454   uint16_t index_;
3455   uint16_t layout_index;
3456   uint32_t selector_base;  /* Used to index into a upb::Handlers table. */
3457   bool is_extension_;
3458   bool lazy_;
3459   bool packed_;
3460   bool proto3_optional_;
3461   upb_descriptortype_t type_;
3462   upb_label_t label_;
3463 };
3464 
3465 struct upb_msgdef {
3466   const upb_msglayout *layout;
3467   const upb_filedef *file;
3468   const char *full_name;
3469   uint32_t selector_count;
3470   uint32_t submsg_field_count;
3471 
3472   /* Tables for looking up fields by number and name. */
3473   upb_inttable itof;
3474   upb_strtable ntof;
3475 
3476   const upb_fielddef *fields;
3477   const upb_oneofdef *oneofs;
3478   int field_count;
3479   int oneof_count;
3480   int real_oneof_count;
3481 
3482   /* Is this a map-entry message? */
3483   bool map_entry;
3484   upb_wellknowntype_t well_known_type;
3485 
3486   /* TODO(haberman): proper extension ranges (there can be multiple). */
3487 };
3488 
3489 struct upb_enumdef {
3490   const upb_filedef *file;
3491   const char *full_name;
3492   upb_strtable ntoi;
3493   upb_inttable iton;
3494   int32_t defaultval;
3495 };
3496 
3497 struct upb_oneofdef {
3498   const upb_msgdef *parent;
3499   const char *full_name;
3500   uint32_t index;
3501   upb_strtable ntof;
3502   upb_inttable itof;
3503 };
3504 
3505 struct upb_filedef {
3506   const char *name;
3507   const char *package;
3508   const char *phpprefix;
3509   const char *phpnamespace;
3510   upb_syntax_t syntax;
3511 
3512   const upb_filedef **deps;
3513   const upb_msgdef *msgs;
3514   const upb_enumdef *enums;
3515   const upb_fielddef *exts;
3516 
3517   int dep_count;
3518   int msg_count;
3519   int enum_count;
3520   int ext_count;
3521 };
3522 
3523 struct upb_symtab {
3524   upb_arena *arena;
3525   upb_strtable syms;  /* full_name -> packed def ptr */
3526   upb_strtable files;  /* file_name -> upb_filedef* */
3527 };
3528 
3529 /* Inside a symtab we store tagged pointers to specific def types. */
3530 typedef enum {
3531   UPB_DEFTYPE_FIELD = 0,
3532 
3533   /* Only inside symtab table. */
3534   UPB_DEFTYPE_MSG = 1,
3535   UPB_DEFTYPE_ENUM = 2,
3536 
3537   /* Only inside message table. */
3538   UPB_DEFTYPE_ONEOF = 1,
3539   UPB_DEFTYPE_FIELD_JSONNAME = 2
3540 } upb_deftype_t;
3541 
unpack_def(upb_value v,upb_deftype_t type)3542 static const void *unpack_def(upb_value v, upb_deftype_t type) {
3543   uintptr_t num = (uintptr_t)upb_value_getconstptr(v);
3544   return (num & 3) == type ? (const void*)(num & ~3) : NULL;
3545 }
3546 
pack_def(const void * ptr,upb_deftype_t type)3547 static upb_value pack_def(const void *ptr, upb_deftype_t type) {
3548   uintptr_t num = (uintptr_t)ptr | type;
3549   return upb_value_constptr((const void*)num);
3550 }
3551 
3552 /* isalpha() etc. from <ctype.h> are locale-dependent, which we don't want. */
upb_isbetween(char c,char low,char high)3553 static bool upb_isbetween(char c, char low, char high) {
3554   return c >= low && c <= high;
3555 }
3556 
upb_isletter(char c)3557 static bool upb_isletter(char c) {
3558   return upb_isbetween(c, 'A', 'Z') || upb_isbetween(c, 'a', 'z') || c == '_';
3559 }
3560 
upb_isalphanum(char c)3561 static bool upb_isalphanum(char c) {
3562   return upb_isletter(c) || upb_isbetween(c, '0', '9');
3563 }
3564 
upb_isident(upb_strview name,bool full,upb_status * s)3565 static bool upb_isident(upb_strview name, bool full, upb_status *s) {
3566   const char *str = name.data;
3567   size_t len = name.size;
3568   bool start = true;
3569   size_t i;
3570   for (i = 0; i < len; i++) {
3571     char c = str[i];
3572     if (c == '.') {
3573       if (start || !full) {
3574         upb_status_seterrf(s, "invalid name: unexpected '.' (%s)", str);
3575         return false;
3576       }
3577       start = true;
3578     } else if (start) {
3579       if (!upb_isletter(c)) {
3580         upb_status_seterrf(
3581             s, "invalid name: path components must start with a letter (%s)",
3582             str);
3583         return false;
3584       }
3585       start = false;
3586     } else {
3587       if (!upb_isalphanum(c)) {
3588         upb_status_seterrf(s, "invalid name: non-alphanumeric character (%s)",
3589                            str);
3590         return false;
3591       }
3592     }
3593   }
3594   return !start;
3595 }
3596 
shortdefname(const char * fullname)3597 static const char *shortdefname(const char *fullname) {
3598   const char *p;
3599 
3600   if (fullname == NULL) {
3601     return NULL;
3602   } else if ((p = strrchr(fullname, '.')) == NULL) {
3603     /* No '.' in the name, return the full string. */
3604     return fullname;
3605   } else {
3606     /* Return one past the last '.'. */
3607     return p + 1;
3608   }
3609 }
3610 
3611 /* All submessage fields are lower than all other fields.
3612  * Secondly, fields are increasing in order. */
field_rank(const upb_fielddef * f)3613 uint32_t field_rank(const upb_fielddef *f) {
3614   uint32_t ret = upb_fielddef_number(f);
3615   const uint32_t high_bit = 1 << 30;
3616   UPB_ASSERT(ret < high_bit);
3617   if (!upb_fielddef_issubmsg(f))
3618     ret |= high_bit;
3619   return ret;
3620 }
3621 
cmp_fields(const void * p1,const void * p2)3622 int cmp_fields(const void *p1, const void *p2) {
3623   const upb_fielddef *f1 = *(upb_fielddef*const*)p1;
3624   const upb_fielddef *f2 = *(upb_fielddef*const*)p2;
3625   return field_rank(f1) - field_rank(f2);
3626 }
3627 
3628 /* A few implementation details of handlers.  We put these here to avoid
3629  * a def -> handlers dependency. */
3630 
3631 #define UPB_STATIC_SELECTOR_COUNT 3  /* Warning: also in upb/handlers.h. */
3632 
upb_handlers_selectorbaseoffset(const upb_fielddef * f)3633 static uint32_t upb_handlers_selectorbaseoffset(const upb_fielddef *f) {
3634   return upb_fielddef_isseq(f) ? 2 : 0;
3635 }
3636 
upb_handlers_selectorcount(const upb_fielddef * f)3637 static uint32_t upb_handlers_selectorcount(const upb_fielddef *f) {
3638   uint32_t ret = 1;
3639   if (upb_fielddef_isseq(f)) ret += 2;    /* STARTSEQ/ENDSEQ */
3640   if (upb_fielddef_isstring(f)) ret += 2; /* [STRING]/STARTSTR/ENDSTR */
3641   if (upb_fielddef_issubmsg(f)) {
3642     /* ENDSUBMSG (STARTSUBMSG is at table beginning) */
3643     ret += 0;
3644     if (upb_fielddef_lazy(f)) {
3645       /* STARTSTR/ENDSTR/STRING (for lazy) */
3646       ret += 3;
3647     }
3648   }
3649   return ret;
3650 }
3651 
upb_status_setoom(upb_status * status)3652 static void upb_status_setoom(upb_status *status) {
3653   upb_status_seterrmsg(status, "out of memory");
3654 }
3655 
assign_msg_indices(upb_msgdef * m,upb_status * s)3656 static bool assign_msg_indices(upb_msgdef *m, upb_status *s) {
3657   /* Sort fields.  upb internally relies on UPB_TYPE_MESSAGE fields having the
3658    * lowest indexes, but we do not publicly guarantee this. */
3659   upb_msg_field_iter j;
3660   int i;
3661   uint32_t selector;
3662   int n = upb_msgdef_numfields(m);
3663   upb_fielddef **fields;
3664 
3665   if (n == 0) {
3666     m->selector_count = UPB_STATIC_SELECTOR_COUNT;
3667     m->submsg_field_count = 0;
3668     return true;
3669   }
3670 
3671   fields = upb_gmalloc(n * sizeof(*fields));
3672   if (!fields) {
3673     upb_status_setoom(s);
3674     return false;
3675   }
3676 
3677   m->submsg_field_count = 0;
3678   for(i = 0, upb_msg_field_begin(&j, m);
3679       !upb_msg_field_done(&j);
3680       upb_msg_field_next(&j), i++) {
3681     upb_fielddef *f = upb_msg_iter_field(&j);
3682     UPB_ASSERT(f->msgdef == m);
3683     if (upb_fielddef_issubmsg(f)) {
3684       m->submsg_field_count++;
3685     }
3686     fields[i] = f;
3687   }
3688 
3689   qsort(fields, n, sizeof(*fields), cmp_fields);
3690 
3691   selector = UPB_STATIC_SELECTOR_COUNT + m->submsg_field_count;
3692   for (i = 0; i < n; i++) {
3693     upb_fielddef *f = fields[i];
3694     f->index_ = i;
3695     f->selector_base = selector + upb_handlers_selectorbaseoffset(f);
3696     selector += upb_handlers_selectorcount(f);
3697   }
3698   m->selector_count = selector;
3699 
3700   upb_gfree(fields);
3701   return true;
3702 }
3703 
check_oneofs(upb_msgdef * m,upb_status * s)3704 static bool check_oneofs(upb_msgdef *m, upb_status *s) {
3705   int i;
3706   int first_synthetic = -1;
3707   upb_oneofdef *mutable_oneofs = (upb_oneofdef*)m->oneofs;
3708 
3709   for (i = 0; i < m->oneof_count; i++) {
3710     mutable_oneofs[i].index = i;
3711 
3712     if (upb_oneofdef_issynthetic(&mutable_oneofs[i])) {
3713       if (first_synthetic == -1) {
3714         first_synthetic = i;
3715       }
3716     } else {
3717       if (first_synthetic != -1) {
3718         upb_status_seterrf(
3719             s, "Synthetic oneofs must be after all other oneofs: %s",
3720             upb_oneofdef_name(&mutable_oneofs[i]));
3721         return false;
3722       }
3723     }
3724   }
3725 
3726   if (first_synthetic == -1) {
3727     m->real_oneof_count = m->oneof_count;
3728   } else {
3729     m->real_oneof_count = first_synthetic;
3730   }
3731 
3732   return true;
3733 }
3734 
assign_msg_wellknowntype(upb_msgdef * m)3735 static void assign_msg_wellknowntype(upb_msgdef *m) {
3736   const char *name = upb_msgdef_fullname(m);
3737   if (name == NULL) {
3738     m->well_known_type = UPB_WELLKNOWN_UNSPECIFIED;
3739     return;
3740   }
3741   if (!strcmp(name, "google.protobuf.Any")) {
3742     m->well_known_type = UPB_WELLKNOWN_ANY;
3743   } else if (!strcmp(name, "google.protobuf.FieldMask")) {
3744     m->well_known_type = UPB_WELLKNOWN_FIELDMASK;
3745   } else if (!strcmp(name, "google.protobuf.Duration")) {
3746     m->well_known_type = UPB_WELLKNOWN_DURATION;
3747   } else if (!strcmp(name, "google.protobuf.Timestamp")) {
3748     m->well_known_type = UPB_WELLKNOWN_TIMESTAMP;
3749   } else if (!strcmp(name, "google.protobuf.DoubleValue")) {
3750     m->well_known_type = UPB_WELLKNOWN_DOUBLEVALUE;
3751   } else if (!strcmp(name, "google.protobuf.FloatValue")) {
3752     m->well_known_type = UPB_WELLKNOWN_FLOATVALUE;
3753   } else if (!strcmp(name, "google.protobuf.Int64Value")) {
3754     m->well_known_type = UPB_WELLKNOWN_INT64VALUE;
3755   } else if (!strcmp(name, "google.protobuf.UInt64Value")) {
3756     m->well_known_type = UPB_WELLKNOWN_UINT64VALUE;
3757   } else if (!strcmp(name, "google.protobuf.Int32Value")) {
3758     m->well_known_type = UPB_WELLKNOWN_INT32VALUE;
3759   } else if (!strcmp(name, "google.protobuf.UInt32Value")) {
3760     m->well_known_type = UPB_WELLKNOWN_UINT32VALUE;
3761   } else if (!strcmp(name, "google.protobuf.BoolValue")) {
3762     m->well_known_type = UPB_WELLKNOWN_BOOLVALUE;
3763   } else if (!strcmp(name, "google.protobuf.StringValue")) {
3764     m->well_known_type = UPB_WELLKNOWN_STRINGVALUE;
3765   } else if (!strcmp(name, "google.protobuf.BytesValue")) {
3766     m->well_known_type = UPB_WELLKNOWN_BYTESVALUE;
3767   } else if (!strcmp(name, "google.protobuf.Value")) {
3768     m->well_known_type = UPB_WELLKNOWN_VALUE;
3769   } else if (!strcmp(name, "google.protobuf.ListValue")) {
3770     m->well_known_type = UPB_WELLKNOWN_LISTVALUE;
3771   } else if (!strcmp(name, "google.protobuf.Struct")) {
3772     m->well_known_type = UPB_WELLKNOWN_STRUCT;
3773   } else {
3774     m->well_known_type = UPB_WELLKNOWN_UNSPECIFIED;
3775   }
3776 }
3777 
3778 
3779 /* upb_enumdef ****************************************************************/
3780 
upb_enumdef_fullname(const upb_enumdef * e)3781 const char *upb_enumdef_fullname(const upb_enumdef *e) {
3782   return e->full_name;
3783 }
3784 
upb_enumdef_name(const upb_enumdef * e)3785 const char *upb_enumdef_name(const upb_enumdef *e) {
3786   return shortdefname(e->full_name);
3787 }
3788 
upb_enumdef_file(const upb_enumdef * e)3789 const upb_filedef *upb_enumdef_file(const upb_enumdef *e) {
3790   return e->file;
3791 }
3792 
upb_enumdef_default(const upb_enumdef * e)3793 int32_t upb_enumdef_default(const upb_enumdef *e) {
3794   UPB_ASSERT(upb_enumdef_iton(e, e->defaultval));
3795   return e->defaultval;
3796 }
3797 
upb_enumdef_numvals(const upb_enumdef * e)3798 int upb_enumdef_numvals(const upb_enumdef *e) {
3799   return (int)upb_strtable_count(&e->ntoi);
3800 }
3801 
upb_enum_begin(upb_enum_iter * i,const upb_enumdef * e)3802 void upb_enum_begin(upb_enum_iter *i, const upb_enumdef *e) {
3803   /* We iterate over the ntoi table, to account for duplicate numbers. */
3804   upb_strtable_begin(i, &e->ntoi);
3805 }
3806 
upb_enum_next(upb_enum_iter * iter)3807 void upb_enum_next(upb_enum_iter *iter) { upb_strtable_next(iter); }
upb_enum_done(upb_enum_iter * iter)3808 bool upb_enum_done(upb_enum_iter *iter) { return upb_strtable_done(iter); }
3809 
upb_enumdef_ntoi(const upb_enumdef * def,const char * name,size_t len,int32_t * num)3810 bool upb_enumdef_ntoi(const upb_enumdef *def, const char *name,
3811                       size_t len, int32_t *num) {
3812   upb_value v;
3813   if (!upb_strtable_lookup2(&def->ntoi, name, len, &v)) {
3814     return false;
3815   }
3816   if (num) *num = upb_value_getint32(v);
3817   return true;
3818 }
3819 
upb_enumdef_iton(const upb_enumdef * def,int32_t num)3820 const char *upb_enumdef_iton(const upb_enumdef *def, int32_t num) {
3821   upb_value v;
3822   return upb_inttable_lookup32(&def->iton, num, &v) ?
3823       upb_value_getcstr(v) : NULL;
3824 }
3825 
upb_enum_iter_name(upb_enum_iter * iter)3826 const char *upb_enum_iter_name(upb_enum_iter *iter) {
3827   return upb_strtable_iter_key(iter).data;
3828 }
3829 
upb_enum_iter_number(upb_enum_iter * iter)3830 int32_t upb_enum_iter_number(upb_enum_iter *iter) {
3831   return upb_value_getint32(upb_strtable_iter_value(iter));
3832 }
3833 
3834 
3835 /* upb_fielddef ***************************************************************/
3836 
upb_fielddef_fullname(const upb_fielddef * f)3837 const char *upb_fielddef_fullname(const upb_fielddef *f) {
3838   return f->full_name;
3839 }
3840 
upb_fielddef_type(const upb_fielddef * f)3841 upb_fieldtype_t upb_fielddef_type(const upb_fielddef *f) {
3842   switch (f->type_) {
3843     case UPB_DESCRIPTOR_TYPE_DOUBLE:
3844       return UPB_TYPE_DOUBLE;
3845     case UPB_DESCRIPTOR_TYPE_FLOAT:
3846       return UPB_TYPE_FLOAT;
3847     case UPB_DESCRIPTOR_TYPE_INT64:
3848     case UPB_DESCRIPTOR_TYPE_SINT64:
3849     case UPB_DESCRIPTOR_TYPE_SFIXED64:
3850       return UPB_TYPE_INT64;
3851     case UPB_DESCRIPTOR_TYPE_INT32:
3852     case UPB_DESCRIPTOR_TYPE_SFIXED32:
3853     case UPB_DESCRIPTOR_TYPE_SINT32:
3854       return UPB_TYPE_INT32;
3855     case UPB_DESCRIPTOR_TYPE_UINT64:
3856     case UPB_DESCRIPTOR_TYPE_FIXED64:
3857       return UPB_TYPE_UINT64;
3858     case UPB_DESCRIPTOR_TYPE_UINT32:
3859     case UPB_DESCRIPTOR_TYPE_FIXED32:
3860       return UPB_TYPE_UINT32;
3861     case UPB_DESCRIPTOR_TYPE_ENUM:
3862       return UPB_TYPE_ENUM;
3863     case UPB_DESCRIPTOR_TYPE_BOOL:
3864       return UPB_TYPE_BOOL;
3865     case UPB_DESCRIPTOR_TYPE_STRING:
3866       return UPB_TYPE_STRING;
3867     case UPB_DESCRIPTOR_TYPE_BYTES:
3868       return UPB_TYPE_BYTES;
3869     case UPB_DESCRIPTOR_TYPE_GROUP:
3870     case UPB_DESCRIPTOR_TYPE_MESSAGE:
3871       return UPB_TYPE_MESSAGE;
3872   }
3873   UPB_UNREACHABLE();
3874 }
3875 
upb_fielddef_descriptortype(const upb_fielddef * f)3876 upb_descriptortype_t upb_fielddef_descriptortype(const upb_fielddef *f) {
3877   return f->type_;
3878 }
3879 
upb_fielddef_index(const upb_fielddef * f)3880 uint32_t upb_fielddef_index(const upb_fielddef *f) {
3881   return f->index_;
3882 }
3883 
upb_fielddef_label(const upb_fielddef * f)3884 upb_label_t upb_fielddef_label(const upb_fielddef *f) {
3885   return f->label_;
3886 }
3887 
upb_fielddef_number(const upb_fielddef * f)3888 uint32_t upb_fielddef_number(const upb_fielddef *f) {
3889   return f->number_;
3890 }
3891 
upb_fielddef_isextension(const upb_fielddef * f)3892 bool upb_fielddef_isextension(const upb_fielddef *f) {
3893   return f->is_extension_;
3894 }
3895 
upb_fielddef_lazy(const upb_fielddef * f)3896 bool upb_fielddef_lazy(const upb_fielddef *f) {
3897   return f->lazy_;
3898 }
3899 
upb_fielddef_packed(const upb_fielddef * f)3900 bool upb_fielddef_packed(const upb_fielddef *f) {
3901   return f->packed_;
3902 }
3903 
upb_fielddef_name(const upb_fielddef * f)3904 const char *upb_fielddef_name(const upb_fielddef *f) {
3905   return shortdefname(f->full_name);
3906 }
3907 
upb_fielddef_jsonname(const upb_fielddef * f)3908 const char *upb_fielddef_jsonname(const upb_fielddef *f) {
3909   return f->json_name;
3910 }
3911 
upb_fielddef_selectorbase(const upb_fielddef * f)3912 uint32_t upb_fielddef_selectorbase(const upb_fielddef *f) {
3913   return f->selector_base;
3914 }
3915 
upb_fielddef_file(const upb_fielddef * f)3916 const upb_filedef *upb_fielddef_file(const upb_fielddef *f) {
3917   return f->file;
3918 }
3919 
upb_fielddef_containingtype(const upb_fielddef * f)3920 const upb_msgdef *upb_fielddef_containingtype(const upb_fielddef *f) {
3921   return f->msgdef;
3922 }
3923 
upb_fielddef_containingoneof(const upb_fielddef * f)3924 const upb_oneofdef *upb_fielddef_containingoneof(const upb_fielddef *f) {
3925   return f->oneof;
3926 }
3927 
upb_fielddef_realcontainingoneof(const upb_fielddef * f)3928 const upb_oneofdef *upb_fielddef_realcontainingoneof(const upb_fielddef *f) {
3929   if (!f->oneof || upb_oneofdef_issynthetic(f->oneof)) return NULL;
3930   return f->oneof;
3931 }
3932 
chkdefaulttype(const upb_fielddef * f,int ctype)3933 static void chkdefaulttype(const upb_fielddef *f, int ctype) {
3934   UPB_UNUSED(f);
3935   UPB_UNUSED(ctype);
3936 }
3937 
upb_fielddef_defaultint64(const upb_fielddef * f)3938 int64_t upb_fielddef_defaultint64(const upb_fielddef *f) {
3939   chkdefaulttype(f, UPB_TYPE_INT64);
3940   return f->defaultval.sint;
3941 }
3942 
upb_fielddef_defaultint32(const upb_fielddef * f)3943 int32_t upb_fielddef_defaultint32(const upb_fielddef *f) {
3944   chkdefaulttype(f, UPB_TYPE_INT32);
3945   return (int32_t)f->defaultval.sint;
3946 }
3947 
upb_fielddef_defaultuint64(const upb_fielddef * f)3948 uint64_t upb_fielddef_defaultuint64(const upb_fielddef *f) {
3949   chkdefaulttype(f, UPB_TYPE_UINT64);
3950   return f->defaultval.uint;
3951 }
3952 
upb_fielddef_defaultuint32(const upb_fielddef * f)3953 uint32_t upb_fielddef_defaultuint32(const upb_fielddef *f) {
3954   chkdefaulttype(f, UPB_TYPE_UINT32);
3955   return (uint32_t)f->defaultval.uint;
3956 }
3957 
upb_fielddef_defaultbool(const upb_fielddef * f)3958 bool upb_fielddef_defaultbool(const upb_fielddef *f) {
3959   chkdefaulttype(f, UPB_TYPE_BOOL);
3960   return f->defaultval.boolean;
3961 }
3962 
upb_fielddef_defaultfloat(const upb_fielddef * f)3963 float upb_fielddef_defaultfloat(const upb_fielddef *f) {
3964   chkdefaulttype(f, UPB_TYPE_FLOAT);
3965   return f->defaultval.flt;
3966 }
3967 
upb_fielddef_defaultdouble(const upb_fielddef * f)3968 double upb_fielddef_defaultdouble(const upb_fielddef *f) {
3969   chkdefaulttype(f, UPB_TYPE_DOUBLE);
3970   return f->defaultval.dbl;
3971 }
3972 
upb_fielddef_defaultstr(const upb_fielddef * f,size_t * len)3973 const char *upb_fielddef_defaultstr(const upb_fielddef *f, size_t *len) {
3974   str_t *str = f->defaultval.str;
3975   UPB_ASSERT(upb_fielddef_type(f) == UPB_TYPE_STRING ||
3976          upb_fielddef_type(f) == UPB_TYPE_BYTES ||
3977          upb_fielddef_type(f) == UPB_TYPE_ENUM);
3978   if (str) {
3979     if (len) *len = str->len;
3980     return str->str;
3981   } else {
3982     if (len) *len = 0;
3983     return NULL;
3984   }
3985 }
3986 
upb_fielddef_msgsubdef(const upb_fielddef * f)3987 const upb_msgdef *upb_fielddef_msgsubdef(const upb_fielddef *f) {
3988   return upb_fielddef_type(f) == UPB_TYPE_MESSAGE ? f->sub.msgdef : NULL;
3989 }
3990 
upb_fielddef_enumsubdef(const upb_fielddef * f)3991 const upb_enumdef *upb_fielddef_enumsubdef(const upb_fielddef *f) {
3992   return upb_fielddef_type(f) == UPB_TYPE_ENUM ? f->sub.enumdef : NULL;
3993 }
3994 
upb_fielddef_layout(const upb_fielddef * f)3995 const upb_msglayout_field *upb_fielddef_layout(const upb_fielddef *f) {
3996   return &f->msgdef->layout->fields[f->layout_index];
3997 }
3998 
upb_fielddef_issubmsg(const upb_fielddef * f)3999 bool upb_fielddef_issubmsg(const upb_fielddef *f) {
4000   return upb_fielddef_type(f) == UPB_TYPE_MESSAGE;
4001 }
4002 
upb_fielddef_isstring(const upb_fielddef * f)4003 bool upb_fielddef_isstring(const upb_fielddef *f) {
4004   return upb_fielddef_type(f) == UPB_TYPE_STRING ||
4005          upb_fielddef_type(f) == UPB_TYPE_BYTES;
4006 }
4007 
upb_fielddef_isseq(const upb_fielddef * f)4008 bool upb_fielddef_isseq(const upb_fielddef *f) {
4009   return upb_fielddef_label(f) == UPB_LABEL_REPEATED;
4010 }
4011 
upb_fielddef_isprimitive(const upb_fielddef * f)4012 bool upb_fielddef_isprimitive(const upb_fielddef *f) {
4013   return !upb_fielddef_isstring(f) && !upb_fielddef_issubmsg(f);
4014 }
4015 
upb_fielddef_ismap(const upb_fielddef * f)4016 bool upb_fielddef_ismap(const upb_fielddef *f) {
4017   return upb_fielddef_isseq(f) && upb_fielddef_issubmsg(f) &&
4018          upb_msgdef_mapentry(upb_fielddef_msgsubdef(f));
4019 }
4020 
upb_fielddef_hassubdef(const upb_fielddef * f)4021 bool upb_fielddef_hassubdef(const upb_fielddef *f) {
4022   return upb_fielddef_issubmsg(f) || upb_fielddef_type(f) == UPB_TYPE_ENUM;
4023 }
4024 
upb_fielddef_haspresence(const upb_fielddef * f)4025 bool upb_fielddef_haspresence(const upb_fielddef *f) {
4026   if (upb_fielddef_isseq(f)) return false;
4027   return upb_fielddef_issubmsg(f) || upb_fielddef_containingoneof(f) ||
4028          f->file->syntax == UPB_SYNTAX_PROTO2;
4029 }
4030 
between(int32_t x,int32_t low,int32_t high)4031 static bool between(int32_t x, int32_t low, int32_t high) {
4032   return x >= low && x <= high;
4033 }
4034 
upb_fielddef_checklabel(int32_t label)4035 bool upb_fielddef_checklabel(int32_t label) { return between(label, 1, 3); }
upb_fielddef_checktype(int32_t type)4036 bool upb_fielddef_checktype(int32_t type) { return between(type, 1, 11); }
upb_fielddef_checkintfmt(int32_t fmt)4037 bool upb_fielddef_checkintfmt(int32_t fmt) { return between(fmt, 1, 3); }
4038 
upb_fielddef_checkdescriptortype(int32_t type)4039 bool upb_fielddef_checkdescriptortype(int32_t type) {
4040   return between(type, 1, 18);
4041 }
4042 
4043 /* upb_msgdef *****************************************************************/
4044 
upb_msgdef_fullname(const upb_msgdef * m)4045 const char *upb_msgdef_fullname(const upb_msgdef *m) {
4046   return m->full_name;
4047 }
4048 
upb_msgdef_file(const upb_msgdef * m)4049 const upb_filedef *upb_msgdef_file(const upb_msgdef *m) {
4050   return m->file;
4051 }
4052 
upb_msgdef_name(const upb_msgdef * m)4053 const char *upb_msgdef_name(const upb_msgdef *m) {
4054   return shortdefname(m->full_name);
4055 }
4056 
upb_msgdef_syntax(const upb_msgdef * m)4057 upb_syntax_t upb_msgdef_syntax(const upb_msgdef *m) {
4058   return m->file->syntax;
4059 }
4060 
upb_msgdef_selectorcount(const upb_msgdef * m)4061 size_t upb_msgdef_selectorcount(const upb_msgdef *m) {
4062   return m->selector_count;
4063 }
4064 
upb_msgdef_submsgfieldcount(const upb_msgdef * m)4065 uint32_t upb_msgdef_submsgfieldcount(const upb_msgdef *m) {
4066   return m->submsg_field_count;
4067 }
4068 
upb_msgdef_itof(const upb_msgdef * m,uint32_t i)4069 const upb_fielddef *upb_msgdef_itof(const upb_msgdef *m, uint32_t i) {
4070   upb_value val;
4071   return upb_inttable_lookup32(&m->itof, i, &val) ?
4072       upb_value_getconstptr(val) : NULL;
4073 }
4074 
upb_msgdef_ntof(const upb_msgdef * m,const char * name,size_t len)4075 const upb_fielddef *upb_msgdef_ntof(const upb_msgdef *m, const char *name,
4076                                     size_t len) {
4077   upb_value val;
4078 
4079   if (!upb_strtable_lookup2(&m->ntof, name, len, &val)) {
4080     return NULL;
4081   }
4082 
4083   return unpack_def(val, UPB_DEFTYPE_FIELD);
4084 }
4085 
upb_msgdef_ntoo(const upb_msgdef * m,const char * name,size_t len)4086 const upb_oneofdef *upb_msgdef_ntoo(const upb_msgdef *m, const char *name,
4087                                     size_t len) {
4088   upb_value val;
4089 
4090   if (!upb_strtable_lookup2(&m->ntof, name, len, &val)) {
4091     return NULL;
4092   }
4093 
4094   return unpack_def(val, UPB_DEFTYPE_ONEOF);
4095 }
4096 
upb_msgdef_lookupname(const upb_msgdef * m,const char * name,size_t len,const upb_fielddef ** f,const upb_oneofdef ** o)4097 bool upb_msgdef_lookupname(const upb_msgdef *m, const char *name, size_t len,
4098                            const upb_fielddef **f, const upb_oneofdef **o) {
4099   upb_value val;
4100 
4101   if (!upb_strtable_lookup2(&m->ntof, name, len, &val)) {
4102     return false;
4103   }
4104 
4105   *o = unpack_def(val, UPB_DEFTYPE_ONEOF);
4106   *f = unpack_def(val, UPB_DEFTYPE_FIELD);
4107   return *o || *f;  /* False if this was a JSON name. */
4108 }
4109 
upb_msgdef_lookupjsonname(const upb_msgdef * m,const char * name,size_t len)4110 const upb_fielddef *upb_msgdef_lookupjsonname(const upb_msgdef *m,
4111                                               const char *name, size_t len) {
4112   upb_value val;
4113   const upb_fielddef* f;
4114 
4115   if (!upb_strtable_lookup2(&m->ntof, name, len, &val)) {
4116     return NULL;
4117   }
4118 
4119   f = unpack_def(val, UPB_DEFTYPE_FIELD);
4120   if (!f) f = unpack_def(val, UPB_DEFTYPE_FIELD_JSONNAME);
4121 
4122   return f;
4123 }
4124 
upb_msgdef_numfields(const upb_msgdef * m)4125 int upb_msgdef_numfields(const upb_msgdef *m) {
4126   return m->field_count;
4127 }
4128 
upb_msgdef_numoneofs(const upb_msgdef * m)4129 int upb_msgdef_numoneofs(const upb_msgdef *m) {
4130   return m->oneof_count;
4131 }
4132 
upb_msgdef_numrealoneofs(const upb_msgdef * m)4133 int upb_msgdef_numrealoneofs(const upb_msgdef *m) {
4134   return m->real_oneof_count;
4135 }
4136 
upb_msgdef_layout(const upb_msgdef * m)4137 const upb_msglayout *upb_msgdef_layout(const upb_msgdef *m) {
4138   return m->layout;
4139 }
4140 
_upb_msgdef_field(const upb_msgdef * m,int i)4141 const upb_fielddef *_upb_msgdef_field(const upb_msgdef *m, int i) {
4142   if (i >= m->field_count) return NULL;
4143   return &m->fields[i];
4144 }
4145 
upb_msgdef_mapentry(const upb_msgdef * m)4146 bool upb_msgdef_mapentry(const upb_msgdef *m) {
4147   return m->map_entry;
4148 }
4149 
upb_msgdef_wellknowntype(const upb_msgdef * m)4150 upb_wellknowntype_t upb_msgdef_wellknowntype(const upb_msgdef *m) {
4151   return m->well_known_type;
4152 }
4153 
upb_msgdef_isnumberwrapper(const upb_msgdef * m)4154 bool upb_msgdef_isnumberwrapper(const upb_msgdef *m) {
4155   upb_wellknowntype_t type = upb_msgdef_wellknowntype(m);
4156   return type >= UPB_WELLKNOWN_DOUBLEVALUE &&
4157          type <= UPB_WELLKNOWN_UINT32VALUE;
4158 }
4159 
upb_msgdef_iswrapper(const upb_msgdef * m)4160 bool upb_msgdef_iswrapper(const upb_msgdef *m) {
4161   upb_wellknowntype_t type = upb_msgdef_wellknowntype(m);
4162   return type >= UPB_WELLKNOWN_DOUBLEVALUE &&
4163          type <= UPB_WELLKNOWN_BOOLVALUE;
4164 }
4165 
upb_msg_field_begin(upb_msg_field_iter * iter,const upb_msgdef * m)4166 void upb_msg_field_begin(upb_msg_field_iter *iter, const upb_msgdef *m) {
4167   upb_inttable_begin(iter, &m->itof);
4168 }
4169 
upb_msg_field_next(upb_msg_field_iter * iter)4170 void upb_msg_field_next(upb_msg_field_iter *iter) { upb_inttable_next(iter); }
4171 
upb_msg_field_done(const upb_msg_field_iter * iter)4172 bool upb_msg_field_done(const upb_msg_field_iter *iter) {
4173   return upb_inttable_done(iter);
4174 }
4175 
upb_msg_iter_field(const upb_msg_field_iter * iter)4176 upb_fielddef *upb_msg_iter_field(const upb_msg_field_iter *iter) {
4177   return (upb_fielddef *)upb_value_getconstptr(upb_inttable_iter_value(iter));
4178 }
4179 
upb_msg_field_iter_setdone(upb_msg_field_iter * iter)4180 void upb_msg_field_iter_setdone(upb_msg_field_iter *iter) {
4181   upb_inttable_iter_setdone(iter);
4182 }
4183 
upb_msg_field_iter_isequal(const upb_msg_field_iter * iter1,const upb_msg_field_iter * iter2)4184 bool upb_msg_field_iter_isequal(const upb_msg_field_iter * iter1,
4185                                 const upb_msg_field_iter * iter2) {
4186   return upb_inttable_iter_isequal(iter1, iter2);
4187 }
4188 
upb_msg_oneof_begin(upb_msg_oneof_iter * iter,const upb_msgdef * m)4189 void upb_msg_oneof_begin(upb_msg_oneof_iter *iter, const upb_msgdef *m) {
4190   upb_strtable_begin(iter, &m->ntof);
4191   /* We need to skip past any initial fields. */
4192   while (!upb_strtable_done(iter) &&
4193          !unpack_def(upb_strtable_iter_value(iter), UPB_DEFTYPE_ONEOF)) {
4194     upb_strtable_next(iter);
4195   }
4196 }
4197 
upb_msg_oneof_next(upb_msg_oneof_iter * iter)4198 void upb_msg_oneof_next(upb_msg_oneof_iter *iter) {
4199   /* We need to skip past fields to return only oneofs. */
4200   do {
4201     upb_strtable_next(iter);
4202   } while (!upb_strtable_done(iter) &&
4203            !unpack_def(upb_strtable_iter_value(iter), UPB_DEFTYPE_ONEOF));
4204 }
4205 
upb_msg_oneof_done(const upb_msg_oneof_iter * iter)4206 bool upb_msg_oneof_done(const upb_msg_oneof_iter *iter) {
4207   return upb_strtable_done(iter);
4208 }
4209 
upb_msg_iter_oneof(const upb_msg_oneof_iter * iter)4210 const upb_oneofdef *upb_msg_iter_oneof(const upb_msg_oneof_iter *iter) {
4211   return unpack_def(upb_strtable_iter_value(iter), UPB_DEFTYPE_ONEOF);
4212 }
4213 
upb_msg_oneof_iter_setdone(upb_msg_oneof_iter * iter)4214 void upb_msg_oneof_iter_setdone(upb_msg_oneof_iter *iter) {
4215   upb_strtable_iter_setdone(iter);
4216 }
4217 
upb_msg_oneof_iter_isequal(const upb_msg_oneof_iter * iter1,const upb_msg_oneof_iter * iter2)4218 bool upb_msg_oneof_iter_isequal(const upb_msg_oneof_iter *iter1,
4219                                 const upb_msg_oneof_iter *iter2) {
4220   return upb_strtable_iter_isequal(iter1, iter2);
4221 }
4222 
4223 /* upb_oneofdef ***************************************************************/
4224 
upb_oneofdef_name(const upb_oneofdef * o)4225 const char *upb_oneofdef_name(const upb_oneofdef *o) {
4226   return shortdefname(o->full_name);
4227 }
4228 
upb_oneofdef_containingtype(const upb_oneofdef * o)4229 const upb_msgdef *upb_oneofdef_containingtype(const upb_oneofdef *o) {
4230   return o->parent;
4231 }
4232 
upb_oneofdef_numfields(const upb_oneofdef * o)4233 int upb_oneofdef_numfields(const upb_oneofdef *o) {
4234   return (int)upb_strtable_count(&o->ntof);
4235 }
4236 
upb_oneofdef_index(const upb_oneofdef * o)4237 uint32_t upb_oneofdef_index(const upb_oneofdef *o) {
4238   return o->index;
4239 }
4240 
upb_oneofdef_issynthetic(const upb_oneofdef * o)4241 bool upb_oneofdef_issynthetic(const upb_oneofdef *o) {
4242   upb_inttable_iter iter;
4243   const upb_fielddef *f;
4244   upb_inttable_begin(&iter, &o->itof);
4245   if (upb_oneofdef_numfields(o) != 1) return false;
4246   f = upb_value_getptr(upb_inttable_iter_value(&iter));
4247   UPB_ASSERT(f);
4248   return f->proto3_optional_;
4249 }
4250 
upb_oneofdef_ntof(const upb_oneofdef * o,const char * name,size_t length)4251 const upb_fielddef *upb_oneofdef_ntof(const upb_oneofdef *o,
4252                                       const char *name, size_t length) {
4253   upb_value val;
4254   return upb_strtable_lookup2(&o->ntof, name, length, &val) ?
4255       upb_value_getptr(val) : NULL;
4256 }
4257 
upb_oneofdef_itof(const upb_oneofdef * o,uint32_t num)4258 const upb_fielddef *upb_oneofdef_itof(const upb_oneofdef *o, uint32_t num) {
4259   upb_value val;
4260   return upb_inttable_lookup32(&o->itof, num, &val) ?
4261       upb_value_getptr(val) : NULL;
4262 }
4263 
upb_oneof_begin(upb_oneof_iter * iter,const upb_oneofdef * o)4264 void upb_oneof_begin(upb_oneof_iter *iter, const upb_oneofdef *o) {
4265   upb_inttable_begin(iter, &o->itof);
4266 }
4267 
upb_oneof_next(upb_oneof_iter * iter)4268 void upb_oneof_next(upb_oneof_iter *iter) {
4269   upb_inttable_next(iter);
4270 }
4271 
upb_oneof_done(upb_oneof_iter * iter)4272 bool upb_oneof_done(upb_oneof_iter *iter) {
4273   return upb_inttable_done(iter);
4274 }
4275 
upb_oneof_iter_field(const upb_oneof_iter * iter)4276 upb_fielddef *upb_oneof_iter_field(const upb_oneof_iter *iter) {
4277   return (upb_fielddef *)upb_value_getconstptr(upb_inttable_iter_value(iter));
4278 }
4279 
upb_oneof_iter_setdone(upb_oneof_iter * iter)4280 void upb_oneof_iter_setdone(upb_oneof_iter *iter) {
4281   upb_inttable_iter_setdone(iter);
4282 }
4283 
4284 /* Dynamic Layout Generation. *************************************************/
4285 
div_round_up(size_t n,size_t d)4286 static size_t div_round_up(size_t n, size_t d) {
4287   return (n + d - 1) / d;
4288 }
4289 
upb_msgval_sizeof(upb_fieldtype_t type)4290 static size_t upb_msgval_sizeof(upb_fieldtype_t type) {
4291   switch (type) {
4292     case UPB_TYPE_DOUBLE:
4293     case UPB_TYPE_INT64:
4294     case UPB_TYPE_UINT64:
4295       return 8;
4296     case UPB_TYPE_ENUM:
4297     case UPB_TYPE_INT32:
4298     case UPB_TYPE_UINT32:
4299     case UPB_TYPE_FLOAT:
4300       return 4;
4301     case UPB_TYPE_BOOL:
4302       return 1;
4303     case UPB_TYPE_MESSAGE:
4304       return sizeof(void*);
4305     case UPB_TYPE_BYTES:
4306     case UPB_TYPE_STRING:
4307       return sizeof(upb_strview);
4308   }
4309   UPB_UNREACHABLE();
4310 }
4311 
upb_msg_fielddefsize(const upb_fielddef * f)4312 static uint8_t upb_msg_fielddefsize(const upb_fielddef *f) {
4313   if (upb_msgdef_mapentry(upb_fielddef_containingtype(f))) {
4314     upb_map_entry ent;
4315     UPB_ASSERT(sizeof(ent.k) == sizeof(ent.v));
4316     return sizeof(ent.k);
4317   } else if (upb_fielddef_isseq(f)) {
4318     return sizeof(void*);
4319   } else {
4320     return upb_msgval_sizeof(upb_fielddef_type(f));
4321   }
4322 }
4323 
upb_msglayout_place(upb_msglayout * l,size_t size)4324 static uint32_t upb_msglayout_place(upb_msglayout *l, size_t size) {
4325   uint32_t ret;
4326 
4327   l->size = UPB_ALIGN_UP(l->size, size);
4328   ret = l->size;
4329   l->size += size;
4330   return ret;
4331 }
4332 
field_number_cmp(const void * p1,const void * p2)4333 static int field_number_cmp(const void *p1, const void *p2) {
4334   const upb_msglayout_field *f1 = p1;
4335   const upb_msglayout_field *f2 = p2;
4336   return f1->number - f2->number;
4337 }
4338 
assign_layout_indices(const upb_msgdef * m,upb_msglayout_field * fields)4339 static void assign_layout_indices(const upb_msgdef *m, upb_msglayout_field *fields) {
4340   int i;
4341   int n = upb_msgdef_numfields(m);
4342   for (i = 0; i < n; i++) {
4343     upb_fielddef *f = (upb_fielddef*)upb_msgdef_itof(m, fields[i].number);
4344     UPB_ASSERT(f);
4345     f->layout_index = i;
4346   }
4347 }
4348 
4349 /* This function is the dynamic equivalent of message_layout.{cc,h} in upbc.
4350  * It computes a dynamic layout for all of the fields in |m|. */
make_layout(const upb_symtab * symtab,const upb_msgdef * m)4351 static bool make_layout(const upb_symtab *symtab, const upb_msgdef *m) {
4352   upb_msglayout *l = (upb_msglayout*)m->layout;
4353   upb_msg_field_iter it;
4354   upb_msg_oneof_iter oit;
4355   size_t hasbit;
4356   size_t submsg_count = m->submsg_field_count;
4357   const upb_msglayout **submsgs;
4358   upb_msglayout_field *fields;
4359   upb_alloc *alloc = upb_arena_alloc(symtab->arena);
4360 
4361   memset(l, 0, sizeof(*l));
4362 
4363   fields = upb_malloc(alloc, upb_msgdef_numfields(m) * sizeof(*fields));
4364   submsgs = upb_malloc(alloc, submsg_count * sizeof(*submsgs));
4365 
4366   if ((!fields && upb_msgdef_numfields(m)) ||
4367       (!submsgs && submsg_count)) {
4368     /* OOM. */
4369     return false;
4370   }
4371 
4372   l->field_count = upb_msgdef_numfields(m);
4373   l->fields = fields;
4374   l->submsgs = submsgs;
4375 
4376   if (upb_msgdef_mapentry(m)) {
4377     /* TODO(haberman): refactor this method so this special case is more
4378      * elegant. */
4379     const upb_fielddef *key = upb_msgdef_itof(m, 1);
4380     const upb_fielddef *val = upb_msgdef_itof(m, 2);
4381     fields[0].number = 1;
4382     fields[1].number = 2;
4383     fields[0].label = UPB_LABEL_OPTIONAL;
4384     fields[1].label = UPB_LABEL_OPTIONAL;
4385     fields[0].presence = 0;
4386     fields[1].presence = 0;
4387     fields[0].descriptortype = upb_fielddef_descriptortype(key);
4388     fields[1].descriptortype = upb_fielddef_descriptortype(val);
4389     fields[0].offset = 0;
4390     fields[1].offset = sizeof(upb_strview);
4391     fields[1].submsg_index = 0;
4392 
4393     if (upb_fielddef_type(val) == UPB_TYPE_MESSAGE) {
4394       submsgs[0] = upb_fielddef_msgsubdef(val)->layout;
4395     }
4396 
4397     l->field_count = 2;
4398     l->size = 2 * sizeof(upb_strview);
4399     l->size = UPB_ALIGN_UP(l->size, 8);
4400     return true;
4401   }
4402 
4403   /* Allocate data offsets in three stages:
4404    *
4405    * 1. hasbits.
4406    * 2. regular fields.
4407    * 3. oneof fields.
4408    *
4409    * OPT: There is a lot of room for optimization here to minimize the size.
4410    */
4411 
4412   /* Allocate hasbits and set basic field attributes. */
4413   submsg_count = 0;
4414   for (upb_msg_field_begin(&it, m), hasbit = 0;
4415        !upb_msg_field_done(&it);
4416        upb_msg_field_next(&it)) {
4417     upb_fielddef* f = upb_msg_iter_field(&it);
4418     upb_msglayout_field *field = &fields[upb_fielddef_index(f)];
4419 
4420     field->number = upb_fielddef_number(f);
4421     field->descriptortype = upb_fielddef_descriptortype(f);
4422     field->label = upb_fielddef_label(f);
4423 
4424     if (field->descriptortype == UPB_DTYPE_STRING &&
4425         f->file->syntax == UPB_SYNTAX_PROTO2) {
4426       /* See TableDescriptorType() in upbc/generator.cc for details and
4427        * rationale. */
4428       field->descriptortype = UPB_DTYPE_BYTES;
4429     }
4430 
4431     if (upb_fielddef_ismap(f)) {
4432       field->label = _UPB_LABEL_MAP;
4433     } else if (upb_fielddef_packed(f)) {
4434       field->label = _UPB_LABEL_PACKED;
4435     }
4436 
4437     if (upb_fielddef_issubmsg(f)) {
4438       const upb_msgdef *subm = upb_fielddef_msgsubdef(f);
4439       field->submsg_index = submsg_count++;
4440       submsgs[field->submsg_index] = subm->layout;
4441     }
4442 
4443     if (upb_fielddef_haspresence(f) && !upb_fielddef_realcontainingoneof(f)) {
4444       /* We don't use hasbit 0, so that 0 can indicate "no presence" in the
4445        * table. This wastes one hasbit, but we don't worry about it for now. */
4446       field->presence = ++hasbit;
4447     } else {
4448       field->presence = 0;
4449     }
4450   }
4451 
4452   /* Account for space used by hasbits. */
4453   l->size = div_round_up(hasbit, 8);
4454 
4455   /* Allocate non-oneof fields. */
4456   for (upb_msg_field_begin(&it, m); !upb_msg_field_done(&it);
4457        upb_msg_field_next(&it)) {
4458     const upb_fielddef* f = upb_msg_iter_field(&it);
4459     size_t field_size = upb_msg_fielddefsize(f);
4460     size_t index = upb_fielddef_index(f);
4461 
4462     if (upb_fielddef_realcontainingoneof(f)) {
4463       /* Oneofs are handled separately below. */
4464       continue;
4465     }
4466 
4467     fields[index].offset = upb_msglayout_place(l, field_size);
4468   }
4469 
4470   /* Allocate oneof fields.  Each oneof field consists of a uint32 for the case
4471    * and space for the actual data. */
4472   for (upb_msg_oneof_begin(&oit, m); !upb_msg_oneof_done(&oit);
4473        upb_msg_oneof_next(&oit)) {
4474     const upb_oneofdef* o = upb_msg_iter_oneof(&oit);
4475     upb_oneof_iter fit;
4476 
4477     size_t case_size = sizeof(uint32_t);  /* Could potentially optimize this. */
4478     size_t field_size = 0;
4479     uint32_t case_offset;
4480     uint32_t data_offset;
4481 
4482     if (upb_oneofdef_issynthetic(o)) continue;
4483 
4484     /* Calculate field size: the max of all field sizes. */
4485     for (upb_oneof_begin(&fit, o);
4486          !upb_oneof_done(&fit);
4487          upb_oneof_next(&fit)) {
4488       const upb_fielddef* f = upb_oneof_iter_field(&fit);
4489       field_size = UPB_MAX(field_size, upb_msg_fielddefsize(f));
4490     }
4491 
4492     /* Align and allocate case offset. */
4493     case_offset = upb_msglayout_place(l, case_size);
4494     data_offset = upb_msglayout_place(l, field_size);
4495 
4496     for (upb_oneof_begin(&fit, o);
4497          !upb_oneof_done(&fit);
4498          upb_oneof_next(&fit)) {
4499       const upb_fielddef* f = upb_oneof_iter_field(&fit);
4500       fields[upb_fielddef_index(f)].offset = data_offset;
4501       fields[upb_fielddef_index(f)].presence = ~case_offset;
4502     }
4503   }
4504 
4505   /* Size of the entire structure should be a multiple of its greatest
4506    * alignment.  TODO: track overall alignment for real? */
4507   l->size = UPB_ALIGN_UP(l->size, 8);
4508 
4509   /* Sort fields by number. */
4510   qsort(fields, upb_msgdef_numfields(m), sizeof(*fields), field_number_cmp);
4511   assign_layout_indices(m, fields);
4512 
4513   return true;
4514 }
4515 
4516 /* Code to build defs from descriptor protos. *********************************/
4517 
4518 /* There is a question of how much validation to do here.  It will be difficult
4519  * to perfectly match the amount of validation performed by proto2.  But since
4520  * this code is used to directly build defs from Ruby (for example) we do need
4521  * to validate important constraints like uniqueness of names and numbers. */
4522 
4523 #define CHK(x) if (!(x)) { return false; }
4524 #define CHK_OOM(x) if (!(x)) { upb_status_setoom(ctx->status); return false; }
4525 
4526 typedef struct {
4527   const upb_symtab *symtab;
4528   upb_filedef *file;              /* File we are building. */
4529   upb_alloc *alloc;               /* Allocate defs here. */
4530   upb_alloc *tmp;                 /* Alloc for addtab and any other tmp data. */
4531   upb_strtable *addtab;           /* full_name -> packed def ptr for new defs */
4532   const upb_msglayout **layouts;  /* NULL if we should build layouts. */
4533   upb_status *status;             /* Record errors here. */
4534 } symtab_addctx;
4535 
strviewdup(const symtab_addctx * ctx,upb_strview view)4536 static char* strviewdup(const symtab_addctx *ctx, upb_strview view) {
4537   return upb_strdup2(view.data, view.size, ctx->alloc);
4538 }
4539 
streql2(const char * a,size_t n,const char * b)4540 static bool streql2(const char *a, size_t n, const char *b) {
4541   return n == strlen(b) && memcmp(a, b, n) == 0;
4542 }
4543 
streql_view(upb_strview view,const char * b)4544 static bool streql_view(upb_strview view, const char *b) {
4545   return streql2(view.data, view.size, b);
4546 }
4547 
makefullname(const symtab_addctx * ctx,const char * prefix,upb_strview name)4548 static const char *makefullname(const symtab_addctx *ctx, const char *prefix,
4549                                 upb_strview name) {
4550   if (prefix) {
4551     /* ret = prefix + '.' + name; */
4552     size_t n = strlen(prefix);
4553     char *ret = upb_malloc(ctx->alloc, n + name.size + 2);
4554     CHK_OOM(ret);
4555     strcpy(ret, prefix);
4556     ret[n] = '.';
4557     memcpy(&ret[n + 1], name.data, name.size);
4558     ret[n + 1 + name.size] = '\0';
4559     return ret;
4560   } else {
4561     return strviewdup(ctx, name);
4562   }
4563 }
4564 
getjsonname(const char * name,char * buf,size_t len)4565 size_t getjsonname(const char *name, char *buf, size_t len) {
4566   size_t src, dst = 0;
4567   bool ucase_next = false;
4568 
4569 #define WRITE(byte) \
4570   ++dst; \
4571   if (dst < len) buf[dst - 1] = byte; \
4572   else if (dst == len) buf[dst - 1] = '\0'
4573 
4574   if (!name) {
4575     WRITE('\0');
4576     return 0;
4577   }
4578 
4579   /* Implement the transformation as described in the spec:
4580    *   1. upper case all letters after an underscore.
4581    *   2. remove all underscores.
4582    */
4583   for (src = 0; name[src]; src++) {
4584     if (name[src] == '_') {
4585       ucase_next = true;
4586       continue;
4587     }
4588 
4589     if (ucase_next) {
4590       WRITE(toupper(name[src]));
4591       ucase_next = false;
4592     } else {
4593       WRITE(name[src]);
4594     }
4595   }
4596 
4597   WRITE('\0');
4598   return dst;
4599 
4600 #undef WRITE
4601 }
4602 
makejsonname(const char * name,upb_alloc * alloc)4603 static char* makejsonname(const char* name, upb_alloc *alloc) {
4604   size_t size = getjsonname(name, NULL, 0);
4605   char* json_name = upb_malloc(alloc, size);
4606   getjsonname(name, json_name, size);
4607   return json_name;
4608 }
4609 
symtab_add(const symtab_addctx * ctx,const char * name,upb_value v)4610 static bool symtab_add(const symtab_addctx *ctx, const char *name,
4611                        upb_value v) {
4612   upb_value tmp;
4613   if (upb_strtable_lookup(ctx->addtab, name, &tmp) ||
4614       upb_strtable_lookup(&ctx->symtab->syms, name, &tmp)) {
4615     upb_status_seterrf(ctx->status, "duplicate symbol '%s'", name);
4616     return false;
4617   }
4618 
4619   CHK_OOM(upb_strtable_insert3(ctx->addtab, name, strlen(name), v, ctx->tmp));
4620   return true;
4621 }
4622 
4623 /* Given a symbol and the base symbol inside which it is defined, find the
4624  * symbol's definition in t. */
resolvename(const upb_strtable * t,const upb_fielddef * f,const char * base,upb_strview sym,upb_deftype_t type,upb_status * status,const void ** def)4625 static bool resolvename(const upb_strtable *t, const upb_fielddef *f,
4626                         const char *base, upb_strview sym,
4627                         upb_deftype_t type, upb_status *status,
4628                         const void **def) {
4629   if(sym.size == 0) return false;
4630   if(sym.data[0] == '.') {
4631     /* Symbols starting with '.' are absolute, so we do a single lookup.
4632      * Slice to omit the leading '.' */
4633     upb_value v;
4634     if (!upb_strtable_lookup2(t, sym.data + 1, sym.size - 1, &v)) {
4635       return false;
4636     }
4637 
4638     *def = unpack_def(v, type);
4639 
4640     if (!*def) {
4641       upb_status_seterrf(status,
4642                          "type mismatch when resolving field %s, name %s",
4643                          f->full_name, sym.data);
4644       return false;
4645     }
4646 
4647     return true;
4648   } else {
4649     /* Remove components from base until we find an entry or run out.
4650      * TODO: This branch is totally broken, but currently not used. */
4651     (void)base;
4652     UPB_ASSERT(false);
4653     return false;
4654   }
4655 }
4656 
symtab_resolve(const symtab_addctx * ctx,const upb_fielddef * f,const char * base,upb_strview sym,upb_deftype_t type)4657 const void *symtab_resolve(const symtab_addctx *ctx, const upb_fielddef *f,
4658                            const char *base, upb_strview sym,
4659                            upb_deftype_t type) {
4660   const void *ret;
4661   if (!resolvename(ctx->addtab, f, base, sym, type, ctx->status, &ret) &&
4662       !resolvename(&ctx->symtab->syms, f, base, sym, type, ctx->status, &ret)) {
4663     if (upb_ok(ctx->status)) {
4664       upb_status_seterrf(ctx->status, "couldn't resolve name '%s'", sym.data);
4665     }
4666     return false;
4667   }
4668   return ret;
4669 }
4670 
create_oneofdef(const symtab_addctx * ctx,upb_msgdef * m,const google_protobuf_OneofDescriptorProto * oneof_proto)4671 static bool create_oneofdef(
4672     const symtab_addctx *ctx, upb_msgdef *m,
4673     const google_protobuf_OneofDescriptorProto *oneof_proto) {
4674   upb_oneofdef *o;
4675   upb_strview name = google_protobuf_OneofDescriptorProto_name(oneof_proto);
4676   upb_value v;
4677 
4678   o = (upb_oneofdef*)&m->oneofs[m->oneof_count++];
4679   o->parent = m;
4680   o->full_name = makefullname(ctx, m->full_name, name);
4681 
4682   v = pack_def(o, UPB_DEFTYPE_ONEOF);
4683   CHK_OOM(symtab_add(ctx, o->full_name, v));
4684   CHK_OOM(upb_strtable_insert3(&m->ntof, name.data, name.size, v, ctx->alloc));
4685 
4686   CHK_OOM(upb_inttable_init2(&o->itof, UPB_CTYPE_CONSTPTR, ctx->alloc));
4687   CHK_OOM(upb_strtable_init2(&o->ntof, UPB_CTYPE_CONSTPTR, ctx->alloc));
4688 
4689   return true;
4690 }
4691 
parse_default(const symtab_addctx * ctx,const char * str,size_t len,upb_fielddef * f)4692 static bool parse_default(const symtab_addctx *ctx, const char *str, size_t len,
4693                           upb_fielddef *f) {
4694   char *end;
4695   char nullz[64];
4696   errno = 0;
4697 
4698   switch (upb_fielddef_type(f)) {
4699     case UPB_TYPE_INT32:
4700     case UPB_TYPE_INT64:
4701     case UPB_TYPE_UINT32:
4702     case UPB_TYPE_UINT64:
4703     case UPB_TYPE_DOUBLE:
4704     case UPB_TYPE_FLOAT:
4705       /* Standard C number parsing functions expect null-terminated strings. */
4706       if (len >= sizeof(nullz) - 1) {
4707         return false;
4708       }
4709       memcpy(nullz, str, len);
4710       nullz[len] = '\0';
4711       str = nullz;
4712       break;
4713     default:
4714       break;
4715   }
4716 
4717   switch (upb_fielddef_type(f)) {
4718     case UPB_TYPE_INT32: {
4719       long val = strtol(str, &end, 0);
4720       CHK(val <= INT32_MAX && val >= INT32_MIN && errno != ERANGE && !*end);
4721       f->defaultval.sint = val;
4722       break;
4723     }
4724     case UPB_TYPE_ENUM: {
4725       const upb_enumdef *e = f->sub.enumdef;
4726       int32_t val;
4727       CHK(upb_enumdef_ntoi(e, str, len, &val));
4728       f->defaultval.sint = val;
4729       break;
4730     }
4731     case UPB_TYPE_INT64: {
4732       /* XXX: Need to write our own strtoll, since it's not available in c89. */
4733       int64_t val = strtol(str, &end, 0);
4734       CHK(val <= INT64_MAX && val >= INT64_MIN && errno != ERANGE && !*end);
4735       f->defaultval.sint = val;
4736       break;
4737     }
4738     case UPB_TYPE_UINT32: {
4739       unsigned long val = strtoul(str, &end, 0);
4740       CHK(val <= UINT32_MAX && errno != ERANGE && !*end);
4741       f->defaultval.uint = val;
4742       break;
4743     }
4744     case UPB_TYPE_UINT64: {
4745       /* XXX: Need to write our own strtoull, since it's not available in c89. */
4746       uint64_t val = strtoul(str, &end, 0);
4747       CHK(val <= UINT64_MAX && errno != ERANGE && !*end);
4748       f->defaultval.uint = val;
4749       break;
4750     }
4751     case UPB_TYPE_DOUBLE: {
4752       double val = strtod(str, &end);
4753       CHK(errno != ERANGE && !*end);
4754       f->defaultval.dbl = val;
4755       break;
4756     }
4757     case UPB_TYPE_FLOAT: {
4758       /* XXX: Need to write our own strtof, since it's not available in c89. */
4759       float val = strtod(str, &end);
4760       CHK(errno != ERANGE && !*end);
4761       f->defaultval.flt = val;
4762       break;
4763     }
4764     case UPB_TYPE_BOOL: {
4765       if (streql2(str, len, "false")) {
4766         f->defaultval.boolean = false;
4767       } else if (streql2(str, len, "true")) {
4768         f->defaultval.boolean = true;
4769       } else {
4770         return false;
4771       }
4772       break;
4773     }
4774     case UPB_TYPE_STRING:
4775       f->defaultval.str = newstr(ctx->alloc, str, len);
4776       break;
4777     case UPB_TYPE_BYTES:
4778       /* XXX: need to interpret the C-escaped value. */
4779       f->defaultval.str = newstr(ctx->alloc, str, len);
4780       break;
4781     case UPB_TYPE_MESSAGE:
4782       /* Should not have a default value. */
4783       return false;
4784   }
4785   return true;
4786 }
4787 
set_default_default(const symtab_addctx * ctx,upb_fielddef * f)4788 static void set_default_default(const symtab_addctx *ctx, upb_fielddef *f) {
4789   switch (upb_fielddef_type(f)) {
4790     case UPB_TYPE_INT32:
4791     case UPB_TYPE_INT64:
4792     case UPB_TYPE_ENUM:
4793       f->defaultval.sint = 0;
4794       break;
4795     case UPB_TYPE_UINT64:
4796     case UPB_TYPE_UINT32:
4797       f->defaultval.uint = 0;
4798       break;
4799     case UPB_TYPE_DOUBLE:
4800     case UPB_TYPE_FLOAT:
4801       f->defaultval.dbl = 0;
4802       break;
4803     case UPB_TYPE_STRING:
4804     case UPB_TYPE_BYTES:
4805       f->defaultval.str = newstr(ctx->alloc, NULL, 0);
4806       break;
4807     case UPB_TYPE_BOOL:
4808       f->defaultval.boolean = false;
4809       break;
4810     case UPB_TYPE_MESSAGE:
4811       break;
4812   }
4813 }
4814 
create_fielddef(const symtab_addctx * ctx,const char * prefix,upb_msgdef * m,const google_protobuf_FieldDescriptorProto * field_proto)4815 static bool create_fielddef(
4816     const symtab_addctx *ctx, const char *prefix, upb_msgdef *m,
4817     const google_protobuf_FieldDescriptorProto *field_proto) {
4818   upb_alloc *alloc = ctx->alloc;
4819   upb_fielddef *f;
4820   const google_protobuf_FieldOptions *options;
4821   upb_strview name;
4822   const char *full_name;
4823   const char *json_name;
4824   const char *shortname;
4825   uint32_t field_number;
4826 
4827   if (!google_protobuf_FieldDescriptorProto_has_name(field_proto)) {
4828     upb_status_seterrmsg(ctx->status, "field has no name");
4829     return false;
4830   }
4831 
4832   name = google_protobuf_FieldDescriptorProto_name(field_proto);
4833   CHK(upb_isident(name, false, ctx->status));
4834   full_name = makefullname(ctx, prefix, name);
4835   shortname = shortdefname(full_name);
4836 
4837   if (google_protobuf_FieldDescriptorProto_has_json_name(field_proto)) {
4838     json_name = strviewdup(
4839         ctx, google_protobuf_FieldDescriptorProto_json_name(field_proto));
4840   } else {
4841     json_name = makejsonname(shortname, ctx->alloc);
4842   }
4843 
4844   field_number = google_protobuf_FieldDescriptorProto_number(field_proto);
4845 
4846   if (field_number == 0 || field_number > UPB_MAX_FIELDNUMBER) {
4847     upb_status_seterrf(ctx->status, "invalid field number (%u)", field_number);
4848     return false;
4849   }
4850 
4851   if (m) {
4852     /* direct message field. */
4853     upb_value v, field_v, json_v;
4854     size_t json_size;
4855 
4856     f = (upb_fielddef*)&m->fields[m->field_count++];
4857     f->msgdef = m;
4858     f->is_extension_ = false;
4859 
4860     if (upb_strtable_lookup(&m->ntof, shortname, NULL)) {
4861       upb_status_seterrf(ctx->status, "duplicate field name (%s)", shortname);
4862       return false;
4863     }
4864 
4865     if (upb_strtable_lookup(&m->ntof, json_name, NULL)) {
4866       upb_status_seterrf(ctx->status, "duplicate json_name (%s)", json_name);
4867       return false;
4868     }
4869 
4870     if (upb_inttable_lookup(&m->itof, field_number, NULL)) {
4871       upb_status_seterrf(ctx->status, "duplicate field number (%u)",
4872                          field_number);
4873       return false;
4874     }
4875 
4876     field_v = pack_def(f, UPB_DEFTYPE_FIELD);
4877     json_v = pack_def(f, UPB_DEFTYPE_FIELD_JSONNAME);
4878     v = upb_value_constptr(f);
4879     json_size = strlen(json_name);
4880 
4881     CHK_OOM(
4882         upb_strtable_insert3(&m->ntof, name.data, name.size, field_v, alloc));
4883     CHK_OOM(upb_inttable_insert2(&m->itof, field_number, v, alloc));
4884 
4885     if (strcmp(shortname, json_name) != 0) {
4886       upb_strtable_insert3(&m->ntof, json_name, json_size, json_v, alloc);
4887     }
4888 
4889     if (ctx->layouts) {
4890       const upb_msglayout_field *fields = m->layout->fields;
4891       int count = m->layout->field_count;
4892       bool found = false;
4893       int i;
4894       for (i = 0; i < count; i++) {
4895         if (fields[i].number == field_number) {
4896           f->layout_index = i;
4897           found = true;
4898           break;
4899         }
4900       }
4901       UPB_ASSERT(found);
4902     }
4903   } else {
4904     /* extension field. */
4905     f = (upb_fielddef*)&ctx->file->exts[ctx->file->ext_count++];
4906     f->is_extension_ = true;
4907     CHK_OOM(symtab_add(ctx, full_name, pack_def(f, UPB_DEFTYPE_FIELD)));
4908   }
4909 
4910   f->full_name = full_name;
4911   f->json_name = json_name;
4912   f->file = ctx->file;
4913   f->type_ = (int)google_protobuf_FieldDescriptorProto_type(field_proto);
4914   f->label_ = (int)google_protobuf_FieldDescriptorProto_label(field_proto);
4915   f->number_ = field_number;
4916   f->oneof = NULL;
4917   f->proto3_optional_ =
4918       google_protobuf_FieldDescriptorProto_proto3_optional(field_proto);
4919 
4920   /* We can't resolve the subdef or (in the case of extensions) the containing
4921    * message yet, because it may not have been defined yet.  We stash a pointer
4922    * to the field_proto until later when we can properly resolve it. */
4923   f->sub.unresolved = field_proto;
4924 
4925   if (f->label_ == UPB_LABEL_REQUIRED && f->file->syntax == UPB_SYNTAX_PROTO3) {
4926     upb_status_seterrf(ctx->status, "proto3 fields cannot be required (%s)",
4927                        f->full_name);
4928     return false;
4929   }
4930 
4931   if (google_protobuf_FieldDescriptorProto_has_oneof_index(field_proto)) {
4932     int oneof_index =
4933         google_protobuf_FieldDescriptorProto_oneof_index(field_proto);
4934     upb_oneofdef *oneof;
4935     upb_value v = upb_value_constptr(f);
4936 
4937     if (upb_fielddef_label(f) != UPB_LABEL_OPTIONAL) {
4938       upb_status_seterrf(ctx->status,
4939                          "fields in oneof must have OPTIONAL label (%s)",
4940                          f->full_name);
4941       return false;
4942     }
4943 
4944     if (!m) {
4945       upb_status_seterrf(ctx->status,
4946                          "oneof_index provided for extension field (%s)",
4947                          f->full_name);
4948       return false;
4949     }
4950 
4951     if (oneof_index >= m->oneof_count) {
4952       upb_status_seterrf(ctx->status, "oneof_index out of range (%s)",
4953                          f->full_name);
4954       return false;
4955     }
4956 
4957     oneof = (upb_oneofdef*)&m->oneofs[oneof_index];
4958     f->oneof = oneof;
4959 
4960     CHK(upb_inttable_insert2(&oneof->itof, f->number_, v, alloc));
4961     CHK(upb_strtable_insert3(&oneof->ntof, name.data, name.size, v, alloc));
4962   } else {
4963     f->oneof = NULL;
4964   }
4965 
4966   options = google_protobuf_FieldDescriptorProto_has_options(field_proto) ?
4967     google_protobuf_FieldDescriptorProto_options(field_proto) : NULL;
4968 
4969   if (options && google_protobuf_FieldOptions_has_packed(options)) {
4970     f->packed_ = google_protobuf_FieldOptions_packed(options);
4971   } else {
4972     /* Repeated fields default to packed for proto3 only. */
4973     f->packed_ = upb_fielddef_isprimitive(f) &&
4974         f->label_ == UPB_LABEL_REPEATED && f->file->syntax == UPB_SYNTAX_PROTO3;
4975   }
4976 
4977   if (options) {
4978     f->lazy_ = google_protobuf_FieldOptions_lazy(options);
4979   } else {
4980     f->lazy_ = false;
4981   }
4982 
4983   return true;
4984 }
4985 
create_enumdef(const symtab_addctx * ctx,const char * prefix,const google_protobuf_EnumDescriptorProto * enum_proto)4986 static bool create_enumdef(
4987     const symtab_addctx *ctx, const char *prefix,
4988     const google_protobuf_EnumDescriptorProto *enum_proto) {
4989   upb_enumdef *e;
4990   const google_protobuf_EnumValueDescriptorProto *const *values;
4991   upb_strview name;
4992   size_t i, n;
4993 
4994   name = google_protobuf_EnumDescriptorProto_name(enum_proto);
4995   CHK(upb_isident(name, false, ctx->status));
4996 
4997   e = (upb_enumdef*)&ctx->file->enums[ctx->file->enum_count++];
4998   e->full_name = makefullname(ctx, prefix, name);
4999   CHK_OOM(symtab_add(ctx, e->full_name, pack_def(e, UPB_DEFTYPE_ENUM)));
5000 
5001   CHK_OOM(upb_strtable_init2(&e->ntoi, UPB_CTYPE_INT32, ctx->alloc));
5002   CHK_OOM(upb_inttable_init2(&e->iton, UPB_CTYPE_CSTR, ctx->alloc));
5003 
5004   e->file = ctx->file;
5005   e->defaultval = 0;
5006 
5007   values = google_protobuf_EnumDescriptorProto_value(enum_proto, &n);
5008 
5009   if (n == 0) {
5010     upb_status_seterrf(ctx->status,
5011                        "enums must contain at least one value (%s)",
5012                        e->full_name);
5013     return false;
5014   }
5015 
5016   for (i = 0; i < n; i++) {
5017     const google_protobuf_EnumValueDescriptorProto *value = values[i];
5018     upb_strview name = google_protobuf_EnumValueDescriptorProto_name(value);
5019     char *name2 = strviewdup(ctx, name);
5020     int32_t num = google_protobuf_EnumValueDescriptorProto_number(value);
5021     upb_value v = upb_value_int32(num);
5022 
5023     if (i == 0 && e->file->syntax == UPB_SYNTAX_PROTO3 && num != 0) {
5024       upb_status_seterrf(ctx->status,
5025                          "for proto3, the first enum value must be zero (%s)",
5026                          e->full_name);
5027       return false;
5028     }
5029 
5030     if (upb_strtable_lookup(&e->ntoi, name2, NULL)) {
5031       upb_status_seterrf(ctx->status, "duplicate enum label '%s'", name2);
5032       return false;
5033     }
5034 
5035     CHK_OOM(name2)
5036     CHK_OOM(
5037         upb_strtable_insert3(&e->ntoi, name2, strlen(name2), v, ctx->alloc));
5038 
5039     if (!upb_inttable_lookup(&e->iton, num, NULL)) {
5040       upb_value v = upb_value_cstr(name2);
5041       CHK_OOM(upb_inttable_insert2(&e->iton, num, v, ctx->alloc));
5042     }
5043   }
5044 
5045   upb_inttable_compact2(&e->iton, ctx->alloc);
5046 
5047   return true;
5048 }
5049 
create_msgdef(symtab_addctx * ctx,const char * prefix,const google_protobuf_DescriptorProto * msg_proto)5050 static bool create_msgdef(symtab_addctx *ctx, const char *prefix,
5051                           const google_protobuf_DescriptorProto *msg_proto) {
5052   upb_msgdef *m;
5053   const google_protobuf_MessageOptions *options;
5054   const google_protobuf_OneofDescriptorProto *const *oneofs;
5055   const google_protobuf_FieldDescriptorProto *const *fields;
5056   const google_protobuf_EnumDescriptorProto *const *enums;
5057   const google_protobuf_DescriptorProto *const *msgs;
5058   size_t i, n;
5059   upb_strview name;
5060 
5061   name = google_protobuf_DescriptorProto_name(msg_proto);
5062   CHK(upb_isident(name, false, ctx->status));
5063 
5064   m = (upb_msgdef*)&ctx->file->msgs[ctx->file->msg_count++];
5065   m->full_name = makefullname(ctx, prefix, name);
5066   CHK_OOM(symtab_add(ctx, m->full_name, pack_def(m, UPB_DEFTYPE_MSG)));
5067 
5068   CHK_OOM(upb_inttable_init2(&m->itof, UPB_CTYPE_CONSTPTR, ctx->alloc));
5069   CHK_OOM(upb_strtable_init2(&m->ntof, UPB_CTYPE_CONSTPTR, ctx->alloc));
5070 
5071   m->file = ctx->file;
5072   m->map_entry = false;
5073 
5074   options = google_protobuf_DescriptorProto_options(msg_proto);
5075 
5076   if (options) {
5077     m->map_entry = google_protobuf_MessageOptions_map_entry(options);
5078   }
5079 
5080   if (ctx->layouts) {
5081     m->layout = *ctx->layouts;
5082     ctx->layouts++;
5083   } else {
5084     /* Allocate now (to allow cross-linking), populate later. */
5085     m->layout = upb_malloc(ctx->alloc, sizeof(*m->layout));
5086   }
5087 
5088   oneofs = google_protobuf_DescriptorProto_oneof_decl(msg_proto, &n);
5089   m->oneof_count = 0;
5090   m->oneofs = upb_malloc(ctx->alloc, sizeof(*m->oneofs) * n);
5091   for (i = 0; i < n; i++) {
5092     CHK(create_oneofdef(ctx, m, oneofs[i]));
5093   }
5094 
5095   fields = google_protobuf_DescriptorProto_field(msg_proto, &n);
5096   m->field_count = 0;
5097   m->fields = upb_malloc(ctx->alloc, sizeof(*m->fields) * n);
5098   for (i = 0; i < n; i++) {
5099     CHK(create_fielddef(ctx, m->full_name, m, fields[i]));
5100   }
5101 
5102   CHK(assign_msg_indices(m, ctx->status));
5103   CHK(check_oneofs(m, ctx->status));
5104   assign_msg_wellknowntype(m);
5105   upb_inttable_compact2(&m->itof, ctx->alloc);
5106 
5107   /* This message is built.  Now build nested messages and enums. */
5108 
5109   enums = google_protobuf_DescriptorProto_enum_type(msg_proto, &n);
5110   for (i = 0; i < n; i++) {
5111     CHK(create_enumdef(ctx, m->full_name, enums[i]));
5112   }
5113 
5114   msgs = google_protobuf_DescriptorProto_nested_type(msg_proto, &n);
5115   for (i = 0; i < n; i++) {
5116     CHK(create_msgdef(ctx, m->full_name, msgs[i]));
5117   }
5118 
5119   return true;
5120 }
5121 
5122 typedef struct {
5123   int msg_count;
5124   int enum_count;
5125   int ext_count;
5126 } decl_counts;
5127 
count_types_in_msg(const google_protobuf_DescriptorProto * msg_proto,decl_counts * counts)5128 static void count_types_in_msg(const google_protobuf_DescriptorProto *msg_proto,
5129                                decl_counts *counts) {
5130   const google_protobuf_DescriptorProto *const *msgs;
5131   size_t i, n;
5132 
5133   counts->msg_count++;
5134 
5135   msgs = google_protobuf_DescriptorProto_nested_type(msg_proto, &n);
5136   for (i = 0; i < n; i++) {
5137     count_types_in_msg(msgs[i], counts);
5138   }
5139 
5140   google_protobuf_DescriptorProto_enum_type(msg_proto, &n);
5141   counts->enum_count += n;
5142 
5143   google_protobuf_DescriptorProto_extension(msg_proto, &n);
5144   counts->ext_count += n;
5145 }
5146 
count_types_in_file(const google_protobuf_FileDescriptorProto * file_proto,decl_counts * counts)5147 static void count_types_in_file(
5148     const google_protobuf_FileDescriptorProto *file_proto,
5149     decl_counts *counts) {
5150   const google_protobuf_DescriptorProto *const *msgs;
5151   size_t i, n;
5152 
5153   msgs = google_protobuf_FileDescriptorProto_message_type(file_proto, &n);
5154   for (i = 0; i < n; i++) {
5155     count_types_in_msg(msgs[i], counts);
5156   }
5157 
5158   google_protobuf_FileDescriptorProto_enum_type(file_proto, &n);
5159   counts->enum_count += n;
5160 
5161   google_protobuf_FileDescriptorProto_extension(file_proto, &n);
5162   counts->ext_count += n;
5163 }
5164 
resolve_fielddef(const symtab_addctx * ctx,const char * prefix,upb_fielddef * f)5165 static bool resolve_fielddef(const symtab_addctx *ctx, const char *prefix,
5166                              upb_fielddef *f) {
5167   upb_strview name;
5168   const google_protobuf_FieldDescriptorProto *field_proto = f->sub.unresolved;
5169 
5170   if (f->is_extension_) {
5171     if (!google_protobuf_FieldDescriptorProto_has_extendee(field_proto)) {
5172       upb_status_seterrf(ctx->status,
5173                          "extension for field '%s' had no extendee",
5174                          f->full_name);
5175       return false;
5176     }
5177 
5178     name = google_protobuf_FieldDescriptorProto_extendee(field_proto);
5179     f->msgdef = symtab_resolve(ctx, f, prefix, name, UPB_DEFTYPE_MSG);
5180     CHK(f->msgdef);
5181   }
5182 
5183   if ((upb_fielddef_issubmsg(f) || f->type_ == UPB_DESCRIPTOR_TYPE_ENUM) &&
5184       !google_protobuf_FieldDescriptorProto_has_type_name(field_proto)) {
5185     upb_status_seterrf(ctx->status, "field '%s' is missing type name",
5186                        f->full_name);
5187     return false;
5188   }
5189 
5190   name = google_protobuf_FieldDescriptorProto_type_name(field_proto);
5191 
5192   if (upb_fielddef_issubmsg(f)) {
5193     f->sub.msgdef = symtab_resolve(ctx, f, prefix, name, UPB_DEFTYPE_MSG);
5194     CHK(f->sub.msgdef);
5195   } else if (f->type_ == UPB_DESCRIPTOR_TYPE_ENUM) {
5196     f->sub.enumdef = symtab_resolve(ctx, f, prefix, name, UPB_DEFTYPE_ENUM);
5197     CHK(f->sub.enumdef);
5198   }
5199 
5200   /* Have to delay resolving of the default value until now because of the enum
5201    * case, since enum defaults are specified with a label. */
5202   if (google_protobuf_FieldDescriptorProto_has_default_value(field_proto)) {
5203     upb_strview defaultval =
5204         google_protobuf_FieldDescriptorProto_default_value(field_proto);
5205 
5206     if (f->file->syntax == UPB_SYNTAX_PROTO3) {
5207       upb_status_seterrf(ctx->status,
5208                          "proto3 fields cannot have explicit defaults (%s)",
5209                          f->full_name);
5210       return false;
5211     }
5212 
5213     if (upb_fielddef_issubmsg(f)) {
5214       upb_status_seterrf(ctx->status,
5215                          "message fields cannot have explicit defaults (%s)",
5216                          f->full_name);
5217       return false;
5218     }
5219 
5220     if (!parse_default(ctx, defaultval.data, defaultval.size, f)) {
5221       upb_status_seterrf(ctx->status,
5222                          "couldn't parse default '" UPB_STRVIEW_FORMAT
5223                          "' for field (%s)",
5224                          UPB_STRVIEW_ARGS(defaultval), f->full_name);
5225       return false;
5226     }
5227   } else {
5228     set_default_default(ctx, f);
5229   }
5230 
5231   return true;
5232 }
5233 
build_filedef(symtab_addctx * ctx,upb_filedef * file,const google_protobuf_FileDescriptorProto * file_proto)5234 static bool build_filedef(
5235     symtab_addctx *ctx, upb_filedef *file,
5236     const google_protobuf_FileDescriptorProto *file_proto) {
5237   upb_alloc *alloc = ctx->alloc;
5238   const google_protobuf_FileOptions *file_options_proto;
5239   const google_protobuf_DescriptorProto *const *msgs;
5240   const google_protobuf_EnumDescriptorProto *const *enums;
5241   const google_protobuf_FieldDescriptorProto *const *exts;
5242   const upb_strview* strs;
5243   size_t i, n;
5244   decl_counts counts = {0, 0, 0};
5245 
5246   count_types_in_file(file_proto, &counts);
5247 
5248   file->msgs = upb_malloc(alloc, sizeof(*file->msgs) * counts.msg_count);
5249   file->enums = upb_malloc(alloc, sizeof(*file->enums) * counts.enum_count);
5250   file->exts = upb_malloc(alloc, sizeof(*file->exts) * counts.ext_count);
5251 
5252   CHK_OOM(counts.msg_count == 0 || file->msgs);
5253   CHK_OOM(counts.enum_count == 0 || file->enums);
5254   CHK_OOM(counts.ext_count == 0 || file->exts);
5255 
5256   /* We increment these as defs are added. */
5257   file->msg_count = 0;
5258   file->enum_count = 0;
5259   file->ext_count = 0;
5260 
5261   if (!google_protobuf_FileDescriptorProto_has_name(file_proto)) {
5262     upb_status_seterrmsg(ctx->status, "File has no name");
5263     return false;
5264   }
5265 
5266   file->name =
5267       strviewdup(ctx, google_protobuf_FileDescriptorProto_name(file_proto));
5268   file->phpprefix = NULL;
5269   file->phpnamespace = NULL;
5270 
5271   if (google_protobuf_FileDescriptorProto_has_package(file_proto)) {
5272     upb_strview package =
5273         google_protobuf_FileDescriptorProto_package(file_proto);
5274     CHK(upb_isident(package, true, ctx->status));
5275     file->package = strviewdup(ctx, package);
5276   } else {
5277     file->package = NULL;
5278   }
5279 
5280   if (google_protobuf_FileDescriptorProto_has_syntax(file_proto)) {
5281     upb_strview syntax =
5282         google_protobuf_FileDescriptorProto_syntax(file_proto);
5283 
5284     if (streql_view(syntax, "proto2")) {
5285       file->syntax = UPB_SYNTAX_PROTO2;
5286     } else if (streql_view(syntax, "proto3")) {
5287       file->syntax = UPB_SYNTAX_PROTO3;
5288     } else {
5289       upb_status_seterrf(ctx->status, "Invalid syntax '" UPB_STRVIEW_FORMAT "'",
5290                          UPB_STRVIEW_ARGS(syntax));
5291       return false;
5292     }
5293   } else {
5294     file->syntax = UPB_SYNTAX_PROTO2;
5295   }
5296 
5297   /* Read options. */
5298   file_options_proto = google_protobuf_FileDescriptorProto_options(file_proto);
5299   if (file_options_proto) {
5300     if (google_protobuf_FileOptions_has_php_class_prefix(file_options_proto)) {
5301       file->phpprefix = strviewdup(
5302           ctx,
5303           google_protobuf_FileOptions_php_class_prefix(file_options_proto));
5304     }
5305     if (google_protobuf_FileOptions_has_php_namespace(file_options_proto)) {
5306       file->phpnamespace = strviewdup(
5307           ctx, google_protobuf_FileOptions_php_namespace(file_options_proto));
5308     }
5309   }
5310 
5311   /* Verify dependencies. */
5312   strs = google_protobuf_FileDescriptorProto_dependency(file_proto, &n);
5313   file->deps = upb_malloc(alloc, sizeof(*file->deps) * n) ;
5314   CHK_OOM(n == 0 || file->deps);
5315 
5316   for (i = 0; i < n; i++) {
5317     upb_strview dep_name = strs[i];
5318     upb_value v;
5319     if (!upb_strtable_lookup2(&ctx->symtab->files, dep_name.data,
5320                               dep_name.size, &v)) {
5321       upb_status_seterrf(ctx->status,
5322                          "Depends on file '" UPB_STRVIEW_FORMAT
5323                          "', but it has not been loaded",
5324                          UPB_STRVIEW_ARGS(dep_name));
5325       return false;
5326     }
5327     file->deps[i] = upb_value_getconstptr(v);
5328   }
5329 
5330   /* Create messages. */
5331   msgs = google_protobuf_FileDescriptorProto_message_type(file_proto, &n);
5332   for (i = 0; i < n; i++) {
5333     CHK(create_msgdef(ctx, file->package, msgs[i]));
5334   }
5335 
5336   /* Create enums. */
5337   enums = google_protobuf_FileDescriptorProto_enum_type(file_proto, &n);
5338   for (i = 0; i < n; i++) {
5339     CHK(create_enumdef(ctx, file->package, enums[i]));
5340   }
5341 
5342   /* Create extensions. */
5343   exts = google_protobuf_FileDescriptorProto_extension(file_proto, &n);
5344   file->exts = upb_malloc(alloc, sizeof(*file->exts) * n);
5345   CHK_OOM(n == 0 || file->exts);
5346   for (i = 0; i < n; i++) {
5347     CHK(create_fielddef(ctx, file->package, NULL, exts[i]));
5348   }
5349 
5350   /* Now that all names are in the table, build layouts and resolve refs. */
5351   for (i = 0; i < (size_t)file->ext_count; i++) {
5352     CHK(resolve_fielddef(ctx, file->package, (upb_fielddef*)&file->exts[i]));
5353   }
5354 
5355   for (i = 0; i < (size_t)file->msg_count; i++) {
5356     const upb_msgdef *m = &file->msgs[i];
5357     int j;
5358     for (j = 0; j < m->field_count; j++) {
5359       CHK(resolve_fielddef(ctx, m->full_name, (upb_fielddef*)&m->fields[j]));
5360     }
5361   }
5362 
5363   if (!ctx->layouts) {
5364     for (i = 0; i < (size_t)file->msg_count; i++) {
5365       const upb_msgdef *m = &file->msgs[i];
5366       make_layout(ctx->symtab, m);
5367     }
5368   }
5369 
5370   return true;
5371  }
5372 
upb_symtab_addtotabs(upb_symtab * s,symtab_addctx * ctx)5373 static bool upb_symtab_addtotabs(upb_symtab *s, symtab_addctx *ctx) {
5374   const upb_filedef *file = ctx->file;
5375   upb_alloc *alloc = upb_arena_alloc(s->arena);
5376   upb_strtable_iter iter;
5377 
5378   CHK_OOM(upb_strtable_insert3(&s->files, file->name, strlen(file->name),
5379                                upb_value_constptr(file), alloc));
5380 
5381   upb_strtable_begin(&iter, ctx->addtab);
5382   for (; !upb_strtable_done(&iter); upb_strtable_next(&iter)) {
5383     upb_strview key = upb_strtable_iter_key(&iter);
5384     upb_value value = upb_strtable_iter_value(&iter);
5385     CHK_OOM(upb_strtable_insert3(&s->syms, key.data, key.size, value, alloc));
5386   }
5387 
5388   return true;
5389 }
5390 
5391 /* upb_filedef ****************************************************************/
5392 
upb_filedef_name(const upb_filedef * f)5393 const char *upb_filedef_name(const upb_filedef *f) {
5394   return f->name;
5395 }
5396 
upb_filedef_package(const upb_filedef * f)5397 const char *upb_filedef_package(const upb_filedef *f) {
5398   return f->package;
5399 }
5400 
upb_filedef_phpprefix(const upb_filedef * f)5401 const char *upb_filedef_phpprefix(const upb_filedef *f) {
5402   return f->phpprefix;
5403 }
5404 
upb_filedef_phpnamespace(const upb_filedef * f)5405 const char *upb_filedef_phpnamespace(const upb_filedef *f) {
5406   return f->phpnamespace;
5407 }
5408 
upb_filedef_syntax(const upb_filedef * f)5409 upb_syntax_t upb_filedef_syntax(const upb_filedef *f) {
5410   return f->syntax;
5411 }
5412 
upb_filedef_msgcount(const upb_filedef * f)5413 int upb_filedef_msgcount(const upb_filedef *f) {
5414   return f->msg_count;
5415 }
5416 
upb_filedef_depcount(const upb_filedef * f)5417 int upb_filedef_depcount(const upb_filedef *f) {
5418   return f->dep_count;
5419 }
5420 
upb_filedef_enumcount(const upb_filedef * f)5421 int upb_filedef_enumcount(const upb_filedef *f) {
5422   return f->enum_count;
5423 }
5424 
upb_filedef_dep(const upb_filedef * f,int i)5425 const upb_filedef *upb_filedef_dep(const upb_filedef *f, int i) {
5426   return i < 0 || i >= f->dep_count ? NULL : f->deps[i];
5427 }
5428 
upb_filedef_msg(const upb_filedef * f,int i)5429 const upb_msgdef *upb_filedef_msg(const upb_filedef *f, int i) {
5430   return i < 0 || i >= f->msg_count ? NULL : &f->msgs[i];
5431 }
5432 
upb_filedef_enum(const upb_filedef * f,int i)5433 const upb_enumdef *upb_filedef_enum(const upb_filedef *f, int i) {
5434   return i < 0 || i >= f->enum_count ? NULL : &f->enums[i];
5435 }
5436 
upb_symtab_free(upb_symtab * s)5437 void upb_symtab_free(upb_symtab *s) {
5438   upb_arena_free(s->arena);
5439   upb_gfree(s);
5440 }
5441 
upb_symtab_new(void)5442 upb_symtab *upb_symtab_new(void) {
5443   upb_symtab *s = upb_gmalloc(sizeof(*s));
5444   upb_alloc *alloc;
5445 
5446   if (!s) {
5447     return NULL;
5448   }
5449 
5450   s->arena = upb_arena_new();
5451   alloc = upb_arena_alloc(s->arena);
5452 
5453   if (!upb_strtable_init2(&s->syms, UPB_CTYPE_CONSTPTR, alloc) ||
5454       !upb_strtable_init2(&s->files, UPB_CTYPE_CONSTPTR, alloc)) {
5455     upb_arena_free(s->arena);
5456     upb_gfree(s);
5457     s = NULL;
5458   }
5459   return s;
5460 }
5461 
upb_symtab_lookupmsg(const upb_symtab * s,const char * sym)5462 const upb_msgdef *upb_symtab_lookupmsg(const upb_symtab *s, const char *sym) {
5463   upb_value v;
5464   return upb_strtable_lookup(&s->syms, sym, &v) ?
5465       unpack_def(v, UPB_DEFTYPE_MSG) : NULL;
5466 }
5467 
upb_symtab_lookupmsg2(const upb_symtab * s,const char * sym,size_t len)5468 const upb_msgdef *upb_symtab_lookupmsg2(const upb_symtab *s, const char *sym,
5469                                         size_t len) {
5470   upb_value v;
5471   return upb_strtable_lookup2(&s->syms, sym, len, &v) ?
5472       unpack_def(v, UPB_DEFTYPE_MSG) : NULL;
5473 }
5474 
upb_symtab_lookupenum(const upb_symtab * s,const char * sym)5475 const upb_enumdef *upb_symtab_lookupenum(const upb_symtab *s, const char *sym) {
5476   upb_value v;
5477   return upb_strtable_lookup(&s->syms, sym, &v) ?
5478       unpack_def(v, UPB_DEFTYPE_ENUM) : NULL;
5479 }
5480 
upb_symtab_lookupfile(const upb_symtab * s,const char * name)5481 const upb_filedef *upb_symtab_lookupfile(const upb_symtab *s, const char *name) {
5482   upb_value v;
5483   return upb_strtable_lookup(&s->files, name, &v) ? upb_value_getconstptr(v)
5484                                                   : NULL;
5485 }
5486 
upb_symtab_lookupfile2(const upb_symtab * s,const char * name,size_t len)5487 const upb_filedef *upb_symtab_lookupfile2(
5488     const upb_symtab *s, const char *name, size_t len) {
5489   upb_value v;
5490   return upb_strtable_lookup2(&s->files, name, len, &v) ?
5491       upb_value_getconstptr(v) : NULL;
5492 }
5493 
upb_symtab_filecount(const upb_symtab * s)5494 int upb_symtab_filecount(const upb_symtab *s) {
5495   return (int)upb_strtable_count(&s->files);
5496 }
5497 
_upb_symtab_addfile(upb_symtab * s,const google_protobuf_FileDescriptorProto * file_proto,const upb_msglayout ** layouts,upb_status * status)5498 static const upb_filedef *_upb_symtab_addfile(
5499     upb_symtab *s, const google_protobuf_FileDescriptorProto *file_proto,
5500     const upb_msglayout **layouts, upb_status *status) {
5501   upb_arena *tmparena = upb_arena_new();
5502   upb_strtable addtab;
5503   upb_alloc *alloc = upb_arena_alloc(s->arena);
5504   upb_filedef *file = upb_malloc(alloc, sizeof(*file));
5505   bool ok;
5506   symtab_addctx ctx;
5507 
5508   ctx.file = file;
5509   ctx.symtab = s;
5510   ctx.alloc = alloc;
5511   ctx.tmp = upb_arena_alloc(tmparena);
5512   ctx.addtab = &addtab;
5513   ctx.layouts = layouts;
5514   ctx.status = status;
5515 
5516   ok = file && upb_strtable_init2(&addtab, UPB_CTYPE_CONSTPTR, ctx.tmp) &&
5517        build_filedef(&ctx, file, file_proto) && upb_symtab_addtotabs(s, &ctx);
5518 
5519   upb_arena_free(tmparena);
5520   return ok ? file : NULL;
5521 }
5522 
upb_symtab_addfile(upb_symtab * s,const google_protobuf_FileDescriptorProto * file_proto,upb_status * status)5523 const upb_filedef *upb_symtab_addfile(
5524     upb_symtab *s, const google_protobuf_FileDescriptorProto *file_proto,
5525     upb_status *status) {
5526   return _upb_symtab_addfile(s, file_proto, NULL, status);
5527 }
5528 
5529 /* Include here since we want most of this file to be stdio-free. */
5530 #include <stdio.h>
5531 
_upb_symtab_loaddefinit(upb_symtab * s,const upb_def_init * init)5532 bool _upb_symtab_loaddefinit(upb_symtab *s, const upb_def_init *init) {
5533   /* Since this function should never fail (it would indicate a bug in upb) we
5534    * print errors to stderr instead of returning error status to the user. */
5535   upb_def_init **deps = init->deps;
5536   google_protobuf_FileDescriptorProto *file;
5537   upb_arena *arena;
5538   upb_status status;
5539 
5540   upb_status_clear(&status);
5541 
5542   if (upb_strtable_lookup(&s->files, init->filename, NULL)) {
5543     return true;
5544   }
5545 
5546   arena = upb_arena_new();
5547 
5548   for (; *deps; deps++) {
5549     if (!_upb_symtab_loaddefinit(s, *deps)) goto err;
5550   }
5551 
5552   file = google_protobuf_FileDescriptorProto_parse(
5553       init->descriptor.data, init->descriptor.size, arena);
5554 
5555   if (!file) {
5556     upb_status_seterrf(
5557         &status,
5558         "Failed to parse compiled-in descriptor for file '%s'. This should "
5559         "never happen.",
5560         init->filename);
5561     goto err;
5562   }
5563 
5564   if (!_upb_symtab_addfile(s, file, init->layouts, &status)) goto err;
5565 
5566   upb_arena_free(arena);
5567   return true;
5568 
5569 err:
5570   fprintf(stderr, "Error loading compiled-in descriptor: %s\n",
5571           upb_status_errmsg(&status));
5572   upb_arena_free(arena);
5573   return false;
5574 }
5575 
5576 #undef CHK
5577 #undef CHK_OOM
5578 
5579 
5580 #include <string.h>
5581 
5582 
get_field_size(const upb_msglayout_field * f)5583 static size_t get_field_size(const upb_msglayout_field *f) {
5584   static unsigned char sizes[] = {
5585     0,/* 0 */
5586     8, /* UPB_DESCRIPTOR_TYPE_DOUBLE */
5587     4, /* UPB_DESCRIPTOR_TYPE_FLOAT */
5588     8, /* UPB_DESCRIPTOR_TYPE_INT64 */
5589     8, /* UPB_DESCRIPTOR_TYPE_UINT64 */
5590     4, /* UPB_DESCRIPTOR_TYPE_INT32 */
5591     8, /* UPB_DESCRIPTOR_TYPE_FIXED64 */
5592     4, /* UPB_DESCRIPTOR_TYPE_FIXED32 */
5593     1, /* UPB_DESCRIPTOR_TYPE_BOOL */
5594     sizeof(upb_strview), /* UPB_DESCRIPTOR_TYPE_STRING */
5595     sizeof(void*), /* UPB_DESCRIPTOR_TYPE_GROUP */
5596     sizeof(void*), /* UPB_DESCRIPTOR_TYPE_MESSAGE */
5597     sizeof(upb_strview), /* UPB_DESCRIPTOR_TYPE_BYTES */
5598     4, /* UPB_DESCRIPTOR_TYPE_UINT32 */
5599     4, /* UPB_DESCRIPTOR_TYPE_ENUM */
5600     4, /* UPB_DESCRIPTOR_TYPE_SFIXED32 */
5601     8, /* UPB_DESCRIPTOR_TYPE_SFIXED64 */
5602     4, /* UPB_DESCRIPTOR_TYPE_SINT32 */
5603     8, /* UPB_DESCRIPTOR_TYPE_SINT64 */
5604   };
5605   return _upb_repeated_or_map(f) ? sizeof(void *) : sizes[f->descriptortype];
5606 }
5607 
5608 /* Strings/bytes are special-cased in maps. */
5609 static char _upb_fieldtype_to_mapsize[12] = {
5610   0,
5611   1,  /* UPB_TYPE_BOOL */
5612   4,  /* UPB_TYPE_FLOAT */
5613   4,  /* UPB_TYPE_INT32 */
5614   4,  /* UPB_TYPE_UINT32 */
5615   4,  /* UPB_TYPE_ENUM */
5616   sizeof(void*),  /* UPB_TYPE_MESSAGE */
5617   8,  /* UPB_TYPE_DOUBLE */
5618   8,  /* UPB_TYPE_INT64 */
5619   8,  /* UPB_TYPE_UINT64 */
5620   0,  /* UPB_TYPE_STRING */
5621   0,  /* UPB_TYPE_BYTES */
5622 };
5623 
5624 /** upb_msg *******************************************************************/
5625 
upb_msg_new(const upb_msgdef * m,upb_arena * a)5626 upb_msg *upb_msg_new(const upb_msgdef *m, upb_arena *a) {
5627   return _upb_msg_new(upb_msgdef_layout(m), a);
5628 }
5629 
in_oneof(const upb_msglayout_field * field)5630 static bool in_oneof(const upb_msglayout_field *field) {
5631   return field->presence < 0;
5632 }
5633 
_upb_msg_getraw(const upb_msg * msg,const upb_fielddef * f)5634 static upb_msgval _upb_msg_getraw(const upb_msg *msg, const upb_fielddef *f) {
5635   const upb_msglayout_field *field = upb_fielddef_layout(f);
5636   const char *mem = UPB_PTR_AT(msg, field->offset, char);
5637   upb_msgval val = {0};
5638   memcpy(&val, mem, get_field_size(field));
5639   return val;
5640 }
5641 
upb_msg_has(const upb_msg * msg,const upb_fielddef * f)5642 bool upb_msg_has(const upb_msg *msg, const upb_fielddef *f) {
5643   const upb_msglayout_field *field = upb_fielddef_layout(f);
5644   if (in_oneof(field)) {
5645     return _upb_getoneofcase_field(msg, field) == field->number;
5646   } else if (field->presence > 0) {
5647     return _upb_hasbit_field(msg, field);
5648   } else {
5649     UPB_ASSERT(field->descriptortype == UPB_DESCRIPTOR_TYPE_MESSAGE ||
5650                field->descriptortype == UPB_DESCRIPTOR_TYPE_GROUP);
5651     return _upb_msg_getraw(msg, f).msg_val != NULL;
5652   }
5653 }
5654 
upb_msg_whichoneof(const upb_msg * msg,const upb_oneofdef * o)5655 const upb_fielddef *upb_msg_whichoneof(const upb_msg *msg,
5656                                        const upb_oneofdef *o) {
5657   upb_oneof_iter i;
5658   const upb_fielddef *f;
5659   const upb_msglayout_field *field;
5660   const upb_msgdef *m = upb_oneofdef_containingtype(o);
5661   uint32_t oneof_case;
5662 
5663   /* This is far from optimal. */
5664   upb_oneof_begin(&i, o);
5665   if (upb_oneof_done(&i)) return false;
5666   f = upb_oneof_iter_field(&i);
5667   field = upb_fielddef_layout(f);
5668   if (in_oneof(field)) {
5669     oneof_case = _upb_getoneofcase_field(msg, field);
5670   } else {
5671     return _upb_hasbit_field(msg, field) ? f : NULL;
5672   }
5673 
5674   return oneof_case ? upb_msgdef_itof(m, oneof_case) : NULL;
5675 }
5676 
upb_msg_get(const upb_msg * msg,const upb_fielddef * f)5677 upb_msgval upb_msg_get(const upb_msg *msg, const upb_fielddef *f) {
5678   if (!upb_fielddef_haspresence(f) || upb_msg_has(msg, f)) {
5679     return _upb_msg_getraw(msg, f);
5680   } else {
5681     /* TODO(haberman): change upb_fielddef to not require this switch(). */
5682     upb_msgval val = {0};
5683     switch (upb_fielddef_type(f)) {
5684       case UPB_TYPE_INT32:
5685       case UPB_TYPE_ENUM:
5686         val.int32_val = upb_fielddef_defaultint32(f);
5687         break;
5688       case UPB_TYPE_INT64:
5689         val.int64_val = upb_fielddef_defaultint64(f);
5690         break;
5691       case UPB_TYPE_UINT32:
5692         val.uint32_val = upb_fielddef_defaultuint32(f);
5693         break;
5694       case UPB_TYPE_UINT64:
5695         val.uint64_val = upb_fielddef_defaultuint64(f);
5696         break;
5697       case UPB_TYPE_FLOAT:
5698         val.float_val = upb_fielddef_defaultfloat(f);
5699         break;
5700       case UPB_TYPE_DOUBLE:
5701         val.double_val = upb_fielddef_defaultdouble(f);
5702         break;
5703       case UPB_TYPE_BOOL:
5704         val.double_val = upb_fielddef_defaultbool(f);
5705         break;
5706       case UPB_TYPE_STRING:
5707       case UPB_TYPE_BYTES:
5708         val.str_val.data = upb_fielddef_defaultstr(f, &val.str_val.size);
5709         break;
5710       case UPB_TYPE_MESSAGE:
5711         val.msg_val = NULL;
5712         break;
5713     }
5714     return val;
5715   }
5716 }
5717 
upb_msg_mutable(upb_msg * msg,const upb_fielddef * f,upb_arena * a)5718 upb_mutmsgval upb_msg_mutable(upb_msg *msg, const upb_fielddef *f,
5719                               upb_arena *a) {
5720   const upb_msglayout_field *field = upb_fielddef_layout(f);
5721   upb_mutmsgval ret;
5722   char *mem = UPB_PTR_AT(msg, field->offset, char);
5723   bool wrong_oneof =
5724       in_oneof(field) && _upb_getoneofcase_field(msg, field) != field->number;
5725 
5726   memcpy(&ret, mem, sizeof(void*));
5727 
5728   if (a && (!ret.msg || wrong_oneof)) {
5729     if (upb_fielddef_ismap(f)) {
5730       const upb_msgdef *entry = upb_fielddef_msgsubdef(f);
5731       const upb_fielddef *key = upb_msgdef_itof(entry, UPB_MAPENTRY_KEY);
5732       const upb_fielddef *value = upb_msgdef_itof(entry, UPB_MAPENTRY_VALUE);
5733       ret.map = upb_map_new(a, upb_fielddef_type(key), upb_fielddef_type(value));
5734     } else if (upb_fielddef_isseq(f)) {
5735       ret.array = upb_array_new(a, upb_fielddef_type(f));
5736     } else {
5737       UPB_ASSERT(upb_fielddef_issubmsg(f));
5738       ret.msg = upb_msg_new(upb_fielddef_msgsubdef(f), a);
5739     }
5740 
5741     memcpy(mem, &ret, sizeof(void*));
5742 
5743     if (wrong_oneof) {
5744       *_upb_oneofcase_field(msg, field) = field->number;
5745     } else if (field->presence > 0) {
5746       _upb_sethas_field(msg, field);
5747     }
5748   }
5749   return ret;
5750 }
5751 
upb_msg_set(upb_msg * msg,const upb_fielddef * f,upb_msgval val,upb_arena * a)5752 void upb_msg_set(upb_msg *msg, const upb_fielddef *f, upb_msgval val,
5753                  upb_arena *a) {
5754   const upb_msglayout_field *field = upb_fielddef_layout(f);
5755   char *mem = UPB_PTR_AT(msg, field->offset, char);
5756   UPB_UNUSED(a);  /* We reserve the right to make set insert into a map. */
5757   memcpy(mem, &val, get_field_size(field));
5758   if (field->presence > 0) {
5759     _upb_sethas_field(msg, field);
5760   } else if (in_oneof(field)) {
5761     *_upb_oneofcase_field(msg, field) = field->number;
5762   }
5763 }
5764 
upb_msg_clearfield(upb_msg * msg,const upb_fielddef * f)5765 void upb_msg_clearfield(upb_msg *msg, const upb_fielddef *f) {
5766   const upb_msglayout_field *field = upb_fielddef_layout(f);
5767   char *mem = UPB_PTR_AT(msg, field->offset, char);
5768 
5769   if (field->presence > 0) {
5770     _upb_clearhas_field(msg, field);
5771   } else if (in_oneof(field)) {
5772     uint32_t *oneof_case = _upb_oneofcase_field(msg, field);
5773     if (*oneof_case != field->number) return;
5774     *oneof_case = 0;
5775   }
5776 
5777   memset(mem, 0, get_field_size(field));
5778 }
5779 
upb_msg_clear(upb_msg * msg,const upb_msgdef * m)5780 void upb_msg_clear(upb_msg *msg, const upb_msgdef *m) {
5781   _upb_msg_clear(msg, upb_msgdef_layout(m));
5782 }
5783 
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)5784 bool upb_msg_next(const upb_msg *msg, const upb_msgdef *m,
5785                   const upb_symtab *ext_pool, const upb_fielddef **out_f,
5786                   upb_msgval *out_val, size_t *iter) {
5787   size_t i = *iter;
5788   const upb_msgval zero = {0};
5789   const upb_fielddef *f;
5790   UPB_UNUSED(ext_pool);
5791   while ((f = _upb_msgdef_field(m, (int)++i)) != NULL) {
5792     upb_msgval val = _upb_msg_getraw(msg, f);
5793 
5794     /* Skip field if unset or empty. */
5795     if (upb_fielddef_haspresence(f)) {
5796       if (!upb_msg_has(msg, f)) continue;
5797     } else {
5798       upb_msgval test = val;
5799       if (upb_fielddef_isstring(f) && !upb_fielddef_isseq(f)) {
5800         /* Clear string pointer, only size matters (ptr could be non-NULL). */
5801         test.str_val.data = NULL;
5802       }
5803       /* Continue if NULL or 0. */
5804       if (memcmp(&test, &zero, sizeof(test)) == 0) continue;
5805 
5806       /* Continue on empty array or map. */
5807       if (upb_fielddef_ismap(f)) {
5808         if (upb_map_size(test.map_val) == 0) continue;
5809       } else if (upb_fielddef_isseq(f)) {
5810         if (upb_array_size(test.array_val) == 0) continue;
5811       }
5812     }
5813 
5814     *out_val = val;
5815     *out_f = f;
5816     *iter = i;
5817     return true;
5818   }
5819   *iter = i;
5820   return false;
5821 }
5822 
_upb_msg_discardunknown(upb_msg * msg,const upb_msgdef * m,int depth)5823 bool _upb_msg_discardunknown(upb_msg *msg, const upb_msgdef *m, int depth) {
5824   size_t iter = UPB_MSG_BEGIN;
5825   const upb_fielddef *f;
5826   upb_msgval val;
5827   bool ret = true;
5828 
5829   if (--depth == 0) return false;
5830 
5831   _upb_msg_discardunknown_shallow(msg);
5832 
5833   while (upb_msg_next(msg, m, NULL /*ext_pool*/, &f, &val, &iter)) {
5834     const upb_msgdef *subm = upb_fielddef_msgsubdef(f);
5835     if (!subm) continue;
5836     if (upb_fielddef_ismap(f)) {
5837       const upb_fielddef *val_f = upb_msgdef_itof(subm, 2);
5838       const upb_msgdef *val_m = upb_fielddef_msgsubdef(val_f);
5839       upb_map *map = (upb_map*)val.map_val;
5840       size_t iter = UPB_MAP_BEGIN;
5841 
5842       if (!val_m) continue;
5843 
5844       while (upb_mapiter_next(map, &iter)) {
5845         upb_msgval map_val = upb_mapiter_value(map, iter);
5846         if (!_upb_msg_discardunknown((upb_msg*)map_val.msg_val, val_m, depth)) {
5847           ret = false;
5848         }
5849       }
5850     } else if (upb_fielddef_isseq(f)) {
5851       const upb_array *arr = val.array_val;
5852       size_t i, n = upb_array_size(arr);
5853       for (i = 0; i < n; i++) {
5854         upb_msgval elem = upb_array_get(arr, i);
5855         if (!_upb_msg_discardunknown((upb_msg*)elem.msg_val, subm, depth)) {
5856           ret = false;
5857         }
5858       }
5859     } else {
5860       if (!_upb_msg_discardunknown((upb_msg*)val.msg_val, subm, depth)) {
5861         ret = false;
5862       }
5863     }
5864   }
5865 
5866   return ret;
5867 }
5868 
upb_msg_discardunknown(upb_msg * msg,const upb_msgdef * m,int maxdepth)5869 bool upb_msg_discardunknown(upb_msg *msg, const upb_msgdef *m, int maxdepth) {
5870   return _upb_msg_discardunknown(msg, m, maxdepth);
5871 }
5872 
5873 /** upb_array *****************************************************************/
5874 
upb_array_new(upb_arena * a,upb_fieldtype_t type)5875 upb_array *upb_array_new(upb_arena *a, upb_fieldtype_t type) {
5876   return _upb_array_new(a, type);
5877 }
5878 
upb_array_size(const upb_array * arr)5879 size_t upb_array_size(const upb_array *arr) {
5880   return arr->len;
5881 }
5882 
upb_array_get(const upb_array * arr,size_t i)5883 upb_msgval upb_array_get(const upb_array *arr, size_t i) {
5884   upb_msgval ret;
5885   const char* data = _upb_array_constptr(arr);
5886   int lg2 = arr->data & 7;
5887   UPB_ASSERT(i < arr->len);
5888   memcpy(&ret, data + (i << lg2), 1 << lg2);
5889   return ret;
5890 }
5891 
upb_array_set(upb_array * arr,size_t i,upb_msgval val)5892 void upb_array_set(upb_array *arr, size_t i, upb_msgval val) {
5893   char* data = _upb_array_ptr(arr);
5894   int lg2 = arr->data & 7;
5895   UPB_ASSERT(i < arr->len);
5896   memcpy(data + (i << lg2), &val, 1 << lg2);
5897 }
5898 
upb_array_append(upb_array * arr,upb_msgval val,upb_arena * arena)5899 bool upb_array_append(upb_array *arr, upb_msgval val, upb_arena *arena) {
5900   if (!_upb_array_realloc(arr, arr->len + 1, arena)) {
5901     return false;
5902   }
5903   arr->len++;
5904   upb_array_set(arr, arr->len - 1, val);
5905   return true;
5906 }
5907 
upb_array_resize(upb_array * arr,size_t size,upb_arena * arena)5908 bool upb_array_resize(upb_array *arr, size_t size, upb_arena *arena) {
5909   return _upb_array_resize(arr, size, arena);
5910 }
5911 
5912 /** upb_map *******************************************************************/
5913 
upb_map_new(upb_arena * a,upb_fieldtype_t key_type,upb_fieldtype_t value_type)5914 upb_map *upb_map_new(upb_arena *a, upb_fieldtype_t key_type,
5915                      upb_fieldtype_t value_type) {
5916   return _upb_map_new(a, _upb_fieldtype_to_mapsize[key_type],
5917                       _upb_fieldtype_to_mapsize[value_type]);
5918 }
5919 
upb_map_size(const upb_map * map)5920 size_t upb_map_size(const upb_map *map) {
5921   return _upb_map_size(map);
5922 }
5923 
upb_map_get(const upb_map * map,upb_msgval key,upb_msgval * val)5924 bool upb_map_get(const upb_map *map, upb_msgval key, upb_msgval *val) {
5925   return _upb_map_get(map, &key, map->key_size, val, map->val_size);
5926 }
5927 
upb_map_set(upb_map * map,upb_msgval key,upb_msgval val,upb_arena * arena)5928 bool upb_map_set(upb_map *map, upb_msgval key, upb_msgval val,
5929                  upb_arena *arena) {
5930   return _upb_map_set(map, &key, map->key_size, &val, map->val_size, arena);
5931 }
5932 
upb_map_delete(upb_map * map,upb_msgval key)5933 bool upb_map_delete(upb_map *map, upb_msgval key) {
5934   return _upb_map_delete(map, &key, map->key_size);
5935 }
5936 
upb_mapiter_next(const upb_map * map,size_t * iter)5937 bool upb_mapiter_next(const upb_map *map, size_t *iter) {
5938   return _upb_map_next(map, iter);
5939 }
5940 
upb_mapiter_done(const upb_map * map,size_t iter)5941 bool upb_mapiter_done(const upb_map *map, size_t iter) {
5942   upb_strtable_iter i;
5943   UPB_ASSERT(iter != UPB_MAP_BEGIN);
5944   i.t = &map->table;
5945   i.index = iter;
5946   return upb_strtable_done(&i);
5947 }
5948 
5949 /* Returns the key and value for this entry of the map. */
upb_mapiter_key(const upb_map * map,size_t iter)5950 upb_msgval upb_mapiter_key(const upb_map *map, size_t iter) {
5951   upb_strtable_iter i;
5952   upb_msgval ret;
5953   i.t = &map->table;
5954   i.index = iter;
5955   _upb_map_fromkey(upb_strtable_iter_key(&i), &ret, map->key_size);
5956   return ret;
5957 }
5958 
upb_mapiter_value(const upb_map * map,size_t iter)5959 upb_msgval upb_mapiter_value(const upb_map *map, size_t iter) {
5960   upb_strtable_iter i;
5961   upb_msgval ret;
5962   i.t = &map->table;
5963   i.index = iter;
5964   _upb_map_fromvalue(upb_strtable_iter_value(&i), &ret, map->val_size);
5965   return ret;
5966 }
5967 
5968 /* void upb_mapiter_setvalue(upb_map *map, size_t iter, upb_msgval value); */
5969 
5970 
5971 #ifdef UPB_MSVC_VSNPRINTF
5972 /* Visual C++ earlier than 2015 doesn't have standard C99 snprintf and
5973  * vsnprintf. To support them, missing functions are manually implemented
5974  * using the existing secure functions. */
msvc_vsnprintf(char * s,size_t n,const char * format,va_list arg)5975 int msvc_vsnprintf(char* s, size_t n, const char* format, va_list arg) {
5976   if (!s) {
5977     return _vscprintf(format, arg);
5978   }
5979   int ret = _vsnprintf_s(s, n, _TRUNCATE, format, arg);
5980   if (ret < 0) {
5981 	ret = _vscprintf(format, arg);
5982   }
5983   return ret;
5984 }
5985 
msvc_snprintf(char * s,size_t n,const char * format,...)5986 int msvc_snprintf(char* s, size_t n, const char* format, ...) {
5987   va_list arg;
5988   va_start(arg, format);
5989   int ret = msvc_vsnprintf(s, n, format, arg);
5990   va_end(arg);
5991   return ret;
5992 }
5993 #endif
5994 
5995 
5996 #include <errno.h>
5997 #include <float.h>
5998 #include <inttypes.h>
5999 #include <limits.h>
6000 #include <setjmp.h>
6001 #include <stdlib.h>
6002 #include <string.h>
6003 
6004 
6005 /* Special header, must be included last. */
6006 
6007 typedef struct {
6008   const char *ptr, *end;
6009   upb_arena *arena;  /* TODO: should we have a tmp arena for tmp data? */
6010   const upb_symtab *any_pool;
6011   int depth;
6012   upb_status *status;
6013   jmp_buf err;
6014   int line;
6015   const char *line_begin;
6016   bool is_first;
6017   int options;
6018   const upb_fielddef *debug_field;
6019 } jsondec;
6020 
6021 enum { JD_OBJECT, JD_ARRAY, JD_STRING, JD_NUMBER, JD_TRUE, JD_FALSE, JD_NULL };
6022 
6023 /* Forward declarations of mutually-recursive functions. */
6024 static void jsondec_wellknown(jsondec *d, upb_msg *msg, const upb_msgdef *m);
6025 static upb_msgval jsondec_value(jsondec *d, const upb_fielddef *f);
6026 static void jsondec_wellknownvalue(jsondec *d, upb_msg *msg,
6027                                    const upb_msgdef *m);
6028 static void jsondec_object(jsondec *d, upb_msg *msg, const upb_msgdef *m);
6029 
jsondec_streql(upb_strview str,const char * lit)6030 static bool jsondec_streql(upb_strview str, const char *lit) {
6031   return str.size == strlen(lit) && memcmp(str.data, lit, str.size) == 0;
6032 }
6033 
jsondec_err(jsondec * d,const char * msg)6034 UPB_NORETURN static void jsondec_err(jsondec *d, const char *msg) {
6035   upb_status_seterrf(d->status, "Error parsing JSON @%d:%d: %s", d->line,
6036                      (int)(d->ptr - d->line_begin), msg);
6037   longjmp(d->err, 1);
6038 }
6039 
jsondec_errf(jsondec * d,const char * fmt,...)6040 UPB_NORETURN static void jsondec_errf(jsondec *d, const char *fmt, ...) {
6041   va_list argp;
6042   upb_status_seterrf(d->status, "Error parsing JSON @%d:%d: ", d->line,
6043                      (int)(d->ptr - d->line_begin));
6044   va_start(argp, fmt);
6045   upb_status_vappenderrf(d->status, fmt, argp);
6046   va_end(argp);
6047   longjmp(d->err, 1);
6048 }
6049 
jsondec_skipws(jsondec * d)6050 static void jsondec_skipws(jsondec *d) {
6051   while (d->ptr != d->end) {
6052     switch (*d->ptr) {
6053       case '\n':
6054         d->line++;
6055         d->line_begin = d->ptr;
6056         /* Fallthrough. */
6057       case '\r':
6058       case '\t':
6059       case ' ':
6060         d->ptr++;
6061         break;
6062       default:
6063         return;
6064     }
6065   }
6066   jsondec_err(d, "Unexpected EOF");
6067 }
6068 
jsondec_tryparsech(jsondec * d,char ch)6069 static bool jsondec_tryparsech(jsondec *d, char ch) {
6070   if (d->ptr == d->end || *d->ptr != ch) return false;
6071   d->ptr++;
6072   return true;
6073 }
6074 
jsondec_parselit(jsondec * d,const char * lit)6075 static void jsondec_parselit(jsondec *d, const char *lit) {
6076   size_t avail = d->end - d->ptr;
6077   size_t len = strlen(lit);
6078   if (avail < len || memcmp(d->ptr, lit, len) != 0) {
6079     jsondec_errf(d, "Expected: '%s'", lit);
6080   }
6081   d->ptr += len;
6082 }
6083 
jsondec_wsch(jsondec * d,char ch)6084 static void jsondec_wsch(jsondec *d, char ch) {
6085   jsondec_skipws(d);
6086   if (!jsondec_tryparsech(d, ch)) {
6087     jsondec_errf(d, "Expected: '%c'", ch);
6088   }
6089 }
6090 
jsondec_true(jsondec * d)6091 static void jsondec_true(jsondec *d) { jsondec_parselit(d, "true"); }
jsondec_false(jsondec * d)6092 static void jsondec_false(jsondec *d) { jsondec_parselit(d, "false"); }
jsondec_null(jsondec * d)6093 static void jsondec_null(jsondec *d) { jsondec_parselit(d, "null"); }
6094 
jsondec_entrysep(jsondec * d)6095 static void jsondec_entrysep(jsondec *d) {
6096   jsondec_skipws(d);
6097   jsondec_parselit(d, ":");
6098 }
6099 
jsondec_rawpeek(jsondec * d)6100 static int jsondec_rawpeek(jsondec *d) {
6101   switch (*d->ptr) {
6102     case '{':
6103       return JD_OBJECT;
6104     case '[':
6105       return JD_ARRAY;
6106     case '"':
6107       return JD_STRING;
6108     case '-':
6109     case '0':
6110     case '1':
6111     case '2':
6112     case '3':
6113     case '4':
6114     case '5':
6115     case '6':
6116     case '7':
6117     case '8':
6118     case '9':
6119       return JD_NUMBER;
6120     case 't':
6121       return JD_TRUE;
6122     case 'f':
6123       return JD_FALSE;
6124     case 'n':
6125       return JD_NULL;
6126     default:
6127       jsondec_errf(d, "Unexpected character: '%c'", *d->ptr);
6128   }
6129 }
6130 
6131 /* JSON object/array **********************************************************/
6132 
6133 /* These are used like so:
6134  *
6135  * jsondec_objstart(d);
6136  * while (jsondec_objnext(d)) {
6137  *   ...
6138  * }
6139  * jsondec_objend(d) */
6140 
jsondec_peek(jsondec * d)6141 static int jsondec_peek(jsondec *d) {
6142   jsondec_skipws(d);
6143   return jsondec_rawpeek(d);
6144 }
6145 
jsondec_push(jsondec * d)6146 static void jsondec_push(jsondec *d) {
6147   if (--d->depth < 0) {
6148     jsondec_err(d, "Recursion limit exceeded");
6149   }
6150   d->is_first = true;
6151 }
6152 
jsondec_seqnext(jsondec * d,char end_ch)6153 static bool jsondec_seqnext(jsondec *d, char end_ch) {
6154   bool is_first = d->is_first;
6155   d->is_first = false;
6156   jsondec_skipws(d);
6157   if (*d->ptr == end_ch) return false;
6158   if (!is_first) jsondec_parselit(d, ",");
6159   return true;
6160 }
6161 
jsondec_arrstart(jsondec * d)6162 static void jsondec_arrstart(jsondec *d) {
6163   jsondec_push(d);
6164   jsondec_wsch(d, '[');
6165 }
6166 
jsondec_arrend(jsondec * d)6167 static void jsondec_arrend(jsondec *d) {
6168   d->depth++;
6169   jsondec_wsch(d, ']');
6170 }
6171 
jsondec_arrnext(jsondec * d)6172 static bool jsondec_arrnext(jsondec *d) {
6173   return jsondec_seqnext(d, ']');
6174 }
6175 
jsondec_objstart(jsondec * d)6176 static void jsondec_objstart(jsondec *d) {
6177   jsondec_push(d);
6178   jsondec_wsch(d, '{');
6179 }
6180 
jsondec_objend(jsondec * d)6181 static void jsondec_objend(jsondec *d) {
6182   d->depth++;
6183   jsondec_wsch(d, '}');
6184 }
6185 
jsondec_objnext(jsondec * d)6186 static bool jsondec_objnext(jsondec *d) {
6187   if (!jsondec_seqnext(d, '}')) return false;
6188   if (jsondec_peek(d) != JD_STRING) {
6189     jsondec_err(d, "Object must start with string");
6190   }
6191   return true;
6192 }
6193 
6194 /* JSON number ****************************************************************/
6195 
jsondec_tryskipdigits(jsondec * d)6196 static bool jsondec_tryskipdigits(jsondec *d) {
6197   const char *start = d->ptr;
6198 
6199   while (d->ptr < d->end) {
6200     if (*d->ptr < '0' || *d->ptr > '9') {
6201       break;
6202     }
6203     d->ptr++;
6204   }
6205 
6206   return d->ptr != start;
6207 }
6208 
jsondec_skipdigits(jsondec * d)6209 static void jsondec_skipdigits(jsondec *d) {
6210   if (!jsondec_tryskipdigits(d)) {
6211     jsondec_err(d, "Expected one or more digits");
6212   }
6213 }
6214 
jsondec_number(jsondec * d)6215 static double jsondec_number(jsondec *d) {
6216   const char *start = d->ptr;
6217 
6218   assert(jsondec_rawpeek(d) == JD_NUMBER);
6219 
6220   /* Skip over the syntax of a number, as specified by JSON. */
6221   if (*d->ptr == '-') d->ptr++;
6222 
6223   if (jsondec_tryparsech(d, '0')) {
6224     if (jsondec_tryskipdigits(d)) {
6225       jsondec_err(d, "number cannot have leading zero");
6226     }
6227   } else {
6228     jsondec_skipdigits(d);
6229   }
6230 
6231   if (d->ptr == d->end) goto parse;
6232   if (jsondec_tryparsech(d, '.')) {
6233     jsondec_skipdigits(d);
6234   }
6235   if (d->ptr == d->end) goto parse;
6236 
6237   if (*d->ptr == 'e' || *d->ptr == 'E') {
6238     d->ptr++;
6239     if (d->ptr == d->end) {
6240       jsondec_err(d, "Unexpected EOF in number");
6241     }
6242     if (*d->ptr == '+' || *d->ptr == '-') {
6243       d->ptr++;
6244     }
6245     jsondec_skipdigits(d);
6246   }
6247 
6248 parse:
6249   /* Having verified the syntax of a JSON number, use strtod() to parse
6250    * (strtod() accepts a superset of JSON syntax). */
6251   errno = 0;
6252   {
6253     char* end;
6254     double val = strtod(start, &end);
6255     assert(end == d->ptr);
6256 
6257     /* Currently the min/max-val conformance tests fail if we check this.  Does
6258      * this mean the conformance tests are wrong or strtod() is wrong, or
6259      * something else?  Investigate further. */
6260     /*
6261     if (errno == ERANGE) {
6262       jsondec_err(d, "Number out of range");
6263     }
6264     */
6265 
6266     if (val > DBL_MAX || val < -DBL_MAX) {
6267       jsondec_err(d, "Number out of range");
6268     }
6269 
6270     return val;
6271   }
6272 }
6273 
6274 /* JSON string ****************************************************************/
6275 
jsondec_escape(jsondec * d)6276 static char jsondec_escape(jsondec *d) {
6277   switch (*d->ptr++) {
6278     case '"':
6279       return '\"';
6280     case '\\':
6281       return '\\';
6282     case '/':
6283       return '/';
6284     case 'b':
6285       return '\b';
6286     case 'f':
6287       return '\f';
6288     case 'n':
6289       return '\n';
6290     case 'r':
6291       return '\r';
6292     case 't':
6293       return '\t';
6294     default:
6295       jsondec_err(d, "Invalid escape char");
6296   }
6297 }
6298 
jsondec_codepoint(jsondec * d)6299 static uint32_t jsondec_codepoint(jsondec *d) {
6300   uint32_t cp = 0;
6301   const char *end;
6302 
6303   if (d->end - d->ptr < 4) {
6304     jsondec_err(d, "EOF inside string");
6305   }
6306 
6307   end = d->ptr + 4;
6308   while (d->ptr < end) {
6309     char ch = *d->ptr++;
6310     if (ch >= '0' && ch <= '9') {
6311       ch -= '0';
6312     } else if (ch >= 'a' && ch <= 'f') {
6313       ch = ch - 'a' + 10;
6314     } else if (ch >= 'A' && ch <= 'F') {
6315       ch = ch - 'A' + 10;
6316     } else {
6317       jsondec_err(d, "Invalid hex digit");
6318     }
6319     cp = (cp << 4) | ch;
6320   }
6321 
6322   return cp;
6323 }
6324 
6325 /* Parses a \uXXXX unicode escape (possibly a surrogate pair). */
jsondec_unicode(jsondec * d,char * out)6326 static size_t jsondec_unicode(jsondec *d, char* out) {
6327   uint32_t cp = jsondec_codepoint(d);
6328   if (cp >= 0xd800 && cp <= 0xdbff) {
6329     /* Surrogate pair: two 16-bit codepoints become a 32-bit codepoint. */
6330     uint32_t high = cp;
6331     uint32_t low;
6332     jsondec_parselit(d, "\\u");
6333     low = jsondec_codepoint(d);
6334     if (low < 0xdc00 || low > 0xdfff) {
6335       jsondec_err(d, "Invalid low surrogate");
6336     }
6337     cp = (high & 0x3ff) << 10;
6338     cp |= (low & 0x3ff);
6339     cp += 0x10000;
6340   } else if (cp >= 0xdc00 && cp <= 0xdfff) {
6341     jsondec_err(d, "Unpaired low surrogate");
6342   }
6343 
6344   /* Write to UTF-8 */
6345   if (cp <= 0x7f) {
6346     out[0] = cp;
6347     return 1;
6348   } else if (cp <= 0x07FF) {
6349     out[0] = ((cp >> 6) & 0x1F) | 0xC0;
6350     out[1] = ((cp >> 0) & 0x3F) | 0x80;
6351     return 2;
6352   } else if (cp <= 0xFFFF) {
6353     out[0] = ((cp >> 12) & 0x0F) | 0xE0;
6354     out[1] = ((cp >> 6) & 0x3F) | 0x80;
6355     out[2] = ((cp >> 0) & 0x3F) | 0x80;
6356     return 3;
6357   } else if (cp < 0x10FFFF) {
6358     out[0] = ((cp >> 18) & 0x07) | 0xF0;
6359     out[1] = ((cp >> 12) & 0x3f) | 0x80;
6360     out[2] = ((cp >> 6) & 0x3f) | 0x80;
6361     out[3] = ((cp >> 0) & 0x3f) | 0x80;
6362     return 4;
6363   } else {
6364     jsondec_err(d, "Invalid codepoint");
6365   }
6366 }
6367 
jsondec_resize(jsondec * d,char ** buf,char ** end,char ** buf_end)6368 static void jsondec_resize(jsondec *d, char **buf, char **end, char **buf_end) {
6369   size_t oldsize = *buf_end - *buf;
6370   size_t len = *end - *buf;
6371   size_t size = UPB_MAX(8, 2 * oldsize);
6372 
6373   *buf = upb_arena_realloc(d->arena, *buf, len, size);
6374   *end = *buf + len;
6375   *buf_end = *buf + size;
6376 }
6377 
jsondec_string(jsondec * d)6378 static upb_strview jsondec_string(jsondec *d) {
6379   char *buf = NULL;
6380   char *end = NULL;
6381   char *buf_end = NULL;
6382 
6383   jsondec_skipws(d);
6384 
6385   if (*d->ptr++ != '"') {
6386     jsondec_err(d, "Expected string");
6387   }
6388 
6389   while (d->ptr < d->end) {
6390     char ch = *d->ptr++;
6391 
6392     if (end == buf_end) {
6393       jsondec_resize(d, &buf, &end, &buf_end);
6394     }
6395 
6396     switch (ch) {
6397       case '"': {
6398         upb_strview ret;
6399         ret.data = buf;
6400         ret.size = end - buf;
6401         *end = '\0';  /* Needed for possible strtod(). */
6402         return ret;
6403       }
6404       case '\\':
6405         if (d->ptr == d->end) goto eof;
6406         if (*d->ptr == 'u') {
6407           d->ptr++;
6408           if (buf_end - end < 4) {
6409             /* Allow space for maximum-sized code point (4 bytes). */
6410             jsondec_resize(d, &buf, &end, &buf_end);
6411           }
6412           end += jsondec_unicode(d, end);
6413         } else {
6414           *end++ = jsondec_escape(d);
6415         }
6416         break;
6417       default:
6418         if ((unsigned char)*d->ptr < 0x20) {
6419           jsondec_err(d, "Invalid char in JSON string");
6420         }
6421         *end++ = ch;
6422         break;
6423     }
6424   }
6425 
6426 eof:
6427   jsondec_err(d, "EOF inside string");
6428 }
6429 
jsondec_skipval(jsondec * d)6430 static void jsondec_skipval(jsondec *d) {
6431   switch (jsondec_peek(d)) {
6432     case JD_OBJECT:
6433       jsondec_objstart(d);
6434       while (jsondec_objnext(d)) {
6435         jsondec_string(d);
6436         jsondec_entrysep(d);
6437         jsondec_skipval(d);
6438       }
6439       jsondec_objend(d);
6440       break;
6441     case JD_ARRAY:
6442       jsondec_arrstart(d);
6443       while (jsondec_arrnext(d)) {
6444         jsondec_skipval(d);
6445       }
6446       jsondec_arrend(d);
6447       break;
6448     case JD_TRUE:
6449       jsondec_true(d);
6450       break;
6451     case JD_FALSE:
6452       jsondec_false(d);
6453       break;
6454     case JD_NULL:
6455       jsondec_null(d);
6456       break;
6457     case JD_STRING:
6458       jsondec_string(d);
6459       break;
6460     case JD_NUMBER:
6461       jsondec_number(d);
6462       break;
6463   }
6464 }
6465 
6466 /* Base64 decoding for bytes fields. ******************************************/
6467 
jsondec_base64_tablelookup(const char ch)6468 static unsigned int jsondec_base64_tablelookup(const char ch) {
6469   /* Table includes the normal base64 chars plus the URL-safe variant. */
6470   const signed char table[256] = {
6471       -1,       -1,       -1,       -1,       -1,       -1,        -1,
6472       -1,       -1,       -1,       -1,       -1,       -1,        -1,
6473       -1,       -1,       -1,       -1,       -1,       -1,        -1,
6474       -1,       -1,       -1,       -1,       -1,       -1,        -1,
6475       -1,       -1,       -1,       -1,       -1,       -1,        -1,
6476       -1,       -1,       -1,       -1,       -1,       -1,        -1,
6477       -1,       62 /*+*/, -1,       62 /*-*/, -1,       63 /*/ */, 52 /*0*/,
6478       53 /*1*/, 54 /*2*/, 55 /*3*/, 56 /*4*/, 57 /*5*/, 58 /*6*/,  59 /*7*/,
6479       60 /*8*/, 61 /*9*/, -1,       -1,       -1,       -1,        -1,
6480       -1,       -1,       0 /*A*/,  1 /*B*/,  2 /*C*/,  3 /*D*/,   4 /*E*/,
6481       5 /*F*/,  6 /*G*/,  07 /*H*/, 8 /*I*/,  9 /*J*/,  10 /*K*/,  11 /*L*/,
6482       12 /*M*/, 13 /*N*/, 14 /*O*/, 15 /*P*/, 16 /*Q*/, 17 /*R*/,  18 /*S*/,
6483       19 /*T*/, 20 /*U*/, 21 /*V*/, 22 /*W*/, 23 /*X*/, 24 /*Y*/,  25 /*Z*/,
6484       -1,       -1,       -1,       -1,       63 /*_*/, -1,        26 /*a*/,
6485       27 /*b*/, 28 /*c*/, 29 /*d*/, 30 /*e*/, 31 /*f*/, 32 /*g*/,  33 /*h*/,
6486       34 /*i*/, 35 /*j*/, 36 /*k*/, 37 /*l*/, 38 /*m*/, 39 /*n*/,  40 /*o*/,
6487       41 /*p*/, 42 /*q*/, 43 /*r*/, 44 /*s*/, 45 /*t*/, 46 /*u*/,  47 /*v*/,
6488       48 /*w*/, 49 /*x*/, 50 /*y*/, 51 /*z*/, -1,       -1,        -1,
6489       -1,       -1,       -1,       -1,       -1,       -1,        -1,
6490       -1,       -1,       -1,       -1,       -1,       -1,        -1,
6491       -1,       -1,       -1,       -1,       -1,       -1,        -1,
6492       -1,       -1,       -1,       -1,       -1,       -1,        -1,
6493       -1,       -1,       -1,       -1,       -1,       -1,        -1,
6494       -1,       -1,       -1,       -1,       -1,       -1,        -1,
6495       -1,       -1,       -1,       -1,       -1,       -1,        -1,
6496       -1,       -1,       -1,       -1,       -1,       -1,        -1,
6497       -1,       -1,       -1,       -1,       -1,       -1,        -1,
6498       -1,       -1,       -1,       -1,       -1,       -1,        -1,
6499       -1,       -1,       -1,       -1,       -1,       -1,        -1,
6500       -1,       -1,       -1,       -1,       -1,       -1,        -1,
6501       -1,       -1,       -1,       -1,       -1,       -1,        -1,
6502       -1,       -1,       -1,       -1,       -1,       -1,        -1,
6503       -1,       -1,       -1,       -1,       -1,       -1,        -1,
6504       -1,       -1,       -1,       -1,       -1,       -1,        -1,
6505       -1,       -1,       -1,       -1,       -1,       -1,        -1,
6506       -1,       -1,       -1,       -1,       -1,       -1,        -1,
6507       -1,       -1,       -1,       -1};
6508 
6509   /* Sign-extend return value so high bit will be set on any unexpected char. */
6510   return table[(unsigned)ch];
6511 }
6512 
jsondec_partialbase64(jsondec * d,const char * ptr,const char * end,char * out)6513 static char *jsondec_partialbase64(jsondec *d, const char *ptr, const char *end,
6514                                    char *out) {
6515   int32_t val = -1;
6516 
6517   switch (end - ptr) {
6518     case 2:
6519       val = jsondec_base64_tablelookup(ptr[0]) << 18 |
6520             jsondec_base64_tablelookup(ptr[1]) << 12;
6521       out[0] = val >> 16;
6522       out += 1;
6523       break;
6524     case 3:
6525       val = jsondec_base64_tablelookup(ptr[0]) << 18 |
6526             jsondec_base64_tablelookup(ptr[1]) << 12 |
6527             jsondec_base64_tablelookup(ptr[2]) << 6;
6528       out[0] = val >> 16;
6529       out[1] = (val >> 8) & 0xff;
6530       out += 2;
6531       break;
6532   }
6533 
6534   if (val < 0) {
6535     jsondec_err(d, "Corrupt base64");
6536   }
6537 
6538   return out;
6539 }
6540 
jsondec_base64(jsondec * d,upb_strview str)6541 static size_t jsondec_base64(jsondec *d, upb_strview str) {
6542   /* We decode in place. This is safe because this is a new buffer (not
6543    * aliasing the input) and because base64 decoding shrinks 4 bytes into 3. */
6544   char *out = (char*)str.data;
6545   const char *ptr = str.data;
6546   const char *end = ptr + str.size;
6547   const char *end4 = ptr + (str.size & -4);  /* Round down to multiple of 4. */
6548 
6549   for (; ptr < end4; ptr += 4, out += 3) {
6550     int val = jsondec_base64_tablelookup(ptr[0]) << 18 |
6551               jsondec_base64_tablelookup(ptr[1]) << 12 |
6552               jsondec_base64_tablelookup(ptr[2]) << 6 |
6553               jsondec_base64_tablelookup(ptr[3]) << 0;
6554 
6555     if (val < 0) {
6556       /* Junk chars or padding. Remove trailing padding, if any. */
6557       if (end - ptr == 4 && ptr[3] == '=') {
6558         if (ptr[2] == '=') {
6559           end -= 2;
6560         } else {
6561           end -= 1;
6562         }
6563       }
6564       break;
6565     }
6566 
6567     out[0] = val >> 16;
6568     out[1] = (val >> 8) & 0xff;
6569     out[2] = val & 0xff;
6570   }
6571 
6572   if (ptr < end) {
6573     /* Process remaining chars. We do not require padding. */
6574     out = jsondec_partialbase64(d, ptr, end, out);
6575   }
6576 
6577   return out - str.data;
6578 }
6579 
6580 /* Low-level integer parsing **************************************************/
6581 
6582 /* We use these hand-written routines instead of strto[u]l() because the "long
6583  * long" variants aren't in c89. Also our version allows setting a ptr limit. */
6584 
jsondec_buftouint64(jsondec * d,const char * ptr,const char * end,uint64_t * val)6585 static const char *jsondec_buftouint64(jsondec *d, const char *ptr,
6586                                        const char *end, uint64_t *val) {
6587   uint64_t u64 = 0;
6588   while (ptr < end) {
6589     unsigned ch = *ptr - '0';
6590     if (ch >= 10) break;
6591     if (u64 > UINT64_MAX / 10 || u64 * 10 > UINT64_MAX - ch) {
6592       jsondec_err(d, "Integer overflow");
6593     }
6594     u64 *= 10;
6595     u64 += ch;
6596     ptr++;
6597   }
6598 
6599   *val = u64;
6600   return ptr;
6601 }
6602 
jsondec_buftoint64(jsondec * d,const char * ptr,const char * end,int64_t * val)6603 static const char *jsondec_buftoint64(jsondec *d, const char *ptr,
6604                                       const char *end, int64_t *val) {
6605   bool neg = false;
6606   uint64_t u64;
6607 
6608   if (ptr != end && *ptr == '-') {
6609     ptr++;
6610     neg = true;
6611   }
6612 
6613   ptr = jsondec_buftouint64(d, ptr, end, &u64);
6614   if (u64 > (uint64_t)INT64_MAX + neg) {
6615     jsondec_err(d, "Integer overflow");
6616   }
6617 
6618   *val = neg ? -u64 : u64;
6619   return ptr;
6620 }
6621 
jsondec_strtouint64(jsondec * d,upb_strview str)6622 static uint64_t jsondec_strtouint64(jsondec *d, upb_strview str) {
6623   const char *end = str.data + str.size;
6624   uint64_t ret;
6625   if (jsondec_buftouint64(d, str.data, end, &ret) != end) {
6626     jsondec_err(d, "Non-number characters in quoted integer");
6627   }
6628   return ret;
6629 }
6630 
jsondec_strtoint64(jsondec * d,upb_strview str)6631 static int64_t jsondec_strtoint64(jsondec *d, upb_strview str) {
6632   const char *end = str.data + str.size;
6633   int64_t ret;
6634   if (jsondec_buftoint64(d, str.data, end, &ret) != end) {
6635     jsondec_err(d, "Non-number characters in quoted integer");
6636   }
6637   return ret;
6638 }
6639 
6640 /* Primitive value types ******************************************************/
6641 
6642 /* Parse INT32 or INT64 value. */
jsondec_int(jsondec * d,const upb_fielddef * f)6643 static upb_msgval jsondec_int(jsondec *d, const upb_fielddef *f) {
6644   upb_msgval val;
6645 
6646   switch (jsondec_peek(d)) {
6647     case JD_NUMBER: {
6648       double dbl = jsondec_number(d);
6649       if (dbl > 9223372036854774784.0 || dbl < -9223372036854775808.0) {
6650         jsondec_err(d, "JSON number is out of range.");
6651       }
6652       val.int64_val = dbl;  /* must be guarded, overflow here is UB */
6653       if (val.int64_val != dbl) {
6654         jsondec_errf(d, "JSON number was not integral (%d != %" PRId64 ")", dbl,
6655                      val.int64_val);
6656       }
6657       break;
6658     }
6659     case JD_STRING: {
6660       upb_strview str = jsondec_string(d);
6661       val.int64_val = jsondec_strtoint64(d, str);
6662       break;
6663     }
6664     default:
6665       jsondec_err(d, "Expected number or string");
6666   }
6667 
6668   if (upb_fielddef_type(f) == UPB_TYPE_INT32) {
6669     if (val.int64_val > INT32_MAX || val.int64_val < INT32_MIN) {
6670       jsondec_err(d, "Integer out of range.");
6671     }
6672     val.int32_val = (int32_t)val.int64_val;
6673   }
6674 
6675   return val;
6676 }
6677 
6678 /* Parse UINT32 or UINT64 value. */
jsondec_uint(jsondec * d,const upb_fielddef * f)6679 static upb_msgval jsondec_uint(jsondec *d, const upb_fielddef *f) {
6680   upb_msgval val;
6681 
6682   switch (jsondec_peek(d)) {
6683     case JD_NUMBER: {
6684       double dbl = jsondec_number(d);
6685       if (dbl > 18446744073709549568.0 || dbl < 0) {
6686         jsondec_err(d, "JSON number is out of range.");
6687       }
6688       val.uint64_val = dbl;  /* must be guarded, overflow here is UB */
6689       if (val.uint64_val != dbl) {
6690         jsondec_errf(d, "JSON number was not integral (%d != %" PRIu64 ")", dbl,
6691                      val.uint64_val);
6692       }
6693       break;
6694     }
6695     case JD_STRING: {
6696       upb_strview str = jsondec_string(d);
6697       val.uint64_val = jsondec_strtouint64(d, str);
6698       break;
6699     }
6700     default:
6701       jsondec_err(d, "Expected number or string");
6702   }
6703 
6704   if (upb_fielddef_type(f) == UPB_TYPE_UINT32) {
6705     if (val.uint64_val > UINT32_MAX) {
6706       jsondec_err(d, "Integer out of range.");
6707     }
6708     val.uint32_val = (uint32_t)val.uint64_val;
6709   }
6710 
6711   return val;
6712 }
6713 
6714 /* Parse DOUBLE or FLOAT value. */
jsondec_double(jsondec * d,const upb_fielddef * f)6715 static upb_msgval jsondec_double(jsondec *d, const upb_fielddef *f) {
6716   upb_strview str;
6717   upb_msgval val;
6718 
6719   switch (jsondec_peek(d)) {
6720     case JD_NUMBER:
6721       val.double_val = jsondec_number(d);
6722       break;
6723     case JD_STRING:
6724       str = jsondec_string(d);
6725       if (jsondec_streql(str, "NaN")) {
6726         val.double_val = UPB_NAN;
6727       } else if (jsondec_streql(str, "Infinity")) {
6728         val.double_val = UPB_INFINITY;
6729       } else if (jsondec_streql(str, "-Infinity")) {
6730         val.double_val = -UPB_INFINITY;
6731       } else {
6732         val.double_val = strtod(str.data, NULL);
6733       }
6734       break;
6735     default:
6736       jsondec_err(d, "Expected number or string");
6737   }
6738 
6739   if (upb_fielddef_type(f) == UPB_TYPE_FLOAT) {
6740     if (val.double_val != UPB_INFINITY && val.double_val != -UPB_INFINITY &&
6741         (val.double_val > FLT_MAX || val.double_val < -FLT_MAX)) {
6742       jsondec_err(d, "Float out of range");
6743     }
6744     val.float_val = val.double_val;
6745   }
6746 
6747   return val;
6748 }
6749 
6750 /* Parse STRING or BYTES value. */
jsondec_strfield(jsondec * d,const upb_fielddef * f)6751 static upb_msgval jsondec_strfield(jsondec *d, const upb_fielddef *f) {
6752   upb_msgval val;
6753   val.str_val = jsondec_string(d);
6754   if (upb_fielddef_type(f) == UPB_TYPE_BYTES) {
6755     val.str_val.size = jsondec_base64(d, val.str_val);
6756   }
6757   return val;
6758 }
6759 
jsondec_enum(jsondec * d,const upb_fielddef * f)6760 static upb_msgval jsondec_enum(jsondec *d, const upb_fielddef *f) {
6761   if (jsondec_peek(d) == JD_STRING) {
6762     const upb_enumdef *e = upb_fielddef_enumsubdef(f);
6763     upb_strview str = jsondec_string(d);
6764     upb_msgval val;
6765     if (!upb_enumdef_ntoi(e, str.data, str.size, &val.int32_val)) {
6766       if (d->options & UPB_JSONDEC_IGNOREUNKNOWN) {
6767         val.int32_val = 0;
6768       } else {
6769         jsondec_errf(d, "Unknown enumerator: '" UPB_STRVIEW_FORMAT "'",
6770                      UPB_STRVIEW_ARGS(str));
6771       }
6772     }
6773     return val;
6774   } else {
6775     return jsondec_int(d, f);
6776   }
6777 }
6778 
jsondec_bool(jsondec * d,const upb_fielddef * f)6779 static upb_msgval jsondec_bool(jsondec *d, const upb_fielddef *f) {
6780   bool is_map_key = upb_fielddef_number(f) == 1 &&
6781                     upb_msgdef_mapentry(upb_fielddef_containingtype(f));
6782   upb_msgval val;
6783 
6784   if (is_map_key) {
6785     upb_strview str = jsondec_string(d);
6786     if (jsondec_streql(str, "true")) {
6787       val.bool_val = true;
6788     } else if (jsondec_streql(str, "false")) {
6789       val.bool_val = false;
6790     } else {
6791       jsondec_err(d, "Invalid boolean map key");
6792     }
6793   } else {
6794     switch (jsondec_peek(d)) {
6795       case JD_TRUE:
6796         val.bool_val = true;
6797         jsondec_true(d);
6798         break;
6799       case JD_FALSE:
6800         val.bool_val = false;
6801         jsondec_false(d);
6802         break;
6803       default:
6804         jsondec_err(d, "Expected true or false");
6805     }
6806   }
6807 
6808   return val;
6809 }
6810 
6811 /* Composite types (array/message/map) ****************************************/
6812 
jsondec_array(jsondec * d,upb_msg * msg,const upb_fielddef * f)6813 static void jsondec_array(jsondec *d, upb_msg *msg, const upb_fielddef *f) {
6814   upb_array *arr = upb_msg_mutable(msg, f, d->arena).array;
6815 
6816   jsondec_arrstart(d);
6817   while (jsondec_arrnext(d)) {
6818     upb_msgval elem = jsondec_value(d, f);
6819     upb_array_append(arr, elem, d->arena);
6820   }
6821   jsondec_arrend(d);
6822 }
6823 
jsondec_map(jsondec * d,upb_msg * msg,const upb_fielddef * f)6824 static void jsondec_map(jsondec *d, upb_msg *msg, const upb_fielddef *f) {
6825   upb_map *map = upb_msg_mutable(msg, f, d->arena).map;
6826   const upb_msgdef *entry = upb_fielddef_msgsubdef(f);
6827   const upb_fielddef *key_f = upb_msgdef_itof(entry, 1);
6828   const upb_fielddef *val_f = upb_msgdef_itof(entry, 2);
6829 
6830   jsondec_objstart(d);
6831   while (jsondec_objnext(d)) {
6832     upb_msgval key, val;
6833     key = jsondec_value(d, key_f);
6834     jsondec_entrysep(d);
6835     val = jsondec_value(d, val_f);
6836     upb_map_set(map, key, val, d->arena);
6837   }
6838   jsondec_objend(d);
6839 }
6840 
jsondec_tomsg(jsondec * d,upb_msg * msg,const upb_msgdef * m)6841 static void jsondec_tomsg(jsondec *d, upb_msg *msg, const upb_msgdef *m) {
6842   if (upb_msgdef_wellknowntype(m) == UPB_WELLKNOWN_UNSPECIFIED) {
6843     jsondec_object(d, msg, m);
6844   } else {
6845     jsondec_wellknown(d, msg, m);
6846   }
6847 }
6848 
jsondec_msg(jsondec * d,const upb_fielddef * f)6849 static upb_msgval jsondec_msg(jsondec *d, const upb_fielddef *f) {
6850   const upb_msgdef *m = upb_fielddef_msgsubdef(f);
6851   upb_msg *msg = upb_msg_new(m, d->arena);
6852   upb_msgval val;
6853 
6854   jsondec_tomsg(d, msg, m);
6855   val.msg_val = msg;
6856   return val;
6857 }
6858 
jsondec_isvalue(const upb_fielddef * f)6859 static bool jsondec_isvalue(const upb_fielddef *f) {
6860   return upb_fielddef_type(f) == UPB_TYPE_MESSAGE &&
6861          upb_msgdef_wellknowntype(upb_fielddef_msgsubdef(f)) ==
6862              UPB_WELLKNOWN_VALUE;
6863 }
6864 
jsondec_field(jsondec * d,upb_msg * msg,const upb_msgdef * m)6865 static void jsondec_field(jsondec *d, upb_msg *msg, const upb_msgdef *m) {
6866   upb_strview name;
6867   const upb_fielddef *f;
6868   const upb_fielddef *preserved;
6869 
6870   name = jsondec_string(d);
6871   jsondec_entrysep(d);
6872   f = upb_msgdef_lookupjsonname(m, name.data, name.size);
6873 
6874   if (!f) {
6875     if ((d->options & UPB_JSONDEC_IGNOREUNKNOWN) == 0) {
6876       jsondec_errf(d, "Unknown field: '" UPB_STRVIEW_FORMAT "'",
6877                    UPB_STRVIEW_ARGS(name));
6878     }
6879     jsondec_skipval(d);
6880     return;
6881   }
6882 
6883   if (upb_fielddef_realcontainingoneof(f) &&
6884       upb_msg_whichoneof(msg, upb_fielddef_containingoneof(f))) {
6885     jsondec_err(d, "More than one field for this oneof.");
6886   }
6887 
6888   if (jsondec_peek(d) == JD_NULL && !jsondec_isvalue(f)) {
6889     /* JSON "null" indicates a default value, so no need to set anything. */
6890     jsondec_null(d);
6891     return;
6892   }
6893 
6894   preserved = d->debug_field;
6895   d->debug_field = f;
6896 
6897   if (upb_fielddef_ismap(f)) {
6898     jsondec_map(d, msg, f);
6899   } else if (upb_fielddef_isseq(f)) {
6900     jsondec_array(d, msg, f);
6901   } else if (upb_fielddef_issubmsg(f)) {
6902     upb_msg *submsg = upb_msg_mutable(msg, f, d->arena).msg;
6903     const upb_msgdef *subm = upb_fielddef_msgsubdef(f);
6904     jsondec_tomsg(d, submsg, subm);
6905   } else {
6906     upb_msgval val = jsondec_value(d, f);
6907     upb_msg_set(msg, f, val, d->arena);
6908   }
6909 
6910   d->debug_field = preserved;
6911 }
6912 
jsondec_object(jsondec * d,upb_msg * msg,const upb_msgdef * m)6913 static void jsondec_object(jsondec *d, upb_msg *msg, const upb_msgdef *m) {
6914   jsondec_objstart(d);
6915   while (jsondec_objnext(d)) {
6916     jsondec_field(d, msg, m);
6917   }
6918   jsondec_objend(d);
6919 }
6920 
jsondec_value(jsondec * d,const upb_fielddef * f)6921 static upb_msgval jsondec_value(jsondec *d, const upb_fielddef *f) {
6922   switch (upb_fielddef_type(f)) {
6923     case UPB_TYPE_BOOL:
6924       return jsondec_bool(d, f);
6925     case UPB_TYPE_FLOAT:
6926     case UPB_TYPE_DOUBLE:
6927       return jsondec_double(d, f);
6928     case UPB_TYPE_UINT32:
6929     case UPB_TYPE_UINT64:
6930       return jsondec_uint(d, f);
6931     case UPB_TYPE_INT32:
6932     case UPB_TYPE_INT64:
6933       return jsondec_int(d, f);
6934     case UPB_TYPE_STRING:
6935     case UPB_TYPE_BYTES:
6936       return jsondec_strfield(d, f);
6937     case UPB_TYPE_ENUM:
6938       return jsondec_enum(d, f);
6939     case UPB_TYPE_MESSAGE:
6940       return jsondec_msg(d, f);
6941     default:
6942       UPB_UNREACHABLE();
6943   }
6944 }
6945 
6946 /* Well-known types ***********************************************************/
6947 
jsondec_tsdigits(jsondec * d,const char ** ptr,size_t digits,const char * after)6948 static int jsondec_tsdigits(jsondec *d, const char **ptr, size_t digits,
6949                             const char *after) {
6950   uint64_t val;
6951   const char *p = *ptr;
6952   const char *end = p + digits;
6953   size_t after_len = after ? strlen(after) : 0;
6954 
6955   UPB_ASSERT(digits <= 9);  /* int can't overflow. */
6956 
6957   if (jsondec_buftouint64(d, p, end, &val) != end ||
6958       (after_len && memcmp(end, after, after_len) != 0)) {
6959     jsondec_err(d, "Malformed timestamp");
6960   }
6961 
6962   UPB_ASSERT(val < INT_MAX);
6963 
6964   *ptr = end + after_len;
6965   return (int)val;
6966 }
6967 
jsondec_nanos(jsondec * d,const char ** ptr,const char * end)6968 static int jsondec_nanos(jsondec *d, const char **ptr, const char *end) {
6969   uint64_t nanos = 0;
6970   const char *p = *ptr;
6971 
6972   if (p != end && *p == '.') {
6973     const char *nano_end = jsondec_buftouint64(d, p + 1, end, &nanos);
6974     int digits = (int)(nano_end - p - 1);
6975     int exp_lg10 = 9 - digits;
6976     if (digits > 9) {
6977       jsondec_err(d, "Too many digits for partial seconds");
6978     }
6979     while (exp_lg10--) nanos *= 10;
6980     *ptr = nano_end;
6981   }
6982 
6983   UPB_ASSERT(nanos < INT_MAX);
6984 
6985   return (int)nanos;
6986 }
6987 
6988 /* jsondec_epochdays(1970, 1, 1) == 1970-01-01 == 0. */
jsondec_epochdays(int y,int m,int d)6989 int jsondec_epochdays(int y, int m, int d) {
6990   const uint32_t year_base = 4800;    /* Before min year, multiple of 400. */
6991   const uint32_t m_adj = m - 3;       /* March-based month. */
6992   const uint32_t carry = m_adj > (uint32_t)m ? 1 : 0;
6993   const uint32_t adjust = carry ? 12 : 0;
6994   const uint32_t y_adj = y + year_base - carry;
6995   const uint32_t month_days = ((m_adj + adjust) * 62719 + 769) / 2048;
6996   const uint32_t leap_days = y_adj / 4 - y_adj / 100 + y_adj / 400;
6997   return y_adj * 365 + leap_days + month_days + (d - 1) - 2472632;
6998 }
6999 
jsondec_unixtime(int y,int m,int d,int h,int min,int s)7000 static int64_t jsondec_unixtime(int y, int m, int d, int h, int min, int s) {
7001   return (int64_t)jsondec_epochdays(y, m, d) * 86400 + h * 3600 + min * 60 + s;
7002 }
7003 
jsondec_timestamp(jsondec * d,upb_msg * msg,const upb_msgdef * m)7004 static void jsondec_timestamp(jsondec *d, upb_msg *msg, const upb_msgdef *m) {
7005   upb_msgval seconds;
7006   upb_msgval nanos;
7007   upb_strview str = jsondec_string(d);
7008   const char *ptr = str.data;
7009   const char *end = ptr + str.size;
7010 
7011   if (str.size < 20) goto malformed;
7012 
7013   {
7014     /* 1972-01-01T01:00:00 */
7015     int year = jsondec_tsdigits(d, &ptr, 4, "-");
7016     int mon = jsondec_tsdigits(d, &ptr, 2, "-");
7017     int day = jsondec_tsdigits(d, &ptr, 2, "T");
7018     int hour = jsondec_tsdigits(d, &ptr, 2, ":");
7019     int min = jsondec_tsdigits(d, &ptr, 2, ":");
7020     int sec = jsondec_tsdigits(d, &ptr, 2, NULL);
7021 
7022     seconds.int64_val = jsondec_unixtime(year, mon, day, hour, min, sec);
7023   }
7024 
7025   nanos.int32_val = jsondec_nanos(d, &ptr, end);
7026 
7027   {
7028     /* [+-]08:00 or Z */
7029     int ofs = 0;
7030     bool neg = false;
7031 
7032     if (ptr == end) goto malformed;
7033 
7034     switch (*ptr++) {
7035       case '-':
7036         neg = true;
7037         /* fallthrough */
7038       case '+':
7039         if ((end - ptr) != 5) goto malformed;
7040         ofs = jsondec_tsdigits(d, &ptr, 2, ":00");
7041         ofs *= 60 * 60;
7042         seconds.int64_val += (neg ? ofs : -ofs);
7043         break;
7044       case 'Z':
7045         if (ptr != end) goto malformed;
7046         break;
7047       default:
7048         goto malformed;
7049     }
7050   }
7051 
7052   if (seconds.int64_val < -62135596800) {
7053     jsondec_err(d, "Timestamp out of range");
7054   }
7055 
7056   upb_msg_set(msg, upb_msgdef_itof(m, 1), seconds, d->arena);
7057   upb_msg_set(msg, upb_msgdef_itof(m, 2), nanos, d->arena);
7058   return;
7059 
7060 malformed:
7061   jsondec_err(d, "Malformed timestamp");
7062 }
7063 
jsondec_duration(jsondec * d,upb_msg * msg,const upb_msgdef * m)7064 static void jsondec_duration(jsondec *d, upb_msg *msg, const upb_msgdef *m) {
7065   upb_msgval seconds;
7066   upb_msgval nanos;
7067   upb_strview str = jsondec_string(d);
7068   const char *ptr = str.data;
7069   const char *end = ptr + str.size;
7070 
7071   /* "3.000000001s", "3s", etc. */
7072   ptr = jsondec_buftoint64(d, ptr, end, &seconds.int64_val);
7073   nanos.int32_val = jsondec_nanos(d, &ptr, end);
7074 
7075   if (end - ptr != 1 || *ptr != 's') {
7076     jsondec_err(d, "Malformed duration");
7077   }
7078 
7079   if (seconds.int64_val < -315576000000LL || seconds.int64_val > 315576000000LL) {
7080     jsondec_err(d, "Duration out of range");
7081   }
7082 
7083   if (seconds.int64_val < 0) {
7084     nanos.int32_val = - nanos.int32_val;
7085   }
7086 
7087   upb_msg_set(msg, upb_msgdef_itof(m, 1), seconds, d->arena);
7088   upb_msg_set(msg, upb_msgdef_itof(m, 2), nanos, d->arena);
7089 }
7090 
jsondec_listvalue(jsondec * d,upb_msg * msg,const upb_msgdef * m)7091 static void jsondec_listvalue(jsondec *d, upb_msg *msg, const upb_msgdef *m) {
7092   const upb_fielddef *values_f = upb_msgdef_itof(m, 1);
7093   const upb_msgdef *value_m = upb_fielddef_msgsubdef(values_f);
7094   upb_array *values = upb_msg_mutable(msg, values_f, d->arena).array;
7095 
7096   jsondec_arrstart(d);
7097   while (jsondec_arrnext(d)) {
7098     upb_msg *value_msg = upb_msg_new(value_m, d->arena);
7099     upb_msgval value;
7100     value.msg_val = value_msg;
7101     upb_array_append(values, value, d->arena);
7102     jsondec_wellknownvalue(d, value_msg, value_m);
7103   }
7104   jsondec_arrend(d);
7105 }
7106 
jsondec_struct(jsondec * d,upb_msg * msg,const upb_msgdef * m)7107 static void jsondec_struct(jsondec *d, upb_msg *msg, const upb_msgdef *m) {
7108   const upb_fielddef *fields_f = upb_msgdef_itof(m, 1);
7109   const upb_msgdef *entry_m = upb_fielddef_msgsubdef(fields_f);
7110   const upb_fielddef *value_f = upb_msgdef_itof(entry_m, 2);
7111   const upb_msgdef *value_m = upb_fielddef_msgsubdef(value_f);
7112   upb_map *fields = upb_msg_mutable(msg, fields_f, d->arena).map;
7113 
7114   jsondec_objstart(d);
7115   while (jsondec_objnext(d)) {
7116     upb_msgval key, value;
7117     upb_msg *value_msg = upb_msg_new(value_m, d->arena);
7118     key.str_val = jsondec_string(d);
7119     value.msg_val = value_msg;
7120     upb_map_set(fields, key, value, d->arena);
7121     jsondec_entrysep(d);
7122     jsondec_wellknownvalue(d, value_msg, value_m);
7123   }
7124   jsondec_objend(d);
7125 }
7126 
jsondec_wellknownvalue(jsondec * d,upb_msg * msg,const upb_msgdef * m)7127 static void jsondec_wellknownvalue(jsondec *d, upb_msg *msg,
7128                                    const upb_msgdef *m) {
7129   upb_msgval val;
7130   const upb_fielddef *f;
7131   upb_msg *submsg;
7132 
7133   switch (jsondec_peek(d)) {
7134     case JD_NUMBER:
7135       /* double number_value = 2; */
7136       f = upb_msgdef_itof(m, 2);
7137       val.double_val = jsondec_number(d);
7138       break;
7139     case JD_STRING:
7140       /* string string_value = 3; */
7141       f = upb_msgdef_itof(m, 3);
7142       val.str_val = jsondec_string(d);
7143       break;
7144     case JD_FALSE:
7145       /* bool bool_value = 4; */
7146       f = upb_msgdef_itof(m, 4);
7147       val.bool_val = false;
7148       jsondec_false(d);
7149       break;
7150     case JD_TRUE:
7151       /* bool bool_value = 4; */
7152       f = upb_msgdef_itof(m, 4);
7153       val.bool_val = true;
7154       jsondec_true(d);
7155       break;
7156     case JD_NULL:
7157       /* NullValue null_value = 1; */
7158       f = upb_msgdef_itof(m, 1);
7159       val.int32_val = 0;
7160       jsondec_null(d);
7161       break;
7162     /* Note: these cases return, because upb_msg_mutable() is enough. */
7163     case JD_OBJECT:
7164       /* Struct struct_value = 5; */
7165       f = upb_msgdef_itof(m, 5);
7166       submsg = upb_msg_mutable(msg, f, d->arena).msg;
7167       jsondec_struct(d, submsg, upb_fielddef_msgsubdef(f));
7168       return;
7169     case JD_ARRAY:
7170       /* ListValue list_value = 6; */
7171       f = upb_msgdef_itof(m, 6);
7172       submsg = upb_msg_mutable(msg, f, d->arena).msg;
7173       jsondec_listvalue(d, submsg, upb_fielddef_msgsubdef(f));
7174       return;
7175     default:
7176       UPB_UNREACHABLE();
7177   }
7178 
7179   upb_msg_set(msg, f, val, d->arena);
7180 }
7181 
jsondec_mask(jsondec * d,const char * buf,const char * end)7182 static upb_strview jsondec_mask(jsondec *d, const char *buf, const char *end) {
7183   /* FieldMask fields grow due to inserted '_' characters, so we can't do the
7184    * transform in place. */
7185   const char *ptr = buf;
7186   upb_strview ret;
7187   char *out;
7188 
7189   ret.size = end - ptr;
7190   while (ptr < end) {
7191     ret.size += (*ptr >= 'A' && *ptr <= 'Z');
7192     ptr++;
7193   }
7194 
7195   out = upb_arena_malloc(d->arena, ret.size);
7196   ptr = buf;
7197   ret.data = out;
7198 
7199   while (ptr < end) {
7200     char ch = *ptr++;
7201     if (ch >= 'A' && ch <= 'Z') {
7202       *out++ = '_';
7203       *out++ = ch + 32;
7204     } else if (ch == '_') {
7205       jsondec_err(d, "field mask may not contain '_'");
7206     } else {
7207       *out++ = ch;
7208     }
7209   }
7210 
7211   return ret;
7212 }
7213 
jsondec_fieldmask(jsondec * d,upb_msg * msg,const upb_msgdef * m)7214 static void jsondec_fieldmask(jsondec *d, upb_msg *msg, const upb_msgdef *m) {
7215   /* repeated string paths = 1; */
7216   const upb_fielddef *paths_f = upb_msgdef_itof(m, 1);
7217   upb_array *arr = upb_msg_mutable(msg, paths_f, d->arena).array;
7218   upb_strview str = jsondec_string(d);
7219   const char *ptr = str.data;
7220   const char *end = ptr + str.size;
7221   upb_msgval val;
7222 
7223   while (ptr < end) {
7224     const char *elem_end = memchr(ptr, ',', end - ptr);
7225     if (elem_end) {
7226       val.str_val = jsondec_mask(d, ptr, elem_end);
7227       ptr = elem_end + 1;
7228     } else {
7229       val.str_val = jsondec_mask(d, ptr, end);
7230       ptr = end;
7231     }
7232     upb_array_append(arr, val, d->arena);
7233   }
7234 }
7235 
jsondec_anyfield(jsondec * d,upb_msg * msg,const upb_msgdef * m)7236 static void jsondec_anyfield(jsondec *d, upb_msg *msg, const upb_msgdef *m) {
7237   if (upb_msgdef_wellknowntype(m) == UPB_WELLKNOWN_UNSPECIFIED) {
7238     /* For regular types: {"@type": "[user type]", "f1": <V1>, "f2": <V2>}
7239      * where f1, f2, etc. are the normal fields of this type. */
7240     jsondec_field(d, msg, m);
7241   } else {
7242     /* For well-known types: {"@type": "[well-known type]", "value": <X>}
7243      * where <X> is whatever encoding the WKT normally uses. */
7244     upb_strview str = jsondec_string(d);
7245     jsondec_entrysep(d);
7246     if (!jsondec_streql(str, "value")) {
7247       jsondec_err(d, "Key for well-known type must be 'value'");
7248     }
7249     jsondec_wellknown(d, msg, m);
7250   }
7251 }
7252 
jsondec_typeurl(jsondec * d,upb_msg * msg,const upb_msgdef * m)7253 static const upb_msgdef *jsondec_typeurl(jsondec *d, upb_msg *msg,
7254                                          const upb_msgdef *m) {
7255   const upb_fielddef *type_url_f = upb_msgdef_itof(m, 1);
7256   const upb_msgdef *type_m;
7257   upb_strview type_url = jsondec_string(d);
7258   const char *end = type_url.data + type_url.size;
7259   const char *ptr = end;
7260   upb_msgval val;
7261 
7262   val.str_val = type_url;
7263   upb_msg_set(msg, type_url_f, val, d->arena);
7264 
7265   /* Find message name after the last '/' */
7266   while (ptr > type_url.data && *--ptr != '/') {}
7267 
7268   if (ptr == type_url.data || ptr == end) {
7269     jsondec_err(d, "Type url must have at least one '/' and non-empty host");
7270   }
7271 
7272   ptr++;
7273   type_m = upb_symtab_lookupmsg2(d->any_pool, ptr, end - ptr);
7274 
7275   if (!type_m) {
7276     jsondec_err(d, "Type was not found");
7277   }
7278 
7279   return type_m;
7280 }
7281 
jsondec_any(jsondec * d,upb_msg * msg,const upb_msgdef * m)7282 static void jsondec_any(jsondec *d, upb_msg *msg, const upb_msgdef *m) {
7283   /* string type_url = 1;
7284    * bytes value = 2; */
7285   const upb_fielddef *value_f = upb_msgdef_itof(m, 2);
7286   upb_msg *any_msg;
7287   const upb_msgdef *any_m = NULL;
7288   const char *pre_type_data = NULL;
7289   const char *pre_type_end = NULL;
7290   upb_msgval encoded;
7291 
7292   jsondec_objstart(d);
7293 
7294   /* Scan looking for "@type", which is not necessarily first. */
7295   while (!any_m && jsondec_objnext(d)) {
7296     const char *start = d->ptr;
7297     upb_strview name = jsondec_string(d);
7298     jsondec_entrysep(d);
7299     if (jsondec_streql(name, "@type")) {
7300       any_m = jsondec_typeurl(d, msg, m);
7301       if (pre_type_data) {
7302         pre_type_end = start;
7303         while (*pre_type_end != ',') pre_type_end--;
7304       }
7305     } else {
7306       if (!pre_type_data) pre_type_data = start;
7307       jsondec_skipval(d);
7308     }
7309   }
7310 
7311   if (!any_m) {
7312     jsondec_err(d, "Any object didn't contain a '@type' field");
7313   }
7314 
7315   any_msg = upb_msg_new(any_m, d->arena);
7316 
7317   if (pre_type_data) {
7318     size_t len = pre_type_end - pre_type_data + 1;
7319     char *tmp = upb_arena_malloc(d->arena, len);
7320     const char *saved_ptr = d->ptr;
7321     const char *saved_end = d->end;
7322     memcpy(tmp, pre_type_data, len - 1);
7323     tmp[len - 1] = '}';
7324     d->ptr = tmp;
7325     d->end = tmp + len;
7326     d->is_first = true;
7327     while (jsondec_objnext(d)) {
7328       jsondec_anyfield(d, any_msg, any_m);
7329     }
7330     d->ptr = saved_ptr;
7331     d->end = saved_end;
7332   }
7333 
7334   while (jsondec_objnext(d)) {
7335     jsondec_anyfield(d, any_msg, any_m);
7336   }
7337 
7338   jsondec_objend(d);
7339 
7340   encoded.str_val.data = upb_encode(any_msg, upb_msgdef_layout(any_m), d->arena,
7341                                     &encoded.str_val.size);
7342   upb_msg_set(msg, value_f, encoded, d->arena);
7343 }
7344 
jsondec_wrapper(jsondec * d,upb_msg * msg,const upb_msgdef * m)7345 static void jsondec_wrapper(jsondec *d, upb_msg *msg, const upb_msgdef *m) {
7346   const upb_fielddef *value_f = upb_msgdef_itof(m, 1);
7347   upb_msgval val = jsondec_value(d, value_f);
7348   upb_msg_set(msg, value_f, val, d->arena);
7349 }
7350 
jsondec_wellknown(jsondec * d,upb_msg * msg,const upb_msgdef * m)7351 static void jsondec_wellknown(jsondec *d, upb_msg *msg, const upb_msgdef *m) {
7352   switch (upb_msgdef_wellknowntype(m)) {
7353     case UPB_WELLKNOWN_ANY:
7354       jsondec_any(d, msg, m);
7355       break;
7356     case UPB_WELLKNOWN_FIELDMASK:
7357       jsondec_fieldmask(d, msg, m);
7358       break;
7359     case UPB_WELLKNOWN_DURATION:
7360       jsondec_duration(d, msg, m);
7361       break;
7362     case UPB_WELLKNOWN_TIMESTAMP:
7363       jsondec_timestamp(d, msg, m);
7364       break;
7365     case UPB_WELLKNOWN_VALUE:
7366       jsondec_wellknownvalue(d, msg, m);
7367       break;
7368     case UPB_WELLKNOWN_LISTVALUE:
7369       jsondec_listvalue(d, msg, m);
7370       break;
7371     case UPB_WELLKNOWN_STRUCT:
7372       jsondec_struct(d, msg, m);
7373       break;
7374     case UPB_WELLKNOWN_DOUBLEVALUE:
7375     case UPB_WELLKNOWN_FLOATVALUE:
7376     case UPB_WELLKNOWN_INT64VALUE:
7377     case UPB_WELLKNOWN_UINT64VALUE:
7378     case UPB_WELLKNOWN_INT32VALUE:
7379     case UPB_WELLKNOWN_UINT32VALUE:
7380     case UPB_WELLKNOWN_STRINGVALUE:
7381     case UPB_WELLKNOWN_BYTESVALUE:
7382     case UPB_WELLKNOWN_BOOLVALUE:
7383       jsondec_wrapper(d, msg, m);
7384       break;
7385     default:
7386       UPB_UNREACHABLE();
7387   }
7388 }
7389 
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)7390 bool upb_json_decode(const char *buf, size_t size, upb_msg *msg,
7391                      const upb_msgdef *m, const upb_symtab *any_pool,
7392                      int options, upb_arena *arena, upb_status *status) {
7393   jsondec d;
7394   d.ptr = buf;
7395   d.end = buf + size;
7396   d.arena = arena;
7397   d.any_pool = any_pool;
7398   d.status = status;
7399   d.options = options;
7400   d.depth = 64;
7401   d.line = 1;
7402   d.line_begin = d.ptr;
7403   d.debug_field = NULL;
7404   d.is_first = false;
7405 
7406   if (setjmp(d.err)) return false;
7407 
7408   jsondec_tomsg(&d, msg, m);
7409   return true;
7410 }
7411 
7412 
7413 #include <ctype.h>
7414 #include <float.h>
7415 #include <inttypes.h>
7416 #include <stdarg.h>
7417 #include <stdio.h>
7418 #include <string.h>
7419 #include <setjmp.h>
7420 
7421 
7422 
7423 typedef struct {
7424   char *buf, *ptr, *end;
7425   size_t overflow;
7426   int indent_depth;
7427   int options;
7428   const upb_symtab *ext_pool;
7429   jmp_buf err;
7430   upb_status *status;
7431   upb_arena *arena;
7432 } jsonenc;
7433 
7434 static void jsonenc_msg(jsonenc *e, const upb_msg *msg, const upb_msgdef *m);
7435 static void jsonenc_scalar(jsonenc *e, upb_msgval val, const upb_fielddef *f);
7436 static void jsonenc_msgfield(jsonenc *e, const upb_msg *msg,
7437                              const upb_msgdef *m);
7438 static void jsonenc_msgfields(jsonenc *e, const upb_msg *msg,
7439                               const upb_msgdef *m);
7440 static void jsonenc_value(jsonenc *e, const upb_msg *msg, const upb_msgdef *m);
7441 
jsonenc_err(jsonenc * e,const char * msg)7442 UPB_NORETURN static void jsonenc_err(jsonenc *e, const char *msg) {
7443   upb_status_seterrmsg(e->status, msg);
7444   longjmp(e->err, 1);
7445 }
7446 
jsonenc_errf(jsonenc * e,const char * fmt,...)7447 UPB_NORETURN static void jsonenc_errf(jsonenc *e, const char *fmt, ...) {
7448   va_list argp;
7449   va_start(argp, fmt);
7450   upb_status_vseterrf(e->status, fmt, argp);
7451   va_end(argp);
7452   longjmp(e->err, 1);
7453 }
7454 
jsonenc_arena(jsonenc * e)7455 static upb_arena *jsonenc_arena(jsonenc *e) {
7456   /* Create lazily, since it's only needed for Any */
7457   if (!e->arena) {
7458     e->arena = upb_arena_new();
7459   }
7460   return e->arena;
7461 }
7462 
jsonenc_putbytes(jsonenc * e,const void * data,size_t len)7463 static void jsonenc_putbytes(jsonenc *e, const void *data, size_t len) {
7464   size_t have = e->end - e->ptr;
7465   if (UPB_LIKELY(have >= len)) {
7466     memcpy(e->ptr, data, len);
7467     e->ptr += len;
7468   } else {
7469     if (have) memcpy(e->ptr, data, have);
7470     e->ptr += have;
7471     e->overflow += (len - have);
7472   }
7473 }
7474 
jsonenc_putstr(jsonenc * e,const char * str)7475 static void jsonenc_putstr(jsonenc *e, const char *str) {
7476   jsonenc_putbytes(e, str, strlen(str));
7477 }
7478 
jsonenc_printf(jsonenc * e,const char * fmt,...)7479 static void jsonenc_printf(jsonenc *e, const char *fmt, ...) {
7480   size_t n;
7481   size_t have = e->end - e->ptr;
7482   va_list args;
7483 
7484   va_start(args, fmt);
7485   n = _upb_vsnprintf(e->ptr, have, fmt, args);
7486   va_end(args);
7487 
7488   if (UPB_LIKELY(have > n)) {
7489     e->ptr += n;
7490   } else {
7491     e->ptr += have;
7492     e->overflow += (n - have);
7493   }
7494 }
7495 
jsonenc_nanos(jsonenc * e,int32_t nanos)7496 static void jsonenc_nanos(jsonenc *e, int32_t nanos) {
7497   int digits = 9;
7498 
7499   if (nanos == 0) return;
7500   if (nanos < 0 || nanos >= 1000000000) {
7501     jsonenc_err(e, "error formatting timestamp as JSON: invalid nanos");
7502   }
7503 
7504   while (nanos % 1000 == 0) {
7505     nanos /= 1000;
7506     digits -= 3;
7507   }
7508 
7509   jsonenc_printf(e, ".%0.*" PRId32, digits, nanos);
7510 }
7511 
jsonenc_timestamp(jsonenc * e,const upb_msg * msg,const upb_msgdef * m)7512 static void jsonenc_timestamp(jsonenc *e, const upb_msg *msg,
7513                               const upb_msgdef *m) {
7514   const upb_fielddef *seconds_f = upb_msgdef_itof(m, 1);
7515   const upb_fielddef *nanos_f = upb_msgdef_itof(m, 2);
7516   int64_t seconds = upb_msg_get(msg, seconds_f).int64_val;
7517   int32_t nanos = upb_msg_get(msg, nanos_f).int32_val;
7518   int L, N, I, J, K, hour, min, sec;
7519 
7520   if (seconds < -62135596800) {
7521     jsonenc_err(e,
7522                 "error formatting timestamp as JSON: minimum acceptable value "
7523                 "is 0001-01-01T00:00:00Z");
7524   } else if (seconds > 253402300799) {
7525     jsonenc_err(e,
7526                 "error formatting timestamp as JSON: maximum acceptable value "
7527                 "is 9999-12-31T23:59:59Z");
7528   }
7529 
7530   /* Julian Day -> Y/M/D, Algorithm from:
7531    * Fliegel, H. F., and Van Flandern, T. C., "A Machine Algorithm for
7532    *   Processing Calendar Dates," Communications of the Association of
7533    *   Computing Machines, vol. 11 (1968), p. 657.  */
7534   L = (int)(seconds / 86400) + 68569 + 2440588;
7535   N = 4 * L / 146097;
7536   L = L - (146097 * N + 3) / 4;
7537   I = 4000 * (L + 1) / 1461001;
7538   L = L - 1461 * I / 4 + 31;
7539   J = 80 * L / 2447;
7540   K = L - 2447 * J / 80;
7541   L = J / 11;
7542   J = J + 2 - 12 * L;
7543   I = 100 * (N - 49) + I + L;
7544 
7545   sec = seconds % 60;
7546   min = (seconds / 60) % 60;
7547   hour = (seconds / 3600) % 24;
7548 
7549   jsonenc_printf(e, "\"%04d-%02d-%02dT%02d:%02d:%02d", I, J, K, hour, min, sec);
7550   jsonenc_nanos(e, nanos);
7551   jsonenc_putstr(e, "Z\"");
7552 }
7553 
jsonenc_duration(jsonenc * e,const upb_msg * msg,const upb_msgdef * m)7554 static void jsonenc_duration(jsonenc *e, const upb_msg *msg, const upb_msgdef *m) {
7555   const upb_fielddef *seconds_f = upb_msgdef_itof(m, 1);
7556   const upb_fielddef *nanos_f = upb_msgdef_itof(m, 2);
7557   int64_t seconds = upb_msg_get(msg, seconds_f).int64_val;
7558   int32_t nanos = upb_msg_get(msg, nanos_f).int32_val;
7559 
7560   if (seconds > 315576000000 || seconds < -315576000000 ||
7561       (seconds < 0) != (nanos < 0)) {
7562     jsonenc_err(e, "bad duration");
7563   }
7564 
7565   if (nanos < 0) {
7566     nanos = -nanos;
7567   }
7568 
7569   jsonenc_printf(e, "\"%" PRId64, seconds);
7570   jsonenc_nanos(e, nanos);
7571   jsonenc_putstr(e, "s\"");
7572 }
7573 
jsonenc_enum(int32_t val,const upb_fielddef * f,jsonenc * e)7574 static void jsonenc_enum(int32_t val, const upb_fielddef *f, jsonenc *e) {
7575   const upb_enumdef *e_def = upb_fielddef_enumsubdef(f);
7576   const char *name = upb_enumdef_iton(e_def, val);
7577 
7578   if (name) {
7579     jsonenc_printf(e, "\"%s\"", name);
7580   } else {
7581     jsonenc_printf(e, "%" PRId32, val);
7582   }
7583 }
7584 
jsonenc_bytes(jsonenc * e,upb_strview str)7585 static void jsonenc_bytes(jsonenc *e, upb_strview str) {
7586   /* This is the regular base64, not the "web-safe" version. */
7587   static const char base64[] =
7588       "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
7589   const unsigned char *ptr = (unsigned char*)str.data;
7590   const unsigned char *end = ptr + str.size;
7591   char buf[4];
7592 
7593   jsonenc_putstr(e, "\"");
7594 
7595   while (end - ptr >= 3) {
7596     buf[0] = base64[ptr[0] >> 2];
7597     buf[1] = base64[((ptr[0] & 0x3) << 4) | (ptr[1] >> 4)];
7598     buf[2] = base64[((ptr[1] & 0xf) << 2) | (ptr[2] >> 6)];
7599     buf[3] = base64[ptr[2] & 0x3f];
7600     jsonenc_putbytes(e, buf, 4);
7601     ptr += 3;
7602   }
7603 
7604   switch (end - ptr) {
7605     case 2:
7606       buf[0] = base64[ptr[0] >> 2];
7607       buf[1] = base64[((ptr[0] & 0x3) << 4) | (ptr[1] >> 4)];
7608       buf[2] = base64[(ptr[1] & 0xf) << 2];
7609       buf[3] = '=';
7610       jsonenc_putbytes(e, buf, 4);
7611       break;
7612     case 1:
7613       buf[0] = base64[ptr[0] >> 2];
7614       buf[1] = base64[((ptr[0] & 0x3) << 4)];
7615       buf[2] = '=';
7616       buf[3] = '=';
7617       jsonenc_putbytes(e, buf, 4);
7618       break;
7619   }
7620 
7621   jsonenc_putstr(e, "\"");
7622 }
7623 
jsonenc_stringbody(jsonenc * e,upb_strview str)7624 static void jsonenc_stringbody(jsonenc *e, upb_strview str) {
7625   const char *ptr = str.data;
7626   const char *end = ptr + str.size;
7627 
7628   while (ptr < end) {
7629     switch (*ptr) {
7630       case '\n':
7631         jsonenc_putstr(e, "\\n");
7632         break;
7633       case '\r':
7634         jsonenc_putstr(e, "\\r");
7635         break;
7636       case '\t':
7637         jsonenc_putstr(e, "\\t");
7638         break;
7639       case '\"':
7640         jsonenc_putstr(e, "\\\"");
7641         break;
7642       case '\f':
7643         jsonenc_putstr(e, "\\f");
7644         break;
7645       case '\b':
7646         jsonenc_putstr(e, "\\b");
7647         break;
7648       case '\\':
7649         jsonenc_putstr(e, "\\\\");
7650         break;
7651       default:
7652         if ((uint8_t)*ptr < 0x20) {
7653           jsonenc_printf(e, "\\u%04x", (int)(uint8_t)*ptr);
7654         } else {
7655           /* This could be a non-ASCII byte.  We rely on the string being valid
7656            * UTF-8. */
7657           jsonenc_putbytes(e, ptr, 1);
7658         }
7659         break;
7660     }
7661     ptr++;
7662   }
7663 }
7664 
jsonenc_string(jsonenc * e,upb_strview str)7665 static void jsonenc_string(jsonenc *e, upb_strview str) {
7666   jsonenc_putstr(e, "\"");
7667   jsonenc_stringbody(e, str);
7668   jsonenc_putstr(e, "\"");
7669 }
7670 
jsonenc_double(jsonenc * e,const char * fmt,double val)7671 static void jsonenc_double(jsonenc *e, const char *fmt, double val) {
7672   if (val == UPB_INFINITY) {
7673     jsonenc_putstr(e, "\"Infinity\"");
7674   } else if (val == -UPB_INFINITY) {
7675     jsonenc_putstr(e, "\"-Infinity\"");
7676   } else if (val != val) {
7677     jsonenc_putstr(e, "\"NaN\"");
7678   } else {
7679     jsonenc_printf(e, fmt, val);
7680   }
7681 }
7682 
jsonenc_wrapper(jsonenc * e,const upb_msg * msg,const upb_msgdef * m)7683 static void jsonenc_wrapper(jsonenc *e, const upb_msg *msg,
7684                             const upb_msgdef *m) {
7685   const upb_fielddef *val_f = upb_msgdef_itof(m, 1);
7686   upb_msgval val = upb_msg_get(msg, val_f);
7687   jsonenc_scalar(e, val, val_f);
7688 }
7689 
jsonenc_getanymsg(jsonenc * e,upb_strview type_url)7690 static const upb_msgdef *jsonenc_getanymsg(jsonenc *e, upb_strview type_url) {
7691   /* Find last '/', if any. */
7692   const char *end = type_url.data + type_url.size;
7693   const char *ptr = end;
7694   const upb_msgdef *ret;
7695 
7696   if (!e->ext_pool) {
7697     jsonenc_err(e, "Tried to encode Any, but no symtab was provided");
7698   }
7699 
7700   if (type_url.size == 0) goto badurl;
7701 
7702   while (true) {
7703     if (--ptr == type_url.data) {
7704       /* Type URL must contain at least one '/', with host before. */
7705       goto badurl;
7706     }
7707     if (*ptr == '/') {
7708       ptr++;
7709       break;
7710     }
7711   }
7712 
7713   ret = upb_symtab_lookupmsg2(e->ext_pool, ptr, end - ptr);
7714 
7715   if (!ret) {
7716     jsonenc_errf(e, "Couldn't find Any type: %.*s", (int)(end - ptr), ptr);
7717   }
7718 
7719   return ret;
7720 
7721 badurl:
7722   jsonenc_errf(
7723       e, "Bad type URL: " UPB_STRVIEW_FORMAT, UPB_STRVIEW_ARGS(type_url));
7724 }
7725 
jsonenc_any(jsonenc * e,const upb_msg * msg,const upb_msgdef * m)7726 static void jsonenc_any(jsonenc *e, const upb_msg *msg, const upb_msgdef *m) {
7727   const upb_fielddef *type_url_f = upb_msgdef_itof(m, 1);
7728   const upb_fielddef *value_f = upb_msgdef_itof(m, 2);
7729   upb_strview type_url = upb_msg_get(msg, type_url_f).str_val;
7730   upb_strview value = upb_msg_get(msg, value_f).str_val;
7731   const upb_msgdef *any_m = jsonenc_getanymsg(e, type_url);
7732   const upb_msglayout *any_layout = upb_msgdef_layout(any_m);
7733   upb_arena *arena = jsonenc_arena(e);
7734   upb_msg *any = upb_msg_new(any_m, arena);
7735 
7736   if (!upb_decode(value.data, value.size, any, any_layout, arena)) {
7737     jsonenc_err(e, "Error decoding message in Any");
7738   }
7739 
7740   jsonenc_putstr(e, "{\"@type\":");
7741   jsonenc_string(e, type_url);
7742   jsonenc_putstr(e, ",");
7743 
7744   if (upb_msgdef_wellknowntype(any_m) == UPB_WELLKNOWN_UNSPECIFIED) {
7745     /* Regular messages: {"@type": "...","foo": 1, "bar": 2} */
7746     jsonenc_msgfields(e, any, any_m);
7747   } else {
7748     /* Well-known type: {"@type": "...","value": <well-known encoding>} */
7749     jsonenc_putstr(e, "\"value\":");
7750     jsonenc_msgfield(e, any, any_m);
7751   }
7752 
7753   jsonenc_putstr(e, "}");
7754 }
7755 
jsonenc_putsep(jsonenc * e,const char * str,bool * first)7756 static void jsonenc_putsep(jsonenc *e, const char *str, bool *first) {
7757   if (*first) {
7758     *first = false;
7759   } else {
7760     jsonenc_putstr(e, str);
7761   }
7762 }
7763 
jsonenc_fieldpath(jsonenc * e,upb_strview path)7764 static void jsonenc_fieldpath(jsonenc *e, upb_strview path) {
7765   const char *ptr = path.data;
7766   const char *end = ptr + path.size;
7767 
7768   while (ptr < end) {
7769     char ch = *ptr;
7770 
7771     if (ch >= 'A' && ch <= 'Z') {
7772       jsonenc_err(e, "Field mask element may not have upper-case letter.");
7773     } else if (ch == '_') {
7774       if (ptr == end - 1 || *(ptr + 1) < 'a' || *(ptr + 1) > 'z') {
7775         jsonenc_err(e, "Underscore must be followed by a lowercase letter.");
7776       }
7777       ch = *++ptr - 32;
7778     }
7779 
7780     jsonenc_putbytes(e, &ch, 1);
7781     ptr++;
7782   }
7783 }
7784 
jsonenc_fieldmask(jsonenc * e,const upb_msg * msg,const upb_msgdef * m)7785 static void jsonenc_fieldmask(jsonenc *e, const upb_msg *msg,
7786                               const upb_msgdef *m) {
7787   const upb_fielddef *paths_f = upb_msgdef_itof(m, 1);
7788   const upb_array *paths = upb_msg_get(msg, paths_f).array_val;
7789   bool first = true;
7790   size_t i, n = 0;
7791 
7792   if (paths) n = upb_array_size(paths);
7793 
7794   jsonenc_putstr(e, "\"");
7795 
7796   for (i = 0; i < n; i++) {
7797     jsonenc_putsep(e, ",", &first);
7798     jsonenc_fieldpath(e, upb_array_get(paths, i).str_val);
7799   }
7800 
7801   jsonenc_putstr(e, "\"");
7802 }
7803 
jsonenc_struct(jsonenc * e,const upb_msg * msg,const upb_msgdef * m)7804 static void jsonenc_struct(jsonenc *e, const upb_msg *msg,
7805                            const upb_msgdef *m) {
7806   const upb_fielddef *fields_f = upb_msgdef_itof(m, 1);
7807   const upb_map *fields = upb_msg_get(msg, fields_f).map_val;
7808   const upb_msgdef *entry_m = upb_fielddef_msgsubdef(fields_f);
7809   const upb_fielddef *value_f = upb_msgdef_itof(entry_m, 2);
7810   size_t iter = UPB_MAP_BEGIN;
7811   bool first = true;
7812 
7813   jsonenc_putstr(e, "{");
7814 
7815   if (fields) {
7816     while (upb_mapiter_next(fields, &iter)) {
7817       upb_msgval key = upb_mapiter_key(fields, iter);
7818       upb_msgval val = upb_mapiter_value(fields, iter);
7819 
7820       jsonenc_putsep(e, ",", &first);
7821       jsonenc_string(e, key.str_val);
7822       jsonenc_putstr(e, ":");
7823       jsonenc_value(e, val.msg_val, upb_fielddef_msgsubdef(value_f));
7824     }
7825   }
7826 
7827   jsonenc_putstr(e, "}");
7828 }
7829 
jsonenc_listvalue(jsonenc * e,const upb_msg * msg,const upb_msgdef * m)7830 static void jsonenc_listvalue(jsonenc *e, const upb_msg *msg,
7831                               const upb_msgdef *m) {
7832   const upb_fielddef *values_f = upb_msgdef_itof(m, 1);
7833   const upb_msgdef *values_m = upb_fielddef_msgsubdef(values_f);
7834   const upb_array *values = upb_msg_get(msg, values_f).array_val;
7835   size_t i;
7836   bool first = true;
7837 
7838   jsonenc_putstr(e, "[");
7839 
7840   if (values) {
7841     const size_t size = upb_array_size(values);
7842     for (i = 0; i < size; i++) {
7843       upb_msgval elem = upb_array_get(values, i);
7844 
7845       jsonenc_putsep(e, ",", &first);
7846       jsonenc_value(e, elem.msg_val, values_m);
7847     }
7848   }
7849 
7850   jsonenc_putstr(e, "]");
7851 }
7852 
jsonenc_value(jsonenc * e,const upb_msg * msg,const upb_msgdef * m)7853 static void jsonenc_value(jsonenc *e, const upb_msg *msg, const upb_msgdef *m) {
7854   /* TODO(haberman): do we want a reflection method to get oneof case? */
7855   size_t iter = UPB_MSG_BEGIN;
7856   const upb_fielddef *f;
7857   upb_msgval val;
7858 
7859   if (!upb_msg_next(msg, m, NULL,  &f, &val, &iter)) {
7860     jsonenc_err(e, "No value set in Value proto");
7861   }
7862 
7863   switch (upb_fielddef_number(f)) {
7864     case 1:
7865       jsonenc_putstr(e, "null");
7866       break;
7867     case 2:
7868       jsonenc_double(e, "%.17g", val.double_val);
7869       break;
7870     case 3:
7871       jsonenc_string(e, val.str_val);
7872       break;
7873     case 4:
7874       jsonenc_putstr(e, val.bool_val ? "true" : "false");
7875       break;
7876     case 5:
7877       jsonenc_struct(e, val.msg_val, upb_fielddef_msgsubdef(f));
7878       break;
7879     case 6:
7880       jsonenc_listvalue(e, val.msg_val, upb_fielddef_msgsubdef(f));
7881       break;
7882   }
7883 }
7884 
jsonenc_msgfield(jsonenc * e,const upb_msg * msg,const upb_msgdef * m)7885 static void jsonenc_msgfield(jsonenc *e, const upb_msg *msg,
7886                              const upb_msgdef *m) {
7887   switch (upb_msgdef_wellknowntype(m)) {
7888     case UPB_WELLKNOWN_UNSPECIFIED:
7889       jsonenc_msg(e, msg, m);
7890       break;
7891     case UPB_WELLKNOWN_ANY:
7892       jsonenc_any(e, msg, m);
7893       break;
7894     case UPB_WELLKNOWN_FIELDMASK:
7895       jsonenc_fieldmask(e, msg, m);
7896       break;
7897     case UPB_WELLKNOWN_DURATION:
7898       jsonenc_duration(e, msg, m);
7899       break;
7900     case UPB_WELLKNOWN_TIMESTAMP:
7901       jsonenc_timestamp(e, msg, m);
7902       break;
7903     case UPB_WELLKNOWN_DOUBLEVALUE:
7904     case UPB_WELLKNOWN_FLOATVALUE:
7905     case UPB_WELLKNOWN_INT64VALUE:
7906     case UPB_WELLKNOWN_UINT64VALUE:
7907     case UPB_WELLKNOWN_INT32VALUE:
7908     case UPB_WELLKNOWN_UINT32VALUE:
7909     case UPB_WELLKNOWN_STRINGVALUE:
7910     case UPB_WELLKNOWN_BYTESVALUE:
7911     case UPB_WELLKNOWN_BOOLVALUE:
7912       jsonenc_wrapper(e, msg, m);
7913       break;
7914     case UPB_WELLKNOWN_VALUE:
7915       jsonenc_value(e, msg, m);
7916       break;
7917     case UPB_WELLKNOWN_LISTVALUE:
7918       jsonenc_listvalue(e, msg, m);
7919       break;
7920     case UPB_WELLKNOWN_STRUCT:
7921       jsonenc_struct(e, msg, m);
7922       break;
7923   }
7924 }
7925 
jsonenc_scalar(jsonenc * e,upb_msgval val,const upb_fielddef * f)7926 static void jsonenc_scalar(jsonenc *e, upb_msgval val, const upb_fielddef *f) {
7927   switch (upb_fielddef_type(f)) {
7928     case UPB_TYPE_BOOL:
7929       jsonenc_putstr(e, val.bool_val ? "true" : "false");
7930       break;
7931     case UPB_TYPE_FLOAT:
7932       jsonenc_double(e, "%.9g", val.float_val);
7933       break;
7934     case UPB_TYPE_DOUBLE:
7935       jsonenc_double(e, "%.17g", val.double_val);
7936       break;
7937     case UPB_TYPE_INT32:
7938       jsonenc_printf(e, "%" PRId32, val.int32_val);
7939       break;
7940     case UPB_TYPE_UINT32:
7941       jsonenc_printf(e, "%" PRIu32, val.uint32_val);
7942       break;
7943     case UPB_TYPE_INT64:
7944       jsonenc_printf(e, "\"%" PRId64 "\"", val.int64_val);
7945       break;
7946     case UPB_TYPE_UINT64:
7947       jsonenc_printf(e, "\"%" PRIu64 "\"", val.uint64_val);
7948       break;
7949     case UPB_TYPE_STRING:
7950       jsonenc_string(e, val.str_val);
7951       break;
7952     case UPB_TYPE_BYTES:
7953       jsonenc_bytes(e, val.str_val);
7954       break;
7955     case UPB_TYPE_ENUM:
7956       jsonenc_enum(val.int32_val, f, e);
7957       break;
7958     case UPB_TYPE_MESSAGE:
7959       jsonenc_msgfield(e, val.msg_val, upb_fielddef_msgsubdef(f));
7960       break;
7961   }
7962 }
7963 
jsonenc_mapkey(jsonenc * e,upb_msgval val,const upb_fielddef * f)7964 static void jsonenc_mapkey(jsonenc *e, upb_msgval val, const upb_fielddef *f) {
7965   jsonenc_putstr(e, "\"");
7966 
7967   switch (upb_fielddef_type(f)) {
7968     case UPB_TYPE_BOOL:
7969       jsonenc_putstr(e, val.bool_val ? "true" : "false");
7970       break;
7971     case UPB_TYPE_INT32:
7972       jsonenc_printf(e, "%" PRId32, val.int32_val);
7973       break;
7974     case UPB_TYPE_UINT32:
7975       jsonenc_printf(e, "%" PRIu32, val.uint32_val);
7976       break;
7977     case UPB_TYPE_INT64:
7978       jsonenc_printf(e, "%" PRId64, val.int64_val);
7979       break;
7980     case UPB_TYPE_UINT64:
7981       jsonenc_printf(e, "%" PRIu64, val.uint64_val);
7982       break;
7983     case UPB_TYPE_STRING:
7984       jsonenc_stringbody(e, val.str_val);
7985       break;
7986     default:
7987       UPB_UNREACHABLE();
7988   }
7989 
7990   jsonenc_putstr(e, "\":");
7991 }
7992 
jsonenc_array(jsonenc * e,const upb_array * arr,const upb_fielddef * f)7993 static void jsonenc_array(jsonenc *e, const upb_array *arr,
7994                          const upb_fielddef *f) {
7995   size_t i;
7996   size_t size = upb_array_size(arr);
7997   bool first = true;
7998 
7999   jsonenc_putstr(e, "[");
8000 
8001   for (i = 0; i < size; i++) {
8002     jsonenc_putsep(e, ",", &first);
8003     jsonenc_scalar(e, upb_array_get(arr, i), f);
8004   }
8005 
8006   jsonenc_putstr(e, "]");
8007 }
8008 
jsonenc_map(jsonenc * e,const upb_map * map,const upb_fielddef * f)8009 static void jsonenc_map(jsonenc *e, const upb_map *map, const upb_fielddef *f) {
8010   const upb_msgdef *entry = upb_fielddef_msgsubdef(f);
8011   const upb_fielddef *key_f = upb_msgdef_itof(entry, 1);
8012   const upb_fielddef *val_f = upb_msgdef_itof(entry, 2);
8013   size_t iter = UPB_MAP_BEGIN;
8014   bool first = true;
8015 
8016   jsonenc_putstr(e, "{");
8017 
8018   while (upb_mapiter_next(map, &iter)) {
8019     jsonenc_putsep(e, ",", &first);
8020     jsonenc_mapkey(e, upb_mapiter_key(map, iter), key_f);
8021     jsonenc_scalar(e, upb_mapiter_value(map, iter), val_f);
8022   }
8023 
8024   jsonenc_putstr(e, "}");
8025 }
8026 
jsonenc_fieldval(jsonenc * e,const upb_fielddef * f,upb_msgval val,bool * first)8027 static void jsonenc_fieldval(jsonenc *e, const upb_fielddef *f,
8028                              upb_msgval val, bool *first) {
8029   const char *name;
8030 
8031   if (e->options & UPB_JSONENC_PROTONAMES) {
8032     name = upb_fielddef_name(f);
8033   } else {
8034     name = upb_fielddef_jsonname(f);
8035   }
8036 
8037   jsonenc_putsep(e, ",", first);
8038   jsonenc_printf(e, "\"%s\":", name);
8039 
8040   if (upb_fielddef_ismap(f)) {
8041     jsonenc_map(e, val.map_val, f);
8042   } else if (upb_fielddef_isseq(f)) {
8043     jsonenc_array(e, val.array_val, f);
8044   } else {
8045     jsonenc_scalar(e, val, f);
8046   }
8047 }
8048 
jsonenc_msgfields(jsonenc * e,const upb_msg * msg,const upb_msgdef * m)8049 static void jsonenc_msgfields(jsonenc *e, const upb_msg *msg,
8050                               const upb_msgdef *m) {
8051   upb_msgval val;
8052   const upb_fielddef *f;
8053   bool first = true;
8054 
8055   if (e->options & UPB_JSONENC_EMITDEFAULTS) {
8056     /* Iterate over all fields. */
8057     upb_msg_field_iter i;
8058     for (upb_msg_field_begin(&i, m); !upb_msg_field_done(&i);
8059          upb_msg_field_next(&i)) {
8060       f = upb_msg_iter_field(&i);
8061       jsonenc_fieldval(e, f, upb_msg_get(msg, f), &first);
8062     }
8063   } else {
8064     /* Iterate over non-empty fields. */
8065     size_t iter = UPB_MSG_BEGIN;
8066     while (upb_msg_next(msg, m, e->ext_pool, &f, &val, &iter)) {
8067       jsonenc_fieldval(e, f, val, &first);
8068     }
8069   }
8070 }
8071 
jsonenc_msg(jsonenc * e,const upb_msg * msg,const upb_msgdef * m)8072 static void jsonenc_msg(jsonenc *e, const upb_msg *msg, const upb_msgdef *m) {
8073   jsonenc_putstr(e, "{");
8074   jsonenc_msgfields(e, msg, m);
8075   jsonenc_putstr(e, "}");
8076 }
8077 
jsonenc_nullz(jsonenc * e,size_t size)8078 static size_t jsonenc_nullz(jsonenc *e, size_t size) {
8079   size_t ret = e->ptr - e->buf + e->overflow;
8080 
8081   if (size > 0) {
8082     if (e->ptr == e->end) e->ptr--;
8083     *e->ptr = '\0';
8084   }
8085 
8086   return ret;
8087 }
8088 
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)8089 size_t upb_json_encode(const upb_msg *msg, const upb_msgdef *m,
8090                        const upb_symtab *ext_pool, int options, char *buf,
8091                        size_t size, upb_status *status) {
8092   jsonenc e;
8093 
8094   e.buf = buf;
8095   e.ptr = buf;
8096   e.end = buf + size;
8097   e.overflow = 0;
8098   e.options = options;
8099   e.ext_pool = ext_pool;
8100   e.status = status;
8101   e.arena = NULL;
8102 
8103   if (setjmp(e.err)) return -1;
8104 
8105   jsonenc_msgfield(&e, msg, m);
8106   if (e.arena) upb_arena_free(e.arena);
8107   return jsonenc_nullz(&e, size);
8108 }
8109 /* See port_def.inc.  This should #undef all macros #defined there. */
8110 
8111 #undef UPB_MAPTYPE_STRING
8112 #undef UPB_SIZE
8113 #undef UPB_PTR_AT
8114 #undef UPB_READ_ONEOF
8115 #undef UPB_WRITE_ONEOF
8116 #undef UPB_INLINE
8117 #undef UPB_ALIGN_UP
8118 #undef UPB_ALIGN_DOWN
8119 #undef UPB_ALIGN_MALLOC
8120 #undef UPB_ALIGN_OF
8121 #undef UPB_FORCEINLINE
8122 #undef UPB_NOINLINE
8123 #undef UPB_NORETURN
8124 #undef UPB_MAX
8125 #undef UPB_MIN
8126 #undef UPB_UNUSED
8127 #undef UPB_ASSUME
8128 #undef UPB_ASSERT
8129 #undef UPB_ASSERT_DEBUGVAR
8130 #undef UPB_UNREACHABLE
8131 #undef UPB_INFINITY
8132 #undef UPB_NAN
8133 #undef UPB_MSVC_VSNPRINTF
8134 #undef _upb_snprintf
8135 #undef _upb_vsnprintf
8136 #undef _upb_va_copy
8137