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