ruby-upb.c
Go to the documentation of this file.
1 /* Amalgamated source file */
2 #include "ruby-upb.h"
3 /*
4  * Copyright (c) 2009-2021, Google LLC
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions are met:
9  * * Redistributions of source code must retain the above copyright
10  * notice, this list of conditions and the following disclaimer.
11  * * Redistributions in binary form must reproduce the above copyright
12  * notice, this list of conditions and the following disclaimer in the
13  * documentation and/or other materials provided with the distribution.
14  * * Neither the name of Google LLC nor the
15  * names of its contributors may be used to endorse or promote products
16  * derived from this software without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
19  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21  * DISCLAIMED. IN NO EVENT SHALL Google LLC BE LIABLE FOR ANY
22  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
25  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28  */
29 
30 /*
31  * This is where we define macros used across upb.
32  *
33  * All of these macros are undef'd in port_undef.inc to avoid leaking them to
34  * users.
35  *
36  * The correct usage is:
37  *
38  * #include "upb/foobar.h"
39  * #include "upb/baz.h"
40  *
41  * // MUST be last included header.
42  * #include "upb/port_def.inc"
43  *
44  * // Code for this file.
45  * // <...>
46  *
47  * // Can be omitted for .c files, required for .h.
48  * #include "upb/port_undef.inc"
49  *
50  * This file is private and must not be included by users!
51  */
52 
53 #if !((defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || \
54  (defined(__cplusplus) && __cplusplus >= 201103L) || \
55  (defined(_MSC_VER) && _MSC_VER >= 1900))
56 #error upb requires C99 or C++11 or MSVC >= 2015.
57 #endif
58 
59 #include <stdint.h>
60 #include <stddef.h>
61 
62 #if UINTPTR_MAX == 0xffffffff
63 #define UPB_SIZE(size32, size64) size32
64 #else
65 #define UPB_SIZE(size32, size64) size64
66 #endif
67 
68 /* If we always read/write as a consistent type to each address, this shouldn't
69  * violate aliasing.
70  */
71 #define UPB_PTR_AT(msg, ofs, type) ((type*)((char*)(msg) + (ofs)))
72 
73 #define UPB_READ_ONEOF(msg, fieldtype, offset, case_offset, case_val, default) \
74  *UPB_PTR_AT(msg, case_offset, int) == case_val \
75  ? *UPB_PTR_AT(msg, offset, fieldtype) \
76  : default
77 
78 #define UPB_WRITE_ONEOF(msg, fieldtype, offset, value, case_offset, case_val) \
79  *UPB_PTR_AT(msg, case_offset, int) = case_val; \
80  *UPB_PTR_AT(msg, offset, fieldtype) = value;
81 
82 #define UPB_MAPTYPE_STRING 0
83 
84 /* UPB_INLINE: inline if possible, emit standalone code if required. */
85 #ifdef __cplusplus
86 #define UPB_INLINE inline
87 #elif defined (__GNUC__) || defined(__clang__)
88 #define UPB_INLINE static __inline__
89 #else
90 #define UPB_INLINE static
91 #endif
92 
93 #define UPB_ALIGN_UP(size, align) (((size) + (align) - 1) / (align) * (align))
94 #define UPB_ALIGN_DOWN(size, align) ((size) / (align) * (align))
95 #define UPB_ALIGN_MALLOC(size) UPB_ALIGN_UP(size, 16)
96 #define UPB_ALIGN_OF(type) offsetof (struct { char c; type member; }, member)
97 
98 /* Hints to the compiler about likely/unlikely branches. */
99 #if defined (__GNUC__) || defined(__clang__)
100 #define UPB_LIKELY(x) __builtin_expect((x),1)
101 #define UPB_UNLIKELY(x) __builtin_expect((x),0)
102 #else
103 #define UPB_LIKELY(x) (x)
104 #define UPB_UNLIKELY(x) (x)
105 #endif
106 
107 /* Macros for function attributes on compilers that support them. */
108 #ifdef __GNUC__
109 #define UPB_FORCEINLINE __inline__ __attribute__((always_inline))
110 #define UPB_NOINLINE __attribute__((noinline))
111 #define UPB_NORETURN __attribute__((__noreturn__))
112 #define UPB_PRINTF(str, first_vararg) __attribute__((format (printf, str, first_vararg)))
113 #elif defined(_MSC_VER)
114 #define UPB_NOINLINE
115 #define UPB_FORCEINLINE
116 #define UPB_NORETURN __declspec(noreturn)
117 #define UPB_PRINTF(str, first_vararg)
118 #else /* !defined(__GNUC__) */
119 #define UPB_FORCEINLINE
120 #define UPB_NOINLINE
121 #define UPB_NORETURN
122 #define UPB_PRINTF(str, first_vararg)
123 #endif
124 
125 #define UPB_MAX(x, y) ((x) > (y) ? (x) : (y))
126 #define UPB_MIN(x, y) ((x) < (y) ? (x) : (y))
127 
128 #define UPB_UNUSED(var) (void)var
129 
130 /* UPB_ASSUME(): in release mode, we tell the compiler to assume this is true.
131  */
132 #ifdef NDEBUG
133 #ifdef __GNUC__
134 #define UPB_ASSUME(expr) if (!(expr)) __builtin_unreachable()
135 #elif defined _MSC_VER
136 #define UPB_ASSUME(expr) if (!(expr)) __assume(0)
137 #else
138 #define UPB_ASSUME(expr) do {} while (false && (expr))
139 #endif
140 #else
141 #define UPB_ASSUME(expr) assert(expr)
142 #endif
143 
144 /* UPB_ASSERT(): in release mode, we use the expression without letting it be
145  * evaluated. This prevents "unused variable" warnings. */
146 #ifdef NDEBUG
147 #define UPB_ASSERT(expr) do {} while (false && (expr))
148 #else
149 #define UPB_ASSERT(expr) assert(expr)
150 #endif
151 
152 #if defined(__GNUC__) || defined(__clang__)
153 #define UPB_UNREACHABLE() do { assert(0); __builtin_unreachable(); } while(0)
154 #else
155 #define UPB_UNREACHABLE() do { assert(0); } while(0)
156 #endif
157 
158 /* UPB_SETJMP() / UPB_LONGJMP(): avoid setting/restoring signal mask. */
159 #ifdef __APPLE__
160 #define UPB_SETJMP(buf) _setjmp(buf)
161 #define UPB_LONGJMP(buf, val) _longjmp(buf, val)
162 #else
163 #define UPB_SETJMP(buf) setjmp(buf)
164 #define UPB_LONGJMP(buf, val) longjmp(buf, val)
165 #endif
166 
167 /* UPB_PTRADD(ptr, ofs): add pointer while avoiding "NULL + 0" UB */
168 #define UPB_PTRADD(ptr, ofs) ((ofs) ? (ptr) + (ofs) : (ptr))
169 
170 /* Configure whether fasttable is switched on or not. *************************/
171 
172 #ifdef __has_attribute
173 #define UPB_HAS_ATTRIBUTE(x) __has_attribute(x)
174 #else
175 #define UPB_HAS_ATTRIBUTE(x) 0
176 #endif
177 
178 #if UPB_HAS_ATTRIBUTE(musttail)
179 #define UPB_MUSTTAIL __attribute__((musttail))
180 #else
181 #define UPB_MUSTTAIL
182 #endif
183 
184 #undef UPB_HAS_ATTRIBUTE
185 
186 /* This check is not fully robust: it does not require that we have "musttail"
187  * support available. We need tail calls to avoid consuming arbitrary amounts
188  * of stack space.
189  *
190  * GCC/Clang can mostly be trusted to generate tail calls as long as
191  * optimization is enabled, but, debug builds will not generate tail calls
192  * unless "musttail" is available.
193  *
194  * We should probably either:
195  * 1. require that the compiler supports musttail.
196  * 2. add some fallback code for when musttail isn't available (ie. return
197  * instead of tail calling). This is safe and portable, but this comes at
198  * a CPU cost.
199  */
200 #if (defined(__x86_64__) || defined(__aarch64__)) && defined(__GNUC__)
201 #define UPB_FASTTABLE_SUPPORTED 1
202 #else
203 #define UPB_FASTTABLE_SUPPORTED 0
204 #endif
205 
206 /* define UPB_ENABLE_FASTTABLE to force fast table support.
207  * This is useful when we want to ensure we are really getting fasttable,
208  * for example for testing or benchmarking. */
209 #if defined(UPB_ENABLE_FASTTABLE)
210 #if !UPB_FASTTABLE_SUPPORTED
211 #error fasttable is x86-64/ARM64 only and requires GCC or Clang.
212 #endif
213 #define UPB_FASTTABLE 1
214 /* Define UPB_TRY_ENABLE_FASTTABLE to use fasttable if possible.
215  * This is useful for releasing code that might be used on multiple platforms,
216  * for example the PHP or Ruby C extensions. */
217 #elif defined(UPB_TRY_ENABLE_FASTTABLE)
218 #define UPB_FASTTABLE UPB_FASTTABLE_SUPPORTED
219 #else
220 #define UPB_FASTTABLE 0
221 #endif
222 
223 /* UPB_FASTTABLE_INIT() allows protos compiled for fasttable to gracefully
224  * degrade to non-fasttable if we are using UPB_TRY_ENABLE_FASTTABLE. */
225 #if !UPB_FASTTABLE && defined(UPB_TRY_ENABLE_FASTTABLE)
226 #define UPB_FASTTABLE_INIT(...)
227 #else
228 #define UPB_FASTTABLE_INIT(...) __VA_ARGS__
229 #endif
230 
231 #undef UPB_FASTTABLE_SUPPORTED
232 
233 /* ASAN poisoning (for arena) *************************************************/
234 
235 #if defined(__SANITIZE_ADDRESS__)
236 #define UPB_ASAN 1
237 #ifdef __cplusplus
238 extern "C" {
239 #endif
240 void __asan_poison_memory_region(void const volatile *addr, size_t size);
241 void __asan_unpoison_memory_region(void const volatile *addr, size_t size);
242 #ifdef __cplusplus
243 } /* extern "C" */
244 #endif
245 #define UPB_POISON_MEMORY_REGION(addr, size) \
246  __asan_poison_memory_region((addr), (size))
247 #define UPB_UNPOISON_MEMORY_REGION(addr, size) \
248  __asan_unpoison_memory_region((addr), (size))
249 #else
250 #define UPB_ASAN 0
251 #define UPB_POISON_MEMORY_REGION(addr, size) \
252  ((void)(addr), (void)(size))
253 #define UPB_UNPOISON_MEMORY_REGION(addr, size) \
254  ((void)(addr), (void)(size))
255 #endif
256 
259 #include <setjmp.h>
260 #include <string.h>
261 
262 
263 /* Must be last. */
264 
265 /* Maps descriptor type -> elem_size_lg2. */
267  -1, /* invalid descriptor type */
268  3, /* DOUBLE */
269  2, /* FLOAT */
270  3, /* INT64 */
271  3, /* UINT64 */
272  2, /* INT32 */
273  3, /* FIXED64 */
274  2, /* FIXED32 */
275  0, /* BOOL */
276  UPB_SIZE(3, 4), /* STRING */
277  UPB_SIZE(2, 3), /* GROUP */
278  UPB_SIZE(2, 3), /* MESSAGE */
279  UPB_SIZE(3, 4), /* BYTES */
280  2, /* UINT32 */
281  2, /* ENUM */
282  2, /* SFIXED32 */
283  3, /* SFIXED64 */
284  2, /* SINT32 */
285  3, /* SINT64 */
286 };
287 
288 /* Maps descriptor type -> upb map size. */
289 static const uint8_t desctype_to_mapsize[] = {
290  -1, /* invalid descriptor type */
291  8, /* DOUBLE */
292  4, /* FLOAT */
293  8, /* INT64 */
294  8, /* UINT64 */
295  4, /* INT32 */
296  8, /* FIXED64 */
297  4, /* FIXED32 */
298  1, /* BOOL */
299  UPB_MAPTYPE_STRING, /* STRING */
300  sizeof(void *), /* GROUP */
301  sizeof(void *), /* MESSAGE */
302  UPB_MAPTYPE_STRING, /* BYTES */
303  4, /* UINT32 */
304  4, /* ENUM */
305  4, /* SFIXED32 */
306  8, /* SFIXED64 */
307  4, /* SINT32 */
308  8, /* SINT64 */
309 };
310 
311 static const unsigned fixed32_ok = (1 << UPB_DTYPE_FLOAT) |
312  (1 << UPB_DTYPE_FIXED32) |
313  (1 << UPB_DTYPE_SFIXED32);
314 
315 static const unsigned fixed64_ok = (1 << UPB_DTYPE_DOUBLE) |
316  (1 << UPB_DTYPE_FIXED64) |
317  (1 << UPB_DTYPE_SFIXED64);
318 
319 /* Op: an action to be performed for a wire-type/field-type combination. */
320 #define OP_SCALAR_LG2(n) (n) /* n in [0, 2, 3] => op in [0, 2, 3] */
321 #define OP_STRING 4
322 #define OP_BYTES 5
323 #define OP_SUBMSG 6
324 /* Ops above are scalar-only. Repeated fields can use any op. */
325 #define OP_FIXPCK_LG2(n) (n + 5) /* n in [2, 3] => op in [7, 8] */
326 #define OP_VARPCK_LG2(n) (n + 9) /* n in [0, 2, 3] => op in [9, 11, 12] */
327 
328 static const int8_t varint_ops[19] = {
329  -1, /* field not found */
330  -1, /* DOUBLE */
331  -1, /* FLOAT */
332  OP_SCALAR_LG2(3), /* INT64 */
333  OP_SCALAR_LG2(3), /* UINT64 */
334  OP_SCALAR_LG2(2), /* INT32 */
335  -1, /* FIXED64 */
336  -1, /* FIXED32 */
337  OP_SCALAR_LG2(0), /* BOOL */
338  -1, /* STRING */
339  -1, /* GROUP */
340  -1, /* MESSAGE */
341  -1, /* BYTES */
342  OP_SCALAR_LG2(2), /* UINT32 */
343  OP_SCALAR_LG2(2), /* ENUM */
344  -1, /* SFIXED32 */
345  -1, /* SFIXED64 */
346  OP_SCALAR_LG2(2), /* SINT32 */
347  OP_SCALAR_LG2(3), /* SINT64 */
348 };
349 
350 static const int8_t delim_ops[37] = {
351  /* For non-repeated field type. */
352  -1, /* field not found */
353  -1, /* DOUBLE */
354  -1, /* FLOAT */
355  -1, /* INT64 */
356  -1, /* UINT64 */
357  -1, /* INT32 */
358  -1, /* FIXED64 */
359  -1, /* FIXED32 */
360  -1, /* BOOL */
361  OP_STRING, /* STRING */
362  -1, /* GROUP */
363  OP_SUBMSG, /* MESSAGE */
364  OP_BYTES, /* BYTES */
365  -1, /* UINT32 */
366  -1, /* ENUM */
367  -1, /* SFIXED32 */
368  -1, /* SFIXED64 */
369  -1, /* SINT32 */
370  -1, /* SINT64 */
371  /* For repeated field type. */
372  OP_FIXPCK_LG2(3), /* REPEATED DOUBLE */
373  OP_FIXPCK_LG2(2), /* REPEATED FLOAT */
374  OP_VARPCK_LG2(3), /* REPEATED INT64 */
375  OP_VARPCK_LG2(3), /* REPEATED UINT64 */
376  OP_VARPCK_LG2(2), /* REPEATED INT32 */
377  OP_FIXPCK_LG2(3), /* REPEATED FIXED64 */
378  OP_FIXPCK_LG2(2), /* REPEATED FIXED32 */
379  OP_VARPCK_LG2(0), /* REPEATED BOOL */
380  OP_STRING, /* REPEATED STRING */
381  OP_SUBMSG, /* REPEATED GROUP */
382  OP_SUBMSG, /* REPEATED MESSAGE */
383  OP_BYTES, /* REPEATED BYTES */
384  OP_VARPCK_LG2(2), /* REPEATED UINT32 */
385  OP_VARPCK_LG2(2), /* REPEATED ENUM */
386  OP_FIXPCK_LG2(2), /* REPEATED SFIXED32 */
387  OP_FIXPCK_LG2(3), /* REPEATED SFIXED64 */
388  OP_VARPCK_LG2(2), /* REPEATED SINT32 */
389  OP_VARPCK_LG2(3), /* REPEATED SINT64 */
390 };
391 
392 typedef union {
393  bool bool_val;
394  uint32_t uint32_val;
395  uint64_t uint64_val;
396  uint32_t size;
397 } wireval;
398 
399 static const char *decode_msg(upb_decstate *d, const char *ptr, upb_msg *msg,
400  const upb_msglayout *layout);
401 
402 UPB_NORETURN static void decode_err(upb_decstate *d) { UPB_LONGJMP(d->err, 1); }
403 
404 // We don't want to mark this NORETURN, see comment in .h.
405 // Unfortunately this code to suppress the warning doesn't appear to be working.
406 #ifdef __clang__
407 #pragma clang diagnostic push
408 #pragma clang diagnostic ignored "-Wunknown-warning-option"
409 #pragma clang diagnostic ignored "-Wsuggest-attribute"
410 #endif
411 
413  longjmp(d->err, 1);
414  return NULL;
415 }
416 
417 #ifdef __clang__
418 #pragma clang diagnostic pop
419 #endif
420 
422  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
423  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
424  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
425  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
426  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
427  1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
428  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
429  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
430  2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
431  2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
432  4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0,
433 };
434 
435 static void decode_verifyutf8(upb_decstate *d, const char *buf, int len) {
437 }
438 
439 static bool decode_reserve(upb_decstate *d, upb_array *arr, size_t elem) {
440  bool need_realloc = arr->size - arr->len < elem;
441  if (need_realloc && !_upb_array_realloc(arr, arr->len + elem, &d->arena)) {
442  decode_err(d);
443  }
444  return need_realloc;
445 }
446 
447 typedef struct {
448  const char *ptr;
449  uint64_t val;
450 } decode_vret;
451 
453 static decode_vret decode_longvarint64(const char *ptr, uint64_t val) {
454  decode_vret ret = {NULL, 0};
455  uint64_t byte;
456  int i;
457  for (i = 1; i < 10; i++) {
458  byte = (uint8_t)ptr[i];
459  val += (byte - 1) << (i * 7);
460  if (!(byte & 0x80)) {
461  ret.ptr = ptr + i + 1;
462  ret.val = val;
463  return ret;
464  }
465  }
466  return ret;
467 }
468 
470 static const char *decode_varint64(upb_decstate *d, const char *ptr,
471  uint64_t *val) {
472  uint64_t byte = (uint8_t)*ptr;
473  if (UPB_LIKELY((byte & 0x80) == 0)) {
474  *val = byte;
475  return ptr + 1;
476  } else {
477  decode_vret res = decode_longvarint64(ptr, byte);
478  if (!res.ptr) decode_err(d);
479  *val = res.val;
480  return res.ptr;
481  }
482 }
483 
485 static const char *decode_tag(upb_decstate *d, const char *ptr,
486  uint32_t *val) {
487  uint64_t byte = (uint8_t)*ptr;
488  if (UPB_LIKELY((byte & 0x80) == 0)) {
489  *val = byte;
490  return ptr + 1;
491  } else {
492  const char *start = ptr;
493  decode_vret res = decode_longvarint64(ptr, byte);
494  ptr = res.ptr;
495  *val = res.val;
496  if (!ptr || *val > UINT32_MAX || ptr - start > 5) decode_err(d);
497  return ptr;
498  }
499 }
500 
501 static void decode_munge(int type, wireval *val) {
502  switch (type) {
504  val->bool_val = val->uint64_val != 0;
505  break;
507  uint32_t n = val->uint32_val;
508  val->uint32_val = (n >> 1) ^ -(int32_t)(n & 1);
509  break;
510  }
512  uint64_t n = val->uint64_val;
513  val->uint64_val = (n >> 1) ^ -(int64_t)(n & 1);
514  break;
515  }
518  if (!_upb_isle()) {
519  /* The next stage will memcpy(dst, &val, 4) */
520  val->uint32_val = val->uint64_val;
521  }
522  break;
523  }
524 }
525 
527  uint32_t field_number,
528  int *last_field_index) {
529  static upb_msglayout_field none = {0, 0, 0, 0, 0, 0};
530 
531  if (l == NULL) return &none;
532 
533  size_t idx = ((size_t)field_number) - 1; // 0 wraps to SIZE_MAX
534  if (idx < l->dense_below) {
535  goto found;
536  }
537 
538  /* Resume scanning from last_field_index since fields are usually in order. */
539  int last = *last_field_index;
540  for (idx = last; idx < l->field_count; idx++) {
541  if (l->fields[idx].number == field_number) {
542  goto found;
543  }
544  }
545 
546  for (idx = 0; idx < last; idx++) {
547  if (l->fields[idx].number == field_number) {
548  goto found;
549  }
550  }
551 
552  return &none; /* Unknown field. */
553 
554  found:
555  UPB_ASSERT(l->fields[idx].number == field_number);
556  *last_field_index = idx;
557  return &l->fields[idx];
558 }
559 
561  upb_msglayout const *const *submsgs,
562  const upb_msglayout_field *field) {
563  const upb_msglayout *subl = submsgs[field->submsg_index];
564  return _upb_msg_new_inl(subl, &d->arena);
565 }
566 
568 const char *decode_isdonefallback(upb_decstate *d, const char *ptr,
569  int overrun) {
570  ptr = decode_isdonefallback_inl(d, ptr, overrun);
571  if (ptr == NULL) {
572  decode_err(d);
573  }
574  return ptr;
575 }
576 
577 static const char *decode_readstr(upb_decstate *d, const char *ptr, int size,
578  upb_strview *str) {
579  if (d->alias) {
580  str->data = ptr;
581  } else {
582  char *data = upb_arena_malloc(&d->arena, size);
583  if (!data) decode_err(d);
584  memcpy(data, ptr, size);
585  str->data = data;
586  }
587  str->size = size;
588  return ptr + size;
589 }
590 
592 static const char *decode_tosubmsg(upb_decstate *d, const char *ptr,
593  upb_msg *submsg,
594  upb_msglayout const *const *submsgs,
595  const upb_msglayout_field *field, int size) {
596  const upb_msglayout *subl = submsgs[field->submsg_index];
597  int saved_delta = decode_pushlimit(d, ptr, size);
598  if (--d->depth < 0) decode_err(d);
599  if (!decode_isdone(d, &ptr)) {
600  ptr = decode_msg(d, ptr, submsg, subl);
601  }
602  if (d->end_group != DECODE_NOGROUP) decode_err(d);
603  decode_poplimit(d, ptr, saved_delta);
604  d->depth++;
605  return ptr;
606 }
607 
609 static const char *decode_group(upb_decstate *d, const char *ptr,
610  upb_msg *submsg, const upb_msglayout *subl,
611  uint32_t number) {
612  if (--d->depth < 0) decode_err(d);
613  if (decode_isdone(d, &ptr)) {
614  decode_err(d);
615  }
616  ptr = decode_msg(d, ptr, submsg, subl);
617  if (d->end_group != number) decode_err(d);
618  d->end_group = DECODE_NOGROUP;
619  d->depth++;
620  return ptr;
621 }
622 
624 static const char *decode_togroup(upb_decstate *d, const char *ptr,
625  upb_msg *submsg,
626  upb_msglayout const *const *submsgs,
627  const upb_msglayout_field *field) {
628  const upb_msglayout *subl = submsgs[field->submsg_index];
629  return decode_group(d, ptr, submsg, subl, field->number);
630 }
631 
632 static const char *decode_toarray(upb_decstate *d, const char *ptr,
633  upb_msg *msg,
634  upb_msglayout const *const *submsgs,
635  const upb_msglayout_field *field, wireval *val,
636  int op) {
637  upb_array **arrp = UPB_PTR_AT(msg, field->offset, void);
638  upb_array *arr = *arrp;
639  void *mem;
640 
641  if (arr) {
642  decode_reserve(d, arr, 1);
643  } else {
644  size_t lg2 = desctype_to_elem_size_lg2[field->descriptortype];
645  arr = _upb_array_new(&d->arena, 4, lg2);
646  if (!arr) decode_err(d);
647  *arrp = arr;
648  }
649 
650  switch (op) {
651  case OP_SCALAR_LG2(0):
652  case OP_SCALAR_LG2(2):
653  case OP_SCALAR_LG2(3):
654  /* Append scalar value. */
655  mem = UPB_PTR_AT(_upb_array_ptr(arr), arr->len << op, void);
656  arr->len++;
657  memcpy(mem, val, 1 << op);
658  return ptr;
659  case OP_STRING:
660  decode_verifyutf8(d, ptr, val->size);
661  /* Fallthrough. */
662  case OP_BYTES: {
663  /* Append bytes. */
664  upb_strview *str = (upb_strview*)_upb_array_ptr(arr) + arr->len;
665  arr->len++;
666  return decode_readstr(d, ptr, val->size, str);
667  }
668  case OP_SUBMSG: {
669  /* Append submessage / group. */
670  upb_msg *submsg = decode_newsubmsg(d, submsgs, field);
671  *UPB_PTR_AT(_upb_array_ptr(arr), arr->len * sizeof(void *), upb_msg *) =
672  submsg;
673  arr->len++;
674  if (UPB_UNLIKELY(field->descriptortype == UPB_DTYPE_GROUP)) {
675  return decode_togroup(d, ptr, submsg, submsgs, field);
676  } else {
677  return decode_tosubmsg(d, ptr, submsg, submsgs, field, val->size);
678  }
679  }
680  case OP_FIXPCK_LG2(2):
681  case OP_FIXPCK_LG2(3): {
682  /* Fixed packed. */
683  int lg2 = op - OP_FIXPCK_LG2(0);
684  int mask = (1 << lg2) - 1;
685  size_t count = val->size >> lg2;
686  if ((val->size & mask) != 0) {
687  decode_err(d); /* Length isn't a round multiple of elem size. */
688  }
689  decode_reserve(d, arr, count);
690  mem = UPB_PTR_AT(_upb_array_ptr(arr), arr->len << lg2, void);
691  arr->len += count;
692  memcpy(mem, ptr, val->size); /* XXX: ptr boundary. */
693  return ptr + val->size;
694  }
695  case OP_VARPCK_LG2(0):
696  case OP_VARPCK_LG2(2):
697  case OP_VARPCK_LG2(3): {
698  /* Varint packed. */
699  int lg2 = op - OP_VARPCK_LG2(0);
700  int scale = 1 << lg2;
701  int saved_limit = decode_pushlimit(d, ptr, val->size);
702  char *out = UPB_PTR_AT(_upb_array_ptr(arr), arr->len << lg2, void);
703  while (!decode_isdone(d, &ptr)) {
704  wireval elem;
705  ptr = decode_varint64(d, ptr, &elem.uint64_val);
706  decode_munge(field->descriptortype, &elem);
707  if (decode_reserve(d, arr, 1)) {
708  out = UPB_PTR_AT(_upb_array_ptr(arr), arr->len << lg2, void);
709  }
710  arr->len++;
711  memcpy(out, &elem, scale);
712  out += scale;
713  }
714  decode_poplimit(d, ptr, saved_limit);
715  return ptr;
716  }
717  default:
718  UPB_UNREACHABLE();
719  }
720 }
721 
722 static const char *decode_tomap(upb_decstate *d, const char *ptr, upb_msg *msg,
723  upb_msglayout const *const *submsgs,
724  const upb_msglayout_field *field, wireval *val) {
725  upb_map **map_p = UPB_PTR_AT(msg, field->offset, upb_map *);
726  upb_map *map = *map_p;
727  upb_map_entry ent;
728  const upb_msglayout *entry = submsgs[field->submsg_index];
729 
730  if (!map) {
731  /* Lazily create map. */
732  const upb_msglayout_field *key_field = &entry->fields[0];
733  const upb_msglayout_field *val_field = &entry->fields[1];
734  char key_size = desctype_to_mapsize[key_field->descriptortype];
735  char val_size = desctype_to_mapsize[val_field->descriptortype];
736  UPB_ASSERT(key_field->offset == 0);
737  UPB_ASSERT(val_field->offset == sizeof(upb_strview));
738  map = _upb_map_new(&d->arena, key_size, val_size);
739  *map_p = map;
740  }
741 
742  /* Parse map entry. */
743  memset(&ent, 0, sizeof(ent));
744 
747  /* Create proactively to handle the case where it doesn't appear. */
748  ent.v.val = upb_value_ptr(_upb_msg_new(entry->submsgs[0], &d->arena));
749  }
750 
751  ptr = decode_tosubmsg(d, ptr, &ent.k, submsgs, field, val->size);
752  _upb_map_set(map, &ent.k, map->key_size, &ent.v, map->val_size, &d->arena);
753  return ptr;
754 }
755 
756 static const char *decode_tomsg(upb_decstate *d, const char *ptr, upb_msg *msg,
757  upb_msglayout const *const *submsgs,
758  const upb_msglayout_field *field, wireval *val,
759  int op) {
760  void *mem = UPB_PTR_AT(msg, field->offset, void);
761  int type = field->descriptortype;
762 
763  /* Set presence if necessary. */
764  if (field->presence > 0) {
766  } else if (field->presence < 0) {
767  /* Oneof case */
768  uint32_t *oneof_case = _upb_oneofcase_field(msg, field);
769  if (op == OP_SUBMSG && *oneof_case != field->number) {
770  memset(mem, 0, sizeof(void*));
771  }
772  *oneof_case = field->number;
773  }
774 
775  /* Store into message. */
776  switch (op) {
777  case OP_SUBMSG: {
778  upb_msg **submsgp = mem;
779  upb_msg *submsg = *submsgp;
780  if (!submsg) {
781  submsg = decode_newsubmsg(d, submsgs, field);
782  *submsgp = submsg;
783  }
785  ptr = decode_togroup(d, ptr, submsg, submsgs, field);
786  } else {
787  ptr = decode_tosubmsg(d, ptr, submsg, submsgs, field, val->size);
788  }
789  break;
790  }
791  case OP_STRING:
792  decode_verifyutf8(d, ptr, val->size);
793  /* Fallthrough. */
794  case OP_BYTES:
795  return decode_readstr(d, ptr, val->size, mem);
796  case OP_SCALAR_LG2(3):
797  memcpy(mem, val, 8);
798  break;
799  case OP_SCALAR_LG2(2):
800  memcpy(mem, val, 4);
801  break;
802  case OP_SCALAR_LG2(0):
803  memcpy(mem, val, 1);
804  break;
805  default:
806  UPB_UNREACHABLE();
807  }
808 
809  return ptr;
810 }
811 
813 static bool decode_tryfastdispatch(upb_decstate *d, const char **ptr,
814  upb_msg *msg, const upb_msglayout *layout) {
815 #if UPB_FASTTABLE
816  if (layout && layout->table_mask != (unsigned char)-1) {
819  *ptr = fastdecode_tagdispatch(d, *ptr, msg, table, 0, tag);
820  return true;
821  }
822 #endif
823  return false;
824 }
825 
827 static const char *decode_msg(upb_decstate *d, const char *ptr, upb_msg *msg,
828  const upb_msglayout *layout) {
829  int last_field_index = 0;
830  while (true) {
831  uint32_t tag;
832  const upb_msglayout_field *field;
833  int field_number;
834  int wire_type;
835  const char *field_start = ptr;
836  wireval val;
837  int op;
838 
839  UPB_ASSERT(ptr < d->limit_ptr);
840  ptr = decode_tag(d, ptr, &tag);
841  field_number = tag >> 3;
842  wire_type = tag & 7;
843 
844  field = upb_find_field(layout, field_number, &last_field_index);
845 
846  switch (wire_type) {
848  ptr = decode_varint64(d, ptr, &val.uint64_val);
849  op = varint_ops[field->descriptortype];
850  decode_munge(field->descriptortype, &val);
851  break;
852  case UPB_WIRE_TYPE_32BIT:
853  memcpy(&val.uint32_val, ptr, 4);
855  ptr += 4;
856  op = OP_SCALAR_LG2(2);
857  if (((1 << field->descriptortype) & fixed32_ok) == 0) goto unknown;
858  break;
859  case UPB_WIRE_TYPE_64BIT:
860  memcpy(&val.uint64_val, ptr, 8);
862  ptr += 8;
863  op = OP_SCALAR_LG2(3);
864  if (((1 << field->descriptortype) & fixed64_ok) == 0) goto unknown;
865  break;
867  int ndx = field->descriptortype;
868  uint64_t size;
869  if (_upb_getmode(field) == _UPB_MODE_ARRAY) ndx += 18;
870  ptr = decode_varint64(d, ptr, &size);
871  if (size >= INT32_MAX ||
872  ptr - d->end + (int32_t)size > d->limit) {
873  decode_err(d); /* Length overflow. */
874  }
875  op = delim_ops[ndx];
876  val.size = size;
877  break;
878  }
880  val.uint32_val = field_number;
881  op = OP_SUBMSG;
882  if (field->descriptortype != UPB_DTYPE_GROUP) goto unknown;
883  break;
885  d->end_group = field_number;
886  return ptr;
887  default:
888  decode_err(d);
889  }
890 
891  if (op >= 0) {
892  /* Parse, using op for dispatch. */
893  switch (_upb_getmode(field)) {
894  case _UPB_MODE_ARRAY:
895  ptr = decode_toarray(d, ptr, msg, layout->submsgs, field, &val, op);
896  break;
897  case _UPB_MODE_MAP:
898  ptr = decode_tomap(d, ptr, msg, layout->submsgs, field, &val);
899  break;
900  case _UPB_MODE_SCALAR:
901  ptr = decode_tomsg(d, ptr, msg, layout->submsgs, field, &val, op);
902  break;
903  default:
904  UPB_UNREACHABLE();
905  }
906  } else {
907  unknown:
908  /* Skip unknown field. */
909  if (field_number == 0) decode_err(d);
910  if (wire_type == UPB_WIRE_TYPE_DELIMITED) ptr += val.size;
911  if (msg) {
912  if (wire_type == UPB_WIRE_TYPE_START_GROUP) {
913  d->unknown = field_start;
914  d->unknown_msg = msg;
915  ptr = decode_group(d, ptr, NULL, NULL, field_number);
916  d->unknown_msg = NULL;
917  field_start = d->unknown;
918  }
919  if (!_upb_msg_addunknown(msg, field_start, ptr - field_start,
920  &d->arena)) {
921  decode_err(d);
922  }
923  } else if (wire_type == UPB_WIRE_TYPE_START_GROUP) {
924  ptr = decode_group(d, ptr, NULL, NULL, field_number);
925  }
926  }
927 
928  if (decode_isdone(d, &ptr)) return ptr;
929  if (decode_tryfastdispatch(d, &ptr, msg, layout)) return ptr;
930  }
931 }
932 
933 const char *fastdecode_generic(struct upb_decstate *d, const char *ptr,
934  upb_msg *msg, intptr_t table, uint64_t hasbits,
935  uint64_t data) {
936  (void)data;
937  *(uint32_t*)msg |= hasbits;
938  return decode_msg(d, ptr, msg, decode_totablep(table));
939 }
940 
941 static bool decode_top(struct upb_decstate *d, const char *buf, void *msg,
942  const upb_msglayout *l) {
943  if (!decode_tryfastdispatch(d, &buf, msg, l)) {
944  decode_msg(d, buf, msg, l);
945  }
946  return d->end_group == DECODE_NOGROUP;
947 }
948 
949 bool _upb_decode(const char *buf, size_t size, void *msg,
950  const upb_msglayout *l, const upb_extreg *extreg, int options,
951  upb_arena *arena) {
952  bool ok;
954  unsigned depth = (unsigned)options >> 16;
955 
956  if (size == 0) {
957  return true;
958  } else if (size <= 16) {
959  memset(&state.patch, 0, 32);
960  memcpy(&state.patch, buf, size);
961  buf = state.patch;
962  state.end = buf + size;
963  state.limit = 0;
964  state.alias = false;
965  } else {
966  state.end = buf + size - 16;
967  state.limit = 16;
968  state.alias = options & UPB_DECODE_ALIAS;
969  }
970 
971  state.limit_ptr = state.end;
972  state.unknown_msg = NULL;
973  state.depth = depth ? depth : 64;
974  state.end_group = DECODE_NOGROUP;
975  state.arena.head = arena->head;
976  state.arena.last_size = arena->last_size;
977  state.arena.cleanup_metadata = arena->cleanup_metadata;
978  state.arena.parent = arena;
979 
980  if (UPB_UNLIKELY(UPB_SETJMP(state.err))) {
981  ok = false;
982  } else {
983  ok = decode_top(&state, buf, msg, l);
984  }
985 
986  arena->head.ptr = state.arena.head.ptr;
987  arena->head.end = state.arena.head.end;
988  arena->cleanup_metadata = state.arena.cleanup_metadata;
989  return ok;
990 }
991 
992 #undef OP_SCALAR_LG2
993 #undef OP_FIXPCK_LG2
994 #undef OP_VARPCK_LG2
995 #undef OP_STRING
996 #undef OP_SUBMSG
997 
999 /* We encode backwards, to avoid pre-computing lengths (one-pass encode). */
1000 
1001 
1002 #include <setjmp.h>
1003 #include <string.h>
1004 
1005 
1006 /* Must be last. */
1007 
1008 #define UPB_PB_VARINT_MAX_LEN 10
1009 
1011 static size_t encode_varint64(uint64_t val, char *buf) {
1012  size_t i = 0;
1013  do {
1014  uint8_t byte = val & 0x7fU;
1015  val >>= 7;
1016  if (val) byte |= 0x80U;
1017  buf[i++] = byte;
1018  } while (val);
1019  return i;
1020 }
1021 
1022 static uint32_t encode_zz32(int32_t n) { return ((uint32_t)n << 1) ^ (n >> 31); }
1023 static uint64_t encode_zz64(int64_t n) { return ((uint64_t)n << 1) ^ (n >> 63); }
1024 
1025 typedef struct {
1026  jmp_buf err;
1027  upb_alloc *alloc;
1028  char *buf, *ptr, *limit;
1029  int options;
1030  int depth;
1031  _upb_mapsorter sorter;
1032 } upb_encstate;
1033 
1034 static size_t upb_roundup_pow2(size_t bytes) {
1035  size_t ret = 128;
1036  while (ret < bytes) {
1037  ret *= 2;
1038  }
1039  return ret;
1040 }
1041 
1043  UPB_LONGJMP(e->err, 1);
1044 }
1045 
1047 static void encode_growbuffer(upb_encstate *e, size_t bytes) {
1048  size_t old_size = e->limit - e->buf;
1049  size_t new_size = upb_roundup_pow2(bytes + (e->limit - e->ptr));
1050  char *new_buf = upb_realloc(e->alloc, e->buf, old_size, new_size);
1051 
1052  if (!new_buf) encode_err(e);
1053 
1054  /* We want previous data at the end, realloc() put it at the beginning. */
1055  if (old_size > 0) {
1056  memmove(new_buf + new_size - old_size, e->buf, old_size);
1057  }
1058 
1059  e->ptr = new_buf + new_size - (e->limit - e->ptr);
1060  e->limit = new_buf + new_size;
1061  e->buf = new_buf;
1062 
1063  e->ptr -= bytes;
1064 }
1065 
1066 /* Call to ensure that at least "bytes" bytes are available for writing at
1067  * e->ptr. Returns false if the bytes could not be allocated. */
1069 static void encode_reserve(upb_encstate *e, size_t bytes) {
1070  if ((size_t)(e->ptr - e->buf) < bytes) {
1072  return;
1073  }
1074 
1075  e->ptr -= bytes;
1076 }
1077 
1078 /* Writes the given bytes to the buffer, handling reserve/advance. */
1079 static void encode_bytes(upb_encstate *e, const void *data, size_t len) {
1080  if (len == 0) return; /* memcpy() with zero size is UB */
1081  encode_reserve(e, len);
1082  memcpy(e->ptr, data, len);
1083 }
1084 
1085 static void encode_fixed64(upb_encstate *e, uint64_t val) {
1086  val = _upb_be_swap64(val);
1087  encode_bytes(e, &val, sizeof(uint64_t));
1088 }
1089 
1090 static void encode_fixed32(upb_encstate *e, uint32_t val) {
1091  val = _upb_be_swap32(val);
1092  encode_bytes(e, &val, sizeof(uint32_t));
1093 }
1094 
1097  size_t len;
1098  char *start;
1099 
1101  len = encode_varint64(val, e->ptr);
1102  start = e->ptr + UPB_PB_VARINT_MAX_LEN - len;
1103  memmove(start, e->ptr, len);
1104  e->ptr = start;
1105 }
1106 
1108 static void encode_varint(upb_encstate *e, uint64_t val) {
1109  if (val < 128 && e->ptr != e->buf) {
1110  --e->ptr;
1111  *e->ptr = val;
1112  } else {
1113  encode_longvarint(e, val);
1114  }
1115 }
1116 
1117 static void encode_double(upb_encstate *e, double d) {
1118  uint64_t u64;
1119  UPB_ASSERT(sizeof(double) == sizeof(uint64_t));
1120  memcpy(&u64, &d, sizeof(uint64_t));
1121  encode_fixed64(e, u64);
1122 }
1123 
1124 static void encode_float(upb_encstate *e, float d) {
1125  uint32_t u32;
1126  UPB_ASSERT(sizeof(float) == sizeof(uint32_t));
1127  memcpy(&u32, &d, sizeof(uint32_t));
1128  encode_fixed32(e, u32);
1129 }
1130 
1131 static void encode_tag(upb_encstate *e, uint32_t field_number,
1132  uint8_t wire_type) {
1133  encode_varint(e, (field_number << 3) | wire_type);
1134 }
1135 
1136 static void encode_fixedarray(upb_encstate *e, const upb_array *arr,
1137  size_t elem_size, uint32_t tag) {
1138  size_t bytes = arr->len * elem_size;
1139  const char* data = _upb_array_constptr(arr);
1140  const char* ptr = data + bytes - elem_size;
1141  if (tag) {
1142  while (true) {
1143  encode_bytes(e, ptr, elem_size);
1144  encode_varint(e, tag);
1145  if (ptr == data) break;
1146  ptr -= elem_size;
1147  }
1148  } else {
1149  encode_bytes(e, data, bytes);
1150  }
1151 }
1152 
1153 static void encode_message(upb_encstate *e, const upb_msg *msg,
1154  const upb_msglayout *m, size_t *size);
1155 
1156 static void encode_scalar(upb_encstate *e, const void *_field_mem,
1157  const upb_msglayout *m, const upb_msglayout_field *f,
1158  bool skip_zero_value) {
1159  const char *field_mem = _field_mem;
1160  int wire_type;
1161 
1162 #define CASE(ctype, type, wtype, encodeval) \
1163  { \
1164  ctype val = *(ctype *)field_mem; \
1165  if (skip_zero_value && val == 0) { \
1166  return; \
1167  } \
1168  encode_##type(e, encodeval); \
1169  wire_type = wtype; \
1170  break; \
1171  }
1172 
1173  switch (f->descriptortype) {
1175  CASE(double, double, UPB_WIRE_TYPE_64BIT, val);
1177  CASE(float, float, UPB_WIRE_TYPE_32BIT, val);
1180  CASE(uint64_t, varint, UPB_WIRE_TYPE_VARINT, val);
1182  CASE(uint32_t, varint, UPB_WIRE_TYPE_VARINT, val);
1185  CASE(int32_t, varint, UPB_WIRE_TYPE_VARINT, (int64_t)val);
1188  CASE(uint64_t, fixed64, UPB_WIRE_TYPE_64BIT, val);
1191  CASE(uint32_t, fixed32, UPB_WIRE_TYPE_32BIT, val);
1193  CASE(bool, varint, UPB_WIRE_TYPE_VARINT, val);
1195  CASE(int32_t, varint, UPB_WIRE_TYPE_VARINT, encode_zz32(val));
1197  CASE(int64_t, varint, UPB_WIRE_TYPE_VARINT, encode_zz64(val));
1200  upb_strview view = *(upb_strview*)field_mem;
1201  if (skip_zero_value && view.size == 0) {
1202  return;
1203  }
1204  encode_bytes(e, view.data, view.size);
1205  encode_varint(e, view.size);
1206  wire_type = UPB_WIRE_TYPE_DELIMITED;
1207  break;
1208  }
1210  size_t size;
1211  void *submsg = *(void **)field_mem;
1212  const upb_msglayout *subm = m->submsgs[f->submsg_index];
1213  if (submsg == NULL) {
1214  return;
1215  }
1216  if (--e->depth == 0) encode_err(e);
1217  encode_tag(e, f->number, UPB_WIRE_TYPE_END_GROUP);
1218  encode_message(e, submsg, subm, &size);
1219  wire_type = UPB_WIRE_TYPE_START_GROUP;
1220  e->depth++;
1221  break;
1222  }
1224  size_t size;
1225  void *submsg = *(void **)field_mem;
1226  const upb_msglayout *subm = m->submsgs[f->submsg_index];
1227  if (submsg == NULL) {
1228  return;
1229  }
1230  if (--e->depth == 0) encode_err(e);
1231  encode_message(e, submsg, subm, &size);
1232  encode_varint(e, size);
1233  wire_type = UPB_WIRE_TYPE_DELIMITED;
1234  e->depth++;
1235  break;
1236  }
1237  default:
1238  UPB_UNREACHABLE();
1239  }
1240 #undef CASE
1241 
1242  encode_tag(e, f->number, wire_type);
1243 }
1244 
1245 static void encode_array(upb_encstate *e, const upb_msg *msg,
1246  const upb_msglayout *m, const upb_msglayout_field *f) {
1247  const upb_array *arr = *UPB_PTR_AT(msg, f->offset, upb_array*);
1248  bool packed = f->mode & _UPB_MODE_IS_PACKED;
1249  size_t pre_len = e->limit - e->ptr;
1250 
1251  if (arr == NULL || arr->len == 0) {
1252  return;
1253  }
1254 
1255 #define VARINT_CASE(ctype, encode) \
1256  { \
1257  const ctype *start = _upb_array_constptr(arr); \
1258  const ctype *ptr = start + arr->len; \
1259  uint32_t tag = packed ? 0 : (f->number << 3) | UPB_WIRE_TYPE_VARINT; \
1260  do { \
1261  ptr--; \
1262  encode_varint(e, encode); \
1263  if (tag) encode_varint(e, tag); \
1264  } while (ptr != start); \
1265  } \
1266  break;
1267 
1268 #define TAG(wire_type) (packed ? 0 : (f->number << 3 | wire_type))
1269 
1270  switch (f->descriptortype) {
1272  encode_fixedarray(e, arr, sizeof(double), TAG(UPB_WIRE_TYPE_64BIT));
1273  break;
1275  encode_fixedarray(e, arr, sizeof(float), TAG(UPB_WIRE_TYPE_32BIT));
1276  break;
1280  break;
1284  break;
1294  VARINT_CASE(bool, *ptr);
1301  const upb_strview *start = _upb_array_constptr(arr);
1302  const upb_strview *ptr = start + arr->len;
1303  do {
1304  ptr--;
1305  encode_bytes(e, ptr->data, ptr->size);
1306  encode_varint(e, ptr->size);
1307  encode_tag(e, f->number, UPB_WIRE_TYPE_DELIMITED);
1308  } while (ptr != start);
1309  return;
1310  }
1312  const void *const*start = _upb_array_constptr(arr);
1313  const void *const*ptr = start + arr->len;
1314  const upb_msglayout *subm = m->submsgs[f->submsg_index];
1315  if (--e->depth == 0) encode_err(e);
1316  do {
1317  size_t size;
1318  ptr--;
1319  encode_tag(e, f->number, UPB_WIRE_TYPE_END_GROUP);
1320  encode_message(e, *ptr, subm, &size);
1321  encode_tag(e, f->number, UPB_WIRE_TYPE_START_GROUP);
1322  } while (ptr != start);
1323  e->depth++;
1324  return;
1325  }
1327  const void *const*start = _upb_array_constptr(arr);
1328  const void *const*ptr = start + arr->len;
1329  const upb_msglayout *subm = m->submsgs[f->submsg_index];
1330  if (--e->depth == 0) encode_err(e);
1331  do {
1332  size_t size;
1333  ptr--;
1334  encode_message(e, *ptr, subm, &size);
1335  encode_varint(e, size);
1336  encode_tag(e, f->number, UPB_WIRE_TYPE_DELIMITED);
1337  } while (ptr != start);
1338  e->depth++;
1339  return;
1340  }
1341  }
1342 #undef VARINT_CASE
1343 
1344  if (packed) {
1345  encode_varint(e, e->limit - e->ptr - pre_len);
1346  encode_tag(e, f->number, UPB_WIRE_TYPE_DELIMITED);
1347  }
1348 }
1349 
1351  const upb_msglayout *layout,
1352  const upb_map_entry *ent) {
1353  const upb_msglayout_field *key_field = &layout->fields[0];
1354  const upb_msglayout_field *val_field = &layout->fields[1];
1355  size_t pre_len = e->limit - e->ptr;
1356  size_t size;
1357  encode_scalar(e, &ent->v, layout, val_field, false);
1358  encode_scalar(e, &ent->k, layout, key_field, false);
1359  size = (e->limit - e->ptr) - pre_len;
1360  encode_varint(e, size);
1362 }
1363 
1364 static void encode_map(upb_encstate *e, const upb_msg *msg,
1365  const upb_msglayout *m, const upb_msglayout_field *f) {
1366  const upb_map *map = *UPB_PTR_AT(msg, f->offset, const upb_map*);
1367  const upb_msglayout *layout = m->submsgs[f->submsg_index];
1368  UPB_ASSERT(layout->field_count == 2);
1369 
1370  if (map == NULL) return;
1371 
1372  if (e->options & UPB_ENCODE_DETERMINISTIC) {
1373  _upb_sortedmap sorted;
1374  _upb_mapsorter_pushmap(&e->sorter, layout->fields[0].descriptortype, map,
1375  &sorted);
1376  upb_map_entry ent;
1377  while (_upb_sortedmap_next(&e->sorter, map, &sorted, &ent)) {
1378  encode_mapentry(e, f->number, layout, &ent);
1379  }
1380  _upb_mapsorter_popmap(&e->sorter, &sorted);
1381  } else {
1383  upb_strtable_begin(&i, &map->table);
1384  for(; !upb_strtable_done(&i); upb_strtable_next(&i)) {
1386  const upb_value val = upb_strtable_iter_value(&i);
1387  upb_map_entry ent;
1388  _upb_map_fromkey(key, &ent.k, map->key_size);
1389  _upb_map_fromvalue(val, &ent.v, map->val_size);
1390  encode_mapentry(e, f->number, layout, &ent);
1391  }
1392  }
1393 }
1394 
1395 static void encode_scalarfield(upb_encstate *e, const char *msg,
1396  const upb_msglayout *m,
1397  const upb_msglayout_field *f) {
1398  bool skip_empty = false;
1399  if (f->presence == 0) {
1400  /* Proto3 presence. */
1401  skip_empty = true;
1402  } else if (f->presence > 0) {
1403  /* Proto2 presence: hasbit. */
1404  if (!_upb_hasbit_field(msg, f)) return;
1405  } else {
1406  /* Field is in a oneof. */
1407  if (_upb_getoneofcase_field(msg, f) != f->number) return;
1408  }
1409  encode_scalar(e, msg + f->offset, m, f, skip_empty);
1410 }
1411 
1412 static void encode_message(upb_encstate *e, const upb_msg *msg,
1413  const upb_msglayout *m, size_t *size) {
1414  size_t pre_len = e->limit - e->ptr;
1415  const upb_msglayout_field *f = &m->fields[m->field_count];
1416  const upb_msglayout_field *first = &m->fields[0];
1417 
1418  if ((e->options & UPB_ENCODE_SKIPUNKNOWN) == 0) {
1419  size_t unknown_size;
1420  const char *unknown = upb_msg_getunknown(msg, &unknown_size);
1421 
1422  if (unknown) {
1423  encode_bytes(e, unknown, unknown_size);
1424  }
1425  }
1426 
1427  while (f != first) {
1428  f--;
1429  switch (_upb_getmode(f)) {
1430  case _UPB_MODE_ARRAY:
1431  encode_array(e, msg, m, f);
1432  break;
1433  case _UPB_MODE_MAP:
1434  encode_map(e, msg, m, f);
1435  break;
1436  case _UPB_MODE_SCALAR:
1437  encode_scalarfield(e, msg, m, f);
1438  break;
1439  default:
1440  UPB_UNREACHABLE();
1441  }
1442  }
1443 
1444  *size = (e->limit - e->ptr) - pre_len;
1445 }
1446 
1447 char *upb_encode_ex(const void *msg, const upb_msglayout *l, int options,
1448  upb_arena *arena, size_t *size) {
1449  upb_encstate e;
1450  unsigned depth = (unsigned)options >> 16;
1451 
1452  e.alloc = upb_arena_alloc(arena);
1453  e.buf = NULL;
1454  e.limit = NULL;
1455  e.ptr = NULL;
1456  e.depth = depth ? depth : 64;
1457  e.options = options;
1458  _upb_mapsorter_init(&e.sorter);
1459  char *ret = NULL;
1460 
1461  if (UPB_SETJMP(e.err)) {
1462  *size = 0;
1463  ret = NULL;
1464  } else {
1465  encode_message(&e, msg, l, size);
1466  *size = e.limit - e.ptr;
1467  if (*size == 0) {
1468  static char ch;
1469  ret = &ch;
1470  } else {
1471  UPB_ASSERT(e.ptr);
1472  ret = e.ptr;
1473  }
1474  }
1475 
1476  _upb_mapsorter_destroy(&e.sorter);
1477  return ret;
1478 }
1479 
1485 static const size_t overhead = sizeof(upb_msg_internaldata);
1486 
1488  ptrdiff_t size = sizeof(upb_msg_internal);
1489  return (upb_msg_internal*)((char*)msg - size);
1490 }
1491 
1493  return _upb_msg_new_inl(l, a);
1494 }
1495 
1497  void *mem = UPB_PTR_AT(msg, -sizeof(upb_msg_internal), char);
1498  memset(mem, 0, upb_msg_sizeof(l));
1499 }
1500 
1501 static bool realloc_internal(upb_msg *msg, size_t need, upb_arena *arena) {
1503  if (!in->internal) {
1504  /* No internal data, allocate from scratch. */
1505  size_t size = UPB_MAX(128, _upb_lg2ceilsize(need + overhead));
1507  if (!internal) return false;
1508  internal->size = size;
1509  internal->unknown_end = overhead;
1510  internal->ext_begin = size;
1511  in->internal = internal;
1512  } else if (in->internal->ext_begin - in->internal->unknown_end < need) {
1513  /* Internal data is too small, reallocate. */
1514  size_t new_size = _upb_lg2ceilsize(in->internal->size + need);
1515  size_t ext_bytes = in->internal->size - in->internal->ext_begin;
1516  size_t new_ext_begin = new_size - ext_bytes;
1517  upb_msg_internaldata *internal =
1518  upb_arena_realloc(arena, in->internal, in->internal->size, new_size);
1519  if (!internal) return false;
1520  if (ext_bytes) {
1521  /* Need to move extension data to the end. */
1522  char *ptr = (char*)internal;
1523  memmove(ptr + new_ext_begin, ptr + internal->ext_begin, ext_bytes);
1524  }
1525  internal->ext_begin = new_ext_begin;
1526  internal->size = new_size;
1527  in->internal = internal;
1528  }
1529  UPB_ASSERT(in->internal->ext_begin - in->internal->unknown_end >= need);
1530  return true;
1531 }
1532 
1533 bool _upb_msg_addunknown(upb_msg *msg, const char *data, size_t len,
1534  upb_arena *arena) {
1535  if (!realloc_internal(msg, len, arena)) return false;
1537  memcpy(UPB_PTR_AT(in->internal, in->internal->unknown_end, char), data, len);
1538  in->internal->unknown_end += len;
1539  return true;
1540 }
1541 
1544  if (in->internal) {
1545  in->internal->unknown_end = overhead;
1546  }
1547 }
1548 
1549 const char *upb_msg_getunknown(const upb_msg *msg, size_t *len) {
1551  if (in->internal) {
1552  *len = in->internal->unknown_end - overhead;
1553  return (char*)(in->internal + 1);
1554  } else {
1555  *len = 0;
1556  return NULL;
1557  }
1558 }
1559 
1560 const upb_msg_ext *_upb_msg_getexts(const upb_msg *msg, size_t *count) {
1562  if (in->internal) {
1563  *count =
1564  (in->internal->size - in->internal->ext_begin) / sizeof(upb_msg_ext);
1565  return UPB_PTR_AT(in->internal, in->internal->ext_begin, void);
1566  } else {
1567  *count = 0;
1568  return NULL;
1569  }
1570 }
1571 
1573  const upb_msglayout_ext *e) {
1574  size_t n;
1575  const upb_msg_ext *ext = _upb_msg_getexts(msg, &n);
1576 
1577  /* For now we use linear search exclusively to find extensions. If this
1578  * becomes an issue due to messages with lots of extensions, we can introduce
1579  * a table of some sort. */
1580  for (size_t i = 0; i < n; i++) {
1581  if (ext[i].ext == e) {
1582  return &ext[i];
1583  }
1584  }
1585 
1586  return NULL;
1587 }
1588 
1590  upb_arena *arena) {
1592  if (ext) return ext;
1593  if (!realloc_internal(msg, sizeof(upb_msg_ext), arena)) return NULL;
1595  in->internal->ext_begin -= sizeof(upb_msg_ext);
1596  ext = UPB_PTR_AT(in->internal, in->internal->ext_begin, void);
1597  memset(ext, 0, sizeof(upb_msg_ext));
1598  ext->ext = e;
1599  return ext;
1600 }
1601 
1604 bool _upb_array_realloc(upb_array *arr, size_t min_size, upb_arena *arena) {
1605  size_t new_size = UPB_MAX(arr->size, 4);
1606  int elem_size_lg2 = arr->data & 7;
1607  size_t old_bytes = arr->size << elem_size_lg2;
1608  size_t new_bytes;
1609  void* ptr = _upb_array_ptr(arr);
1610 
1611  /* Log2 ceiling of size. */
1612  while (new_size < min_size) new_size *= 2;
1613 
1614  new_bytes = new_size << elem_size_lg2;
1615  ptr = upb_arena_realloc(arena, ptr, old_bytes, new_bytes);
1616 
1617  if (!ptr) {
1618  return false;
1619  }
1620 
1621  arr->data = _upb_tag_arrptr(ptr, elem_size_lg2);
1622  arr->size = new_size;
1623  return true;
1624 }
1625 
1626 static upb_array *getorcreate_array(upb_array **arr_ptr, int elem_size_lg2,
1627  upb_arena *arena) {
1628  upb_array *arr = *arr_ptr;
1629  if (!arr) {
1630  arr = _upb_array_new(arena, 4, elem_size_lg2);
1631  if (!arr) return NULL;
1632  *arr_ptr = arr;
1633  }
1634  return arr;
1635 }
1636 
1638  int elem_size_lg2, upb_arena *arena) {
1639  upb_array *arr = getorcreate_array(arr_ptr, elem_size_lg2, arena);
1640  return arr && _upb_array_resize(arr, size, arena) ? _upb_array_ptr(arr)
1641  : NULL;
1642 }
1643 
1644 bool _upb_array_append_fallback(upb_array **arr_ptr, const void *value,
1645  int elem_size_lg2, upb_arena *arena) {
1646  upb_array *arr = getorcreate_array(arr_ptr, elem_size_lg2, arena);
1647  if (!arr) return false;
1648 
1649  size_t elems = arr->len;
1650 
1651  if (!_upb_array_resize(arr, elems + 1, arena)) {
1652  return false;
1653  }
1654 
1655  char *data = _upb_array_ptr(arr);
1656  memcpy(data + (elems << elem_size_lg2), value, 1 << elem_size_lg2);
1657  return true;
1658 }
1659 
1662 upb_map *_upb_map_new(upb_arena *a, size_t key_size, size_t value_size) {
1663  upb_map *map = upb_arena_malloc(a, sizeof(upb_map));
1664 
1665  if (!map) {
1666  return NULL;
1667  }
1668 
1669  upb_strtable_init(&map->table, 4, a);
1670  map->key_size = key_size;
1671  map->val_size = value_size;
1672 
1673  return map;
1674 }
1675 
1676 static void _upb_mapsorter_getkeys(const void *_a, const void *_b, void *a_key,
1677  void *b_key, size_t size) {
1678  const upb_tabent *const*a = _a;
1679  const upb_tabent *const*b = _b;
1680  upb_strview a_tabkey = upb_tabstrview((*a)->key);
1681  upb_strview b_tabkey = upb_tabstrview((*b)->key);
1682  _upb_map_fromkey(a_tabkey, a_key, size);
1683  _upb_map_fromkey(b_tabkey, b_key, size);
1684 }
1685 
1686 static int _upb_mapsorter_cmpi64(const void *_a, const void *_b) {
1687  int64_t a, b;
1688  _upb_mapsorter_getkeys(_a, _b, &a, &b, 8);
1689  return a - b;
1690 }
1691 
1692 static int _upb_mapsorter_cmpu64(const void *_a, const void *_b) {
1693  uint64_t a, b;
1694  _upb_mapsorter_getkeys(_a, _b, &a, &b, 8);
1695  return a - b;
1696 }
1697 
1698 static int _upb_mapsorter_cmpi32(const void *_a, const void *_b) {
1699  int32_t a, b;
1700  _upb_mapsorter_getkeys(_a, _b, &a, &b, 4);
1701  return a - b;
1702 }
1703 
1704 static int _upb_mapsorter_cmpu32(const void *_a, const void *_b) {
1705  uint32_t a, b;
1706  _upb_mapsorter_getkeys(_a, _b, &a, &b, 4);
1707  return a - b;
1708 }
1709 
1710 static int _upb_mapsorter_cmpbool(const void *_a, const void *_b) {
1711  bool a, b;
1712  _upb_mapsorter_getkeys(_a, _b, &a, &b, 1);
1713  return a - b;
1714 }
1715 
1716 static int _upb_mapsorter_cmpstr(const void *_a, const void *_b) {
1717  upb_strview a, b;
1719  size_t common_size = UPB_MIN(a.size, b.size);
1720  int cmp = memcmp(a.data, b.data, common_size);
1721  if (cmp) return cmp;
1722  return a.size - b.size;
1723 }
1724 
1726  const upb_map *map, _upb_sortedmap *sorted) {
1727  int map_size = _upb_map_size(map);
1728  sorted->start = s->size;
1729  sorted->pos = sorted->start;
1730  sorted->end = sorted->start + map_size;
1731 
1732  /* Grow s->entries if necessary. */
1733  if (sorted->end > s->cap) {
1734  s->cap = _upb_lg2ceilsize(sorted->end);
1735  s->entries = realloc(s->entries, s->cap * sizeof(*s->entries));
1736  if (!s->entries) return false;
1737  }
1738 
1739  s->size = sorted->end;
1740 
1741  /* Copy non-empty entries from the table to s->entries. */
1742  upb_tabent const**dst = &s->entries[sorted->start];
1743  const upb_tabent *src = map->table.t.entries;
1744  const upb_tabent *end = src + upb_table_size(&map->table.t);
1745  for (; src < end; src++) {
1746  if (!upb_tabent_isempty(src)) {
1747  *dst = src;
1748  dst++;
1749  }
1750  }
1751  UPB_ASSERT(dst == &s->entries[sorted->end]);
1752 
1753  /* Sort entries according to the key type. */
1754 
1755  int (*compar)(const void *, const void *);
1756 
1757  switch (key_type) {
1761  compar = _upb_mapsorter_cmpi64;
1762  break;
1765  compar = _upb_mapsorter_cmpu64;
1766  break;
1771  compar = _upb_mapsorter_cmpi32;
1772  break;
1775  compar = _upb_mapsorter_cmpu32;
1776  break;
1778  compar = _upb_mapsorter_cmpbool;
1779  break;
1781  compar = _upb_mapsorter_cmpstr;
1782  break;
1783  default:
1784  UPB_UNREACHABLE();
1785  }
1786 
1787  qsort(&s->entries[sorted->start], map_size, sizeof(*s->entries), compar);
1788  return true;
1789 }
1790 
1793 struct upb_extreg {
1794  upb_arena *arena;
1795  upb_strtable exts; /* Key is upb_msglayout* concatenated with fieldnum. */
1796 };
1797 
1798 #define EXTREG_KEY_SIZE (sizeof(upb_msglayout*) + sizeof(uint32_t))
1799 
1800 static void extreg_key(char *buf, const upb_msglayout *l, uint32_t fieldnum) {
1801  memcpy(buf, &l, sizeof(l));
1802  memcpy(buf + sizeof(l), &fieldnum, sizeof(fieldnum));
1803 }
1804 
1806  upb_extreg *r = upb_arena_malloc(arena, sizeof(*r));
1807  if (!r) return NULL;
1808  r->arena = arena;
1809  if (!upb_strtable_init(&r->exts, 8, arena)) return NULL;
1810  return r;
1811 }
1812 
1814  char buf[EXTREG_KEY_SIZE];
1815  const upb_msglayout_ext *start = e;
1816  const upb_msglayout_ext *end = e + count;
1817  for (; e < end; e++) {
1818  extreg_key(buf, e->extendee, e->field.number);
1819  if (!upb_strtable_insert(&r->exts, buf, EXTREG_KEY_SIZE,
1820  upb_value_constptr(e), r->arena)) {
1821  goto failure;
1822  }
1823  }
1824  return true;
1825 
1826 failure:
1827  /* Back out the entries previously added. */
1828  for (end = e, e = start; e < end; e++) {
1829  extreg_key(buf, e->extendee, e->field.number);
1830  upb_strtable_remove(&r->exts, buf, EXTREG_KEY_SIZE, NULL);
1831  }
1832  return false;
1833 }
1834 
1836  const upb_msglayout *l,
1837  uint32_t num) {
1838  char buf[EXTREG_KEY_SIZE];
1839  upb_value v;
1840  extreg_key(buf, l, num);
1841  if (upb_strtable_lookup2(&r->exts, buf, EXTREG_KEY_SIZE, &v)) {
1842  return upb_value_getconstptr(v);
1843  } else {
1844  return NULL;
1845  }
1846 }
1847 
1849 /*
1850  * upb_table Implementation
1851  *
1852  * Implementation is heavily inspired by Lua's ltable.c.
1853  */
1854 
1855 #include <string.h>
1856 
1857 
1858 /* Must be last. */
1859 
1860 #define UPB_MAXARRSIZE 16 /* 64k. */
1861 
1862 /* From Chromium. */
1863 #define ARRAY_SIZE(x) \
1864  ((sizeof(x)/sizeof(0[x])) / ((size_t)(!(sizeof(x) % sizeof(0[x])))))
1865 
1866 static const double MAX_LOAD = 0.85;
1867 
1868 /* The minimum utilization of the array part of a mixed hash/array table. This
1869  * is a speed/memory-usage tradeoff (though it's not straightforward because of
1870  * cache effects). The lower this is, the more memory we'll use. */
1871 static const double MIN_DENSITY = 0.1;
1872 
1873 static bool is_pow2(uint64_t v) { return v == 0 || (v & (v - 1)) == 0; }
1874 
1876  upb_value ret;
1877  _upb_value_setval(&ret, val);
1878  return ret;
1879 }
1880 
1881 static int log2ceil(uint64_t v) {
1882  int ret = 0;
1883  bool pow2 = is_pow2(v);
1884  while (v >>= 1) ret++;
1885  ret = pow2 ? ret : ret + 1; /* Ceiling. */
1886  return UPB_MIN(UPB_MAXARRSIZE, ret);
1887 }
1888 
1889 char *upb_strdup2(const char *s, size_t len, upb_arena *a) {
1890  size_t n;
1891  char *p;
1892 
1893  /* Prevent overflow errors. */
1894  if (len == SIZE_MAX) return NULL;
1895  /* Always null-terminate, even if binary data; but don't rely on the input to
1896  * have a null-terminating byte since it may be a raw binary buffer. */
1897  n = len + 1;
1898  p = upb_arena_malloc(a, n);
1899  if (p) {
1900  memcpy(p, s, len);
1901  p[len] = 0;
1902  }
1903  return p;
1904 }
1905 
1906 /* A type to represent the lookup key of either a strtable or an inttable. */
1907 typedef union {
1908  uintptr_t num;
1909  struct {
1910  const char *str;
1911  size_t len;
1912  } str;
1913 } lookupkey_t;
1914 
1915 static lookupkey_t strkey2(const char *str, size_t len) {
1916  lookupkey_t k;
1917  k.str.str = str;
1918  k.str.len = len;
1919  return k;
1920 }
1921 
1923  lookupkey_t k;
1924  k.num = key;
1925  return k;
1926 }
1927 
1930 
1931 /* Base table (shared code) ***************************************************/
1932 
1934  return (uint32_t)key;
1935 }
1936 
1937 static const upb_tabent *upb_getentry(const upb_table *t, uint32_t hash) {
1938  return t->entries + (hash & t->mask);
1939 }
1940 
1941 static bool upb_arrhas(upb_tabval key) {
1942  return key.val != (uint64_t)-1;
1943 }
1944 
1945 
1946 static bool isfull(upb_table *t) {
1947  return t->count == t->max_count;
1948 }
1949 
1950 static bool init(upb_table *t, uint8_t size_lg2, upb_arena *a) {
1951  size_t bytes;
1952 
1953  t->count = 0;
1954  t->size_lg2 = size_lg2;
1955  t->mask = upb_table_size(t) ? upb_table_size(t) - 1 : 0;
1956  t->max_count = upb_table_size(t) * MAX_LOAD;
1957  bytes = upb_table_size(t) * sizeof(upb_tabent);
1958  if (bytes > 0) {
1959  t->entries = upb_arena_malloc(a, bytes);
1960  if (!t->entries) return false;
1961  memset(t->entries, 0, bytes);
1962  } else {
1963  t->entries = NULL;
1964  }
1965  return true;
1966 }
1967 
1969  upb_tabent *begin = t->entries;
1971  for (e = e + 1; e < end; e++) {
1972  if (upb_tabent_isempty(e)) return e;
1973  }
1974  for (e = begin; e < end; e++) {
1975  if (upb_tabent_isempty(e)) return e;
1976  }
1977  UPB_ASSERT(false);
1978  return NULL;
1979 }
1980 
1982  return (upb_tabent*)upb_getentry(t, hash);
1983 }
1984 
1986  uint32_t hash, eqlfunc_t *eql) {
1987  const upb_tabent *e;
1988 
1989  if (t->size_lg2 == 0) return NULL;
1990  e = upb_getentry(t, hash);
1991  if (upb_tabent_isempty(e)) return NULL;
1992  while (1) {
1993  if (eql(e->key, key)) return e;
1994  if ((e = e->next) == NULL) return NULL;
1995  }
1996 }
1997 
1999  uint32_t hash, eqlfunc_t *eql) {
2000  return (upb_tabent*)findentry(t, key, hash, eql);
2001 }
2002 
2003 static bool lookup(const upb_table *t, lookupkey_t key, upb_value *v,
2004  uint32_t hash, eqlfunc_t *eql) {
2005  const upb_tabent *e = findentry(t, key, hash, eql);
2006  if (e) {
2007  if (v) {
2008  _upb_value_setval(v, e->val.val);
2009  }
2010  return true;
2011  } else {
2012  return false;
2013  }
2014 }
2015 
2016 /* The given key must not already exist in the table. */
2017 static void insert(upb_table *t, lookupkey_t key, upb_tabkey tabkey,
2018  upb_value val, uint32_t hash,
2019  hashfunc_t *hashfunc, eqlfunc_t *eql) {
2020  upb_tabent *mainpos_e;
2021  upb_tabent *our_e;
2022 
2023  UPB_ASSERT(findentry(t, key, hash, eql) == NULL);
2024 
2025  t->count++;
2026  mainpos_e = getentry_mutable(t, hash);
2027  our_e = mainpos_e;
2028 
2029  if (upb_tabent_isempty(mainpos_e)) {
2030  /* Our main position is empty; use it. */
2031  our_e->next = NULL;
2032  } else {
2033  /* Collision. */
2034  upb_tabent *new_e = emptyent(t, mainpos_e);
2035  /* Head of collider's chain. */
2036  upb_tabent *chain = getentry_mutable(t, hashfunc(mainpos_e->key));
2037  if (chain == mainpos_e) {
2038  /* Existing ent is in its main position (it has the same hash as us, and
2039  * is the head of our chain). Insert to new ent and append to this chain. */
2040  new_e->next = mainpos_e->next;
2041  mainpos_e->next = new_e;
2042  our_e = new_e;
2043  } else {
2044  /* Existing ent is not in its main position (it is a node in some other
2045  * chain). This implies that no existing ent in the table has our hash.
2046  * Evict it (updating its chain) and use its ent for head of our chain. */
2047  *new_e = *mainpos_e; /* copies next. */
2048  while (chain->next != mainpos_e) {
2049  chain = (upb_tabent*)chain->next;
2050  UPB_ASSERT(chain);
2051  }
2052  chain->next = new_e;
2053  our_e = mainpos_e;
2054  our_e->next = NULL;
2055  }
2056  }
2057  our_e->key = tabkey;
2058  our_e->val.val = val.val;
2059  UPB_ASSERT(findentry(t, key, hash, eql) == our_e);
2060 }
2061 
2062 static bool rm(upb_table *t, lookupkey_t key, upb_value *val,
2063  upb_tabkey *removed, uint32_t hash, eqlfunc_t *eql) {
2064  upb_tabent *chain = getentry_mutable(t, hash);
2065  if (upb_tabent_isempty(chain)) return false;
2066  if (eql(chain->key, key)) {
2067  /* Element to remove is at the head of its chain. */
2068  t->count--;
2069  if (val) _upb_value_setval(val, chain->val.val);
2070  if (removed) *removed = chain->key;
2071  if (chain->next) {
2072  upb_tabent *move = (upb_tabent*)chain->next;
2073  *chain = *move;
2074  move->key = 0; /* Make the slot empty. */
2075  } else {
2076  chain->key = 0; /* Make the slot empty. */
2077  }
2078  return true;
2079  } else {
2080  /* Element to remove is either in a non-head position or not in the
2081  * table. */
2082  while (chain->next && !eql(chain->next->key, key)) {
2083  chain = (upb_tabent*)chain->next;
2084  }
2085  if (chain->next) {
2086  /* Found element to remove. */
2087  upb_tabent *rm = (upb_tabent*)chain->next;
2088  t->count--;
2089  if (val) _upb_value_setval(val, chain->next->val.val);
2090  if (removed) *removed = rm->key;
2091  rm->key = 0; /* Make the slot empty. */
2092  chain->next = rm->next;
2093  return true;
2094  } else {
2095  /* Element to remove is not in the table. */
2096  return false;
2097  }
2098  }
2099 }
2100 
2101 static size_t next(const upb_table *t, size_t i) {
2102  do {
2103  if (++i >= upb_table_size(t))
2104  return SIZE_MAX - 1; /* Distinct from -1. */
2105  } while(upb_tabent_isempty(&t->entries[i]));
2106 
2107  return i;
2108 }
2109 
2110 static size_t begin(const upb_table *t) {
2111  return next(t, -1);
2112 }
2113 
2114 
2115 /* upb_strtable ***************************************************************/
2116 
2117 /* A simple "subclass" of upb_table that only adds a hash function for strings. */
2118 
2120  uint32_t len = (uint32_t) k2.str.len;
2121  char *str = upb_arena_malloc(a, k2.str.len + sizeof(uint32_t) + 1);
2122  if (str == NULL) return 0;
2123  memcpy(str, &len, sizeof(uint32_t));
2124  if (k2.str.len) memcpy(str + sizeof(uint32_t), k2.str.str, k2.str.len);
2125  str[sizeof(uint32_t) + k2.str.len] = '\0';
2126  return (uintptr_t)str;
2127 }
2128 
2129 /* Adapted from ABSL's wyhash. */
2130 
2131 static uint64_t UnalignedLoad64(const void *p) {
2132  uint64_t val;
2133  memcpy(&val, p, 8);
2134  return val;
2135 }
2136 
2137 static uint32_t UnalignedLoad32(const void *p) {
2138  uint32_t val;
2139  memcpy(&val, p, 4);
2140  return val;
2141 }
2142 
2143 #if defined(_MSC_VER) && defined(_M_X64)
2144 #include <intrin.h>
2145 #endif
2146 
2147 /* Computes a * b, returning the low 64 bits of the result and storing the high
2148  * 64 bits in |*high|. */
2149 static uint64_t upb_umul128(uint64_t v0, uint64_t v1, uint64_t* out_high) {
2150 #ifdef __SIZEOF_INT128__
2151  __uint128_t p = v0;
2152  p *= v1;
2153  *out_high = (uint64_t)(p >> 64);
2154  return (uint64_t)p;
2155 #elif defined(_MSC_VER) && defined(_M_X64)
2156  return _umul128(v0, v1, out_high);
2157 #else
2158  uint64_t a32 = v0 >> 32;
2159  uint64_t a00 = v0 & 0xffffffff;
2160  uint64_t b32 = v1 >> 32;
2161  uint64_t b00 = v1 & 0xffffffff;
2162  uint64_t high = a32 * b32;
2163  uint64_t low = a00 * b00;
2164  uint64_t mid1 = a32 * b00;
2165  uint64_t mid2 = a00 * b32;
2166  low += (mid1 << 32) + (mid2 << 32);
2167  // Omit carry bit, for mixing we do not care about exact numerical precision.
2168  high += (mid1 >> 32) + (mid2 >> 32);
2169  *out_high = high;
2170  return low;
2171 #endif
2172 }
2173 
2175  uint64_t high;
2176  uint64_t low = upb_umul128(v0, v1, &high);
2177  return low ^ high;
2178 }
2179 
2180 uint64_t Wyhash(const void *data, size_t len, uint64_t seed,
2181  const uint64_t salt[]) {
2182  const uint8_t* ptr = (const uint8_t*)data;
2183  uint64_t starting_length = (uint64_t)len;
2184  uint64_t current_state = seed ^ salt[0];
2185 
2186  if (len > 64) {
2187  // If we have more than 64 bytes, we're going to handle chunks of 64
2188  // bytes at a time. We're going to build up two separate hash states
2189  // which we will then hash together.
2190  uint64_t duplicated_state = current_state;
2191 
2192  do {
2194  uint64_t b = UnalignedLoad64(ptr + 8);
2195  uint64_t c = UnalignedLoad64(ptr + 16);
2196  uint64_t d = UnalignedLoad64(ptr + 24);
2197  uint64_t e = UnalignedLoad64(ptr + 32);
2198  uint64_t f = UnalignedLoad64(ptr + 40);
2199  uint64_t g = UnalignedLoad64(ptr + 48);
2200  uint64_t h = UnalignedLoad64(ptr + 56);
2201 
2202  uint64_t cs0 = WyhashMix(a ^ salt[1], b ^ current_state);
2203  uint64_t cs1 = WyhashMix(c ^ salt[2], d ^ current_state);
2204  current_state = (cs0 ^ cs1);
2205 
2206  uint64_t ds0 = WyhashMix(e ^ salt[3], f ^ duplicated_state);
2207  uint64_t ds1 = WyhashMix(g ^ salt[4], h ^ duplicated_state);
2208  duplicated_state = (ds0 ^ ds1);
2209 
2210  ptr += 64;
2211  len -= 64;
2212  } while (len > 64);
2213 
2214  current_state = current_state ^ duplicated_state;
2215  }
2216 
2217  // We now have a data `ptr` with at most 64 bytes and the current state
2218  // of the hashing state machine stored in current_state.
2219  while (len > 16) {
2221  uint64_t b = UnalignedLoad64(ptr + 8);
2222 
2223  current_state = WyhashMix(a ^ salt[1], b ^ current_state);
2224 
2225  ptr += 16;
2226  len -= 16;
2227  }
2228 
2229  // We now have a data `ptr` with at most 16 bytes.
2230  uint64_t a = 0;
2231  uint64_t b = 0;
2232  if (len > 8) {
2233  // When we have at least 9 and at most 16 bytes, set A to the first 64
2234  // bits of the input and B to the last 64 bits of the input. Yes, they will
2235  // overlap in the middle if we are working with less than the full 16
2236  // bytes.
2237  a = UnalignedLoad64(ptr);
2238  b = UnalignedLoad64(ptr + len - 8);
2239  } else if (len > 3) {
2240  // If we have at least 4 and at most 8 bytes, set A to the first 32
2241  // bits and B to the last 32 bits.
2242  a = UnalignedLoad32(ptr);
2243  b = UnalignedLoad32(ptr + len - 4);
2244  } else if (len > 0) {
2245  // If we have at least 1 and at most 3 bytes, read all of the provided
2246  // bits into A, with some adjustments.
2247  a = ((ptr[0] << 16) | (ptr[len >> 1] << 8) | ptr[len - 1]);
2248  b = 0;
2249  } else {
2250  a = 0;
2251  b = 0;
2252  }
2253 
2254  uint64_t w = WyhashMix(a ^ salt[1], b ^ current_state);
2255  uint64_t z = salt[1] ^ starting_length;
2256  return WyhashMix(w, z);
2257 }
2258 
2259 const uint64_t kWyhashSalt[5] = {
2260  0x243F6A8885A308D3ULL, 0x13198A2E03707344ULL, 0xA4093822299F31D0ULL,
2261  0x082EFA98EC4E6C89ULL, 0x452821E638D01377ULL,
2262 };
2263 
2264 static uint32_t table_hash(const char *p, size_t n) {
2265  return Wyhash(p, n, 0, kWyhashSalt);
2266 }
2267 
2269  uint32_t len;
2270  char *str = upb_tabstr(key, &len);
2271  return table_hash(str, len);
2272 }
2273 
2275  uint32_t len;
2276  char *str = upb_tabstr(k1, &len);
2277  return len == k2.str.len && (len == 0 || memcmp(str, k2.str.str, len) == 0);
2278 }
2279 
2280 bool upb_strtable_init(upb_strtable *t, size_t expected_size, upb_arena *a) {
2281  // Multiply by approximate reciprocal of MAX_LOAD (0.85), with pow2 denominator.
2282  size_t need_entries = (expected_size + 1) * 1204 / 1024;
2283  UPB_ASSERT(need_entries >= expected_size * 0.85);
2284  int size_lg2 = _upb_lg2ceil(need_entries);
2285  return init(&t->t, size_lg2, a);
2286 }
2287 
2289  size_t bytes = upb_table_size(&t->t) * sizeof(upb_tabent);
2290  t->t.count = 0;
2291  memset((char*)t->t.entries, 0, bytes);
2292 }
2293 
2294 bool upb_strtable_resize(upb_strtable *t, size_t size_lg2, upb_arena *a) {
2295  upb_strtable new_table;
2297 
2298  if (!init(&new_table.t, size_lg2, a))
2299  return false;
2300  upb_strtable_begin(&i, t);
2301  for ( ; !upb_strtable_done(&i); upb_strtable_next(&i)) {
2303  upb_strtable_insert(&new_table, key.data, key.size,
2305  }
2306  *t = new_table;
2307  return true;
2308 }
2309 
2310 bool upb_strtable_insert(upb_strtable *t, const char *k, size_t len,
2311  upb_value v, upb_arena *a) {
2312  lookupkey_t key;
2313  upb_tabkey tabkey;
2314  uint32_t hash;
2315 
2316  if (isfull(&t->t)) {
2317  /* Need to resize. New table of double the size, add old elements to it. */
2318  if (!upb_strtable_resize(t, t->t.size_lg2 + 1, a)) {
2319  return false;
2320  }
2321  }
2322 
2323  key = strkey2(k, len);
2324  tabkey = strcopy(key, a);
2325  if (tabkey == 0) return false;
2326 
2327  hash = table_hash(key.str.str, key.str.len);
2328  insert(&t->t, key, tabkey, v, hash, &strhash, &streql);
2329  return true;
2330 }
2331 
2332 bool upb_strtable_lookup2(const upb_strtable *t, const char *key, size_t len,
2333  upb_value *v) {
2335  return lookup(&t->t, strkey2(key, len), v, hash, &streql);
2336 }
2337 
2338 bool upb_strtable_remove(upb_strtable *t, const char *key, size_t len,
2339  upb_value *val) {
2341  upb_tabkey tabkey;
2342  return rm(&t->t, strkey2(key, len), val, &tabkey, hash, &streql);
2343 }
2344 
2345 /* Iteration */
2346 
2348  i->t = t;
2349  i->index = begin(&t->t);
2350 }
2351 
2353  i->index = next(&i->t->t, i->index);
2354 }
2355 
2357  if (!i->t) return true;
2358  return i->index >= upb_table_size(&i->t->t) ||
2360 }
2361 
2363  upb_strview key;
2364  uint32_t len;
2366  key.data = upb_tabstr(str_tabent(i)->key, &len);
2367  key.size = len;
2368  return key;
2369 }
2370 
2373  return _upb_value_val(str_tabent(i)->val.val);
2374 }
2375 
2377  i->t = NULL;
2378  i->index = SIZE_MAX;
2379 }
2380 
2382  const upb_strtable_iter *i2) {
2384  return true;
2385  return i1->t == i2->t && i1->index == i2->index;
2386 }
2387 
2388 
2389 /* upb_inttable ***************************************************************/
2390 
2391 /* For inttables we use a hybrid structure where small keys are kept in an
2392  * array and large keys are put in the hash table. */
2393 
2395 
2397  return k1 == k2.num;
2398 }
2399 
2401  return (upb_tabval*)t->array;
2402 }
2403 
2405  if (key < t->array_size) {
2406  return upb_arrhas(t->array[key]) ? &(mutable_array(t)[key]) : NULL;
2407  } else {
2408  upb_tabent *e =
2410  return e ? &e->val : NULL;
2411  }
2412 }
2413 
2415  uintptr_t key) {
2416  return inttable_val((upb_inttable*)t, key);
2417 }
2418 
2420  return t->t.count + t->array_count;
2421 }
2422 
2423 static void check(upb_inttable *t) {
2424  UPB_UNUSED(t);
2425 #if defined(UPB_DEBUG_TABLE) && !defined(NDEBUG)
2426  {
2427  /* This check is very expensive (makes inserts/deletes O(N)). */
2428  size_t count = 0;
2430  upb_inttable_begin(&i, t);
2431  for(; !upb_inttable_done(&i); upb_inttable_next(&i), count++) {
2433  }
2435  }
2436 #endif
2437 }
2438 
2439 bool upb_inttable_sizedinit(upb_inttable *t, size_t asize, int hsize_lg2,
2440  upb_arena *a) {
2441  size_t array_bytes;
2442 
2443  if (!init(&t->t, hsize_lg2, a)) return false;
2444  /* Always make the array part at least 1 long, so that we know key 0
2445  * won't be in the hash part, which simplifies things. */
2446  t->array_size = UPB_MAX(1, asize);
2447  t->array_count = 0;
2448  array_bytes = t->array_size * sizeof(upb_value);
2449  t->array = upb_arena_malloc(a, array_bytes);
2450  if (!t->array) {
2451  return false;
2452  }
2453  memset(mutable_array(t), 0xff, array_bytes);
2454  check(t);
2455  return true;
2456 }
2457 
2459  return upb_inttable_sizedinit(t, 0, 4, a);
2460 }
2461 
2463  upb_arena *a) {
2464  upb_tabval tabval;
2465  tabval.val = val.val;
2466  UPB_ASSERT(upb_arrhas(tabval)); /* This will reject (uint64_t)-1. Fix this. */
2467 
2468  if (key < t->array_size) {
2469  UPB_ASSERT(!upb_arrhas(t->array[key]));
2470  t->array_count++;
2471  mutable_array(t)[key].val = val.val;
2472  } else {
2473  if (isfull(&t->t)) {
2474  /* Need to resize the hash part, but we re-use the array part. */
2475  size_t i;
2476  upb_table new_table;
2477 
2478  if (!init(&new_table, t->t.size_lg2 + 1, a)) {
2479  return false;
2480  }
2481 
2482  for (i = begin(&t->t); i < upb_table_size(&t->t); i = next(&t->t, i)) {
2483  const upb_tabent *e = &t->t.entries[i];
2484  uint32_t hash;
2485  upb_value v;
2486 
2487  _upb_value_setval(&v, e->val.val);
2488  hash = upb_inthash(e->key);
2489  insert(&new_table, intkey(e->key), e->key, v, hash, &inthash, &inteql);
2490  }
2491 
2492  UPB_ASSERT(t->t.count == new_table.count);
2493 
2494  t->t = new_table;
2495  }
2496  insert(&t->t, intkey(key), key, val, upb_inthash(key), &inthash, &inteql);
2497  }
2498  check(t);
2499  return true;
2500 }
2501 
2503  const upb_tabval *table_v = inttable_val_const(t, key);
2504  if (!table_v) return false;
2505  if (v) _upb_value_setval(v, table_v->val);
2506  return true;
2507 }
2508 
2510  upb_tabval *table_v = inttable_val(t, key);
2511  if (!table_v) return false;
2512  table_v->val = val.val;
2513  return true;
2514 }
2515 
2517  bool success;
2518  if (key < t->array_size) {
2519  if (upb_arrhas(t->array[key])) {
2521  t->array_count--;
2522  if (val) {
2523  _upb_value_setval(val, t->array[key].val);
2524  }
2525  mutable_array(t)[key] = empty;
2526  success = true;
2527  } else {
2528  success = false;
2529  }
2530  } else {
2531  success = rm(&t->t, intkey(key), val, NULL, upb_inthash(key), &inteql);
2532  }
2533  check(t);
2534  return success;
2535 }
2536 
2538  /* A power-of-two histogram of the table keys. */
2539  size_t counts[UPB_MAXARRSIZE + 1] = {0};
2540 
2541  /* The max key in each bucket. */
2542  uintptr_t max[UPB_MAXARRSIZE + 1] = {0};
2543 
2545  size_t arr_count;
2546  int size_lg2;
2547  upb_inttable new_t;
2548 
2549  upb_inttable_begin(&i, t);
2550  for (; !upb_inttable_done(&i); upb_inttable_next(&i)) {
2552  int bucket = log2ceil(key);
2553  max[bucket] = UPB_MAX(max[bucket], key);
2554  counts[bucket]++;
2555  }
2556 
2557  /* Find the largest power of two that satisfies the MIN_DENSITY
2558  * definition (while actually having some keys). */
2559  arr_count = upb_inttable_count(t);
2560 
2561  for (size_lg2 = ARRAY_SIZE(counts) - 1; size_lg2 > 0; size_lg2--) {
2562  if (counts[size_lg2] == 0) {
2563  /* We can halve again without losing any entries. */
2564  continue;
2565  } else if (arr_count >= (1 << size_lg2) * MIN_DENSITY) {
2566  break;
2567  }
2568 
2569  arr_count -= counts[size_lg2];
2570  }
2571 
2572  UPB_ASSERT(arr_count <= upb_inttable_count(t));
2573 
2574  {
2575  /* Insert all elements into new, perfectly-sized table. */
2576  size_t arr_size = max[size_lg2] + 1; /* +1 so arr[max] will fit. */
2577  size_t hash_count = upb_inttable_count(t) - arr_count;
2578  size_t hash_size = hash_count ? (hash_count / MAX_LOAD) + 1 : 0;
2579  int hashsize_lg2 = log2ceil(hash_size);
2580 
2581  upb_inttable_sizedinit(&new_t, arr_size, hashsize_lg2, a);
2582  upb_inttable_begin(&i, t);
2583  for (; !upb_inttable_done(&i); upb_inttable_next(&i)) {
2586  }
2587  UPB_ASSERT(new_t.array_size == arr_size);
2588  UPB_ASSERT(new_t.t.size_lg2 == hashsize_lg2);
2589  }
2590  *t = new_t;
2591 }
2592 
2593 /* Iteration. */
2594 
2595 static const upb_tabent *int_tabent(const upb_inttable_iter *i) {
2596  UPB_ASSERT(!i->array_part);
2597  return &i->t->t.entries[i->index];
2598 }
2599 
2601  UPB_ASSERT(i->array_part);
2602  return i->t->array[i->index];
2603 }
2604 
2606  i->t = t;
2607  i->index = -1;
2608  i->array_part = true;
2610 }
2611 
2613  const upb_inttable *t = iter->t;
2614  if (iter->array_part) {
2615  while (++iter->index < t->array_size) {
2616  if (upb_arrhas(int_arrent(iter))) {
2617  return;
2618  }
2619  }
2620  iter->array_part = false;
2621  iter->index = begin(&t->t);
2622  } else {
2623  iter->index = next(&t->t, iter->index);
2624  }
2625 }
2626 
2628  if (!i->t) return true;
2629  if (i->array_part) {
2630  return i->index >= i->t->array_size ||
2631  !upb_arrhas(int_arrent(i));
2632  } else {
2633  return i->index >= upb_table_size(&i->t->t) ||
2635  }
2636 }
2637 
2640  return i->array_part ? i->index : int_tabent(i)->key;
2641 }
2642 
2645  return _upb_value_val(
2646  i->array_part ? i->t->array[i->index].val : int_tabent(i)->val.val);
2647 }
2648 
2650  i->t = NULL;
2651  i->index = SIZE_MAX;
2652  i->array_part = false;
2653 }
2654 
2656  const upb_inttable_iter *i2) {
2658  return true;
2659  return i1->t == i2->t && i1->index == i2->index &&
2660  i1->array_part == i2->array_part;
2661 }
2662 
2665 #include <errno.h>
2666 #include <stdarg.h>
2667 #include <stddef.h>
2668 #include <stdint.h>
2669 #include <stdio.h>
2670 #include <stdlib.h>
2671 #include <string.h>
2672 
2673 
2674 /* upb_status *****************************************************************/
2675 
2677  if (!status) return;
2678  status->ok = true;
2679  status->msg[0] = '\0';
2680 }
2681 
2682 bool upb_ok(const upb_status *status) { return status->ok; }
2683 
2684 const char *upb_status_errmsg(const upb_status *status) { return status->msg; }
2685 
2687  if (!status) return;
2688  status->ok = false;
2689  strncpy(status->msg, msg, UPB_STATUS_MAX_MESSAGE - 1);
2690  status->msg[UPB_STATUS_MAX_MESSAGE - 1] = '\0';
2691 }
2692 
2693 void upb_status_seterrf(upb_status *status, const char *fmt, ...) {
2694  va_list args;
2695  va_start(args, fmt);
2697  va_end(args);
2698 }
2699 
2700 void upb_status_vseterrf(upb_status *status, const char *fmt, va_list args) {
2701  if (!status) return;
2702  status->ok = false;
2703  vsnprintf(status->msg, sizeof(status->msg), fmt, args);
2704  status->msg[UPB_STATUS_MAX_MESSAGE - 1] = '\0';
2705 }
2706 
2707 void upb_status_vappenderrf(upb_status *status, const char *fmt, va_list args) {
2708  size_t len;
2709  if (!status) return;
2710  status->ok = false;
2711  len = strlen(status->msg);
2712  vsnprintf(status->msg + len, sizeof(status->msg) - len, fmt, args);
2713  status->msg[UPB_STATUS_MAX_MESSAGE - 1] = '\0';
2714 }
2715 
2716 /* upb_alloc ******************************************************************/
2717 
2718 static void *upb_global_allocfunc(upb_alloc *alloc, void *ptr, size_t oldsize,
2719  size_t size) {
2720  UPB_UNUSED(alloc);
2721  UPB_UNUSED(oldsize);
2722  if (size == 0) {
2723  free(ptr);
2724  return NULL;
2725  } else {
2726  return realloc(ptr, size);
2727  }
2728 }
2729 
2730 static uint32_t *upb_cleanup_pointer(uintptr_t cleanup_metadata) {
2731  return (uint32_t *)(cleanup_metadata & ~0x1);
2732 }
2733 
2734 static bool upb_cleanup_has_initial_block(uintptr_t cleanup_metadata) {
2735  return cleanup_metadata & 0x1;
2736 }
2737 
2739  bool has_initial_block) {
2740  return (uintptr_t)cleanup | has_initial_block;
2741 }
2742 
2744 
2745 /* upb_arena ******************************************************************/
2746 
2747 /* Be conservative and choose 16 in case anyone is using SSE. */
2748 
2749 struct mem_block {
2750  struct mem_block *next;
2751  uint32_t size;
2753  /* Data follows. */
2754 };
2755 
2756 typedef struct cleanup_ent {
2758  void *ud;
2759 } cleanup_ent;
2760 
2761 static const size_t memblock_reserve = UPB_ALIGN_UP(sizeof(mem_block), 16);
2762 
2764  /* Path splitting keeps time complexity down, see:
2765  * https://en.wikipedia.org/wiki/Disjoint-set_data_structure */
2766  while (a->parent != a) {
2767  upb_arena *next = a->parent;
2768  a->parent = next->parent;
2769  a = next;
2770  }
2771  return a;
2772 }
2773 
2775  size_t size) {
2776  mem_block *block = ptr;
2777 
2778  /* The block is for arena |a|, but should appear in the freelist of |root|. */
2779  block->next = root->freelist;
2780  block->size = (uint32_t)size;
2781  block->cleanups = 0;
2782  root->freelist = block;
2783  a->last_size = block->size;
2784  if (!root->freelist_tail) root->freelist_tail = block;
2785 
2786  a->head.ptr = UPB_PTR_AT(block, memblock_reserve, char);
2787  a->head.end = UPB_PTR_AT(block, size, char);
2788  a->cleanup_metadata = upb_cleanup_metadata(
2789  &block->cleanups, upb_cleanup_has_initial_block(a->cleanup_metadata));
2790 
2791  UPB_POISON_MEMORY_REGION(a->head.ptr, a->head.end - a->head.ptr);
2792 }
2793 
2794 static bool upb_arena_allocblock(upb_arena *a, size_t size) {
2796  size_t block_size = UPB_MAX(size, a->last_size * 2) + memblock_reserve;
2797  mem_block *block = upb_malloc(root->block_alloc, block_size);
2798 
2799  if (!block) return false;
2800  upb_arena_addblock(a, root, block, block_size);
2801  return true;
2802 }
2803 
2805  if (!upb_arena_allocblock(a, size)) return NULL; /* Out of memory. */
2807  return upb_arena_malloc(a, size);
2808 }
2809 
2810 static void *upb_arena_doalloc(upb_alloc *alloc, void *ptr, size_t oldsize,
2811  size_t size) {
2812  upb_arena *a = (upb_arena*)alloc; /* upb_alloc is initial member. */
2813  return upb_arena_realloc(a, ptr, oldsize, size);
2814 }
2815 
2816 /* Public Arena API ***********************************************************/
2817 
2819  const size_t first_block_overhead = sizeof(upb_arena) + memblock_reserve;
2820  upb_arena *a;
2821 
2822  /* We need to malloc the initial block. */
2823  n = first_block_overhead + 256;
2824  if (!alloc || !(mem = upb_malloc(alloc, n))) {
2825  return NULL;
2826  }
2827 
2828  a = UPB_PTR_AT(mem, n - sizeof(*a), upb_arena);
2829  n -= sizeof(*a);
2830 
2831  a->head.alloc.func = &upb_arena_doalloc;
2832  a->block_alloc = alloc;
2833  a->parent = a;
2834  a->refcount = 1;
2835  a->freelist = NULL;
2836  a->freelist_tail = NULL;
2837  a->cleanup_metadata = upb_cleanup_metadata(NULL, false);
2838 
2839  upb_arena_addblock(a, a, mem, n);
2840 
2841  return a;
2842 }
2843 
2845  upb_arena *a;
2846 
2847  /* Round block size down to alignof(*a) since we will allocate the arena
2848  * itself at the end. */
2850 
2851  if (UPB_UNLIKELY(n < sizeof(upb_arena))) {
2852  return arena_initslow(mem, n, alloc);
2853  }
2854 
2855  a = UPB_PTR_AT(mem, n - sizeof(*a), upb_arena);
2856 
2857  a->head.alloc.func = &upb_arena_doalloc;
2858  a->block_alloc = alloc;
2859  a->parent = a;
2860  a->refcount = 1;
2861  a->last_size = UPB_MAX(128, n);
2862  a->head.ptr = mem;
2863  a->head.end = UPB_PTR_AT(mem, n - sizeof(*a), char);
2864  a->freelist = NULL;
2865  a->cleanup_metadata = upb_cleanup_metadata(NULL, true);
2866 
2867  return a;
2868 }
2869 
2870 static void arena_dofree(upb_arena *a) {
2871  mem_block *block = a->freelist;
2872  UPB_ASSERT(a->parent == a);
2873  UPB_ASSERT(a->refcount == 0);
2874 
2875  while (block) {
2876  /* Load first since we are deleting block. */
2877  mem_block *next = block->next;
2878 
2879  if (block->cleanups > 0) {
2880  cleanup_ent *end = UPB_PTR_AT(block, block->size, void);
2881  cleanup_ent *ptr = end - block->cleanups;
2882 
2883  for (; ptr < end; ptr++) {
2884  ptr->cleanup(ptr->ud);
2885  }
2886  }
2887 
2888  upb_free(a->block_alloc, block);
2889  block = next;
2890  }
2891 }
2892 
2894  a = arena_findroot(a);
2895  if (--a->refcount == 0) arena_dofree(a);
2896 }
2897 
2899  cleanup_ent *ent;
2900  uint32_t* cleanups = upb_cleanup_pointer(a->cleanup_metadata);
2901 
2902  if (!cleanups || _upb_arenahas(a) < sizeof(cleanup_ent)) {
2903  if (!upb_arena_allocblock(a, 128)) return false; /* Out of memory. */
2904  UPB_ASSERT(_upb_arenahas(a) >= sizeof(cleanup_ent));
2905  cleanups = upb_cleanup_pointer(a->cleanup_metadata);
2906  }
2907 
2908  a->head.end -= sizeof(cleanup_ent);
2909  ent = (cleanup_ent*)a->head.end;
2910  (*cleanups)++;
2912 
2913  ent->cleanup = func;
2914  ent->ud = ud;
2915 
2916  return true;
2917 }
2918 
2920  upb_arena *r1 = arena_findroot(a1);
2921  upb_arena *r2 = arena_findroot(a2);
2922 
2923  if (r1 == r2) return true; /* Already fused. */
2924 
2925  /* Do not fuse initial blocks since we cannot lifetime extend them. */
2926  if (upb_cleanup_has_initial_block(r1->cleanup_metadata)) return false;
2927  if (upb_cleanup_has_initial_block(r2->cleanup_metadata)) return false;
2928 
2929  /* Only allow fuse with a common allocator */
2930  if (r1->block_alloc != r2->block_alloc) return false;
2931 
2932  /* We want to join the smaller tree to the larger tree.
2933  * So swap first if they are backwards. */
2934  if (r1->refcount < r2->refcount) {
2935  upb_arena *tmp = r1;
2936  r1 = r2;
2937  r2 = tmp;
2938  }
2939 
2940  /* r1 takes over r2's freelist and refcount. */
2941  r1->refcount += r2->refcount;
2942  if (r2->freelist_tail) {
2943  UPB_ASSERT(r2->freelist_tail->next == NULL);
2944  r2->freelist_tail->next = r1->freelist;
2945  r1->freelist = r2->freelist;
2946  }
2947  r2->parent = r1;
2948  return true;
2949 }
2950 
2952 // Fast decoder: ~3x the speed of decode.c, but requires x86-64/ARM64.
2953 // Also the table size grows by 2x.
2954 //
2955 // Could potentially be ported to other 64-bit archs that pass at least six
2956 // arguments in registers and have 8 unused high bits in pointers.
2957 //
2958 // The overall design is to create specialized functions for every possible
2959 // field type (eg. oneof boolean field with a 1 byte tag) and then dispatch
2960 // to the specialized function as quickly as possible.
2961 
2962 
2963 
2964 /* Must be last. */
2965 
2966 #if UPB_FASTTABLE
2967 
2968 // The standard set of arguments passed to each parsing function.
2969 // Thanks to x86-64 calling conventions, these will stay in registers.
2970 #define UPB_PARSE_PARAMS \
2971  upb_decstate *d, const char *ptr, upb_msg *msg, intptr_t table, \
2972  uint64_t hasbits, uint64_t data
2973 
2974 #define UPB_PARSE_ARGS d, ptr, msg, table, hasbits, data
2975 
2976 #define RETURN_GENERIC(m) \
2977  /* Uncomment either of these for debugging purposes. */ \
2978  /* fprintf(stderr, m); */ \
2979  /*__builtin_trap(); */ \
2980  return fastdecode_generic(d, ptr, msg, table, hasbits, 0);
2981 
2982 typedef enum {
2983  CARD_s = 0, /* Singular (optional, non-repeated) */
2984  CARD_o = 1, /* Oneof */
2985  CARD_r = 2, /* Repeated */
2986  CARD_p = 3 /* Packed Repeated */
2987 } upb_card;
2988 
2990 static const char *fastdecode_isdonefallback(UPB_PARSE_PARAMS) {
2991  int overrun = data;
2992  ptr = decode_isdonefallback_inl(d, ptr, overrun);
2993  if (ptr == NULL) {
2994  return fastdecode_err(d);
2995  }
2997  UPB_MUSTTAIL return fastdecode_tagdispatch(UPB_PARSE_ARGS);
2998 }
2999 
3001 static const char *fastdecode_dispatch(UPB_PARSE_PARAMS) {
3002  if (UPB_UNLIKELY(ptr >= d->limit_ptr)) {
3003  int overrun = ptr - d->end;
3004  if (UPB_LIKELY(overrun == d->limit)) {
3005  // Parse is finished.
3006  *(uint32_t*)msg |= hasbits; // Sync hasbits.
3007  return ptr;
3008  } else {
3009  data = overrun;
3010  UPB_MUSTTAIL return fastdecode_isdonefallback(UPB_PARSE_ARGS);
3011  }
3012  }
3013 
3014  // Read two bytes of tag data (for a one-byte tag, the high byte is junk).
3016  UPB_MUSTTAIL return fastdecode_tagdispatch(UPB_PARSE_ARGS);
3017 }
3018 
3020 static bool fastdecode_checktag(uint16_t data, int tagbytes) {
3021  if (tagbytes == 1) {
3022  return (data & 0xff) == 0;
3023  } else {
3024  return data == 0;
3025  }
3026 }
3027 
3029 static const char *fastdecode_longsize(const char *ptr, int *size) {
3030  int i;
3031  UPB_ASSERT(*size & 0x80);
3032  *size &= 0xff;
3033  for (i = 0; i < 3; i++) {
3034  ptr++;
3035  size_t byte = (uint8_t)ptr[-1];
3036  *size += (byte - 1) << (7 + 7 * i);
3037  if (UPB_LIKELY((byte & 0x80) == 0)) return ptr;
3038  }
3039  ptr++;
3040  size_t byte = (uint8_t)ptr[-1];
3041  // len is limited by 2gb not 4gb, hence 8 and not 16 as normally expected
3042  // for a 32 bit varint.
3043  if (UPB_UNLIKELY(byte >= 8)) return NULL;
3044  *size += (byte - 1) << 28;
3045  return ptr;
3046 }
3047 
3049 static bool fastdecode_boundscheck(const char *ptr, size_t len,
3050  const char *end) {
3051  uintptr_t uptr = (uintptr_t)ptr;
3052  uintptr_t uend = (uintptr_t)end + 16;
3053  uintptr_t res = uptr + len;
3054  return res < uptr || res > uend;
3055 }
3056 
3058 static bool fastdecode_boundscheck2(const char *ptr, size_t len,
3059  const char *end) {
3060  // This is one extra branch compared to the more normal:
3061  // return (size_t)(end - ptr) < size;
3062  // However it is one less computation if we are just about to use "ptr + len":
3063  // https://godbolt.org/z/35YGPz
3064  // In microbenchmarks this shows an overall 4% improvement.
3065  uintptr_t uptr = (uintptr_t)ptr;
3066  uintptr_t uend = (uintptr_t)end;
3067  uintptr_t res = uptr + len;
3068  return res < uptr || res > uend;
3069 }
3070 
3071 typedef const char *fastdecode_delimfunc(upb_decstate *d, const char *ptr,
3072  void *ctx);
3073 
3075 static const char *fastdecode_delimited(upb_decstate *d, const char *ptr,
3076  fastdecode_delimfunc *func, void *ctx) {
3077  ptr++;
3078  int len = (int8_t)ptr[-1];
3079  if (fastdecode_boundscheck2(ptr, len, d->limit_ptr)) {
3080  // Slow case: Sub-message is >=128 bytes and/or exceeds the current buffer.
3081  // If it exceeds the buffer limit, limit/limit_ptr will change during
3082  // sub-message parsing, so we need to preserve delta, not limit.
3083  if (UPB_UNLIKELY(len & 0x80)) {
3084  // Size varint >1 byte (length >= 128).
3085  ptr = fastdecode_longsize(ptr, &len);
3086  if (!ptr) {
3087  // Corrupt wire format: size exceeded INT_MAX.
3088  return NULL;
3089  }
3090  }
3091  if (ptr - d->end + (int)len > d->limit) {
3092  // Corrupt wire format: invalid limit.
3093  return NULL;
3094  }
3095  int delta = decode_pushlimit(d, ptr, len);
3096  ptr = func(d, ptr, ctx);
3097  decode_poplimit(d, ptr, delta);
3098  } else {
3099  // Fast case: Sub-message is <128 bytes and fits in the current buffer.
3100  // This means we can preserve limit/limit_ptr verbatim.
3101  const char *saved_limit_ptr = d->limit_ptr;
3102  int saved_limit = d->limit;
3103  d->limit_ptr = ptr + len;
3104  d->limit = d->limit_ptr - d->end;
3105  UPB_ASSERT(d->limit_ptr == d->end + UPB_MIN(0, d->limit));
3106  ptr = func(d, ptr, ctx);
3107  d->limit_ptr = saved_limit_ptr;
3108  d->limit = saved_limit;
3109  UPB_ASSERT(d->limit_ptr == d->end + UPB_MIN(0, d->limit));
3110  }
3111  return ptr;
3112 }
3113 
3114 /* singular, oneof, repeated field handling ***********************************/
3115 
3116 typedef struct {
3117  upb_array *arr;
3118  void *end;
3119 } fastdecode_arr;
3120 
3121 typedef enum {
3122  FD_NEXT_ATLIMIT,
3123  FD_NEXT_SAMEFIELD,
3124  FD_NEXT_OTHERFIELD
3125 } fastdecode_next;
3126 
3127 typedef struct {
3128  void *dst;
3129  fastdecode_next next;
3130  uint32_t tag;
3131 } fastdecode_nextret;
3132 
3134 static void *fastdecode_resizearr(upb_decstate *d, void *dst,
3135  fastdecode_arr *farr, int valbytes) {
3136  if (UPB_UNLIKELY(dst == farr->end)) {
3137  size_t old_size = farr->arr->size;
3138  size_t old_bytes = old_size * valbytes;
3139  size_t new_size = old_size * 2;
3140  size_t new_bytes = new_size * valbytes;
3141  char *old_ptr = _upb_array_ptr(farr->arr);
3142  char *new_ptr = upb_arena_realloc(&d->arena, old_ptr, old_bytes, new_bytes);
3143  uint8_t elem_size_lg2 = __builtin_ctz(valbytes);
3144  farr->arr->size = new_size;
3145  farr->arr->data = _upb_array_tagptr(new_ptr, elem_size_lg2);
3146  dst = (void*)(new_ptr + (old_size * valbytes));
3147  farr->end = (void*)(new_ptr + (new_size * valbytes));
3148  }
3149  return dst;
3150 }
3151 
3153 static bool fastdecode_tagmatch(uint32_t tag, uint64_t data, int tagbytes) {
3154  if (tagbytes == 1) {
3155  return (uint8_t)tag == (uint8_t)data;
3156  } else {
3157  return (uint16_t)tag == (uint16_t)data;
3158  }
3159 }
3160 
3162 static void fastdecode_commitarr(void *dst, fastdecode_arr *farr,
3163  int valbytes) {
3164  farr->arr->len =
3165  (size_t)((char *)dst - (char *)_upb_array_ptr(farr->arr)) / valbytes;
3166 }
3167 
3169 static fastdecode_nextret fastdecode_nextrepeated(upb_decstate *d, void *dst,
3170  const char **ptr,
3171  fastdecode_arr *farr,
3172  uint64_t data, int tagbytes,
3173  int valbytes) {
3174  fastdecode_nextret ret;
3175  dst = (char *)dst + valbytes;
3176 
3177  if (UPB_LIKELY(!decode_isdone(d, ptr))) {
3178  ret.tag = fastdecode_loadtag(*ptr);
3179  if (fastdecode_tagmatch(ret.tag, data, tagbytes)) {
3180  ret.next = FD_NEXT_SAMEFIELD;
3181  } else {
3182  fastdecode_commitarr(dst, farr, valbytes);
3183  ret.next = FD_NEXT_OTHERFIELD;
3184  }
3185  } else {
3186  fastdecode_commitarr(dst, farr, valbytes);
3187  ret.next = FD_NEXT_ATLIMIT;
3188  }
3189 
3190  ret.dst = dst;
3191  return ret;
3192 }
3193 
3195 static void *fastdecode_fieldmem(upb_msg *msg, uint64_t data) {
3196  size_t ofs = data >> 48;
3197  return (char *)msg + ofs;
3198 }
3199 
3201 static void *fastdecode_getfield(upb_decstate *d, const char *ptr, upb_msg *msg,
3202  uint64_t *data, uint64_t *hasbits,
3203  fastdecode_arr *farr, int valbytes,
3204  upb_card card) {
3205  switch (card) {
3206  case CARD_s: {
3207  uint8_t hasbit_index = *data >> 24;
3208  // Set hasbit and return pointer to scalar field.
3209  *hasbits |= 1ull << hasbit_index;
3210  return fastdecode_fieldmem(msg, *data);
3211  }
3212  case CARD_o: {
3213  uint16_t case_ofs = *data >> 32;
3214  uint32_t *oneof_case = UPB_PTR_AT(msg, case_ofs, uint32_t);
3215  uint8_t field_number = *data >> 24;
3216  *oneof_case = field_number;
3217  return fastdecode_fieldmem(msg, *data);
3218  }
3219  case CARD_r: {
3220  // Get pointer to upb_array and allocate/expand if necessary.
3221  uint8_t elem_size_lg2 = __builtin_ctz(valbytes);
3222  upb_array **arr_p = fastdecode_fieldmem(msg, *data);
3223  char *begin;
3224  *(uint32_t*)msg |= *hasbits;
3225  *hasbits = 0;
3226  if (UPB_LIKELY(!*arr_p)) {
3227  farr->arr = _upb_array_new(&d->arena, 8, elem_size_lg2);
3228  *arr_p = farr->arr;
3229  } else {
3230  farr->arr = *arr_p;
3231  }
3232  begin = _upb_array_ptr(farr->arr);
3233  farr->end = begin + (farr->arr->size * valbytes);
3235  return begin + (farr->arr->len * valbytes);
3236  }
3237  default:
3238  UPB_UNREACHABLE();
3239  }
3240 }
3241 
3243 static bool fastdecode_flippacked(uint64_t *data, int tagbytes) {
3244  *data ^= (0x2 ^ 0x0); // Patch data to match packed wiretype.
3245  return fastdecode_checktag(*data, tagbytes);
3246 }
3247 
3248 #define FASTDECODE_CHECKPACKED(tagbytes, card, func) \
3249  if (UPB_UNLIKELY(!fastdecode_checktag(data, tagbytes))) { \
3250  if (card == CARD_r && fastdecode_flippacked(&data, tagbytes)) { \
3251  UPB_MUSTTAIL return func(UPB_PARSE_ARGS); \
3252  } \
3253  RETURN_GENERIC("packed check tag mismatch\n"); \
3254  }
3255 
3256 /* varint fields **************************************************************/
3257 
3259 static uint64_t fastdecode_munge(uint64_t val, int valbytes, bool zigzag) {
3260  if (valbytes == 1) {
3261  return val != 0;
3262  } else if (zigzag) {
3263  if (valbytes == 4) {
3264  uint32_t n = val;
3265  return (n >> 1) ^ -(int32_t)(n & 1);
3266  } else if (valbytes == 8) {
3267  return (val >> 1) ^ -(int64_t)(val & 1);
3268  }
3269  UPB_UNREACHABLE();
3270  }
3271  return val;
3272 }
3273 
3275 static const char *fastdecode_varint64(const char *ptr, uint64_t *val) {
3276  ptr++;
3277  *val = (uint8_t)ptr[-1];
3278  if (UPB_UNLIKELY(*val & 0x80)) {
3279  int i;
3280  for (i = 0; i < 8; i++) {
3281  ptr++;
3282  uint64_t byte = (uint8_t)ptr[-1];
3283  *val += (byte - 1) << (7 + 7 * i);
3284  if (UPB_LIKELY((byte & 0x80) == 0)) goto done;
3285  }
3286  ptr++;
3287  uint64_t byte = (uint8_t)ptr[-1];
3288  if (byte > 1) {
3289  return NULL;
3290  }
3291  *val += (byte - 1) << 63;
3292  }
3293 done:
3294  UPB_ASSUME(ptr != NULL);
3295  return ptr;
3296 }
3297 
3298 #define FASTDECODE_UNPACKEDVARINT(d, ptr, msg, table, hasbits, data, tagbytes, \
3299  valbytes, card, zigzag, packed) \
3300  uint64_t val; \
3301  void *dst; \
3302  fastdecode_arr farr; \
3303  \
3304  FASTDECODE_CHECKPACKED(tagbytes, card, packed); \
3305  \
3306  dst = fastdecode_getfield(d, ptr, msg, &data, &hasbits, &farr, valbytes, \
3307  card); \
3308  if (card == CARD_r) { \
3309  if (UPB_UNLIKELY(!dst)) { \
3310  RETURN_GENERIC("need array resize\n"); \
3311  } \
3312  } \
3313  \
3314  again: \
3315  if (card == CARD_r) { \
3316  dst = fastdecode_resizearr(d, dst, &farr, valbytes); \
3317  } \
3318  \
3319  ptr += tagbytes; \
3320  ptr = fastdecode_varint64(ptr, &val); \
3321  if (ptr == NULL) \
3322  return fastdecode_err(d); \
3323  val = fastdecode_munge(val, valbytes, zigzag); \
3324  memcpy(dst, &val, valbytes); \
3325  \
3326  if (card == CARD_r) { \
3327  fastdecode_nextret ret = fastdecode_nextrepeated( \
3328  d, dst, &ptr, &farr, data, tagbytes, valbytes); \
3329  switch (ret.next) { \
3330  case FD_NEXT_SAMEFIELD: \
3331  dst = ret.dst; \
3332  goto again; \
3333  case FD_NEXT_OTHERFIELD: \
3334  data = ret.tag; \
3335  UPB_MUSTTAIL return fastdecode_tagdispatch(UPB_PARSE_ARGS); \
3336  case FD_NEXT_ATLIMIT: \
3337  return ptr; \
3338  } \
3339  } \
3340  \
3341  UPB_MUSTTAIL return fastdecode_dispatch(UPB_PARSE_ARGS);
3342 
3343 typedef struct {
3344  uint8_t valbytes;
3345  bool zigzag;
3346  void *dst;
3347  fastdecode_arr farr;
3348 } fastdecode_varintdata;
3349 
3351 static const char *fastdecode_topackedvarint(upb_decstate *d, const char *ptr,
3352  void *ctx) {
3353  fastdecode_varintdata *data = ctx;
3354  void *dst = data->dst;
3355  uint64_t val;
3356 
3357  while (!decode_isdone(d, &ptr)) {
3358  dst = fastdecode_resizearr(d, dst, &data->farr, data->valbytes);
3359  ptr = fastdecode_varint64(ptr, &val);
3360  if (ptr == NULL) return NULL;
3361  val = fastdecode_munge(val, data->valbytes, data->zigzag);
3362  memcpy(dst, &val, data->valbytes);
3363  dst = (char *)dst + data->valbytes;
3364  }
3365 
3366  fastdecode_commitarr(dst, &data->farr, data->valbytes);
3367  return ptr;
3368 }
3369 
3370 #define FASTDECODE_PACKEDVARINT(d, ptr, msg, table, hasbits, data, tagbytes, \
3371  valbytes, zigzag, unpacked) \
3372  fastdecode_varintdata ctx = {valbytes, zigzag}; \
3373  \
3374  FASTDECODE_CHECKPACKED(tagbytes, CARD_r, unpacked); \
3375  \
3376  ctx.dst = fastdecode_getfield(d, ptr, msg, &data, &hasbits, &ctx.farr, \
3377  valbytes, CARD_r); \
3378  if (UPB_UNLIKELY(!ctx.dst)) { \
3379  RETURN_GENERIC("need array resize\n"); \
3380  } \
3381  \
3382  ptr += tagbytes; \
3383  ptr = fastdecode_delimited(d, ptr, &fastdecode_topackedvarint, &ctx); \
3384  \
3385  if (UPB_UNLIKELY(ptr == NULL)) { \
3386  return fastdecode_err(d); \
3387  } \
3388  \
3389  UPB_MUSTTAIL return fastdecode_dispatch(d, ptr, msg, table, hasbits, 0);
3390 
3391 #define FASTDECODE_VARINT(d, ptr, msg, table, hasbits, data, tagbytes, \
3392  valbytes, card, zigzag, unpacked, packed) \
3393  if (card == CARD_p) { \
3394  FASTDECODE_PACKEDVARINT(d, ptr, msg, table, hasbits, data, tagbytes, \
3395  valbytes, zigzag, unpacked); \
3396  } else { \
3397  FASTDECODE_UNPACKEDVARINT(d, ptr, msg, table, hasbits, data, tagbytes, \
3398  valbytes, card, zigzag, packed); \
3399  }
3400 
3401 #define z_ZZ true
3402 #define b_ZZ false
3403 #define v_ZZ false
3404 
3405 /* Generate all combinations:
3406  * {s,o,r,p} x {b1,v4,z4,v8,z8} x {1bt,2bt} */
3407 
3408 #define F(card, type, valbytes, tagbytes) \
3409  UPB_NOINLINE \
3410  const char *upb_p##card##type##valbytes##_##tagbytes##bt(UPB_PARSE_PARAMS) { \
3411  FASTDECODE_VARINT(d, ptr, msg, table, hasbits, data, tagbytes, valbytes, \
3412  CARD_##card, type##_ZZ, \
3413  upb_pr##type##valbytes##_##tagbytes##bt, \
3414  upb_pp##type##valbytes##_##tagbytes##bt); \
3415  }
3416 
3417 #define TYPES(card, tagbytes) \
3418  F(card, b, 1, tagbytes) \
3419  F(card, v, 4, tagbytes) \
3420  F(card, v, 8, tagbytes) \
3421  F(card, z, 4, tagbytes) \
3422  F(card, z, 8, tagbytes)
3423 
3424 #define TAGBYTES(card) \
3425  TYPES(card, 1) \
3426  TYPES(card, 2)
3427 
3428 TAGBYTES(s)
3429 TAGBYTES(o)
3430 TAGBYTES(r)
3431 TAGBYTES(p)
3432 
3433 #undef z_ZZ
3434 #undef b_ZZ
3435 #undef v_ZZ
3436 #undef o_ONEOF
3437 #undef s_ONEOF
3438 #undef r_ONEOF
3439 #undef F
3440 #undef TYPES
3441 #undef TAGBYTES
3442 #undef FASTDECODE_UNPACKEDVARINT
3443 #undef FASTDECODE_PACKEDVARINT
3444 #undef FASTDECODE_VARINT
3445 
3446 
3447 /* fixed fields ***************************************************************/
3448 
3449 #define FASTDECODE_UNPACKEDFIXED(d, ptr, msg, table, hasbits, data, tagbytes, \
3450  valbytes, card, packed) \
3451  void *dst; \
3452  fastdecode_arr farr; \
3453  \
3454  FASTDECODE_CHECKPACKED(tagbytes, card, packed) \
3455  \
3456  dst = fastdecode_getfield(d, ptr, msg, &data, &hasbits, &farr, valbytes, \
3457  card); \
3458  if (card == CARD_r) { \
3459  if (UPB_UNLIKELY(!dst)) { \
3460  RETURN_GENERIC("couldn't allocate array in arena\n"); \
3461  } \
3462  } \
3463  \
3464  again: \
3465  if (card == CARD_r) { \
3466  dst = fastdecode_resizearr(d, dst, &farr, valbytes); \
3467  } \
3468  \
3469  ptr += tagbytes; \
3470  memcpy(dst, ptr, valbytes); \
3471  ptr += valbytes; \
3472  \
3473  if (card == CARD_r) { \
3474  fastdecode_nextret ret = fastdecode_nextrepeated( \
3475  d, dst, &ptr, &farr, data, tagbytes, valbytes); \
3476  switch (ret.next) { \
3477  case FD_NEXT_SAMEFIELD: \
3478  dst = ret.dst; \
3479  goto again; \
3480  case FD_NEXT_OTHERFIELD: \
3481  data = ret.tag; \
3482  UPB_MUSTTAIL return fastdecode_tagdispatch(UPB_PARSE_ARGS); \
3483  case FD_NEXT_ATLIMIT: \
3484  return ptr; \
3485  } \
3486  } \
3487  \
3488  UPB_MUSTTAIL return fastdecode_dispatch(UPB_PARSE_ARGS);
3489 
3490 #define FASTDECODE_PACKEDFIXED(d, ptr, msg, table, hasbits, data, tagbytes, \
3491  valbytes, unpacked) \
3492  FASTDECODE_CHECKPACKED(tagbytes, CARD_r, unpacked) \
3493  \
3494  ptr += tagbytes; \
3495  int size = (uint8_t)ptr[0]; \
3496  ptr++; \
3497  if (size & 0x80) { \
3498  ptr = fastdecode_longsize(ptr, &size); \
3499  } \
3500  \
3501  if (UPB_UNLIKELY(fastdecode_boundscheck(ptr, size, d->limit_ptr) || \
3502  (size % valbytes) != 0)) { \
3503  return fastdecode_err(d); \
3504  } \
3505  \
3506  upb_array **arr_p = fastdecode_fieldmem(msg, data); \
3507  upb_array *arr = *arr_p; \
3508  uint8_t elem_size_lg2 = __builtin_ctz(valbytes); \
3509  int elems = size / valbytes; \
3510  \
3511  if (UPB_LIKELY(!arr)) { \
3512  *arr_p = arr = _upb_array_new(&d->arena, elems, elem_size_lg2); \
3513  if (!arr) { \
3514  return fastdecode_err(d); \
3515  } \
3516  } else { \
3517  _upb_array_resize(arr, elems, &d->arena); \
3518  } \
3519  \
3520  char *dst = _upb_array_ptr(arr); \
3521  memcpy(dst, ptr, size); \
3522  arr->len = elems; \
3523  \
3524  ptr += size; \
3525  UPB_MUSTTAIL return fastdecode_dispatch(UPB_PARSE_ARGS);
3526 
3527 #define FASTDECODE_FIXED(d, ptr, msg, table, hasbits, data, tagbytes, \
3528  valbytes, card, unpacked, packed) \
3529  if (card == CARD_p) { \
3530  FASTDECODE_PACKEDFIXED(d, ptr, msg, table, hasbits, data, tagbytes, \
3531  valbytes, unpacked); \
3532  } else { \
3533  FASTDECODE_UNPACKEDFIXED(d, ptr, msg, table, hasbits, data, tagbytes, \
3534  valbytes, card, packed); \
3535  }
3536 
3537 /* Generate all combinations:
3538  * {s,o,r,p} x {f4,f8} x {1bt,2bt} */
3539 
3540 #define F(card, valbytes, tagbytes) \
3541  UPB_NOINLINE \
3542  const char *upb_p##card##f##valbytes##_##tagbytes##bt(UPB_PARSE_PARAMS) { \
3543  FASTDECODE_FIXED(d, ptr, msg, table, hasbits, data, tagbytes, valbytes, \
3544  CARD_##card, upb_ppf##valbytes##_##tagbytes##bt, \
3545  upb_prf##valbytes##_##tagbytes##bt); \
3546  }
3547 
3548 #define TYPES(card, tagbytes) \
3549  F(card, 4, tagbytes) \
3550  F(card, 8, tagbytes)
3551 
3552 #define TAGBYTES(card) \
3553  TYPES(card, 1) \
3554  TYPES(card, 2)
3555 
3556 TAGBYTES(s)
3557 TAGBYTES(o)
3558 TAGBYTES(r)
3559 TAGBYTES(p)
3560 
3561 #undef F
3562 #undef TYPES
3563 #undef TAGBYTES
3564 #undef FASTDECODE_UNPACKEDFIXED
3565 #undef FASTDECODE_PACKEDFIXED
3566 
3567 /* string fields **************************************************************/
3568 
3569 typedef const char *fastdecode_copystr_func(struct upb_decstate *d,
3570  const char *ptr, upb_msg *msg,
3571  const upb_msglayout *table,
3572  uint64_t hasbits, upb_strview *dst);
3573 
3575 static const char *fastdecode_verifyutf8(upb_decstate *d, const char *ptr,
3577  uint64_t hasbits, uint64_t data) {
3579  if (!decode_verifyutf8_inl(dst->data, dst->size)) {
3580  return fastdecode_err(d);
3581  }
3582  UPB_MUSTTAIL return fastdecode_dispatch(UPB_PARSE_ARGS);
3583 }
3584 
3585 #define FASTDECODE_LONGSTRING(d, ptr, msg, table, hasbits, dst, validate_utf8) \
3586  int size = (uint8_t)ptr[0]; /* Could plumb through hasbits. */ \
3587  ptr++; \
3588  if (size & 0x80) { \
3589  ptr = fastdecode_longsize(ptr, &size); \
3590  } \
3591  \
3592  if (UPB_UNLIKELY(fastdecode_boundscheck(ptr, size, d->limit_ptr))) { \
3593  dst->size = 0; \
3594  return fastdecode_err(d); \
3595  } \
3596  \
3597  if (d->alias) { \
3598  dst->data = ptr; \
3599  dst->size = size; \
3600  } else { \
3601  char *data = upb_arena_malloc(&d->arena, size); \
3602  if (!data) { \
3603  return fastdecode_err(d); \
3604  } \
3605  memcpy(data, ptr, size); \
3606  dst->data = data; \
3607  dst->size = size; \
3608  } \
3609  \
3610  ptr += size; \
3611  if (validate_utf8) { \
3612  data = (uint64_t)dst; \
3613  UPB_MUSTTAIL return fastdecode_verifyutf8(UPB_PARSE_ARGS); \
3614  } else { \
3615  UPB_MUSTTAIL return fastdecode_dispatch(UPB_PARSE_ARGS); \
3616  }
3617 
3619 static const char *fastdecode_longstring_utf8(struct upb_decstate *d,
3620  const char *ptr, upb_msg *msg,
3621  intptr_t table, uint64_t hasbits,
3622  uint64_t data) {
3624  FASTDECODE_LONGSTRING(d, ptr, msg, table, hasbits, dst, true);
3625 }
3626 
3628 static const char *fastdecode_longstring_noutf8(struct upb_decstate *d,
3629  const char *ptr, upb_msg *msg,
3630  intptr_t table,
3631  uint64_t hasbits,
3632  uint64_t data) {
3634  FASTDECODE_LONGSTRING(d, ptr, msg, table, hasbits, dst, false);
3635 }
3636 
3638 static void fastdecode_docopy(upb_decstate *d, const char *ptr, uint32_t size,
3639  int copy, char *data, upb_strview *dst) {
3640  d->arena.head.ptr += copy;
3641  dst->data = data;
3643  memcpy(data, ptr, copy);
3645 }
3646 
3647 #define FASTDECODE_COPYSTRING(d, ptr, msg, table, hasbits, data, tagbytes, \
3648  card, validate_utf8) \
3649  upb_strview *dst; \
3650  fastdecode_arr farr; \
3651  int64_t size; \
3652  size_t arena_has; \
3653  size_t common_has; \
3654  char *buf; \
3655  \
3656  UPB_ASSERT(!d->alias); \
3657  UPB_ASSERT(fastdecode_checktag(data, tagbytes)); \
3658  \
3659  dst = fastdecode_getfield(d, ptr, msg, &data, &hasbits, &farr, \
3660  sizeof(upb_strview), card); \
3661  \
3662  again: \
3663  if (card == CARD_r) { \
3664  dst = fastdecode_resizearr(d, dst, &farr, sizeof(upb_strview)); \
3665  } \
3666  \
3667  size = (uint8_t)ptr[tagbytes]; \
3668  ptr += tagbytes + 1; \
3669  dst->size = size; \
3670  \
3671  buf = d->arena.head.ptr; \
3672  arena_has = _upb_arenahas(&d->arena); \
3673  common_has = UPB_MIN(arena_has, (d->end - ptr) + 16); \
3674  \
3675  if (UPB_LIKELY(size <= 15 - tagbytes)) { \
3676  if (arena_has < 16) \
3677  goto longstr; \
3678  d->arena.head.ptr += 16; \
3679  memcpy(buf, ptr - tagbytes - 1, 16); \
3680  dst->data = buf + tagbytes + 1; \
3681  } else if (UPB_LIKELY(size <= 32)) { \
3682  if (UPB_UNLIKELY(common_has < 32)) \
3683  goto longstr; \
3684  fastdecode_docopy(d, ptr, size, 32, buf, dst); \
3685  } else if (UPB_LIKELY(size <= 64)) { \
3686  if (UPB_UNLIKELY(common_has < 64)) \
3687  goto longstr; \
3688  fastdecode_docopy(d, ptr, size, 64, buf, dst); \
3689  } else if (UPB_LIKELY(size < 128)) { \
3690  if (UPB_UNLIKELY(common_has < 128)) \
3691  goto longstr; \
3692  fastdecode_docopy(d, ptr, size, 128, buf, dst); \
3693  } else { \
3694  goto longstr; \
3695  } \
3696  \
3697  ptr += size; \
3698  \
3699  if (card == CARD_r) { \
3700  if (validate_utf8 && !decode_verifyutf8_inl(dst->data, dst->size)) { \
3701  return fastdecode_err(d); \
3702  } \
3703  fastdecode_nextret ret = fastdecode_nextrepeated( \
3704  d, dst, &ptr, &farr, data, tagbytes, sizeof(upb_strview)); \
3705  switch (ret.next) { \
3706  case FD_NEXT_SAMEFIELD: \
3707  dst = ret.dst; \
3708  goto again; \
3709  case FD_NEXT_OTHERFIELD: \
3710  data = ret.tag; \
3711  UPB_MUSTTAIL return fastdecode_tagdispatch(UPB_PARSE_ARGS); \
3712  case FD_NEXT_ATLIMIT: \
3713  return ptr; \
3714  } \
3715  } \
3716  \
3717  if (card != CARD_r && validate_utf8) { \
3718  data = (uint64_t)dst; \
3719  UPB_MUSTTAIL return fastdecode_verifyutf8(UPB_PARSE_ARGS); \
3720  } \
3721  \
3722  UPB_MUSTTAIL return fastdecode_dispatch(UPB_PARSE_ARGS); \
3723  \
3724  longstr: \
3725  ptr--; \
3726  if (validate_utf8) { \
3727  UPB_MUSTTAIL return fastdecode_longstring_utf8(d, ptr, msg, table, \
3728  hasbits, (uint64_t)dst); \
3729  } else { \
3730  UPB_MUSTTAIL return fastdecode_longstring_noutf8(d, ptr, msg, table, \
3731  hasbits, (uint64_t)dst); \
3732  }
3733 
3734 #define FASTDECODE_STRING(d, ptr, msg, table, hasbits, data, tagbytes, card, \
3735  copyfunc, validate_utf8) \
3736  upb_strview *dst; \
3737  fastdecode_arr farr; \
3738  int64_t size; \
3739  \
3740  if (UPB_UNLIKELY(!fastdecode_checktag(data, tagbytes))) { \
3741  RETURN_GENERIC("string field tag mismatch\n"); \
3742  } \
3743  \
3744  if (UPB_UNLIKELY(!d->alias)) { \
3745  UPB_MUSTTAIL return copyfunc(UPB_PARSE_ARGS); \
3746  } \
3747  \
3748  dst = fastdecode_getfield(d, ptr, msg, &data, &hasbits, &farr, \
3749  sizeof(upb_strview), card); \
3750  \
3751  again: \
3752  if (card == CARD_r) { \
3753  dst = fastdecode_resizearr(d, dst, &farr, sizeof(upb_strview)); \
3754  } \
3755  \
3756  size = (int8_t)ptr[tagbytes]; \
3757  ptr += tagbytes + 1; \
3758  dst->data = ptr; \
3759  dst->size = size; \
3760  \
3761  if (UPB_UNLIKELY(fastdecode_boundscheck(ptr, size, d->end))) { \
3762  ptr--; \
3763  if (validate_utf8) { \
3764  return fastdecode_longstring_utf8(d, ptr, msg, table, hasbits, \
3765  (uint64_t)dst); \
3766  } else { \
3767  return fastdecode_longstring_noutf8(d, ptr, msg, table, hasbits, \
3768  (uint64_t)dst); \
3769  } \
3770  } \
3771  \
3772  ptr += size; \
3773  \
3774  if (card == CARD_r) { \
3775  if (validate_utf8 && !decode_verifyutf8_inl(dst->data, dst->size)) { \
3776  return fastdecode_err(d); \
3777  } \
3778  fastdecode_nextret ret = fastdecode_nextrepeated( \
3779  d, dst, &ptr, &farr, data, tagbytes, sizeof(upb_strview)); \
3780  switch (ret.next) { \
3781  case FD_NEXT_SAMEFIELD: \
3782  dst = ret.dst; \
3783  if (UPB_UNLIKELY(!d->alias)) { \
3784  /* Buffer flipped and we can't alias any more. Bounce to */ \
3785  /* copyfunc(), but via dispatch since we need to reload table */ \
3786  /* data also. */ \
3787  fastdecode_commitarr(dst, &farr, sizeof(upb_strview)); \
3788  data = ret.tag; \
3789  UPB_MUSTTAIL return fastdecode_tagdispatch(UPB_PARSE_ARGS); \
3790  } \
3791  goto again; \
3792  case FD_NEXT_OTHERFIELD: \
3793  data = ret.tag; \
3794  UPB_MUSTTAIL return fastdecode_tagdispatch(UPB_PARSE_ARGS); \
3795  case FD_NEXT_ATLIMIT: \
3796  return ptr; \
3797  } \
3798  } \
3799  \
3800  if (card != CARD_r && validate_utf8) { \
3801  data = (uint64_t)dst; \
3802  UPB_MUSTTAIL return fastdecode_verifyutf8(UPB_PARSE_ARGS); \
3803  } \
3804  \
3805  UPB_MUSTTAIL return fastdecode_dispatch(UPB_PARSE_ARGS);
3806 
3807 /* Generate all combinations:
3808  * {p,c} x {s,o,r} x {s, b} x {1bt,2bt} */
3809 
3810 #define s_VALIDATE true
3811 #define b_VALIDATE false
3812 
3813 #define F(card, tagbytes, type) \
3814  UPB_NOINLINE \
3815  const char *upb_c##card##type##_##tagbytes##bt(UPB_PARSE_PARAMS) { \
3816  FASTDECODE_COPYSTRING(d, ptr, msg, table, hasbits, data, tagbytes, \
3817  CARD_##card, type##_VALIDATE); \
3818  } \
3819  const char *upb_p##card##type##_##tagbytes##bt(UPB_PARSE_PARAMS) { \
3820  FASTDECODE_STRING(d, ptr, msg, table, hasbits, data, tagbytes, \
3821  CARD_##card, upb_c##card##type##_##tagbytes##bt, \
3822  type##_VALIDATE); \
3823  }
3824 
3825 #define UTF8(card, tagbytes) \
3826  F(card, tagbytes, s) \
3827  F(card, tagbytes, b)
3828 
3829 #define TAGBYTES(card) \
3830  UTF8(card, 1) \
3831  UTF8(card, 2)
3832 
3833 TAGBYTES(s)
3834 TAGBYTES(o)
3835 TAGBYTES(r)
3836 
3837 #undef s_VALIDATE
3838 #undef b_VALIDATE
3839 #undef F
3840 #undef TAGBYTES
3841 #undef FASTDECODE_LONGSTRING
3842 #undef FASTDECODE_COPYSTRING
3843 #undef FASTDECODE_STRING
3844 
3845 /* message fields *************************************************************/
3846 
3847 UPB_INLINE
3848 upb_msg *decode_newmsg_ceil(upb_decstate *d, const upb_msglayout *l,
3849  int msg_ceil_bytes) {
3850  size_t size = l->size + sizeof(upb_msg_internal);
3851  char *msg_data;
3852  if (UPB_LIKELY(msg_ceil_bytes > 0 &&
3853  _upb_arenahas(&d->arena) >= msg_ceil_bytes)) {
3854  UPB_ASSERT(size <= (size_t)msg_ceil_bytes);
3855  msg_data = d->arena.head.ptr;
3856  d->arena.head.ptr += size;
3857  UPB_UNPOISON_MEMORY_REGION(msg_data, msg_ceil_bytes);
3858  memset(msg_data, 0, msg_ceil_bytes);
3859  UPB_POISON_MEMORY_REGION(msg_data + size, msg_ceil_bytes - size);
3860  } else {
3861  msg_data = (char*)upb_arena_malloc(&d->arena, size);
3862  memset(msg_data, 0, size);
3863  }
3864  return msg_data + sizeof(upb_msg_internal);
3865 }
3866 
3867 typedef struct {
3868  intptr_t table;
3869  upb_msg *msg;
3870 } fastdecode_submsgdata;
3871 
3873 static const char *fastdecode_tosubmsg(upb_decstate *d, const char *ptr,
3874  void *ctx) {
3875  fastdecode_submsgdata *submsg = ctx;
3876  ptr = fastdecode_dispatch(d, ptr, submsg->msg, submsg->table, 0, 0);
3877  UPB_ASSUME(ptr != NULL);
3878  return ptr;
3879 }
3880 
3881 #define FASTDECODE_SUBMSG(d, ptr, msg, table, hasbits, data, tagbytes, \
3882  msg_ceil_bytes, card) \
3883  \
3884  if (UPB_UNLIKELY(!fastdecode_checktag(data, tagbytes))) { \
3885  RETURN_GENERIC("submessage field tag mismatch\n"); \
3886  } \
3887  \
3888  if (--d->depth == 0) return fastdecode_err(d); \
3889  \
3890  upb_msg **dst; \
3891  uint32_t submsg_idx = (data >> 16) & 0xff; \
3892  const upb_msglayout *tablep = decode_totablep(table); \
3893  const upb_msglayout *subtablep = tablep->submsgs[submsg_idx]; \
3894  fastdecode_submsgdata submsg = {decode_totable(subtablep)}; \
3895  fastdecode_arr farr; \
3896  \
3897  if (subtablep->table_mask == (uint8_t)-1) { \
3898  RETURN_GENERIC("submessage doesn't have fast tables."); \
3899  } \
3900  \
3901  dst = fastdecode_getfield(d, ptr, msg, &data, &hasbits, &farr, \
3902  sizeof(upb_msg *), card); \
3903  \
3904  if (card == CARD_s) { \
3905  *(uint32_t *)msg |= hasbits; \
3906  hasbits = 0; \
3907  } \
3908  \
3909  again: \
3910  if (card == CARD_r) { \
3911  dst = fastdecode_resizearr(d, dst, &farr, sizeof(upb_msg *)); \
3912  } \
3913  \
3914  submsg.msg = *dst; \
3915  \
3916  if (card == CARD_r || UPB_LIKELY(!submsg.msg)) { \
3917  *dst = submsg.msg = decode_newmsg_ceil(d, subtablep, msg_ceil_bytes); \
3918  } \
3919  \
3920  ptr += tagbytes; \
3921  ptr = fastdecode_delimited(d, ptr, fastdecode_tosubmsg, &submsg); \
3922  \
3923  if (UPB_UNLIKELY(ptr == NULL || d->end_group != DECODE_NOGROUP)) { \
3924  return fastdecode_err(d); \
3925  } \
3926  \
3927  if (card == CARD_r) { \
3928  fastdecode_nextret ret = fastdecode_nextrepeated( \
3929  d, dst, &ptr, &farr, data, tagbytes, sizeof(upb_msg *)); \
3930  switch (ret.next) { \
3931  case FD_NEXT_SAMEFIELD: \
3932  dst = ret.dst; \
3933  goto again; \
3934  case FD_NEXT_OTHERFIELD: \
3935  d->depth++; \
3936  data = ret.tag; \
3937  UPB_MUSTTAIL return fastdecode_tagdispatch(UPB_PARSE_ARGS); \
3938  case FD_NEXT_ATLIMIT: \
3939  d->depth++; \
3940  return ptr; \
3941  } \
3942  } \
3943  \
3944  d->depth++; \
3945  UPB_MUSTTAIL return fastdecode_dispatch(UPB_PARSE_ARGS);
3946 
3947 #define F(card, tagbytes, size_ceil, ceil_arg) \
3948  const char *upb_p##card##m_##tagbytes##bt_max##size_ceil##b( \
3949  UPB_PARSE_PARAMS) { \
3950  FASTDECODE_SUBMSG(d, ptr, msg, table, hasbits, data, tagbytes, ceil_arg, \
3951  CARD_##card); \
3952  }
3953 
3954 #define SIZES(card, tagbytes) \
3955  F(card, tagbytes, 64, 64) \
3956  F(card, tagbytes, 128, 128) \
3957  F(card, tagbytes, 192, 192) \
3958  F(card, tagbytes, 256, 256) \
3959  F(card, tagbytes, max, -1)
3960 
3961 #define TAGBYTES(card) \
3962  SIZES(card, 1) \
3963  SIZES(card, 2)
3964 
3965 TAGBYTES(s)
3966 TAGBYTES(o)
3967 TAGBYTES(r)
3968 
3969 #undef TAGBYTES
3970 #undef SIZES
3971 #undef F
3972 #undef FASTDECODE_SUBMSG
3973 
3974 #endif /* UPB_FASTTABLE */
3975 /* This file was generated by upbc (the upb compiler) from the input
3977  * file:
3978  *
3979  * google/protobuf/descriptor.proto
3980  *
3981  * Do not edit -- your changes will be discarded when the file is
3982  * regenerated. */
3983 
3984 #include <stddef.h>
3985 
3986 
3989 };
3990 
3992  {1, UPB_SIZE(0, 0), 0, 0, 11, _UPB_MODE_ARRAY},
3993 };
3994 
3998  UPB_SIZE(8, 8), 1, false, 1, 255,
3999 };
4000 
4008 };
4009 
4011  {1, UPB_SIZE(4, 8), 1, 0, 12, _UPB_MODE_SCALAR},
4012  {2, UPB_SIZE(12, 24), 2, 0, 12, _UPB_MODE_SCALAR},
4013  {3, UPB_SIZE(36, 72), 0, 0, 12, _UPB_MODE_ARRAY},
4014  {4, UPB_SIZE(40, 80), 0, 0, 11, _UPB_MODE_ARRAY},
4015  {5, UPB_SIZE(44, 88), 0, 1, 11, _UPB_MODE_ARRAY},
4016  {6, UPB_SIZE(48, 96), 0, 4, 11, _UPB_MODE_ARRAY},
4017  {7, UPB_SIZE(52, 104), 0, 2, 11, _UPB_MODE_ARRAY},
4018  {8, UPB_SIZE(28, 56), 3, 3, 11, _UPB_MODE_SCALAR},
4019  {9, UPB_SIZE(32, 64), 4, 5, 11, _UPB_MODE_SCALAR},
4020  {10, UPB_SIZE(56, 112), 0, 0, 5, _UPB_MODE_ARRAY},
4021  {11, UPB_SIZE(60, 120), 0, 0, 5, _UPB_MODE_ARRAY},
4022  {12, UPB_SIZE(20, 40), 5, 0, 12, _UPB_MODE_SCALAR},
4023 };
4024 
4028  UPB_SIZE(64, 128), 12, false, 12, 255,
4029 };
4030 
4039 };
4040 
4042  {1, UPB_SIZE(4, 8), 1, 0, 12, _UPB_MODE_SCALAR},
4043  {2, UPB_SIZE(16, 32), 0, 4, 11, _UPB_MODE_ARRAY},
4044  {3, UPB_SIZE(20, 40), 0, 0, 11, _UPB_MODE_ARRAY},
4045  {4, UPB_SIZE(24, 48), 0, 3, 11, _UPB_MODE_ARRAY},
4046  {5, UPB_SIZE(28, 56), 0, 1, 11, _UPB_MODE_ARRAY},
4047  {6, UPB_SIZE(32, 64), 0, 4, 11, _UPB_MODE_ARRAY},
4048  {7, UPB_SIZE(12, 24), 2, 5, 11, _UPB_MODE_SCALAR},
4049  {8, UPB_SIZE(36, 72), 0, 6, 11, _UPB_MODE_ARRAY},
4050  {9, UPB_SIZE(40, 80), 0, 2, 11, _UPB_MODE_ARRAY},
4051  {10, UPB_SIZE(44, 88), 0, 0, 12, _UPB_MODE_ARRAY},
4052 };
4053 
4057  UPB_SIZE(48, 96), 10, false, 10, 255,
4058 };
4059 
4062 };
4063 
4065  {1, UPB_SIZE(4, 4), 1, 0, 5, _UPB_MODE_SCALAR},
4066  {2, UPB_SIZE(8, 8), 2, 0, 5, _UPB_MODE_SCALAR},
4067  {3, UPB_SIZE(12, 16), 3, 0, 11, _UPB_MODE_SCALAR},
4068 };
4069 
4073  UPB_SIZE(16, 24), 3, false, 3, 255,
4074 };
4075 
4077  {1, UPB_SIZE(4, 4), 1, 0, 5, _UPB_MODE_SCALAR},
4078  {2, UPB_SIZE(8, 8), 2, 0, 5, _UPB_MODE_SCALAR},
4079 };
4080 
4082  NULL,
4084  UPB_SIZE(16, 16), 2, false, 2, 255,
4085 };
4086 
4089 };
4090 
4092  {999, UPB_SIZE(0, 0), 0, 0, 11, _UPB_MODE_ARRAY},
4093 };
4094 
4098  UPB_SIZE(8, 8), 1, false, 0, 255,
4099 };
4100 
4103 };
4104 
4106  {1, UPB_SIZE(24, 24), 1, 0, 12, _UPB_MODE_SCALAR},
4107  {2, UPB_SIZE(32, 40), 2, 0, 12, _UPB_MODE_SCALAR},
4108  {3, UPB_SIZE(12, 12), 3, 0, 5, _UPB_MODE_SCALAR},
4109  {4, UPB_SIZE(4, 4), 4, 0, 14, _UPB_MODE_SCALAR},
4110  {5, UPB_SIZE(8, 8), 5, 0, 14, _UPB_MODE_SCALAR},
4111  {6, UPB_SIZE(40, 56), 6, 0, 12, _UPB_MODE_SCALAR},
4112  {7, UPB_SIZE(48, 72), 7, 0, 12, _UPB_MODE_SCALAR},
4113  {8, UPB_SIZE(64, 104), 8, 0, 11, _UPB_MODE_SCALAR},
4114  {9, UPB_SIZE(16, 16), 9, 0, 5, _UPB_MODE_SCALAR},
4115  {10, UPB_SIZE(56, 88), 10, 0, 12, _UPB_MODE_SCALAR},
4116  {17, UPB_SIZE(20, 20), 11, 0, 8, _UPB_MODE_SCALAR},
4117 };
4118 
4122  UPB_SIZE(72, 112), 11, false, 10, 255,
4123 };
4124 
4127 };
4128 
4130  {1, UPB_SIZE(4, 8), 1, 0, 12, _UPB_MODE_SCALAR},
4131  {2, UPB_SIZE(12, 24), 2, 0, 11, _UPB_MODE_SCALAR},
4132 };
4133 
4137  UPB_SIZE(16, 32), 2, false, 2, 255,
4138 };
4139 
4144 };
4145 
4147  {1, UPB_SIZE(4, 8), 1, 0, 12, _UPB_MODE_SCALAR},
4148  {2, UPB_SIZE(16, 32), 0, 2, 11, _UPB_MODE_ARRAY},
4149  {3, UPB_SIZE(12, 24), 2, 1, 11, _UPB_MODE_SCALAR},
4150  {4, UPB_SIZE(20, 40), 0, 0, 11, _UPB_MODE_ARRAY},
4151  {5, UPB_SIZE(24, 48), 0, 0, 12, _UPB_MODE_ARRAY},
4152 };
4153 
4157  UPB_SIZE(32, 64), 5, false, 5, 255,
4158 };
4159 
4161  {1, UPB_SIZE(4, 4), 1, 0, 5, _UPB_MODE_SCALAR},
4162  {2, UPB_SIZE(8, 8), 2, 0, 5, _UPB_MODE_SCALAR},
4163 };
4164 
4166  NULL,
4168  UPB_SIZE(16, 16), 2, false, 2, 255,
4169 };
4170 
4173 };
4174 
4176  {1, UPB_SIZE(8, 8), 1, 0, 12, _UPB_MODE_SCALAR},
4177  {2, UPB_SIZE(4, 4), 2, 0, 5, _UPB_MODE_SCALAR},
4178  {3, UPB_SIZE(16, 24), 3, 0, 11, _UPB_MODE_SCALAR},
4179 };
4180 
4184  UPB_SIZE(24, 32), 3, false, 3, 255,
4185 };
4186 
4190 };
4191 
4193  {1, UPB_SIZE(4, 8), 1, 0, 12, _UPB_MODE_SCALAR},
4194  {2, UPB_SIZE(16, 32), 0, 0, 11, _UPB_MODE_ARRAY},
4195  {3, UPB_SIZE(12, 24), 2, 1, 11, _UPB_MODE_SCALAR},
4196 };
4197 
4201  UPB_SIZE(24, 48), 3, false, 3, 255,
4202 };
4203 
4206 };
4207 
4209  {1, UPB_SIZE(4, 8), 1, 0, 12, _UPB_MODE_SCALAR},
4210  {2, UPB_SIZE(12, 24), 2, 0, 12, _UPB_MODE_SCALAR},
4211  {3, UPB_SIZE(20, 40), 3, 0, 12, _UPB_MODE_SCALAR},
4212  {4, UPB_SIZE(28, 56), 4, 0, 11, _UPB_MODE_SCALAR},
4213  {5, UPB_SIZE(1, 1), 5, 0, 8, _UPB_MODE_SCALAR},
4214  {6, UPB_SIZE(2, 2), 6, 0, 8, _UPB_MODE_SCALAR},
4215 };
4216 
4220  UPB_SIZE(32, 64), 6, false, 6, 255,
4221 };
4222 
4225 };
4226 
4228  {1, UPB_SIZE(20, 24), 1, 0, 12, _UPB_MODE_SCALAR},
4229  {8, UPB_SIZE(28, 40), 2, 0, 12, _UPB_MODE_SCALAR},
4230  {9, UPB_SIZE(4, 4), 3, 0, 14, _UPB_MODE_SCALAR},
4231  {10, UPB_SIZE(8, 8), 4, 0, 8, _UPB_MODE_SCALAR},
4232  {11, UPB_SIZE(36, 56), 5, 0, 12, _UPB_MODE_SCALAR},
4233  {16, UPB_SIZE(9, 9), 6, 0, 8, _UPB_MODE_SCALAR},
4234  {17, UPB_SIZE(10, 10), 7, 0, 8, _UPB_MODE_SCALAR},
4235  {18, UPB_SIZE(11, 11), 8, 0, 8, _UPB_MODE_SCALAR},
4236  {20, UPB_SIZE(12, 12), 9, 0, 8, _UPB_MODE_SCALAR},
4237  {23, UPB_SIZE(13, 13), 10, 0, 8, _UPB_MODE_SCALAR},
4238  {27, UPB_SIZE(14, 14), 11, 0, 8, _UPB_MODE_SCALAR},
4239  {31, UPB_SIZE(15, 15), 12, 0, 8, _UPB_MODE_SCALAR},
4240  {36, UPB_SIZE(44, 72), 13, 0, 12, _UPB_MODE_SCALAR},
4241  {37, UPB_SIZE(52, 88), 14, 0, 12, _UPB_MODE_SCALAR},
4242  {39, UPB_SIZE(60, 104), 15, 0, 12, _UPB_MODE_SCALAR},
4243  {40, UPB_SIZE(68, 120), 16, 0, 12, _UPB_MODE_SCALAR},
4244  {41, UPB_SIZE(76, 136), 17, 0, 12, _UPB_MODE_SCALAR},
4245  {42, UPB_SIZE(16, 16), 18, 0, 8, _UPB_MODE_SCALAR},
4246  {44, UPB_SIZE(84, 152), 19, 0, 12, _UPB_MODE_SCALAR},
4247  {45, UPB_SIZE(92, 168), 20, 0, 12, _UPB_MODE_SCALAR},
4248  {999, UPB_SIZE(100, 184), 0, 0, 11, _UPB_MODE_ARRAY},
4249 };
4250 
4254  UPB_SIZE(104, 192), 21, false, 1, 255,
4255 };
4256 
4259 };
4260 
4262  {1, UPB_SIZE(1, 1), 1, 0, 8, _UPB_MODE_SCALAR},
4263  {2, UPB_SIZE(2, 2), 2, 0, 8, _UPB_MODE_SCALAR},
4264  {3, UPB_SIZE(3, 3), 3, 0, 8, _UPB_MODE_SCALAR},
4265  {7, UPB_SIZE(4, 4), 4, 0, 8, _UPB_MODE_SCALAR},
4266  {999, UPB_SIZE(8, 8), 0, 0, 11, _UPB_MODE_ARRAY},
4267 };
4268 
4272  UPB_SIZE(16, 16), 5, false, 3, 255,
4273 };
4274 
4277 };
4278 
4280  {1, UPB_SIZE(4, 4), 1, 0, 14, _UPB_MODE_SCALAR},
4281  {2, UPB_SIZE(12, 12), 2, 0, 8, _UPB_MODE_SCALAR},
4282  {3, UPB_SIZE(13, 13), 3, 0, 8, _UPB_MODE_SCALAR},
4283  {5, UPB_SIZE(14, 14), 4, 0, 8, _UPB_MODE_SCALAR},
4284  {6, UPB_SIZE(8, 8), 5, 0, 14, _UPB_MODE_SCALAR},
4285  {10, UPB_SIZE(15, 15), 6, 0, 8, _UPB_MODE_SCALAR},
4286  {999, UPB_SIZE(16, 16), 0, 0, 11, _UPB_MODE_ARRAY},
4287 };
4288 
4292  UPB_SIZE(24, 24), 7, false, 3, 255,
4293 };
4294 
4297 };
4298 
4300  {999, UPB_SIZE(0, 0), 0, 0, 11, _UPB_MODE_ARRAY},
4301 };
4302 
4306  UPB_SIZE(8, 8), 1, false, 0, 255,
4307 };
4308 
4311 };
4312 
4314  {2, UPB_SIZE(1, 1), 1, 0, 8, _UPB_MODE_SCALAR},
4315  {3, UPB_SIZE(2, 2), 2, 0, 8, _UPB_MODE_SCALAR},
4316  {999, UPB_SIZE(4, 8), 0, 0, 11, _UPB_MODE_ARRAY},
4317 };
4318 
4322  UPB_SIZE(8, 16), 3, false, 0, 255,
4323 };
4324 
4327 };
4328 
4330  {1, UPB_SIZE(1, 1), 1, 0, 8, _UPB_MODE_SCALAR},
4331  {999, UPB_SIZE(4, 8), 0, 0, 11, _UPB_MODE_ARRAY},
4332 };
4333 
4337  UPB_SIZE(8, 16), 2, false, 1, 255,
4338 };
4339 
4342 };
4343 
4345  {33, UPB_SIZE(1, 1), 1, 0, 8, _UPB_MODE_SCALAR},
4346  {999, UPB_SIZE(4, 8), 0, 0, 11, _UPB_MODE_ARRAY},
4347 };
4348 
4352  UPB_SIZE(8, 16), 2, false, 0, 255,
4353 };
4354 
4357 };
4358 
4360  {33, UPB_SIZE(8, 8), 1, 0, 8, _UPB_MODE_SCALAR},
4361  {34, UPB_SIZE(4, 4), 2, 0, 14, _UPB_MODE_SCALAR},
4362  {999, UPB_SIZE(12, 16), 0, 0, 11, _UPB_MODE_ARRAY},
4363 };
4364 
4368  UPB_SIZE(16, 24), 3, false, 0, 255,
4369 };
4370 
4373 };
4374 
4376  {2, UPB_SIZE(56, 80), 0, 0, 11, _UPB_MODE_ARRAY},
4377  {3, UPB_SIZE(32, 32), 1, 0, 12, _UPB_MODE_SCALAR},
4378  {4, UPB_SIZE(8, 8), 2, 0, 4, _UPB_MODE_SCALAR},
4379  {5, UPB_SIZE(16, 16), 3, 0, 3, _UPB_MODE_SCALAR},
4380  {6, UPB_SIZE(24, 24), 4, 0, 1, _UPB_MODE_SCALAR},
4381  {7, UPB_SIZE(40, 48), 5, 0, 12, _UPB_MODE_SCALAR},
4382  {8, UPB_SIZE(48, 64), 6, 0, 12, _UPB_MODE_SCALAR},
4383 };
4384 
4388  UPB_SIZE(64, 96), 7, false, 0, 255,
4389 };
4390 
4392  {1, UPB_SIZE(4, 8), 1, 0, 12, _UPB_MODE_SCALAR},
4393  {2, UPB_SIZE(1, 1), 2, 0, 8, _UPB_MODE_SCALAR},
4394 };
4395 
4397  NULL,
4399  UPB_SIZE(16, 32), 2, false, 2, 255,
4400 };
4401 
4404 };
4405 
4407  {1, UPB_SIZE(0, 0), 0, 0, 11, _UPB_MODE_ARRAY},
4408 };
4409 
4413  UPB_SIZE(8, 8), 1, false, 1, 255,
4414 };
4415 
4417  {1, UPB_SIZE(20, 40), 0, 0, 5, _UPB_MODE_ARRAY | _UPB_MODE_IS_PACKED},
4418  {2, UPB_SIZE(24, 48), 0, 0, 5, _UPB_MODE_ARRAY | _UPB_MODE_IS_PACKED},
4419  {3, UPB_SIZE(4, 8), 1, 0, 12, _UPB_MODE_SCALAR},
4420  {4, UPB_SIZE(12, 24), 2, 0, 12, _UPB_MODE_SCALAR},
4421  {6, UPB_SIZE(28, 56), 0, 0, 12, _UPB_MODE_ARRAY},
4422 };
4423 
4425  NULL,
4427  UPB_SIZE(32, 64), 5, false, 4, 255,
4428 };
4429 
4432 };
4433 
4435  {1, UPB_SIZE(0, 0), 0, 0, 11, _UPB_MODE_ARRAY},
4436 };
4437 
4441  UPB_SIZE(8, 8), 1, false, 1, 255,
4442 };
4443 
4445  {1, UPB_SIZE(20, 32), 0, 0, 5, _UPB_MODE_ARRAY | _UPB_MODE_IS_PACKED},
4446  {2, UPB_SIZE(12, 16), 1, 0, 12, _UPB_MODE_SCALAR},
4447  {3, UPB_SIZE(4, 4), 2, 0, 5, _UPB_MODE_SCALAR},
4448  {4, UPB_SIZE(8, 8), 3, 0, 5, _UPB_MODE_SCALAR},
4449 };
4450 
4452  NULL,
4454  UPB_SIZE(24, 48), 4, false, 4, 255,
4455 };
4456 
4457 
4458 
4461 #include <ctype.h>
4462 #include <errno.h>
4463 #include <setjmp.h>
4464 #include <stdlib.h>
4465 #include <string.h>
4466 
4467 
4468 /* Must be last. */
4469 
4470 typedef struct {
4471  size_t len;
4472  char str[1]; /* Null-terminated string data follows. */
4473 } str_t;
4474 
4475 struct upb_fielddef {
4476  const upb_filedef *file;
4477  const upb_msgdef *msgdef;
4478  const char *full_name;
4479  const char *json_name;
4480  union {
4481  int64_t sint;
4482  uint64_t uint;
4483  double dbl;
4484  float flt;
4485  bool boolean;
4486  str_t *str;
4487  } defaultval;
4488  const upb_oneofdef *oneof;
4489  union {
4490  const upb_msgdef *msgdef;
4491  const upb_enumdef *enumdef;
4493  } sub;
4494  uint32_t number_;
4495  uint16_t index_;
4497  bool is_extension_;
4498  bool lazy_;
4499  bool packed_;
4500  bool proto3_optional_;
4503 };
4504 
4505 struct upb_msgdef {
4506  const upb_msglayout *layout;
4507  const upb_filedef *file;
4508  const char *full_name;
4509 
4510  /* Tables for looking up fields by number and name. */
4513 
4514  const upb_fielddef *fields;
4515  const upb_oneofdef *oneofs;
4516  int field_count;
4517  int oneof_count;
4518  int real_oneof_count;
4519 
4520  /* Is this a map-entry message? */
4521  bool map_entry;
4523 
4524  /* TODO(haberman): proper extension ranges (there can be multiple). */
4525 };
4526 
4527 struct upb_enumdef {
4528  const upb_filedef *file;
4529  const char *full_name;
4533 };
4534 
4535 struct upb_oneofdef {
4536  const upb_msgdef *parent;
4537  const char *full_name;
4538  int field_count;
4539  bool synthetic;
4540  const upb_fielddef **fields;
4543 };
4544 
4545 struct upb_filedef {
4546  const char *name;
4547  const char *package;
4548  const char *phpprefix;
4549  const char *phpnamespace;
4550 
4551  const upb_filedef **deps;
4552  const upb_msgdef *msgs;
4553  const upb_enumdef *enums;
4554  const upb_fielddef *exts;
4555  const upb_symtab *symtab;
4556 
4557  int dep_count;
4558  int msg_count;
4559  int enum_count;
4560  int ext_count;
4562 };
4563 
4564 struct upb_symtab {
4565  upb_arena *arena;
4566  upb_strtable syms; /* full_name -> packed def ptr */
4567  upb_strtable files; /* file_name -> upb_filedef* */
4568  size_t bytes_loaded;
4569 };
4570 
4571 /* Inside a symtab we store tagged pointers to specific def types. */
4572 typedef enum {
4574 
4575  /* Only inside symtab table. */
4578 
4579  /* Only inside message table. */
4582 } upb_deftype_t;
4583 
4584 static const void *unpack_def(upb_value v, upb_deftype_t type) {
4585  uintptr_t num = (uintptr_t)upb_value_getconstptr(v);
4586  return (num & 3) == type ? (const void*)(num & ~3) : NULL;
4587 }
4588 
4589 static upb_value pack_def(const void *ptr, upb_deftype_t type) {
4591  return upb_value_constptr((const void*)num);
4592 }
4593 
4594 /* isalpha() etc. from <ctype.h> are locale-dependent, which we don't want. */
4595 static bool upb_isbetween(char c, char low, char high) {
4596  return c >= low && c <= high;
4597 }
4598 
4599 static bool upb_isletter(char c) {
4600  return upb_isbetween(c, 'A', 'Z') || upb_isbetween(c, 'a', 'z') || c == '_';
4601 }
4602 
4603 static bool upb_isalphanum(char c) {
4604  return upb_isletter(c) || upb_isbetween(c, '0', '9');
4605 }
4606 
4607 static const char *shortdefname(const char *fullname) {
4608  const char *p;
4609 
4610  if (fullname == NULL) {
4611  return NULL;
4612  } else if ((p = strrchr(fullname, '.')) == NULL) {
4613  /* No '.' in the name, return the full string. */
4614  return fullname;
4615  } else {
4616  /* Return one past the last '.'. */
4617  return p + 1;
4618  }
4619 }
4620 
4621 /* All submessage fields are lower than all other fields.
4622  * Secondly, fields are increasing in order. */
4625  const uint32_t high_bit = 1 << 30;
4626  UPB_ASSERT(ret < high_bit);
4627  if (!upb_fielddef_issubmsg(f))
4628  ret |= high_bit;
4629  return ret;
4630 }
4631 
4632 int cmp_fields(const void *p1, const void *p2) {
4633  const upb_fielddef *f1 = *(upb_fielddef*const*)p1;
4634  const upb_fielddef *f2 = *(upb_fielddef*const*)p2;
4635  return field_rank(f1) - field_rank(f2);
4636 }
4637 
4639  upb_status_seterrmsg(status, "out of memory");
4640 }
4641 
4643  const char *name = upb_msgdef_fullname(m);
4644  if (name == NULL) {
4645  m->well_known_type = UPB_WELLKNOWN_UNSPECIFIED;
4646  return;
4647  }
4648  if (!strcmp(name, "google.protobuf.Any")) {
4649  m->well_known_type = UPB_WELLKNOWN_ANY;
4650  } else if (!strcmp(name, "google.protobuf.FieldMask")) {
4651  m->well_known_type = UPB_WELLKNOWN_FIELDMASK;
4652  } else if (!strcmp(name, "google.protobuf.Duration")) {
4653  m->well_known_type = UPB_WELLKNOWN_DURATION;
4654  } else if (!strcmp(name, "google.protobuf.Timestamp")) {
4655  m->well_known_type = UPB_WELLKNOWN_TIMESTAMP;
4656  } else if (!strcmp(name, "google.protobuf.DoubleValue")) {
4657  m->well_known_type = UPB_WELLKNOWN_DOUBLEVALUE;
4658  } else if (!strcmp(name, "google.protobuf.FloatValue")) {
4659  m->well_known_type = UPB_WELLKNOWN_FLOATVALUE;
4660  } else if (!strcmp(name, "google.protobuf.Int64Value")) {
4661  m->well_known_type = UPB_WELLKNOWN_INT64VALUE;
4662  } else if (!strcmp(name, "google.protobuf.UInt64Value")) {
4663  m->well_known_type = UPB_WELLKNOWN_UINT64VALUE;
4664  } else if (!strcmp(name, "google.protobuf.Int32Value")) {
4665  m->well_known_type = UPB_WELLKNOWN_INT32VALUE;
4666  } else if (!strcmp(name, "google.protobuf.UInt32Value")) {
4667  m->well_known_type = UPB_WELLKNOWN_UINT32VALUE;
4668  } else if (!strcmp(name, "google.protobuf.BoolValue")) {
4669  m->well_known_type = UPB_WELLKNOWN_BOOLVALUE;
4670  } else if (!strcmp(name, "google.protobuf.StringValue")) {
4671  m->well_known_type = UPB_WELLKNOWN_STRINGVALUE;
4672  } else if (!strcmp(name, "google.protobuf.BytesValue")) {
4673  m->well_known_type = UPB_WELLKNOWN_BYTESVALUE;
4674  } else if (!strcmp(name, "google.protobuf.Value")) {
4675  m->well_known_type = UPB_WELLKNOWN_VALUE;
4676  } else if (!strcmp(name, "google.protobuf.ListValue")) {
4677  m->well_known_type = UPB_WELLKNOWN_LISTVALUE;
4678  } else if (!strcmp(name, "google.protobuf.Struct")) {
4679  m->well_known_type = UPB_WELLKNOWN_STRUCT;
4680  } else {
4681  m->well_known_type = UPB_WELLKNOWN_UNSPECIFIED;
4682  }
4683 }
4684 
4685 
4686 /* upb_enumdef ****************************************************************/
4687 
4688 const char *upb_enumdef_fullname(const upb_enumdef *e) {
4689  return e->full_name;
4690 }
4691 
4692 const char *upb_enumdef_name(const upb_enumdef *e) {
4693  return shortdefname(e->full_name);
4694 }
4695 
4697  return e->file;
4698 }
4699 
4701  UPB_ASSERT(upb_enumdef_iton(e, e->defaultval));
4702  return e->defaultval;
4703 }
4704 
4706  return (int)upb_strtable_count(&e->ntoi);
4707 }
4708 
4710  /* We iterate over the ntoi table, to account for duplicate numbers. */
4711  upb_strtable_begin(i, &e->ntoi);
4712 }
4713 
4716 
4717 bool upb_enumdef_ntoi(const upb_enumdef *def, const char *name,
4718  size_t len, int32_t *num) {
4719  upb_value v;
4720  if (!upb_strtable_lookup2(&def->ntoi, name, len, &v)) {
4721  return false;
4722  }
4723  if (num) *num = upb_value_getint32(v);
4724  return true;
4725 }
4726 
4728  upb_value v;
4729  return upb_inttable_lookup(&def->iton, num, &v) ? upb_value_getcstr(v) : NULL;
4730 }
4731 
4734 }
4735 
4737  return upb_value_getint32(upb_strtable_iter_value(iter));
4738 }
4739 
4740 
4741 /* upb_fielddef ***************************************************************/
4742 
4743 const char *upb_fielddef_fullname(const upb_fielddef *f) {
4744  return f->full_name;
4745 }
4746 
4748  switch (f->type_) {
4750  return UPB_TYPE_DOUBLE;
4752  return UPB_TYPE_FLOAT;
4756  return UPB_TYPE_INT64;
4760  return UPB_TYPE_INT32;
4763  return UPB_TYPE_UINT64;
4766  return UPB_TYPE_UINT32;
4768  return UPB_TYPE_ENUM;
4770  return UPB_TYPE_BOOL;
4772  return UPB_TYPE_STRING;
4774  return UPB_TYPE_BYTES;
4777  return UPB_TYPE_MESSAGE;
4778  }
4779  UPB_UNREACHABLE();
4780 }
4781 
4783  return f->type_;
4784 }
4785 
4787  return f->index_;
4788 }
4789 
4791  return f->label_;
4792 }
4793 
4795  return f->number_;
4796 }
4797 
4799  return f->is_extension_;
4800 }
4801 
4803  return f->lazy_;
4804 }
4805 
4807  return f->packed_;
4808 }
4809 
4810 const char *upb_fielddef_name(const upb_fielddef *f) {
4811  return shortdefname(f->full_name);
4812 }
4813 
4814 const char *upb_fielddef_jsonname(const upb_fielddef *f) {
4815  return f->json_name;
4816 }
4817 
4819  return f->file;
4820 }
4821 
4823  return f->msgdef;
4824 }
4825 
4827  return f->oneof;
4828 }
4829 
4831  if (!f->oneof || upb_oneofdef_issynthetic(f->oneof)) return NULL;
4832  return f->oneof;
4833 }
4834 
4837  upb_msgval ret;
4838  if (upb_fielddef_isstring(f)) {
4839  str_t *str = f->defaultval.str;
4840  if (str) {
4841  ret.str_val.data = str->str;
4842  ret.str_val.size = str->len;
4843  } else {
4844  ret.str_val.size = 0;
4845  }
4846  } else {
4847  memcpy(&ret, &f->defaultval, 8);
4848  }
4849  return ret;
4850 }
4851 
4852 static void chkdefaulttype(const upb_fielddef *f, int ctype) {
4853  UPB_UNUSED(f);
4854  UPB_UNUSED(ctype);
4855 }
4856 
4859  return f->defaultval.sint;
4860 }
4861 
4864  return (int32_t)f->defaultval.sint;
4865 }
4866 
4869  return f->defaultval.uint;
4870 }
4871 
4874  return (uint32_t)f->defaultval.uint;
4875 }
4876 
4879  return f->defaultval.boolean;
4880 }
4881 
4884  return f->defaultval.flt;
4885 }
4886 
4889  return f->defaultval.dbl;
4890 }
4891 
4892 const char *upb_fielddef_defaultstr(const upb_fielddef *f, size_t *len) {
4893  str_t *str = f->defaultval.str;
4897  if (str) {
4898  if (len) *len = str->len;
4899  return str->str;
4900  } else {
4901  if (len) *len = 0;
4902  return NULL;
4903  }
4904 }
4905 
4907  return upb_fielddef_type(f) == UPB_TYPE_MESSAGE ? f->sub.msgdef : NULL;
4908 }
4909 
4911  return upb_fielddef_type(f) == UPB_TYPE_ENUM ? f->sub.enumdef : NULL;
4912 }
4913 
4915  return &f->msgdef->layout->fields[f->layout_index];
4916 }
4917 
4920 }
4921 
4923  return upb_fielddef_type(f) == UPB_TYPE_STRING ||
4925 }
4926 
4929 }
4930 
4933 }
4934 
4938 }
4939 
4942 }
4943 
4945  if (upb_fielddef_isseq(f)) return false;
4947  f->file->syntax == UPB_SYNTAX_PROTO2;
4948 }
4949 
4950 static bool between(int32_t x, int32_t low, int32_t high) {
4951  return x >= low && x <= high;
4952 }
4953 
4957 
4959  return between(type, 1, 18);
4960 }
4961 
4962 /* upb_msgdef *****************************************************************/
4963 
4964 const char *upb_msgdef_fullname(const upb_msgdef *m) {
4965  return m->full_name;
4966 }
4967 
4969  return m->file;
4970 }
4971 
4972 const char *upb_msgdef_name(const upb_msgdef *m) {
4973  return shortdefname(m->full_name);
4974 }
4975 
4977  return m->file->syntax;
4978 }
4979 
4981  upb_value val;
4982  return upb_inttable_lookup(&m->itof, i, &val) ? upb_value_getconstptr(val)
4983  : NULL;
4984 }
4985 
4986 const upb_fielddef *upb_msgdef_ntof(const upb_msgdef *m, const char *name,
4987  size_t len) {
4988  upb_value val;
4989 
4990  if (!upb_strtable_lookup2(&m->ntof, name, len, &val)) {
4991  return NULL;
4992  }
4993 
4994  return unpack_def(val, UPB_DEFTYPE_FIELD);
4995 }
4996 
4997 const upb_oneofdef *upb_msgdef_ntoo(const upb_msgdef *m, const char *name,
4998  size_t len) {
4999  upb_value val;
5000 
5001  if (!upb_strtable_lookup2(&m->ntof, name, len, &val)) {
5002  return NULL;
5003  }
5004 
5005  return unpack_def(val, UPB_DEFTYPE_ONEOF);
5006 }
5007 
5008 bool upb_msgdef_lookupname(const upb_msgdef *m, const char *name, size_t len,
5009  const upb_fielddef **f, const upb_oneofdef **o) {
5010  upb_value val;
5011 
5012  if (!upb_strtable_lookup2(&m->ntof, name, len, &val)) {
5013  return false;
5014  }
5015 
5016  *o = unpack_def(val, UPB_DEFTYPE_ONEOF);
5017  *f = unpack_def(val, UPB_DEFTYPE_FIELD);
5018  return *o || *f; /* False if this was a JSON name. */
5019 }
5020 
5022  const char *name, size_t len) {
5023  upb_value val;
5024  const upb_fielddef* f;
5025 
5026  if (!upb_strtable_lookup2(&m->ntof, name, len, &val)) {
5027  return NULL;
5028  }
5029 
5030  f = unpack_def(val, UPB_DEFTYPE_FIELD);
5031  if (!f) f = unpack_def(val, UPB_DEFTYPE_FIELD_JSONNAME);
5032 
5033  return f;
5034 }
5035 
5037  return m->field_count;
5038 }
5039 
5041  return m->oneof_count;
5042 }
5043 
5045  return m->real_oneof_count;
5046 }
5047 
5049  return m->field_count;
5050 }
5051 
5053  return m->oneof_count;
5054 }
5055 
5057  return m->real_oneof_count;
5058 }
5059 
5061  return m->layout;
5062 }
5063 
5065  UPB_ASSERT(i >= 0 && i < m->field_count);
5066  return &m->fields[i];
5067 }
5068 
5070  UPB_ASSERT(i >= 0 && i < m->oneof_count);
5071  return &m->oneofs[i];
5072 }
5073 
5075  return m->map_entry;
5076 }
5077 
5079  return m->well_known_type;
5080 }
5081 
5084  return type >= UPB_WELLKNOWN_DOUBLEVALUE &&
5086 }
5087 
5090  return type >= UPB_WELLKNOWN_DOUBLEVALUE &&
5092 }
5093 
5095  upb_inttable_begin(iter, &m->itof);
5096 }
5097 
5099 
5101  return upb_inttable_done(iter);
5102 }
5103 
5105  return (upb_fielddef *)upb_value_getconstptr(upb_inttable_iter_value(iter));
5106 }
5107 
5110 }
5111 
5113  const upb_msg_field_iter * iter2) {
5114  return upb_inttable_iter_isequal(iter1, iter2);
5115 }
5116 
5118  upb_strtable_begin(iter, &m->ntof);
5119  /* We need to skip past any initial fields. */
5120  while (!upb_strtable_done(iter) &&
5123  }
5124 }
5125 
5127  /* We need to skip past fields to return only oneofs. */
5128  do {
5130  } while (!upb_strtable_done(iter) &&
5132 }
5133 
5135  return upb_strtable_done(iter);
5136 }
5137 
5140 }
5141 
5144 }
5145 
5147  const upb_msg_oneof_iter *iter2) {
5148  return upb_strtable_iter_isequal(iter1, iter2);
5149 }
5150 
5151 /* upb_oneofdef ***************************************************************/
5152 
5153 const char *upb_oneofdef_name(const upb_oneofdef *o) {
5154  return shortdefname(o->full_name);
5155 }
5156 
5158  return o->parent;
5159 }
5160 
5162  return o->field_count;
5163 }
5164 
5166  UPB_ASSERT(i < o->field_count);
5167  return o->fields[i];
5168 }
5169 
5171  return o->field_count;
5172 }
5173 
5175  return o - o->parent->oneofs;
5176 }
5177 
5179  return o->synthetic;
5180 }
5181 
5183  const char *name, size_t length) {
5184  upb_value val;
5185  return upb_strtable_lookup2(&o->ntof, name, length, &val) ?
5186  upb_value_getptr(val) : NULL;
5187 }
5188 
5190  upb_value val;
5191  return upb_inttable_lookup(&o->itof, num, &val) ? upb_value_getptr(val)
5192  : NULL;
5193 }
5194 
5196  upb_inttable_begin(iter, &o->itof);
5197 }
5198 
5201 }
5202 
5204  return upb_inttable_done(iter);
5205 }
5206 
5208  return (upb_fielddef *)upb_value_getconstptr(upb_inttable_iter_value(iter));
5209 }
5210 
5213 }
5214 
5215 /* upb_filedef ****************************************************************/
5216 
5217 const char *upb_filedef_name(const upb_filedef *f) {
5218  return f->name;
5219 }
5220 
5221 const char *upb_filedef_package(const upb_filedef *f) {
5222  return f->package;
5223 }
5224 
5225 const char *upb_filedef_phpprefix(const upb_filedef *f) {
5226  return f->phpprefix;
5227 }
5228 
5230  return f->phpnamespace;
5231 }
5232 
5234  return f->syntax;
5235 }
5236 
5238  return f->msg_count;
5239 }
5240 
5242  return f->dep_count;
5243 }
5244 
5246  return f->enum_count;
5247 }
5248 
5250  return i < 0 || i >= f->dep_count ? NULL : f->deps[i];
5251 }
5252 
5254  return i < 0 || i >= f->msg_count ? NULL : &f->msgs[i];
5255 }
5256 
5258  return i < 0 || i >= f->enum_count ? NULL : &f->enums[i];
5259 }
5260 
5262  return f->symtab;
5263 }
5264 
5266  upb_arena_free(s->arena);
5267  upb_gfree(s);
5268 }
5269 
5271  upb_symtab *s = upb_gmalloc(sizeof(*s));
5272 
5273  if (!s) {
5274  return NULL;
5275  }
5276 
5277  s->arena = upb_arena_new();
5278  s->bytes_loaded = 0;
5279 
5280  if (!upb_strtable_init(&s->syms, 32, s->arena) ||
5281  !upb_strtable_init(&s->files, 4, s->arena)) {
5282  upb_arena_free(s->arena);
5283  upb_gfree(s);
5284  s = NULL;
5285  }
5286  return s;
5287 }
5288 
5289 const upb_msgdef *upb_symtab_lookupmsg(const upb_symtab *s, const char *sym) {
5290  upb_value v;
5291  return upb_strtable_lookup(&s->syms, sym, &v) ?
5292  unpack_def(v, UPB_DEFTYPE_MSG) : NULL;
5293 }
5294 
5295 const upb_msgdef *upb_symtab_lookupmsg2(const upb_symtab *s, const char *sym,
5296  size_t len) {
5297  upb_value v;
5298  return upb_strtable_lookup2(&s->syms, sym, len, &v) ?
5299  unpack_def(v, UPB_DEFTYPE_MSG) : NULL;
5300 }
5301 
5302 const upb_enumdef *upb_symtab_lookupenum(const upb_symtab *s, const char *sym) {
5303  upb_value v;
5304  return upb_strtable_lookup(&s->syms, sym, &v) ?
5305  unpack_def(v, UPB_DEFTYPE_ENUM) : NULL;
5306 }
5307 
5308 const upb_filedef *upb_symtab_lookupfile(const upb_symtab *s, const char *name) {
5309  upb_value v;
5310  return upb_strtable_lookup(&s->files, name, &v) ? upb_value_getconstptr(v)
5311  : NULL;
5312 }
5313 
5315  const upb_symtab *s, const char *name, size_t len) {
5316  upb_value v;
5317  return upb_strtable_lookup2(&s->files, name, len, &v) ?
5318  upb_value_getconstptr(v) : NULL;
5319 }
5320 
5322  return (int)upb_strtable_count(&s->files);
5323 }
5324 
5325 /* Code to build defs from descriptor protos. *********************************/
5326 
5327 /* There is a question of how much validation to do here. It will be difficult
5328  * to perfectly match the amount of validation performed by proto2. But since
5329  * this code is used to directly build defs from Ruby (for example) we do need
5330  * to validate important constraints like uniqueness of names and numbers. */
5331 
5332 #define CHK_OOM(x) if (!(x)) { symtab_oomerr(ctx); }
5333 
5334 typedef struct {
5335  upb_symtab *symtab;
5336  upb_filedef *file; /* File we are building. */
5337  upb_arena *arena; /* Allocate defs here. */
5338  const upb_msglayout **layouts; /* NULL if we should build layouts. */
5339  upb_status *status; /* Record errors here. */
5340  jmp_buf err; /* longjmp() on error. */
5341 } symtab_addctx;
5342 
5344 static void symtab_errf(symtab_addctx *ctx, const char *fmt, ...) {
5345  va_list argp;
5346  va_start(argp, fmt);
5347  upb_status_vseterrf(ctx->status, fmt, argp);
5348  va_end(argp);
5349  UPB_LONGJMP(ctx->err, 1);
5350 }
5351 
5354  upb_status_setoom(ctx->status);
5355  UPB_LONGJMP(ctx->err, 1);
5356 }
5357 
5359  void *ret = upb_arena_malloc(ctx->arena, bytes);
5360  if (!ret) symtab_oomerr(ctx);
5361  return ret;
5362 }
5363 
5364 static void check_ident(symtab_addctx *ctx, upb_strview name, bool full) {
5365  const char *str = name.data;
5366  size_t len = name.size;
5367  bool start = true;
5368  size_t i;
5369  for (i = 0; i < len; i++) {
5370  char c = str[i];
5371  if (c == '.') {
5372  if (start || !full) {
5373  symtab_errf(ctx, "invalid name: unexpected '.' (%.*s)", (int)len, str);
5374  }
5375  start = true;
5376  } else if (start) {
5377  if (!upb_isletter(c)) {
5378  symtab_errf(
5379  ctx,
5380  "invalid name: path components must start with a letter (%.*s)",
5381  (int)len, str);
5382  }
5383  start = false;
5384  } else {
5385  if (!upb_isalphanum(c)) {
5386  symtab_errf(ctx, "invalid name: non-alphanumeric character (%.*s)",
5387  (int)len, str);
5388  }
5389  }
5390  }
5391  if (start) {
5392  symtab_errf(ctx, "invalid name: empty part (%.*s)", (int)len, str);
5393  }
5394 }
5395 
5396 static size_t div_round_up(size_t n, size_t d) {
5397  return (n + d - 1) / d;
5398 }
5399 
5401  switch (type) {
5402  case UPB_TYPE_DOUBLE:
5403  case UPB_TYPE_INT64:
5404  case UPB_TYPE_UINT64:
5405  return 8;
5406  case UPB_TYPE_ENUM:
5407  case UPB_TYPE_INT32:
5408  case UPB_TYPE_UINT32:
5409  case UPB_TYPE_FLOAT:
5410  return 4;
5411  case UPB_TYPE_BOOL:
5412  return 1;
5413  case UPB_TYPE_MESSAGE:
5414  return sizeof(void*);
5415  case UPB_TYPE_BYTES:
5416  case UPB_TYPE_STRING:
5417  return sizeof(upb_strview);
5418  }
5419  UPB_UNREACHABLE();
5420 }
5421 
5424  upb_map_entry ent;
5425  UPB_ASSERT(sizeof(ent.k) == sizeof(ent.v));
5426  return sizeof(ent.k);
5427  } else if (upb_fielddef_isseq(f)) {
5428  return sizeof(void*);
5429  } else {
5431  }
5432 }
5433 
5435  uint32_t ret;
5436 
5437  l->size = UPB_ALIGN_UP(l->size, size);
5438  ret = l->size;
5439  l->size += size;
5440  return ret;
5441 }
5442 
5443 static int field_number_cmp(const void *p1, const void *p2) {
5444  const upb_msglayout_field *f1 = p1;
5445  const upb_msglayout_field *f2 = p2;
5446  return f1->number - f2->number;
5447 }
5448 
5451  int i;
5452  int n = upb_msgdef_numfields(m);
5453  int dense_below = 0;
5454  for (i = 0; i < n; i++) {
5456  UPB_ASSERT(f);
5457  f->layout_index = i;
5458  if (i < UINT8_MAX && fields[i].number == i + 1 &&
5459  (i == 0 || fields[i-1].number == i)) {
5460  dense_below = i + 1;
5461  }
5462  }
5463  l->dense_below = dense_below;
5464 }
5465 
5467  field->number = upb_fielddef_number(f);
5468  field->descriptortype = upb_fielddef_descriptortype(f);
5469 
5470  if (field->descriptortype == UPB_DTYPE_STRING &&
5471  f->file->syntax == UPB_SYNTAX_PROTO2) {
5472  /* See TableDescriptorType() in upbc/generator.cc for details and
5473  * rationale. */
5474  field->descriptortype = UPB_DTYPE_BYTES;
5475  }
5476 
5477  if (upb_fielddef_ismap(f)) {
5478  field->mode = _UPB_MODE_MAP;
5479  } else if (upb_fielddef_isseq(f)) {
5480  field->mode = _UPB_MODE_ARRAY;
5481  } else {
5482  field->mode = _UPB_MODE_SCALAR;
5483  }
5484 
5485  if (upb_fielddef_packed(f)) {
5486  field->mode |= _UPB_MODE_IS_PACKED;
5487  }
5488 }
5489 
5490 /* This function is the dynamic equivalent of message_layout.{cc,h} in upbc.
5491  * It computes a dynamic layout for all of the fields in |m|. */
5492 static void make_layout(symtab_addctx *ctx, const upb_msgdef *m) {
5493  upb_msglayout *l = (upb_msglayout*)m->layout;
5495  upb_msg_oneof_iter oit;
5496  size_t hasbit;
5497  size_t field_count = upb_msgdef_numfields(m);
5498  size_t submsg_count = 0;
5499  const upb_msglayout **submsgs;
5501 
5502  memset(l, 0, sizeof(*l) + sizeof(_upb_fasttable_entry));
5503 
5504  /* Count sub-messages. */
5505  for (size_t i = 0; i < field_count; i++) {
5506  if (upb_fielddef_issubmsg(&m->fields[i])) {
5507  submsg_count++;
5508  }
5509  }
5510 
5511  fields = symtab_alloc(ctx, field_count * sizeof(*fields));
5512  submsgs = symtab_alloc(ctx, submsg_count * sizeof(*submsgs));
5513 
5514  l->field_count = upb_msgdef_numfields(m);
5515  l->fields = fields;
5516  l->submsgs = submsgs;
5517  l->table_mask = 0;
5518 
5519  /* TODO(haberman): initialize fast tables so that reflection-based parsing
5520  * can get the same speeds as linked-in types. */
5521  l->fasttable[0].field_parser = &fastdecode_generic;
5522  l->fasttable[0].field_data = 0;
5523 
5524  if (upb_msgdef_mapentry(m)) {
5525  /* TODO(haberman): refactor this method so this special case is more
5526  * elegant. */
5527  const upb_fielddef *key = upb_msgdef_itof(m, 1);
5528  const upb_fielddef *val = upb_msgdef_itof(m, 2);
5529  fields[0].number = 1;
5530  fields[1].number = 2;
5531  fields[0].mode = _UPB_MODE_SCALAR;
5532  fields[1].mode = _UPB_MODE_SCALAR;
5533  fields[0].presence = 0;
5534  fields[1].presence = 0;
5535  fields[0].descriptortype = upb_fielddef_descriptortype(key);
5536  fields[1].descriptortype = upb_fielddef_descriptortype(val);
5537  fields[0].offset = 0;
5538  fields[1].offset = sizeof(upb_strview);
5539  fields[1].submsg_index = 0;
5540 
5541  if (upb_fielddef_type(val) == UPB_TYPE_MESSAGE) {
5542  submsgs[0] = upb_fielddef_msgsubdef(val)->layout;
5543  }
5544 
5545  l->field_count = 2;
5546  l->size = 2 * sizeof(upb_strview);
5547  l->size = UPB_ALIGN_UP(l->size, 8);
5548  return;
5549  }
5550 
5551  /* Allocate data offsets in three stages:
5552  *
5553  * 1. hasbits.
5554  * 2. regular fields.
5555  * 3. oneof fields.
5556  *
5557  * OPT: There is a lot of room for optimization here to minimize the size.
5558  */
5559 
5560  /* Allocate hasbits and set basic field attributes. */
5561  submsg_count = 0;
5562  for (upb_msg_field_begin(&it, m), hasbit = 0;
5564  upb_msg_field_next(&it)) {
5567 
5569 
5570  if (upb_fielddef_issubmsg(f)) {
5571  const upb_msgdef *subm = upb_fielddef_msgsubdef(f);
5572  field->submsg_index = submsg_count++;
5573  submsgs[field->submsg_index] = subm->layout;
5574  }
5575 
5577  /* We don't use hasbit 0, so that 0 can indicate "no presence" in the
5578  * table. This wastes one hasbit, but we don't worry about it for now. */
5579  field->presence = ++hasbit;
5580  } else {
5581  field->presence = 0;
5582  }
5583  }
5584 
5585  /* Account for space used by hasbits. */
5586  l->size = div_round_up(hasbit + 1, 8);
5587 
5588  /* Allocate non-oneof fields. */
5590  upb_msg_field_next(&it)) {
5591  const upb_fielddef* f = upb_msg_iter_field(&it);
5592  size_t field_size = upb_msg_fielddefsize(f);
5593  size_t index = upb_fielddef_index(f);
5594 
5596  /* Oneofs are handled separately below. */
5597  continue;
5598  }
5599 
5600  fields[index].offset = upb_msglayout_place(l, field_size);
5601  }
5602 
5603  /* Allocate oneof fields. Each oneof field consists of a uint32 for the case
5604  * and space for the actual data. */
5605  for (upb_msg_oneof_begin(&oit, m); !upb_msg_oneof_done(&oit);
5606  upb_msg_oneof_next(&oit)) {
5607  const upb_oneofdef* o = upb_msg_iter_oneof(&oit);
5608  upb_oneof_iter fit;
5609 
5610  size_t case_size = sizeof(uint32_t); /* Could potentially optimize this. */
5611  size_t field_size = 0;
5612  uint32_t case_offset;
5613  uint32_t data_offset;
5614 
5615  if (upb_oneofdef_issynthetic(o)) continue;
5616 
5617  /* Calculate field size: the max of all field sizes. */
5618  for (upb_oneof_begin(&fit, o);
5619  !upb_oneof_done(&fit);
5620  upb_oneof_next(&fit)) {
5621  const upb_fielddef* f = upb_oneof_iter_field(&fit);
5622  field_size = UPB_MAX(field_size, upb_msg_fielddefsize(f));
5623  }
5624 
5625  /* Align and allocate case offset. */
5626  case_offset = upb_msglayout_place(l, case_size);
5627  data_offset = upb_msglayout_place(l, field_size);
5628 
5629  for (upb_oneof_begin(&fit, o);
5630  !upb_oneof_done(&fit);
5631  upb_oneof_next(&fit)) {
5632  const upb_fielddef* f = upb_oneof_iter_field(&fit);
5633  fields[upb_fielddef_index(f)].offset = data_offset;
5634  fields[upb_fielddef_index(f)].presence = ~case_offset;
5635  }
5636  }
5637 
5638  /* Size of the entire structure should be a multiple of its greatest
5639  * alignment. TODO: track overall alignment for real? */
5640  l->size = UPB_ALIGN_UP(l->size, 8);
5641 
5642  /* Sort fields by number. */
5645 }
5646 
5647 static char *strviewdup(symtab_addctx *ctx, upb_strview view) {
5648  return upb_strdup2(view.data, view.size, ctx->arena);
5649 }
5650 
5651 static bool streql2(const char *a, size_t n, const char *b) {
5652  return n == strlen(b) && memcmp(a, b, n) == 0;
5653 }
5654 
5655 static bool streql_view(upb_strview view, const char *b) {
5656  return streql2(view.data, view.size, b);
5657 }
5658 
5659 static const char *makefullname(symtab_addctx *ctx, const char *prefix,
5660  upb_strview name) {
5661  if (prefix) {
5662  /* ret = prefix + '.' + name; */
5663  size_t n = strlen(prefix);
5664  char *ret = symtab_alloc(ctx, n + name.size + 2);
5665  strcpy(ret, prefix);
5666  ret[n] = '.';
5667  memcpy(&ret[n + 1], name.data, name.size);
5668  ret[n + 1 + name.size] = '\0';
5669  return ret;
5670  } else {
5671  return strviewdup(ctx, name);
5672  }
5673 }
5674 
5676  int i;
5677  int synthetic_count = 0;
5678  upb_oneofdef *mutable_oneofs = (upb_oneofdef*)m->oneofs;
5679 
5680  for (i = 0; i < m->oneof_count; i++) {
5681  upb_oneofdef *o = &mutable_oneofs[i];
5682 
5683  if (o->synthetic && o->field_count != 1) {
5684  symtab_errf(ctx, "Synthetic oneofs must have one field, not %d: %s",
5685  o->field_count, upb_oneofdef_name(o));
5686  }
5687 
5688  if (o->synthetic) {
5689  synthetic_count++;
5690  } else if (synthetic_count != 0) {
5691  symtab_errf(ctx, "Synthetic oneofs must be after all other oneofs: %s",
5692  upb_oneofdef_name(o));
5693  }
5694 
5695  o->fields = symtab_alloc(ctx, sizeof(upb_fielddef *) * o->field_count);
5696  o->field_count = 0;
5697  }
5698 
5699  for (i = 0; i < m->field_count; i++) {
5700  const upb_fielddef *f = &m->fields[i];
5701  upb_oneofdef *o = (upb_oneofdef*)f->oneof;
5702  if (o) {
5703  o->fields[o->field_count++] = f;
5704  }
5705  }
5706 
5707  m->real_oneof_count = m->oneof_count - synthetic_count;
5708 }
5709 
5710 size_t getjsonname(const char *name, char *buf, size_t len) {
5711  size_t src, dst = 0;
5712  bool ucase_next = false;
5713 
5714 #define WRITE(byte) \
5715  ++dst; \
5716  if (dst < len) buf[dst - 1] = byte; \
5717  else if (dst == len) buf[dst - 1] = '\0'
5718 
5719  if (!name) {
5720  WRITE('\0');
5721  return 0;
5722  }
5723 
5724  /* Implement the transformation as described in the spec:
5725  * 1. upper case all letters after an underscore.
5726  * 2. remove all underscores.
5727  */
5728  for (src = 0; name[src]; src++) {
5729  if (name[src] == '_') {
5730  ucase_next = true;
5731  continue;
5732  }
5733 
5734  if (ucase_next) {
5735  WRITE(toupper(name[src]));
5736  ucase_next = false;
5737  } else {
5738  WRITE(name[src]);
5739  }
5740  }
5741 
5742  WRITE('\0');
5743  return dst;
5744 
5745 #undef WRITE
5746 }
5747 
5748 static char* makejsonname(symtab_addctx *ctx, const char* name) {
5749  size_t size = getjsonname(name, NULL, 0);
5750  char* json_name = symtab_alloc(ctx, size);
5751  getjsonname(name, json_name, size);
5752  return json_name;
5753 }
5754 
5755 static void symtab_add(symtab_addctx *ctx, const char *name, upb_value v) {
5756  if (upb_strtable_lookup(&ctx->symtab->syms, name, NULL)) {
5757  symtab_errf(ctx, "duplicate symbol '%s'", name);
5758  }
5759  size_t len = strlen(name);
5761  ctx->symtab->arena));
5762 }
5763 
5764 /* Given a symbol and the base symbol inside which it is defined, find the
5765  * symbol's definition in t. */
5766 static const void *symtab_resolve(symtab_addctx *ctx, const upb_fielddef *f,
5767  const char *base, upb_strview sym,
5768  upb_deftype_t type) {
5769  const upb_strtable *t = &ctx->symtab->syms;
5770  if(sym.size == 0) goto notfound;
5771  if(sym.data[0] == '.') {
5772  /* Symbols starting with '.' are absolute, so we do a single lookup.
5773  * Slice to omit the leading '.' */
5774  upb_value v;
5775  if (!upb_strtable_lookup2(t, sym.data + 1, sym.size - 1, &v)) {
5776  goto notfound;
5777  }
5778 
5779  const void *ret = unpack_def(v, type);
5780  if (!ret) {
5781  symtab_errf(ctx, "type mismatch when resolving field %s, name %s",
5782  f->full_name, sym.data);
5783  }
5784  return ret;
5785  } else {
5786  /* Remove components from base until we find an entry or run out.
5787  * TODO: This branch is totally broken, but currently not used. */
5788  (void)base;
5789  UPB_ASSERT(false);
5790  goto notfound;
5791  }
5792 
5793 notfound:
5794  symtab_errf(ctx, "couldn't resolve name '" UPB_STRVIEW_FORMAT "'",
5795  UPB_STRVIEW_ARGS(sym));
5796 }
5797 
5798 static void create_oneofdef(
5800  const google_protobuf_OneofDescriptorProto *oneof_proto) {
5801  upb_oneofdef *o;
5803  upb_value v;
5804 
5805  o = (upb_oneofdef*)&m->oneofs[m->oneof_count++];
5806  o->parent = m;
5807  o->full_name = makefullname(ctx, m->full_name, name);
5808  o->field_count = 0;
5809  o->synthetic = false;
5810 
5812  symtab_add(ctx, o->full_name, v);
5813  CHK_OOM(upb_strtable_insert(&m->ntof, name.data, name.size, v, ctx->arena));
5814 
5815  CHK_OOM(upb_inttable_init(&o->itof, ctx->arena));
5816  CHK_OOM(upb_strtable_init(&o->ntof, 4, ctx->arena));
5817 }
5818 
5819 static str_t *newstr(symtab_addctx *ctx, const char *data, size_t len) {
5820  str_t *ret = symtab_alloc(ctx, sizeof(*ret) + len);
5821  if (!ret) return NULL;
5822  ret->len = len;
5823  if (len) memcpy(ret->str, data, len);
5824  ret->str[len] = '\0';
5825  return ret;
5826 }
5827 
5828 static void parse_default(symtab_addctx *ctx, const char *str, size_t len,
5829  upb_fielddef *f) {
5830  char *end;
5831  char nullz[64];
5832  errno = 0;
5833 
5834  switch (upb_fielddef_type(f)) {
5835  case UPB_TYPE_INT32:
5836  case UPB_TYPE_INT64:
5837  case UPB_TYPE_UINT32:
5838  case UPB_TYPE_UINT64:
5839  case UPB_TYPE_DOUBLE:
5840  case UPB_TYPE_FLOAT:
5841  /* Standard C number parsing functions expect null-terminated strings. */
5842  if (len >= sizeof(nullz) - 1) {
5843  symtab_errf(ctx, "Default too long: %.*s", (int)len, str);
5844  }
5845  memcpy(nullz, str, len);
5846  nullz[len] = '\0';
5847  str = nullz;
5848  break;
5849  default:
5850  break;
5851  }
5852 
5853  switch (upb_fielddef_type(f)) {
5854  case UPB_TYPE_INT32: {
5855  long val = strtol(str, &end, 0);
5856  if (val > INT32_MAX || val < INT32_MIN || errno == ERANGE || *end) {
5857  goto invalid;
5858  }
5859  f->defaultval.sint = val;
5860  break;
5861  }
5862  case UPB_TYPE_ENUM: {
5863  const upb_enumdef *e = f->sub.enumdef;
5864  int32_t val;
5865  if (!upb_enumdef_ntoi(e, str, len, &val)) {
5866  goto invalid;
5867  }
5868  f->defaultval.sint = val;
5869  break;
5870  }
5871  case UPB_TYPE_INT64: {
5872  long long val = strtoll(str, &end, 0);
5873  if (val > INT64_MAX || val < INT64_MIN || errno == ERANGE || *end) {
5874  goto invalid;
5875  }
5876  f->defaultval.sint = val;
5877  break;
5878  }
5879  case UPB_TYPE_UINT32: {
5880  unsigned long val = strtoul(str, &end, 0);
5881  if (val > UINT32_MAX || errno == ERANGE || *end) {
5882  goto invalid;
5883  }
5884  f->defaultval.uint = val;
5885  break;
5886  }
5887  case UPB_TYPE_UINT64: {
5888  unsigned long long val = strtoull(str, &end, 0);
5889  if (val > UINT64_MAX || errno == ERANGE || *end) {
5890  goto invalid;
5891  }
5892  f->defaultval.uint = val;
5893  break;
5894  }
5895  case UPB_TYPE_DOUBLE: {
5896  double val = strtod(str, &end);
5897  if (errno == ERANGE || *end) {
5898  goto invalid;
5899  }
5900  f->defaultval.dbl = val;
5901  break;
5902  }
5903  case UPB_TYPE_FLOAT: {
5904  float val = strtof(str, &end);
5905  if (errno == ERANGE || *end) {
5906  goto invalid;
5907  }
5908  f->defaultval.flt = val;
5909  break;
5910  }
5911  case UPB_TYPE_BOOL: {
5912  if (streql2(str, len, "false")) {
5913  f->defaultval.boolean = false;
5914  } else if (streql2(str, len, "true")) {
5915  f->defaultval.boolean = true;
5916  } else {
5917  }
5918  break;
5919  }
5920  case UPB_TYPE_STRING:
5921  f->defaultval.str = newstr(ctx, str, len);
5922  break;
5923  case UPB_TYPE_BYTES:
5924  /* XXX: need to interpret the C-escaped value. */
5925  f->defaultval.str = newstr(ctx, str, len);
5926  break;
5927  case UPB_TYPE_MESSAGE:
5928  /* Should not have a default value. */
5929  symtab_errf(ctx, "Message should not have a default (%s)",
5931  }
5932 
5933  return;
5934 
5935 invalid:
5936  symtab_errf(ctx, "Invalid default '%.*s' for field %s", (int)len, str,
5938 }
5939 
5941  switch (upb_fielddef_type(f)) {
5942  case UPB_TYPE_INT32:
5943  case UPB_TYPE_INT64:
5944  case UPB_TYPE_ENUM:
5945  f->defaultval.sint = 0;
5946  break;
5947  case UPB_TYPE_UINT64:
5948  case UPB_TYPE_UINT32:
5949  f->defaultval.uint = 0;
5950  break;
5951  case UPB_TYPE_DOUBLE:
5952  case UPB_TYPE_FLOAT:
5953  f->defaultval.dbl = 0;
5954  break;
5955  case UPB_TYPE_STRING:
5956  case UPB_TYPE_BYTES:
5957  f->defaultval.str = newstr(ctx, NULL, 0);
5958  break;
5959  case UPB_TYPE_BOOL:
5960  f->defaultval.boolean = false;
5961  break;
5962  case UPB_TYPE_MESSAGE:
5963  break;
5964  }
5965 }
5966 
5967 static void create_fielddef(
5968  symtab_addctx *ctx, const char *prefix, upb_msgdef *m,
5969  const google_protobuf_FieldDescriptorProto *field_proto) {
5970  upb_fielddef *f;
5972  upb_strview name;
5973  const char *full_name;
5974  const char *json_name;
5975  const char *shortname;
5976  uint32_t field_number;
5977 
5979  symtab_errf(ctx, "field has no name (%s)", upb_msgdef_fullname(m));
5980  }
5981 
5983  check_ident(ctx, name, false);
5984  full_name = makefullname(ctx, prefix, name);
5985  shortname = shortdefname(full_name);
5986 
5988  json_name = strviewdup(
5990  } else {
5991  json_name = makejsonname(ctx, shortname);
5992  }
5993 
5994  field_number = google_protobuf_FieldDescriptorProto_number(field_proto);
5995 
5996  if (field_number == 0 || field_number > UPB_MAX_FIELDNUMBER) {
5997  symtab_errf(ctx, "invalid field number (%u)", field_number);
5998  }
5999 
6000  if (m) {
6001  /* direct message field. */
6002  upb_value v, field_v, json_v;
6003  size_t json_size;
6004 
6005  f = (upb_fielddef*)&m->fields[m->field_count];
6006  f->index_ = m->field_count++;
6007  f->msgdef = m;
6008  f->is_extension_ = false;
6009 
6010  if (upb_strtable_lookup(&m->ntof, shortname, NULL)) {
6011  symtab_errf(ctx, "duplicate field name (%s)", shortname);
6012  }
6013 
6014  if (upb_strtable_lookup(&m->ntof, json_name, NULL)) {
6015  symtab_errf(ctx, "duplicate json_name (%s)", json_name);
6016  }
6017 
6018  if (upb_inttable_lookup(&m->itof, field_number, NULL)) {
6019  symtab_errf(ctx, "duplicate field number (%u)", field_number);
6020  }
6021 
6022  field_v = pack_def(f, UPB_DEFTYPE_FIELD);
6024  v = upb_value_constptr(f);
6025  json_size = strlen(json_name);
6026 
6027  CHK_OOM(upb_strtable_insert(&m->ntof, name.data, name.size, field_v,
6028  ctx->arena));
6029  CHK_OOM(upb_inttable_insert(&m->itof, field_number, v, ctx->arena));
6030 
6031  if (strcmp(shortname, json_name) != 0) {
6032  upb_strtable_insert(&m->ntof, json_name, json_size, json_v, ctx->arena);
6033  }
6034 
6035  if (ctx->layouts) {
6036  const upb_msglayout_field *fields = m->layout->fields;
6037  int count = m->layout->field_count;
6038  bool found = false;
6039  int i;
6040  for (i = 0; i < count; i++) {
6041  if (fields[i].number == field_number) {
6042  f->layout_index = i;
6043  found = true;
6044  break;
6045  }
6046  }
6047  UPB_ASSERT(found);
6048  }
6049  } else {
6050  /* extension field. */
6051  f = (upb_fielddef*)&ctx->file->exts[ctx->file->ext_count++];
6052  f->is_extension_ = true;
6053  symtab_add(ctx, full_name, pack_def(f, UPB_DEFTYPE_FIELD));
6054  }
6055 
6056  f->full_name = full_name;
6057  f->json_name = json_name;
6058  f->file = ctx->file;
6059  f->type_ = (int)google_protobuf_FieldDescriptorProto_type(field_proto);
6060  f->label_ = (int)google_protobuf_FieldDescriptorProto_label(field_proto);
6061  f->number_ = field_number;
6062  f->oneof = NULL;
6063  f->proto3_optional_ =
6065 
6066  /* We can't resolve the subdef or (in the case of extensions) the containing
6067  * message yet, because it may not have been defined yet. We stash a pointer
6068  * to the field_proto until later when we can properly resolve it. */
6069  f->sub.unresolved = field_proto;
6070 
6071  if (f->label_ == UPB_LABEL_REQUIRED && f->file->syntax == UPB_SYNTAX_PROTO3) {
6072  symtab_errf(ctx, "proto3 fields cannot be required (%s)", f->full_name);
6073  }
6074 
6076  int oneof_index =
6078  upb_oneofdef *oneof;
6079  upb_value v = upb_value_constptr(f);
6080 
6082  symtab_errf(ctx, "fields in oneof must have OPTIONAL label (%s)",
6083  f->full_name);
6084  }
6085 
6086  if (!m) {
6087  symtab_errf(ctx, "oneof_index provided for extension field (%s)",
6088  f->full_name);
6089  }
6090 
6091  if (oneof_index >= m->oneof_count) {
6092  symtab_errf(ctx, "oneof_index out of range (%s)", f->full_name);
6093  }
6094 
6095  oneof = (upb_oneofdef *)&m->oneofs[oneof_index];
6096  f->oneof = oneof;
6097 
6098  oneof->field_count++;
6099  if (f->proto3_optional_) {
6100  oneof->synthetic = true;
6101  }
6102  CHK_OOM(upb_inttable_insert(&oneof->itof, f->number_, v, ctx->arena));
6103  CHK_OOM(
6104  upb_strtable_insert(&oneof->ntof, name.data, name.size, v, ctx->arena));
6105  } else {
6106  f->oneof = NULL;
6107  if (f->proto3_optional_) {
6108  symtab_errf(ctx, "field with proto3_optional was not in a oneof (%s)",
6109  f->full_name);
6110  }
6111  }
6112 
6115 
6118  } else {
6119  /* Repeated fields default to packed for proto3 only. */
6120  f->packed_ = upb_fielddef_isprimitive(f) &&
6121  f->label_ == UPB_LABEL_REPEATED && f->file->syntax == UPB_SYNTAX_PROTO3;
6122  }
6123 
6124  if (options) {
6126  } else {
6127  f->lazy_ = false;
6128  }
6129 }
6130 
6131 static void create_enumdef(
6132  symtab_addctx *ctx, const char *prefix,
6133  const google_protobuf_EnumDescriptorProto *enum_proto) {
6134  upb_enumdef *e;
6136  upb_strview name;
6137  size_t i, n;
6138 
6140  check_ident(ctx, name, false);
6141 
6142  e = (upb_enumdef*)&ctx->file->enums[ctx->file->enum_count++];
6143  e->full_name = makefullname(ctx, prefix, name);
6144  symtab_add(ctx, e->full_name, pack_def(e, UPB_DEFTYPE_ENUM));
6145 
6147  CHK_OOM(upb_strtable_init(&e->ntoi, n, ctx->arena));
6148  CHK_OOM(upb_inttable_init(&e->iton, ctx->arena));
6149 
6150  e->file = ctx->file;
6151  e->defaultval = 0;
6152 
6153  if (n == 0) {
6154  symtab_errf(ctx, "enums must contain at least one value (%s)",
6155  e->full_name);
6156  }
6157 
6158  for (i = 0; i < n; i++) {
6161  char *name2 = strviewdup(ctx, name);
6163  upb_value v = upb_value_int32(num);
6164 
6165  if (i == 0 && e->file->syntax == UPB_SYNTAX_PROTO3 && num != 0) {
6166  symtab_errf(ctx, "for proto3, the first enum value must be zero (%s)",
6167  e->full_name);
6168  }
6169 
6170  if (upb_strtable_lookup(&e->ntoi, name2, NULL)) {
6171  symtab_errf(ctx, "duplicate enum label '%s'", name2);
6172  }
6173 
6174  CHK_OOM(name2)
6175  CHK_OOM(upb_strtable_insert(&e->ntoi, name2, strlen(name2), v, ctx->arena));
6176 
6177  if (!upb_inttable_lookup(&e->iton, num, NULL)) {
6178  upb_value v = upb_value_cstr(name2);
6179  CHK_OOM(upb_inttable_insert(&e->iton, num, v, ctx->arena));
6180  }
6181  }
6182 
6183  upb_inttable_compact(&e->iton, ctx->arena);
6184 }
6185 
6186 static void create_msgdef(symtab_addctx *ctx, const char *prefix,
6187  const google_protobuf_DescriptorProto *msg_proto) {
6188  upb_msgdef *m;
6190  const google_protobuf_OneofDescriptorProto *const *oneofs;
6192  const google_protobuf_EnumDescriptorProto *const *enums;
6193  const google_protobuf_DescriptorProto *const *msgs;
6194  size_t i, n_oneof, n_field, n;
6195  upb_strview name;
6196 
6198  check_ident(ctx, name, false);
6199 
6200  m = (upb_msgdef*)&ctx->file->msgs[ctx->file->msg_count++];
6201  m->full_name = makefullname(ctx, prefix, name);
6202  symtab_add(ctx, m->full_name, pack_def(m, UPB_DEFTYPE_MSG));
6203 
6204  oneofs = google_protobuf_DescriptorProto_oneof_decl(msg_proto, &n_oneof);
6205  fields = google_protobuf_DescriptorProto_field(msg_proto, &n_field);
6206 
6207  CHK_OOM(upb_inttable_init(&m->itof, ctx->arena));
6208  CHK_OOM(upb_strtable_init(&m->ntof, n_oneof + n_field, ctx->arena));
6209 
6210  m->file = ctx->file;
6211  m->map_entry = false;
6212 
6214 
6215  if (options) {
6217  }
6218 
6219  if (ctx->layouts) {
6220  m->layout = *ctx->layouts;
6221  ctx->layouts++;
6222  } else {
6223  /* Allocate now (to allow cross-linking), populate later. */
6224  m->layout = symtab_alloc(
6225  ctx, sizeof(*m->layout) + sizeof(_upb_fasttable_entry));
6226  }
6227 
6228  m->oneof_count = 0;
6229  m->oneofs = symtab_alloc(ctx, sizeof(*m->oneofs) * n_oneof);
6230  for (i = 0; i < n_oneof; i++) {
6231  create_oneofdef(ctx, m, oneofs[i]);
6232  }
6233 
6234  m->field_count = 0;
6235  m->fields = symtab_alloc(ctx, sizeof(*m->fields) * n_field);
6236  for (i = 0; i < n_field; i++) {
6237  create_fielddef(ctx, m->full_name, m, fields[i]);
6238  }
6239 
6240  finalize_oneofs(ctx, m);
6242  upb_inttable_compact(&m->itof, ctx->arena);
6243 
6244  /* This message is built. Now build nested messages and enums. */
6245 
6246  enums = google_protobuf_DescriptorProto_enum_type(msg_proto, &n);
6247  for (i = 0; i < n; i++) {
6248  create_enumdef(ctx, m->full_name, enums[i]);
6249  }
6250 
6251  msgs = google_protobuf_DescriptorProto_nested_type(msg_proto, &n);
6252  for (i = 0; i < n; i++) {
6253  create_msgdef(ctx, m->full_name, msgs[i]);
6254  }
6255 }
6256 
6258  upb_filedef *file) {
6259  const google_protobuf_DescriptorProto *const *msgs;
6260  size_t i, n;
6261 
6262  file->msg_count++;
6263 
6264  msgs = google_protobuf_DescriptorProto_nested_type(msg_proto, &n);
6265  for (i = 0; i < n; i++) {
6266  count_types_in_msg(msgs[i], file);
6267  }
6268 
6270  file->enum_count += n;
6271 
6273  file->ext_count += n;
6274 }
6275 
6277  const google_protobuf_FileDescriptorProto *file_proto,
6278  upb_filedef *file) {
6279  const google_protobuf_DescriptorProto *const *msgs;
6280  size_t i, n;
6281 
6283  for (i = 0; i < n; i++) {
6284  count_types_in_msg(msgs[i], file);
6285  }
6286 
6288  file->enum_count += n;
6289 
6291  file->ext_count += n;
6292 }
6293 
6294 static void resolve_fielddef(symtab_addctx *ctx, const char *prefix,
6295  upb_fielddef *f) {
6296  upb_strview name;
6297  const google_protobuf_FieldDescriptorProto *field_proto = f->sub.unresolved;
6298 
6299  if (f->is_extension_) {
6301  symtab_errf(ctx, "extension for field '%s' had no extendee",
6302  f->full_name);
6303  }
6304 
6306  f->msgdef = symtab_resolve(ctx, f, prefix, name, UPB_DEFTYPE_MSG);
6307  }
6308 
6309  if ((upb_fielddef_issubmsg(f) || f->type_ == UPB_DESCRIPTOR_TYPE_ENUM) &&
6311  symtab_errf(ctx, "field '%s' is missing type name", f->full_name);
6312  }
6313 
6315 
6316  if (upb_fielddef_issubmsg(f)) {
6317  f->sub.msgdef = symtab_resolve(ctx, f, prefix, name, UPB_DEFTYPE_MSG);
6318  } else if (f->type_ == UPB_DESCRIPTOR_TYPE_ENUM) {
6319  f->sub.enumdef = symtab_resolve(ctx, f, prefix, name, UPB_DEFTYPE_ENUM);
6320  }
6321 
6322  /* Have to delay resolving of the default value until now because of the enum
6323  * case, since enum defaults are specified with a label. */
6325  upb_strview defaultval =
6327 
6328  if (f->file->syntax == UPB_SYNTAX_PROTO3) {
6329  symtab_errf(ctx, "proto3 fields cannot have explicit defaults (%s)",
6330  f->full_name);
6331  }
6332 
6333  if (upb_fielddef_issubmsg(f)) {
6334  symtab_errf(ctx, "message fields cannot have explicit defaults (%s)",
6335  f->full_name);
6336  }
6337 
6338  parse_default(ctx, defaultval.data, defaultval.size, f);
6339  } else {
6341  }
6342 }
6343 
6344 static void build_filedef(
6346  const google_protobuf_FileDescriptorProto *file_proto) {
6347  const google_protobuf_FileOptions *file_options_proto;
6348  const google_protobuf_DescriptorProto *const *msgs;
6349  const google_protobuf_EnumDescriptorProto *const *enums;
6350  const google_protobuf_FieldDescriptorProto *const *exts;
6351  const upb_strview* strs;
6352  size_t i, n;
6353 
6354  file->symtab = ctx->symtab;
6355 
6356  /* One pass to count and allocate. */
6357  file->msg_count = 0;
6358  file->enum_count = 0;
6359  file->ext_count = 0;
6360  count_types_in_file(file_proto, file);
6361  file->msgs = symtab_alloc(ctx, sizeof(*file->msgs) * file->msg_count);
6362  file->enums = symtab_alloc(ctx, sizeof(*file->enums) * file->enum_count);
6363  file->exts = symtab_alloc(ctx, sizeof(*file->exts) * file->ext_count);
6364 
6365  /* In the second pass we increment these as defs are added. */
6366  file->msg_count = 0;
6367  file->enum_count = 0;
6368  file->ext_count = 0;
6369 
6371  symtab_errf(ctx, "File has no name");
6372  }
6373 
6374  file->name =
6376  file->phpprefix = NULL;
6377  file->phpnamespace = NULL;
6378 
6380  upb_strview package =
6381  google_protobuf_FileDescriptorProto_package(file_proto);
6382  check_ident(ctx, package, true);
6383  file->package = strviewdup(ctx, package);
6384  } else {
6385  file->package = NULL;
6386  }
6387 
6391 
6392  if (streql_view(syntax, "proto2")) {
6393  file->syntax = UPB_SYNTAX_PROTO2;
6394  } else if (streql_view(syntax, "proto3")) {
6395  file->syntax = UPB_SYNTAX_PROTO3;
6396  } else {
6397  symtab_errf(ctx, "Invalid syntax '" UPB_STRVIEW_FORMAT "'",
6399  }
6400  } else {
6401  file->syntax = UPB_SYNTAX_PROTO2;
6402  }
6403 
6404  /* Read options. */
6405  file_options_proto = google_protobuf_FileDescriptorProto_options(file_proto);
6406  if (file_options_proto) {
6407  if (google_protobuf_FileOptions_has_php_class_prefix(file_options_proto)) {
6408  file->phpprefix = strviewdup(
6409  ctx,
6410  google_protobuf_FileOptions_php_class_prefix(file_options_proto));
6411  }
6412  if (google_protobuf_FileOptions_has_php_namespace(file_options_proto)) {
6413  file->phpnamespace = strviewdup(
6414  ctx, google_protobuf_FileOptions_php_namespace(file_options_proto));
6415  }
6416  }
6417 
6418  /* Verify dependencies. */
6420  file->deps = symtab_alloc(ctx, sizeof(*file->deps) * n);
6421 
6422  for (i = 0; i < n; i++) {
6423  upb_strview dep_name = strs[i];
6424  upb_value v;
6425  if (!upb_strtable_lookup2(&ctx->symtab->files, dep_name.data,
6426  dep_name.size, &v)) {
6427  symtab_errf(ctx,
6428  "Depends on file '" UPB_STRVIEW_FORMAT
6429  "', but it has not been loaded",
6430  UPB_STRVIEW_ARGS(dep_name));
6431  }
6432  file->deps[i] = upb_value_getconstptr(v);
6433  }
6434 
6435  /* Create messages. */
6437  for (i = 0; i < n; i++) {
6438  create_msgdef(ctx, file->package, msgs[i]);
6439  }
6440 
6441  /* Create enums. */
6442  enums = google_protobuf_FileDescriptorProto_enum_type(file_proto, &n);
6443  for (i = 0; i < n; i++) {
6444  create_enumdef(ctx, file->package, enums[i]);
6445  }
6446 
6447  /* Create extensions. */
6448  exts = google_protobuf_FileDescriptorProto_extension(file_proto, &n);
6449  file->exts = symtab_alloc(ctx, sizeof(*file->exts) * n);
6450  for (i = 0; i < n; i++) {
6451  create_fielddef(ctx, file->package, NULL, exts[i]);
6452  }
6453 
6454  /* Now that all names are in the table, build layouts and resolve refs. */
6455  for (i = 0; i < (size_t)file->ext_count; i++) {
6456  resolve_fielddef(ctx, file->package, (upb_fielddef*)&file->exts[i]);
6457  }
6458 
6459  for (i = 0; i < (size_t)file->msg_count; i++) {
6460  const upb_msgdef *m = &file->msgs[i];
6461  int j;
6462  for (j = 0; j < m->field_count; j++) {
6463  resolve_fielddef(ctx, m->full_name, (upb_fielddef*)&m->fields[j]);
6464  }
6465  }
6466 
6467  if (!ctx->layouts) {
6468  for (i = 0; i < (size_t)file->msg_count; i++) {
6469  const upb_msgdef *m = &file->msgs[i];
6470  make_layout(ctx, m);
6471  }
6472  }
6473 }
6474 
6476  int i;
6477  for (i = 0; i < file->msg_count; i++) {
6478  const char *name = file->msgs[i].full_name;
6479  upb_strtable_remove(&s->syms, name, strlen(name), NULL);
6480  }
6481  for (i = 0; i < file->enum_count; i++) {
6482  const char *name = file->enums[i].full_name;
6483  upb_strtable_remove(&s->syms, name, strlen(name), NULL);
6484  }
6485  for (i = 0; i < file->ext_count; i++) {
6486  const char *name = file->exts[i].full_name;
6487  upb_strtable_remove(&s->syms, name, strlen(name), NULL);
6488  }
6489 }
6490 
6492  upb_symtab *s, const google_protobuf_FileDescriptorProto *file_proto,
6493  const upb_msglayout **layouts, upb_status *status) {
6496 
6497  if (upb_strtable_lookup2(&s->files, name.data, name.size, NULL)) {
6498  upb_status_seterrf(status, "duplicate file name (%.*s)",
6500  return NULL;
6501  }
6502 
6503  ctx.symtab = s;
6504  ctx.layouts = layouts;
6505  ctx.status = status;
6506  ctx.file = NULL;
6507  ctx.arena = upb_arena_new();
6508 
6509  if (!ctx.arena) {
6511  return NULL;
6512  }
6513 
6514  if (UPB_UNLIKELY(UPB_SETJMP(ctx.err))) {
6516  if (ctx.file) {
6517  remove_filedef(s, ctx.file);
6518  ctx.file = NULL;
6519  }
6520  } else {
6521  ctx.file = symtab_alloc(&ctx, sizeof(*ctx.file));
6522  build_filedef(&ctx, ctx.file, file_proto);
6523  upb_strtable_insert(&s->files, name.data, name.size,
6524  upb_value_constptr(ctx.file), ctx.arena);
6526  upb_arena_fuse(s->arena, ctx.arena);
6527  }
6528 
6530  return ctx.file;
6531 }
6532 
6534  upb_symtab *s, const google_protobuf_FileDescriptorProto *file_proto,
6535  upb_status *status) {
6536  return _upb_symtab_addfile(s, file_proto, NULL, status);
6537 }
6538 
6539 /* Include here since we want most of this file to be stdio-free. */
6540 #include <stdio.h>
6541 
6543  /* Since this function should never fail (it would indicate a bug in upb) we
6544  * print errors to stderr instead of returning error status to the user. */
6545  upb_def_init **deps = init->deps;
6547  upb_arena *arena;
6549 
6551 
6552  if (upb_strtable_lookup(&s->files, init->filename, NULL)) {
6553  return true;
6554  }
6555 
6556  arena = upb_arena_new();
6557 
6558  for (; *deps; deps++) {
6559  if (!_upb_symtab_loaddefinit(s, *deps)) goto err;
6560  }
6561 
6563  init->descriptor.data, init->descriptor.size, NULL, UPB_DECODE_ALIAS,
6564  arena);
6565  s->bytes_loaded += init->descriptor.size;
6566 
6567  if (!file) {
6569  &status,
6570  "Failed to parse compiled-in descriptor for file '%s'. This should "
6571  "never happen.",
6572  init->filename);
6573  goto err;
6574  }
6575 
6576  if (!_upb_symtab_addfile(s, file, init->layouts, &status)) goto err;
6577 
6579  return true;
6580 
6581 err:
6582  fprintf(stderr, "Error loading compiled-in descriptor: %s\n",
6585  return false;
6586 }
6587 
6589  return s->bytes_loaded;
6590 }
6591 
6593  return s->arena;
6594 }
6595 
6596 #undef CHK_OOM
6597 
6600 #include <string.h>
6601 
6602 
6603 static size_t get_field_size(const upb_msglayout_field *f) {
6604  static unsigned char sizes[] = {
6605  0,/* 0 */
6606  8, /* UPB_DESCRIPTOR_TYPE_DOUBLE */
6607  4, /* UPB_DESCRIPTOR_TYPE_FLOAT */
6608  8, /* UPB_DESCRIPTOR_TYPE_INT64 */
6609  8, /* UPB_DESCRIPTOR_TYPE_UINT64 */
6610  4, /* UPB_DESCRIPTOR_TYPE_INT32 */
6611  8, /* UPB_DESCRIPTOR_TYPE_FIXED64 */
6612  4, /* UPB_DESCRIPTOR_TYPE_FIXED32 */
6613  1, /* UPB_DESCRIPTOR_TYPE_BOOL */
6614  sizeof(upb_strview), /* UPB_DESCRIPTOR_TYPE_STRING */
6615  sizeof(void*), /* UPB_DESCRIPTOR_TYPE_GROUP */
6616  sizeof(void*), /* UPB_DESCRIPTOR_TYPE_MESSAGE */
6617  sizeof(upb_strview), /* UPB_DESCRIPTOR_TYPE_BYTES */
6618  4, /* UPB_DESCRIPTOR_TYPE_UINT32 */
6619  4, /* UPB_DESCRIPTOR_TYPE_ENUM */
6620  4, /* UPB_DESCRIPTOR_TYPE_SFIXED32 */
6621  8, /* UPB_DESCRIPTOR_TYPE_SFIXED64 */
6622  4, /* UPB_DESCRIPTOR_TYPE_SINT32 */
6623  8, /* UPB_DESCRIPTOR_TYPE_SINT64 */
6624  };
6625  return _upb_repeated_or_map(f) ? sizeof(void *) : sizes[f->descriptortype];
6626 }
6627 
6628 /* Strings/bytes are special-cased in maps. */
6629 static char _upb_fieldtype_to_mapsize[12] = {
6630  0,
6631  1, /* UPB_TYPE_BOOL */
6632  4, /* UPB_TYPE_FLOAT */
6633  4, /* UPB_TYPE_INT32 */
6634  4, /* UPB_TYPE_UINT32 */
6635  4, /* UPB_TYPE_ENUM */
6636  sizeof(void*), /* UPB_TYPE_MESSAGE */
6637  8, /* UPB_TYPE_DOUBLE */
6638  8, /* UPB_TYPE_INT64 */
6639  8, /* UPB_TYPE_UINT64 */
6640  0, /* UPB_TYPE_STRING */
6641  0, /* UPB_TYPE_BYTES */
6642 };
6643 
6644 static const char _upb_fieldtype_to_sizelg2[12] = {
6645  0,
6646  0, /* UPB_TYPE_BOOL */
6647  2, /* UPB_TYPE_FLOAT */
6648  2, /* UPB_TYPE_INT32 */
6649  2, /* UPB_TYPE_UINT32 */
6650  2, /* UPB_TYPE_ENUM */
6651  UPB_SIZE(2, 3), /* UPB_TYPE_MESSAGE */
6652  3, /* UPB_TYPE_DOUBLE */
6653  3, /* UPB_TYPE_INT64 */
6654  3, /* UPB_TYPE_UINT64 */
6655  UPB_SIZE(3, 4), /* UPB_TYPE_STRING */
6656  UPB_SIZE(3, 4), /* UPB_TYPE_BYTES */
6657 };
6658 
6662  return _upb_msg_new(upb_msgdef_layout(m), a);
6663 }
6664 
6665 static bool in_oneof(const upb_msglayout_field *field) {
6666  return field->presence < 0;
6667 }
6668 
6671  const char *mem = UPB_PTR_AT(msg, field->offset, char);
6672  upb_msgval val = {0};
6673  memcpy(&val, mem, get_field_size(field));
6674  return val;
6675 }
6676 
6677 bool upb_msg_has(const upb_msg *msg, const upb_fielddef *f) {
6679  if (in_oneof(field)) {
6680  return _upb_getoneofcase_field(msg, field) == field->number;
6681  } else if (field->presence > 0) {
6682  return _upb_hasbit_field(msg, field);
6683  } else {
6684  UPB_ASSERT(field->descriptortype == UPB_DESCRIPTOR_TYPE_MESSAGE ||
6685  field->descriptortype == UPB_DESCRIPTOR_TYPE_GROUP);
6686  return _upb_msg_getraw(msg, f).msg_val != NULL;
6687  }
6688 }
6689 
6691  const upb_oneofdef *o) {
6692  const upb_fielddef *f = upb_oneofdef_field(o, 0);
6693  if (upb_oneofdef_issynthetic(o)) {
6695  return upb_msg_has(msg, f) ? f : NULL;
6696  } else {
6698  uint32_t oneof_case = _upb_getoneofcase_field(msg, field);
6699  f = oneof_case ? upb_oneofdef_itof(o, oneof_case) : NULL;
6700  UPB_ASSERT((f != NULL) == (oneof_case != 0));
6701  return f;
6702  }
6703 }
6704 
6707  return _upb_msg_getraw(msg, f);
6708  } else {
6709  return upb_fielddef_default(f);
6710  }
6711 }
6712 
6714  upb_arena *a) {
6717  char *mem = UPB_PTR_AT(msg, field->offset, char);
6718  bool wrong_oneof =
6720 
6721  memcpy(&ret, mem, sizeof(void*));
6722 
6723  if (a && (!ret.msg || wrong_oneof)) {
6724  if (upb_fielddef_ismap(f)) {
6725  const upb_msgdef *entry = upb_fielddef_msgsubdef(f);
6729  } else if (upb_fielddef_isseq(f)) {
6730  ret.array = upb_array_new(a, upb_fielddef_type(f));
6731  } else {
6734  }
6735 
6736  memcpy(mem, &ret, sizeof(void*));
6737 
6738  if (wrong_oneof) {
6739  *_upb_oneofcase_field(msg, field) = field->number;
6740  } else if (field->presence > 0) {
6742  }
6743  }
6744  return ret;
6745 }
6746 
6748  upb_arena *a) {
6750  char *mem = UPB_PTR_AT(msg, field->offset, char);
6751  UPB_UNUSED(a); /* We reserve the right to make set insert into a map. */
6752  memcpy(mem, &val, get_field_size(field));
6753  if (field->presence > 0) {
6755  } else if (in_oneof(field)) {
6756  *_upb_oneofcase_field(msg, field) = field->number;
6757  }
6758 }
6759 
6762  char *mem = UPB_PTR_AT(msg, field->offset, char);
6763 
6764  if (field->presence > 0) {
6766  } else if (in_oneof(field)) {
6767  uint32_t *oneof_case = _upb_oneofcase_field(msg, field);
6768  if (*oneof_case != field->number) return;
6769  *oneof_case = 0;
6770  }
6771 
6773 }
6774 
6777 }
6778 
6779 bool upb_msg_next(const upb_msg *msg, const upb_msgdef *m,
6780  const upb_symtab *ext_pool, const upb_fielddef **out_f,
6781  upb_msgval *out_val, size_t *iter) {
6782  int i = *iter;
6783  int n = upb_msgdef_fieldcount(m);
6784  const upb_msgval zero = {0};
6785  UPB_UNUSED(ext_pool);
6786  while (++i < n) {
6787  const upb_fielddef *f = upb_msgdef_field(m, i);
6788  upb_msgval val = _upb_msg_getraw(msg, f);
6789 
6790  /* Skip field if unset or empty. */
6791  if (upb_fielddef_haspresence(f)) {
6792  if (!upb_msg_has(msg, f)) continue;
6793  } else {
6794  upb_msgval test = val;
6796  /* Clear string pointer, only size matters (ptr could be non-NULL). */
6797  test.str_val.data = NULL;
6798  }
6799  /* Continue if NULL or 0. */
6800  if (memcmp(&test, &zero, sizeof(test)) == 0) continue;
6801 
6802  /* Continue on empty array or map. */
6803  if (upb_fielddef_ismap(f)) {
6804  if (upb_map_size(test.map_val) == 0) continue;
6805  } else if (upb_fielddef_isseq(f)) {
6806  if (upb_array_size(test.array_val) == 0) continue;
6807  }
6808  }
6809 
6810  *out_val = val;
6811  *out_f = f;
6812  *iter = i;
6813  return true;
6814  }
6815  *iter = i;
6816  return false;
6817 }
6818 
6820  size_t iter = UPB_MSG_BEGIN;
6821  const upb_fielddef *f;
6822  upb_msgval val;
6823  bool ret = true;
6824 
6825  if (--depth == 0) return false;
6826 
6828 
6829  while (upb_msg_next(msg, m, NULL /*ext_pool*/, &f, &val, &iter)) {
6830  const upb_msgdef *subm = upb_fielddef_msgsubdef(f);
6831  if (!subm) continue;
6832  if (upb_fielddef_ismap(f)) {
6833  const upb_fielddef *val_f = upb_msgdef_itof(subm, 2);
6834  const upb_msgdef *val_m = upb_fielddef_msgsubdef(val_f);
6835  upb_map *map = (upb_map*)val.map_val;
6836  size_t iter = UPB_MAP_BEGIN;
6837 
6838  if (!val_m) continue;
6839 
6840  while (upb_mapiter_next(map, &iter)) {
6841  upb_msgval map_val = upb_mapiter_value(map, iter);
6842  if (!_upb_msg_discardunknown((upb_msg*)map_val.msg_val, val_m, depth)) {
6843  ret = false;
6844  }
6845  }
6846  } else if (upb_fielddef_isseq(f)) {
6847  const upb_array *arr = val.array_val;
6848  size_t i, n = upb_array_size(arr);
6849  for (i = 0; i < n; i++) {
6850  upb_msgval elem = upb_array_get(arr, i);
6851  if (!_upb_msg_discardunknown((upb_msg*)elem.msg_val, subm, depth)) {
6852  ret = false;
6853  }
6854  }
6855  } else {
6856  if (!_upb_msg_discardunknown((upb_msg*)val.msg_val, subm, depth)) {
6857  ret = false;
6858  }
6859  }
6860  }
6861 
6862  return ret;
6863 }
6864 
6865 bool upb_msg_discardunknown(upb_msg *msg, const upb_msgdef *m, int maxdepth) {
6866  return _upb_msg_discardunknown(msg, m, maxdepth);
6867 }
6868 
6873 }
6874 
6875 size_t upb_array_size(const upb_array *arr) {
6876  return arr->len;
6877 }
6878 
6879 upb_msgval upb_array_get(const upb_array *arr, size_t i) {
6880  upb_msgval ret;
6881  const char* data = _upb_array_constptr(arr);
6882  int lg2 = arr->data & 7;
6883  UPB_ASSERT(i < arr->len);
6884  memcpy(&ret, data + (i << lg2), 1 << lg2);
6885  return ret;
6886 }
6887 
6888 void upb_array_set(upb_array *arr, size_t i, upb_msgval val) {
6889  char* data = _upb_array_ptr(arr);
6890  int lg2 = arr->data & 7;
6891  UPB_ASSERT(i < arr->len);
6892  memcpy(data + (i << lg2), &val, 1 << lg2);
6893 }
6894 
6896  if (!upb_array_resize(arr, arr->len + 1, arena)) {
6897  return false;
6898  }
6899  upb_array_set(arr, arr->len - 1, val);
6900  return true;
6901 }
6902 
6904  return _upb_array_resize(arr, size, arena);
6905 }
6906 
6913 }
6914 
6915 size_t upb_map_size(const upb_map *map) {
6916  return _upb_map_size(map);
6917 }
6918 
6920  return _upb_map_get(map, &key, map->key_size, val, map->val_size);
6921 }
6922 
6925 }
6926 
6928  upb_arena *arena) {
6929  return _upb_map_set(map, &key, map->key_size, &val, map->val_size, arena);
6930 }
6931 
6933  return _upb_map_delete(map, &key, map->key_size);
6934 }
6935 
6936 bool upb_mapiter_next(const upb_map *map, size_t *iter) {
6937  return _upb_map_next(map, iter);
6938 }
6939 
6940 bool upb_mapiter_done(const upb_map *map, size_t iter) {
6943  i.t = &map->table;
6944  i.index = iter;
6945  return upb_strtable_done(&i);
6946 }
6947 
6948 /* Returns the key and value for this entry of the map. */
6951  upb_msgval ret;
6952  i.t = &map->table;
6953  i.index = iter;
6955  return ret;
6956 }
6957 
6960  upb_msgval ret;
6961  i.t = &map->table;
6962  i.index = iter;
6964  return ret;
6965 }
6966 
6967 /* void upb_mapiter_setvalue(upb_map *map, size_t iter, upb_msgval value); */
6968 
6971 #include <errno.h>
6972 #include <float.h>
6973 #include <inttypes.h>
6974 #include <limits.h>
6975 #include <math.h>
6976 #include <setjmp.h>
6977 #include <stdlib.h>
6978 #include <string.h>
6979 
6980 
6981 /* Special header, must be included last. */
6982 
6983 typedef struct {
6984  const char *ptr, *end;
6985  upb_arena *arena; /* TODO: should we have a tmp arena for tmp data? */
6986  const upb_symtab *any_pool;
6987  int depth;
6988  upb_status *status;
6989  jmp_buf err;
6990  int line;
6991  const char *line_begin;
6992  bool is_first;
6993  int options;
6994  const upb_fielddef *debug_field;
6995 } jsondec;
6996 
6998 
6999 /* Forward declarations of mutually-recursive functions. */
7000 static void jsondec_wellknown(jsondec *d, upb_msg *msg, const upb_msgdef *m);
7001 static upb_msgval jsondec_value(jsondec *d, const upb_fielddef *f);
7002 static void jsondec_wellknownvalue(jsondec *d, upb_msg *msg,
7003  const upb_msgdef *m);
7004 static void jsondec_object(jsondec *d, upb_msg *msg, const upb_msgdef *m);
7005 
7006 static bool jsondec_streql(upb_strview str, const char *lit) {
7007  return str.size == strlen(lit) && memcmp(str.data, lit, str.size) == 0;
7008 }
7009 
7010 static bool jsondec_isnullvalue(const upb_fielddef *f) {
7011  return upb_fielddef_type(f) == UPB_TYPE_ENUM &&
7013  "google.protobuf.NullValue") == 0;
7014 }
7015 
7016 static bool jsondec_isvalue(const upb_fielddef *f) {
7017  return (upb_fielddef_type(f) == UPB_TYPE_MESSAGE &&
7021 }
7022 
7023 UPB_NORETURN static void jsondec_err(jsondec *d, const char *msg) {
7024  upb_status_seterrf(d->status, "Error parsing JSON @%d:%d: %s", d->line,
7025  (int)(d->ptr - d->line_begin), msg);
7026  UPB_LONGJMP(d->err, 1);
7027 }
7028 
7029 UPB_PRINTF(2, 3)
7030 UPB_NORETURN static void jsondec_errf(jsondec *d, const char *fmt, ...) {
7031  va_list argp;
7032  upb_status_seterrf(d->status, "Error parsing JSON @%d:%d: ", d->line,
7033  (int)(d->ptr - d->line_begin));
7034  va_start(argp, fmt);
7035  upb_status_vappenderrf(d->status, fmt, argp);
7036  va_end(argp);
7037  UPB_LONGJMP(d->err, 1);
7038 }
7039 
7040 static void jsondec_skipws(jsondec *d) {
7041  while (d->ptr != d->end) {
7042  switch (*d->ptr) {
7043  case '\n':
7044  d->line++;
7045  d->line_begin = d->ptr;
7046  /* Fallthrough. */
7047  case '\r':
7048  case '\t':
7049  case ' ':
7050  d->ptr++;
7051  break;
7052  default:
7053  return;
7054  }
7055  }
7056  jsondec_err(d, "Unexpected EOF");
7057 }
7058 
7059 static bool jsondec_tryparsech(jsondec *d, char ch) {
7060  if (d->ptr == d->end || *d->ptr != ch) return false;
7061  d->ptr++;
7062  return true;
7063 }
7064 
7065 static void jsondec_parselit(jsondec *d, const char *lit) {
7066  size_t avail = d->end - d->ptr;
7067  size_t len = strlen(lit);
7068  if (avail < len || memcmp(d->ptr, lit, len) != 0) {
7069  jsondec_errf(d, "Expected: '%s'", lit);
7070  }
7071  d->ptr += len;
7072 }
7073 
7074 static void jsondec_wsch(jsondec *d, char ch) {
7075  jsondec_skipws(d);
7076  if (!jsondec_tryparsech(d, ch)) {
7077  jsondec_errf(d, "Expected: '%c'", ch);
7078  }
7079 }
7080 
7081 static void jsondec_true(jsondec *d) { jsondec_parselit(d, "true"); }
7082 static void jsondec_false(jsondec *d) { jsondec_parselit(d, "false"); }
7083 static void jsondec_null(jsondec *d) { jsondec_parselit(d, "null"); }
7084 
7085 static void jsondec_entrysep(jsondec *d) {
7086  jsondec_skipws(d);
7087  jsondec_parselit(d, ":");
7088 }
7089 
7090 static int jsondec_rawpeek(jsondec *d) {
7091  switch (*d->ptr) {
7092  case '{':
7093  return JD_OBJECT;
7094  case '[':
7095  return JD_ARRAY;
7096  case '"':
7097  return JD_STRING;
7098  case '-':
7099  case '0':
7100  case '1':
7101  case '2':
7102  case '3':
7103  case '4':
7104  case '5':
7105  case '6':
7106  case '7':
7107  case '8':
7108  case '9':
7109  return JD_NUMBER;
7110  case 't':
7111  return JD_TRUE;
7112  case 'f':
7113  return JD_FALSE;
7114  case 'n':
7115  return JD_NULL;
7116  default:
7117  jsondec_errf(d, "Unexpected character: '%c'", *d->ptr);
7118  }
7119 }
7120 
7121 /* JSON object/array **********************************************************/
7122 
7123 /* These are used like so:
7124  *
7125  * jsondec_objstart(d);
7126  * while (jsondec_objnext(d)) {
7127  * ...
7128  * }
7129  * jsondec_objend(d) */
7130 
7131 static int jsondec_peek(jsondec *d) {
7132  jsondec_skipws(d);
7133  return jsondec_rawpeek(d);
7134 }
7135 
7136 static void jsondec_push(jsondec *d) {
7137  if (--d->depth < 0) {
7138  jsondec_err(d, "Recursion limit exceeded");
7139  }
7140  d->is_first = true;
7141 }
7142 
7143 static bool jsondec_seqnext(jsondec *d, char end_ch) {
7144  bool is_first = d->is_first;
7145  d->is_first = false;
7146  jsondec_skipws(d);
7147  if (*d->ptr == end_ch) return false;
7148  if (!is_first) jsondec_parselit(d, ",");
7149  return true;
7150 }
7151 
7152 static void jsondec_arrstart(jsondec *d) {
7153  jsondec_push(d);
7154  jsondec_wsch(d, '[');
7155 }
7156 
7157 static void jsondec_arrend(jsondec *d) {
7158  d->depth++;
7159  jsondec_wsch(d, ']');
7160 }
7161 
7162 static bool jsondec_arrnext(jsondec *d) {
7163  return jsondec_seqnext(d, ']');
7164 }
7165 
7166 static void jsondec_objstart(jsondec *d) {
7167  jsondec_push(d);
7168  jsondec_wsch(d, '{');
7169 }
7170 
7171 static void jsondec_objend(jsondec *d) {
7172  d->depth++;
7173  jsondec_wsch(d, '}');
7174 }
7175 
7176 static bool jsondec_objnext(jsondec *d) {
7177  if (!jsondec_seqnext(d, '}')) return false;
7178  if (jsondec_peek(d) != JD_STRING) {
7179  jsondec_err(d, "Object must start with string");
7180  }
7181  return true;
7182 }
7183 
7184 /* JSON number ****************************************************************/
7185 
7187  const char *start = d->ptr;
7188 
7189  while (d->ptr < d->end) {
7190  if (*d->ptr < '0' || *d->ptr > '9') {
7191  break;
7192  }
7193  d->ptr++;
7194  }
7195 
7196  return d->ptr != start;
7197 }
7198 
7200  if (!jsondec_tryskipdigits(d)) {
7201  jsondec_err(d, "Expected one or more digits");
7202  }
7203 }
7204 
7205 static double jsondec_number(jsondec *d) {
7206  const char *start = d->ptr;
7207 
7208  assert(jsondec_rawpeek(d) == JD_NUMBER);
7209 
7210  /* Skip over the syntax of a number, as specified by JSON. */
7211  if (*d->ptr == '-') d->ptr++;
7212 
7213  if (jsondec_tryparsech(d, '0')) {
7214  if (jsondec_tryskipdigits(d)) {
7215  jsondec_err(d, "number cannot have leading zero");
7216  }
7217  } else {
7219  }
7220 
7221  if (d->ptr == d->end) goto parse;
7222  if (jsondec_tryparsech(d, '.')) {
7224  }
7225  if (d->ptr == d->end) goto parse;
7226 
7227  if (*d->ptr == 'e' || *d->ptr == 'E') {
7228  d->ptr++;
7229  if (d->ptr == d->end) {
7230  jsondec_err(d, "Unexpected EOF in number");
7231  }
7232  if (*d->ptr == '+' || *d->ptr == '-') {
7233  d->ptr++;
7234  }
7236  }
7237 
7238 parse:
7239  /* Having verified the syntax of a JSON number, use strtod() to parse
7240  * (strtod() accepts a superset of JSON syntax). */
7241  errno = 0;
7242  {
7243  char* end;
7244  double val = strtod(start, &end);
7245  assert(end == d->ptr);
7246 
7247  /* Currently the min/max-val conformance tests fail if we check this. Does
7248  * this mean the conformance tests are wrong or strtod() is wrong, or
7249  * something else? Investigate further. */
7250  /*
7251  if (errno == ERANGE) {
7252  jsondec_err(d, "Number out of range");
7253  }
7254  */
7255 
7256  if (val > DBL_MAX || val < -DBL_MAX) {
7257  jsondec_err(d, "Number out of range");
7258  }
7259 
7260  return val;
7261  }
7262 }
7263 
7264 /* JSON string ****************************************************************/
7265 
7266 static char jsondec_escape(jsondec *d) {
7267  switch (*d->ptr++) {
7268  case '"':
7269  return '\"';
7270  case '\\':
7271  return '\\';
7272  case '/':
7273  return '/';
7274  case 'b':
7275  return '\b';
7276  case 'f':
7277  return '\f';
7278  case 'n':
7279  return '\n';
7280  case 'r':
7281  return '\r';
7282  case 't':
7283  return '\t';
7284  default:
7285  jsondec_err(d, "Invalid escape char");
7286  }
7287 }
7288 
7290  uint32_t cp = 0;
7291  const char *end;
7292 
7293  if (d->end - d->ptr < 4) {
7294  jsondec_err(d, "EOF inside string");
7295  }
7296 
7297  end = d->ptr + 4;
7298  while (d->ptr < end) {
7299  char ch = *d->ptr++;
7300  if (ch >= '0' && ch <= '9') {
7301  ch -= '0';
7302  } else if (ch >= 'a' && ch <= 'f') {
7303  ch = ch - 'a' + 10;
7304  } else if (ch >= 'A' && ch <= 'F') {
7305  ch = ch - 'A' + 10;
7306  } else {
7307  jsondec_err(d, "Invalid hex digit");
7308  }
7309  cp = (cp << 4) | ch;
7310  }
7311 
7312  return cp;
7313 }
7314 
7315 /* Parses a \uXXXX unicode escape (possibly a surrogate pair). */
7316 static size_t jsondec_unicode(jsondec *d, char* out) {
7318  if (cp >= 0xd800 && cp <= 0xdbff) {
7319  /* Surrogate pair: two 16-bit codepoints become a 32-bit codepoint. */
7320  uint32_t high = cp;
7321  uint32_t low;
7322  jsondec_parselit(d, "\\u");
7323  low = jsondec_codepoint(d);
7324  if (low < 0xdc00 || low > 0xdfff) {
7325  jsondec_err(d, "Invalid low surrogate");
7326  }
7327  cp = (high & 0x3ff) << 10;
7328  cp |= (low & 0x3ff);
7329  cp += 0x10000;
7330  } else if (cp >= 0xdc00 && cp <= 0xdfff) {
7331  jsondec_err(d, "Unpaired low surrogate");
7332  }
7333 
7334  /* Write to UTF-8 */
7335  if (cp <= 0x7f) {
7336  out[0] = cp;
7337  return 1;
7338  } else if (cp <= 0x07FF) {
7339  out[0] = ((cp >> 6) & 0x1F) | 0xC0;
7340  out[1] = ((cp >> 0) & 0x3F) | 0x80;
7341  return 2;
7342  } else if (cp <= 0xFFFF) {
7343  out[0] = ((cp >> 12) & 0x0F) | 0xE0;
7344  out[1] = ((cp >> 6) & 0x3F) | 0x80;
7345  out[2] = ((cp >> 0) & 0x3F) | 0x80;
7346  return 3;
7347  } else if (cp < 0x10FFFF) {
7348  out[0] = ((cp >> 18) & 0x07) | 0xF0;
7349  out[1] = ((cp >> 12) & 0x3f) | 0x80;
7350  out[2] = ((cp >> 6) & 0x3f) | 0x80;
7351  out[3] = ((cp >> 0) & 0x3f) | 0x80;
7352  return 4;
7353  } else {
7354  jsondec_err(d, "Invalid codepoint");
7355  }
7356 }
7357 
7358 static void jsondec_resize(jsondec *d, char **buf, char **end, char **buf_end) {
7359  size_t oldsize = *buf_end - *buf;
7360  size_t len = *end - *buf;
7361  size_t size = UPB_MAX(8, 2 * oldsize);
7362 
7363  *buf = upb_arena_realloc(d->arena, *buf, len, size);
7364  if (!*buf) jsondec_err(d, "Out of memory");
7365 
7366  *end = *buf + len;
7367  *buf_end = *buf + size;
7368 }
7369 
7371  char *buf = NULL;
7372  char *end = NULL;
7373  char *buf_end = NULL;
7374 
7375  jsondec_skipws(d);
7376 
7377  if (*d->ptr++ != '"') {
7378  jsondec_err(d, "Expected string");
7379  }
7380 
7381  while (d->ptr < d->end) {
7382  char ch = *d->ptr++;
7383 
7384  if (end == buf_end) {
7385  jsondec_resize(d, &buf, &end, &buf_end);
7386  }
7387 
7388  switch (ch) {
7389  case '"': {
7390  upb_strview ret;
7391  ret.data = buf;
7392  ret.size = end - buf;
7393  *end = '\0'; /* Needed for possible strtod(). */
7394  return ret;
7395  }
7396  case '\\':
7397  if (d->ptr == d->end) goto eof;
7398  if (*d->ptr == 'u') {
7399  d->ptr++;
7400  if (buf_end - end < 4) {
7401  /* Allow space for maximum-sized code point (4 bytes). */
7402  jsondec_resize(d, &buf, &end, &buf_end);
7403  }
7404  end += jsondec_unicode(d, end);
7405  } else {
7406  *end++ = jsondec_escape(d);
7407  }
7408  break;
7409  default:
7410  if ((unsigned char)*d->ptr < 0x20) {
7411  jsondec_err(d, "Invalid char in JSON string");
7412  }
7413  *end++ = ch;
7414  break;
7415  }
7416  }
7417 
7418 eof:
7419  jsondec_err(d, "EOF inside string");
7420 }
7421 
7422 static void jsondec_skipval(jsondec *d) {
7423  switch (jsondec_peek(d)) {
7424  case JD_OBJECT:
7426  while (jsondec_objnext(d)) {
7427  jsondec_string(d);
7429  jsondec_skipval(d);
7430  }
7431  jsondec_objend(d);
7432  break;
7433  case JD_ARRAY:
7435  while (jsondec_arrnext(d)) {
7436  jsondec_skipval(d);
7437  }
7438  jsondec_arrend(d);
7439  break;
7440  case JD_TRUE:
7441  jsondec_true(d);
7442  break;
7443  case JD_FALSE:
7444  jsondec_false(d);
7445  break;
7446  case JD_NULL:
7447  jsondec_null(d);
7448  break;
7449  case JD_STRING:
7450  jsondec_string(d);
7451  break;
7452  case JD_NUMBER:
7453  jsondec_number(d);
7454  break;
7455  }
7456 }
7457 
7458 /* Base64 decoding for bytes fields. ******************************************/
7459 
7460 static unsigned int jsondec_base64_tablelookup(const char ch) {
7461  /* Table includes the normal base64 chars plus the URL-safe variant. */
7462  const signed char table[256] = {
7463  -1, -1, -1, -1, -1, -1, -1,
7464  -1, -1, -1, -1, -1, -1, -1,
7465  -1, -1, -1, -1, -1, -1, -1,
7466  -1, -1, -1, -1, -1, -1, -1,
7467  -1, -1, -1, -1, -1, -1, -1,
7468  -1, -1, -1, -1, -1, -1, -1,
7469  -1, 62 /*+*/, -1, 62 /*-*/, -1, 63 /*/ */, 52 /*0*/,
7470  53 /*1*/, 54 /*2*/, 55 /*3*/, 56 /*4*/, 57 /*5*/, 58 /*6*/, 59 /*7*/,
7471  60 /*8*/, 61 /*9*/, -1, -1, -1, -1, -1,
7472  -1, -1, 0 /*A*/, 1 /*B*/, 2 /*C*/, 3 /*D*/, 4 /*E*/,
7473  5 /*F*/, 6 /*G*/, 07 /*H*/, 8 /*I*/, 9 /*J*/, 10 /*K*/, 11 /*L*/,
7474  12 /*M*/, 13 /*N*/, 14 /*O*/, 15 /*P*/, 16 /*Q*/, 17 /*R*/, 18 /*S*/,
7475  19 /*T*/, 20 /*U*/, 21 /*V*/, 22 /*W*/, 23 /*X*/, 24 /*Y*/, 25 /*Z*/,
7476  -1, -1, -1, -1, 63 /*_*/, -1, 26 /*a*/,
7477  27 /*b*/, 28 /*c*/, 29 /*d*/, 30 /*e*/, 31 /*f*/, 32 /*g*/, 33 /*h*/,
7478  34 /*i*/, 35 /*j*/, 36 /*k*/, 37 /*l*/, 38 /*m*/, 39 /*n*/, 40 /*o*/,
7479  41 /*p*/, 42 /*q*/, 43 /*r*/, 44 /*s*/, 45 /*t*/, 46 /*u*/, 47 /*v*/,
7480  48 /*w*/, 49 /*x*/, 50 /*y*/, 51 /*z*/, -1, -1, -1,
7481  -1, -1, -1, -1, -1, -1, -1,
7482  -1, -1, -1, -1, -1, -1, -1,
7483  -1, -1, -1, -1, -1, -1, -1,
7484  -1, -1, -1, -1, -1, -1, -1,
7485  -1, -1, -1, -1, -1, -1, -1,
7486  -1, -1, -1, -1, -1, -1, -1,
7487  -1, -1, -1, -1, -1, -1, -1,
7488  -1, -1, -1, -1, -1, -1, -1,
7489  -1, -1, -1, -1, -1, -1, -1,
7490  -1, -1, -1, -1, -1, -1, -1,
7491  -1, -1, -1, -1, -1, -1, -1,
7492  -1, -1, -1, -1, -1, -1, -1,
7493  -1, -1, -1, -1, -1, -1, -1,
7494  -1, -1, -1, -1, -1, -1, -1,
7495  -1, -1, -1, -1, -1, -1, -1,
7496  -1, -1, -1, -1, -1, -1, -1,
7497  -1, -1, -1, -1, -1, -1, -1,
7498  -1, -1, -1, -1, -1, -1, -1,
7499  -1, -1, -1, -1};
7500 
7501  /* Sign-extend return value so high bit will be set on any unexpected char. */
7502  return table[(unsigned)ch];
7503 }
7504 
7505 static char *jsondec_partialbase64(jsondec *d, const char *ptr, const char *end,
7506  char *out) {
7507  int32_t val = -1;
7508 
7509  switch (end - ptr) {
7510  case 2:
7511  val = jsondec_base64_tablelookup(ptr[0]) << 18 |
7512  jsondec_base64_tablelookup(ptr[1]) << 12;
7513  out[0] = val >> 16;
7514  out += 1;
7515  break;
7516  case 3:
7517  val = jsondec_base64_tablelookup(ptr[0]) << 18 |
7518  jsondec_base64_tablelookup(ptr[1]) << 12 |
7520  out[0] = val >> 16;
7521  out[1] = (val >> 8) & 0xff;
7522  out += 2;
7523  break;
7524  }
7525 
7526  if (val < 0) {
7527  jsondec_err(d, "Corrupt base64");
7528  }
7529 
7530  return out;
7531 }
7532 
7534  /* We decode in place. This is safe because this is a new buffer (not
7535  * aliasing the input) and because base64 decoding shrinks 4 bytes into 3. */
7536  char *out = (char*)str.data;
7537  const char *ptr = str.data;
7538  const char *end = ptr + str.size;
7539  const char *end4 = ptr + (str.size & -4); /* Round down to multiple of 4. */
7540 
7541  for (; ptr < end4; ptr += 4, out += 3) {
7542  int val = jsondec_base64_tablelookup(ptr[0]) << 18 |
7543  jsondec_base64_tablelookup(ptr[1]) << 12 |
7544  jsondec_base64_tablelookup(ptr[2]) << 6 |
7546 
7547  if (val < 0) {
7548  /* Junk chars or padding. Remove trailing padding, if any. */
7549  if (end - ptr == 4 && ptr[3] == '=') {
7550  if (ptr[2] == '=') {
7551  end -= 2;
7552  } else {
7553  end -= 1;
7554  }
7555  }
7556  break;
7557  }
7558 
7559  out[0] = val >> 16;
7560  out[1] = (val >> 8) & 0xff;
7561  out[2] = val & 0xff;
7562  }
7563 
7564  if (ptr < end) {
7565  /* Process remaining chars. We do not require padding. */
7567  }
7568 
7569  return out - str.data;
7570 }
7571 
7572 /* Low-level integer parsing **************************************************/
7573 
7574 /* We use these hand-written routines instead of strto[u]l() because the "long
7575  * long" variants aren't in c89. Also our version allows setting a ptr limit. */
7576 
7577 static const char *jsondec_buftouint64(jsondec *d, const char *ptr,
7578  const char *end, uint64_t *val) {
7579  uint64_t u64 = 0;
7580  while (ptr < end) {
7581  unsigned ch = *ptr - '0';
7582  if (ch >= 10) break;
7583  if (u64 > UINT64_MAX / 10 || u64 * 10 > UINT64_MAX - ch) {
7584  jsondec_err(d, "Integer overflow");
7585  }
7586  u64 *= 10;
7587  u64 += ch;
7588  ptr++;
7589  }
7590 
7591  *val = u64;
7592  return ptr;
7593 }
7594 
7595 static const char *jsondec_buftoint64(jsondec *d, const char *ptr,
7596  const char *end, int64_t *val) {
7597  bool neg = false;
7598  uint64_t u64;
7599 
7600  if (ptr != end && *ptr == '-') {
7601  ptr++;
7602  neg = true;
7603  }
7604 
7605  ptr = jsondec_buftouint64(d, ptr, end, &u64);
7606  if (u64 > (uint64_t)INT64_MAX + neg) {
7607  jsondec_err(d, "Integer overflow");
7608  }
7609 
7610  *val = neg ? -u64 : u64;
7611  return ptr;
7612 }
7613 
7615  const char *end = str.data + str.size;
7616  uint64_t ret;
7617  if (jsondec_buftouint64(d, str.data, end, &ret) != end) {
7618  jsondec_err(d, "Non-number characters in quoted integer");
7619  }
7620  return ret;
7621 }
7622 
7624  const char *end = str.data + str.size;
7625  int64_t ret;
7626  if (jsondec_buftoint64(d, str.data, end, &ret) != end) {
7627  jsondec_err(d, "Non-number characters in quoted integer");
7628  }
7629  return ret;
7630 }
7631 
7632 /* Primitive value types ******************************************************/
7633 
7634 /* Parse INT32 or INT64 value. */
7636  upb_msgval val;
7637 
7638  switch (jsondec_peek(d)) {
7639  case JD_NUMBER: {
7640  double dbl = jsondec_number(d);
7641  if (dbl > 9223372036854774784.0 || dbl < -9223372036854775808.0) {
7642  jsondec_err(d, "JSON number is out of range.");
7643  }
7644  val.int64_val = dbl; /* must be guarded, overflow here is UB */
7645  if (val.int64_val != dbl) {
7646  jsondec_errf(d, "JSON number was not integral (%f != %" PRId64 ")", dbl,
7647  val.int64_val);
7648  }
7649  break;
7650  }
7651  case JD_STRING: {
7654  break;
7655  }
7656  default:
7657  jsondec_err(d, "Expected number or string");
7658  }
7659 
7661  if (val.int64_val > INT32_MAX || val.int64_val < INT32_MIN) {
7662  jsondec_err(d, "Integer out of range.");
7663  }
7664  val.int32_val = (int32_t)val.int64_val;
7665  }
7666 
7667  return val;
7668 }
7669 
7670 /* Parse UINT32 or UINT64 value. */
7672  upb_msgval val = {0};
7673 
7674  switch (jsondec_peek(d)) {
7675  case JD_NUMBER: {
7676  double dbl = jsondec_number(d);
7677  if (dbl > 18446744073709549568.0 || dbl < 0) {
7678  jsondec_err(d, "JSON number is out of range.");
7679  }
7680  val.uint64_val = dbl; /* must be guarded, overflow here is UB */
7681  if (val.uint64_val != dbl) {
7682  jsondec_errf(d, "JSON number was not integral (%f != %" PRIu64 ")", dbl,
7683  val.uint64_val);
7684  }
7685  break;
7686  }
7687  case JD_STRING: {
7690  break;
7691  }
7692  default:
7693  jsondec_err(d, "Expected number or string");
7694  }
7695 
7697  if (val.uint64_val > UINT32_MAX) {
7698  jsondec_err(d, "Integer out of range.");
7699  }
7700  val.uint32_val = (uint32_t)val.uint64_val;
7701  }
7702 
7703  return val;
7704 }
7705 
7706 /* Parse DOUBLE or FLOAT value. */
7708  upb_strview str;
7709  upb_msgval val = {0};
7710 
7711  switch (jsondec_peek(d)) {
7712  case JD_NUMBER:
7713  val.double_val = jsondec_number(d);
7714  break;
7715  case JD_STRING:
7716  str = jsondec_string(d);
7717  if (jsondec_streql(str, "NaN")) {
7718  val.double_val = NAN;
7719  } else if (jsondec_streql(str, "Infinity")) {
7720  val.double_val = INFINITY;
7721  } else if (jsondec_streql(str, "-Infinity")) {
7722  val.double_val = -INFINITY;
7723  } else {
7724  val.double_val = strtod(str.data, NULL);
7725  }
7726  break;
7727  default:
7728  jsondec_err(d, "Expected number or string");
7729  }
7730 
7732  if (val.double_val != INFINITY && val.double_val != -INFINITY &&
7733  (val.double_val > FLT_MAX || val.double_val < -FLT_MAX)) {
7734  jsondec_err(d, "Float out of range");
7735  }
7736  val.float_val = val.double_val;
7737  }
7738 
7739  return val;
7740 }
7741 
7742 /* Parse STRING or BYTES value. */
7744  upb_msgval val;
7745  val.str_val = jsondec_string(d);
7747  val.str_val.size = jsondec_base64(d, val.str_val);
7748  }
7749  return val;
7750 }
7751 
7753  switch (jsondec_peek(d)) {
7754  case JD_STRING: {
7757  upb_msgval val;
7758  if (!upb_enumdef_ntoi(e, str.data, str.size, &val.int32_val)) {
7759  if (d->options & UPB_JSONDEC_IGNOREUNKNOWN) {
7760  val.int32_val = 0;
7761  } else {
7762  jsondec_errf(d, "Unknown enumerator: '" UPB_STRVIEW_FORMAT "'",
7764  }
7765  }
7766  return val;
7767  }
7768  case JD_NULL: {
7769  if (jsondec_isnullvalue(f)) {
7770  upb_msgval val;
7771  jsondec_null(d);
7772  val.int32_val = 0;
7773  return val;
7774  }
7775  }
7776  /* Fallthrough. */
7777  default:
7778  return jsondec_int(d, f);
7779  }
7780 }
7781 
7783  bool is_map_key = upb_fielddef_number(f) == 1 &&
7785  upb_msgval val;
7786 
7787  if (is_map_key) {
7789  if (jsondec_streql(str, "true")) {
7790  val.bool_val = true;
7791  } else if (jsondec_streql(str, "false")) {
7792  val.bool_val = false;
7793  } else {
7794  jsondec_err(d, "Invalid boolean map key");
7795  }
7796  } else {
7797  switch (jsondec_peek(d)) {
7798  case JD_TRUE:
7799  val.bool_val = true;
7800  jsondec_true(d);
7801  break;
7802  case JD_FALSE:
7803  val.bool_val = false;
7804  jsondec_false(d);
7805  break;
7806  default:
7807  jsondec_err(d, "Expected true or false");
7808  }
7809  }
7810 
7811  return val;
7812 }
7813 
7814 /* Composite types (array/message/map) ****************************************/
7815 
7816 static void jsondec_array(jsondec *d, upb_msg *msg, const upb_fielddef *f) {
7817  upb_array *arr = upb_msg_mutable(msg, f, d->arena).array;
7818 
7820  while (jsondec_arrnext(d)) {
7822  upb_array_append(arr, elem, d->arena);
7823  }
7824  jsondec_arrend(d);
7825 }
7826 
7827 static void jsondec_map(jsondec *d, upb_msg *msg, const upb_fielddef *f) {
7828  upb_map *map = upb_msg_mutable(msg, f, d->arena).map;
7829  const upb_msgdef *entry = upb_fielddef_msgsubdef(f);
7830  const upb_fielddef *key_f = upb_msgdef_itof(entry, 1);
7831  const upb_fielddef *val_f = upb_msgdef_itof(entry, 2);
7832 
7834  while (jsondec_objnext(d)) {
7835  upb_msgval key, val;
7836  key = jsondec_value(d, key_f);
7838  val = jsondec_value(d, val_f);
7839  upb_map_set(map, key, val, d->arena);
7840  }
7841  jsondec_objend(d);
7842 }
7843 
7844 static void jsondec_tomsg(jsondec *d, upb_msg *msg, const upb_msgdef *m) {
7846  jsondec_object(d, msg, m);
7847  } else {
7848  jsondec_wellknown(d, msg, m);
7849  }
7850 }
7851 
7854  upb_msg *msg = upb_msg_new(m, d->arena);
7855  upb_msgval val;
7856 
7857  jsondec_tomsg(d, msg, m);
7858  val.msg_val = msg;
7859  return val;
7860 }
7861 
7862 static void jsondec_field(jsondec *d, upb_msg *msg, const upb_msgdef *m) {
7863  upb_strview name;
7864  const upb_fielddef *f;
7865  const upb_fielddef *preserved;
7866 
7867  name = jsondec_string(d);
7869  f = upb_msgdef_lookupjsonname(m, name.data, name.size);
7870 
7871  if (!f) {
7872  if ((d->options & UPB_JSONDEC_IGNOREUNKNOWN) == 0) {
7873  jsondec_errf(d, "No such field: " UPB_STRVIEW_FORMAT,
7875  }
7876  jsondec_skipval(d);
7877  return;
7878  }
7879 
7880  if (jsondec_peek(d) == JD_NULL && !jsondec_isvalue(f)) {
7881  /* JSON "null" indicates a default value, so no need to set anything. */
7882  jsondec_null(d);
7883  return;
7884  }
7885 
7888  jsondec_err(d, "More than one field for this oneof.");
7889  }
7890 
7891  preserved = d->debug_field;
7892  d->debug_field = f;
7893 
7894  if (upb_fielddef_ismap(f)) {
7895  jsondec_map(d, msg, f);
7896  } else if (upb_fielddef_isseq(f)) {
7897  jsondec_array(d, msg, f);
7898  } else if (upb_fielddef_issubmsg(f)) {
7899  upb_msg *submsg = upb_msg_mutable(msg, f, d->arena).msg;
7900  const upb_msgdef *subm = upb_fielddef_msgsubdef(f);
7901  jsondec_tomsg(d, submsg, subm);
7902  } else {
7903  upb_msgval val = jsondec_value(d, f);
7904  upb_msg_set(msg, f, val, d->arena);
7905  }
7906 
7907  d->debug_field = preserved;
7908 }
7909 
7910 static void jsondec_object(jsondec *d, upb_msg *msg, const upb_msgdef *m) {
7912  while (jsondec_objnext(d)) {
7913  jsondec_field(d, msg, m);
7914  }
7915  jsondec_objend(d);
7916 }
7917 
7919  switch (upb_fielddef_type(f)) {
7920  case UPB_TYPE_BOOL:
7921  return jsondec_bool(d, f);
7922  case UPB_TYPE_FLOAT:
7923  case UPB_TYPE_DOUBLE:
7924  return jsondec_double(d, f);
7925  case UPB_TYPE_UINT32:
7926  case UPB_TYPE_UINT64:
7927  return jsondec_uint(d, f);
7928  case UPB_TYPE_INT32:
7929  case UPB_TYPE_INT64:
7930  return jsondec_int(d, f);
7931  case UPB_TYPE_STRING:
7932  case UPB_TYPE_BYTES:
7933  return jsondec_strfield(d, f);
7934  case UPB_TYPE_ENUM:
7935  return jsondec_enum(d, f);
7936  case UPB_TYPE_MESSAGE:
7937  return jsondec_msg(d, f);
7938  default:
7939  UPB_UNREACHABLE();
7940  }
7941 }
7942 
7943 /* Well-known types ***********************************************************/
7944 
7945 static int jsondec_tsdigits(jsondec *d, const char **ptr, size_t digits,
7946  const char *after) {
7947  uint64_t val;
7948  const char *p = *ptr;
7949  const char *end = p + digits;
7950  size_t after_len = after ? strlen(after) : 0;
7951 
7952  UPB_ASSERT(digits <= 9); /* int can't overflow. */
7953 
7954  if (jsondec_buftouint64(d, p, end, &val) != end ||
7955  (after_len && memcmp(end, after, after_len) != 0)) {
7956  jsondec_err(d, "Malformed timestamp");
7957  }
7958 
7959  UPB_ASSERT(val < INT_MAX);
7960 
7961  *ptr = end + after_len;
7962  return (int)val;
7963 }
7964 
7965 static int jsondec_nanos(jsondec *d, const char **ptr, const char *end) {
7966  uint64_t nanos = 0;
7967  const char *p = *ptr;
7968 
7969  if (p != end && *p == '.') {
7970  const char *nano_end = jsondec_buftouint64(d, p + 1, end, &nanos);
7971  int digits = (int)(nano_end - p - 1);
7972  int exp_lg10 = 9 - digits;
7973  if (digits > 9) {
7974  jsondec_err(d, "Too many digits for partial seconds");
7975  }
7976  while (exp_lg10--) nanos *= 10;
7977  *ptr = nano_end;
7978  }
7979 
7980  UPB_ASSERT(nanos < INT_MAX);
7981 
7982  return (int)nanos;
7983 }
7984 
7985 /* jsondec_epochdays(1970, 1, 1) == 1970-01-01 == 0. */
7986 int jsondec_epochdays(int y, int m, int d) {
7987  const uint32_t year_base = 4800; /* Before min year, multiple of 400. */
7988  const uint32_t m_adj = m - 3; /* March-based month. */
7989  const uint32_t carry = m_adj > (uint32_t)m ? 1 : 0;
7990  const uint32_t adjust = carry ? 12 : 0;
7991  const uint32_t y_adj = y + year_base - carry;
7992  const uint32_t month_days = ((m_adj + adjust) * 62719 + 769) / 2048;
7993  const uint32_t leap_days = y_adj / 4 - y_adj / 100 + y_adj / 400;
7994  return y_adj * 365 + leap_days + month_days + (d - 1) - 2472632;
7995 }
7996 
7997 static int64_t jsondec_unixtime(int y, int m, int d, int h, int min, int s) {
7998  return (int64_t)jsondec_epochdays(y, m, d) * 86400 + h * 3600 + min * 60 + s;
7999 }
8000 
8001 static void jsondec_timestamp(jsondec *d, upb_msg *msg, const upb_msgdef *m) {
8003  upb_msgval nanos;
8005  const char *ptr = str.data;
8006  const char *end = ptr + str.size;
8007 
8008  if (str.size < 20) goto malformed;
8009 
8010  {
8011  /* 1972-01-01T01:00:00 */
8012  int year = jsondec_tsdigits(d, &ptr, 4, "-");
8013  int mon = jsondec_tsdigits(d, &ptr, 2, "-");
8014  int day = jsondec_tsdigits(d, &ptr, 2, "T");
8015  int hour = jsondec_tsdigits(d, &ptr, 2, ":");
8016  int min = jsondec_tsdigits(d, &ptr, 2, ":");
8017  int sec = jsondec_tsdigits(d, &ptr, 2, NULL);
8018 
8019  seconds.int64_val = jsondec_unixtime(year, mon, day, hour, min, sec);
8020  }
8021 
8022  nanos.int32_val = jsondec_nanos(d, &ptr, end);
8023 
8024  {
8025  /* [+-]08:00 or Z */
8026  int ofs_hour = 0;
8027  int ofs_min = 0;
8028  bool neg = false;
8029 
8030  if (ptr == end) goto malformed;
8031 
8032  switch (*ptr++) {
8033  case '-':
8034  neg = true;
8035  /* fallthrough */
8036  case '+':
8037  if ((end - ptr) != 5) goto malformed;
8038  ofs_hour = jsondec_tsdigits(d, &ptr, 2, ":");
8039  ofs_min = jsondec_tsdigits(d, &ptr, 2, NULL);
8040  ofs_min = ((ofs_hour * 60) + ofs_min) * 60;
8041  seconds.int64_val += (neg ? ofs_min : -ofs_min);
8042  break;
8043  case 'Z':
8044  if (ptr != end) goto malformed;
8045  break;
8046  default:
8047  goto malformed;
8048  }
8049  }
8050 
8051  if (seconds.int64_val < -62135596800) {
8052  jsondec_err(d, "Timestamp out of range");
8053  }
8054 
8055  upb_msg_set(msg, upb_msgdef_itof(m, 1), seconds, d->arena);
8056  upb_msg_set(msg, upb_msgdef_itof(m, 2), nanos, d->arena);
8057  return;
8058 
8059 malformed:
8060  jsondec_err(d, "Malformed timestamp");
8061 }
8062 
8063 static void jsondec_duration(jsondec *d, upb_msg *msg, const upb_msgdef *m) {
8065  upb_msgval nanos;
8067  const char *ptr = str.data;
8068  const char *end = ptr + str.size;
8069  const int64_t max = (uint64_t)3652500 * 86400;
8070 
8071  /* "3.000000001s", "3s", etc. */
8072  ptr = jsondec_buftoint64(d, ptr, end, &seconds.int64_val);
8073  nanos.int32_val = jsondec_nanos(d, &ptr, end);
8074 
8075  if (end - ptr != 1 || *ptr != 's') {
8076  jsondec_err(d, "Malformed duration");
8077  }
8078 
8079  if (seconds.int64_val < -max || seconds.int64_val > max) {
8080  jsondec_err(d, "Duration out of range");
8081  }
8082 
8083  if (seconds.int64_val < 0) {
8084  nanos.int32_val = - nanos.int32_val;
8085  }
8086 
8087  upb_msg_set(msg, upb_msgdef_itof(m, 1), seconds, d->arena);
8088  upb_msg_set(msg, upb_msgdef_itof(m, 2), nanos, d->arena);
8089 }
8090 
8091 static void jsondec_listvalue(jsondec *d, upb_msg *msg, const upb_msgdef *m) {
8092  const upb_fielddef *values_f = upb_msgdef_itof(m, 1);
8093  const upb_msgdef *value_m = upb_fielddef_msgsubdef(values_f);
8094  upb_array *values = upb_msg_mutable(msg, values_f, d->arena).array;
8095 
8097  while (jsondec_arrnext(d)) {
8098  upb_msg *value_msg = upb_msg_new(value_m, d->arena);
8099  upb_msgval value;
8100  value.msg_val = value_msg;
8101  upb_array_append(values, value, d->arena);
8102  jsondec_wellknownvalue(d, value_msg, value_m);
8103  }
8104  jsondec_arrend(d);
8105 }
8106 
8107 static void jsondec_struct(jsondec *d, upb_msg *msg, const upb_msgdef *m) {
8108  const upb_fielddef *fields_f = upb_msgdef_itof(m, 1);
8109  const upb_msgdef *entry_m = upb_fielddef_msgsubdef(fields_f);
8110  const upb_fielddef *value_f = upb_msgdef_itof(entry_m, 2);
8111  const upb_msgdef *value_m = upb_fielddef_msgsubdef(value_f);
8112  upb_map *fields = upb_msg_mutable(msg, fields_f, d->arena).map;
8113 
8115  while (jsondec_objnext(d)) {
8116  upb_msgval key, value;
8117  upb_msg *value_msg = upb_msg_new(value_m, d->arena);
8118  key.str_val = jsondec_string(d);
8119  value.msg_val = value_msg;
8120  upb_map_set(fields, key, value, d->arena);
8122  jsondec_wellknownvalue(d, value_msg, value_m);
8123  }
8124  jsondec_objend(d);
8125 }
8126 
8128  const upb_msgdef *m) {
8129  upb_msgval val;
8130  const upb_fielddef *f;
8131  upb_msg *submsg;
8132 
8133  switch (jsondec_peek(d)) {
8134  case JD_NUMBER:
8135  /* double number_value = 2; */
8136  f = upb_msgdef_itof(m, 2);
8137  val.double_val = jsondec_number(d);
8138  break;
8139  case JD_STRING:
8140  /* string string_value = 3; */
8141  f = upb_msgdef_itof(m, 3);
8142  val.str_val = jsondec_string(d);
8143  break;
8144  case JD_FALSE:
8145  /* bool bool_value = 4; */
8146  f = upb_msgdef_itof(m, 4);
8147  val.bool_val = false;
8148  jsondec_false(d);
8149  break;
8150  case JD_TRUE:
8151  /* bool bool_value = 4; */
8152  f = upb_msgdef_itof(m, 4);
8153  val.bool_val = true;
8154  jsondec_true(d);
8155  break;
8156  case JD_NULL:
8157  /* NullValue null_value = 1; */
8158  f = upb_msgdef_itof(m, 1);
8159  val.int32_val = 0;
8160  jsondec_null(d);
8161  break;
8162  /* Note: these cases return, because upb_msg_mutable() is enough. */
8163  case JD_OBJECT:
8164  /* Struct struct_value = 5; */
8165  f = upb_msgdef_itof(m, 5);
8166  submsg = upb_msg_mutable(msg, f, d->arena).msg;
8168  return;
8169  case JD_ARRAY:
8170  /* ListValue list_value = 6; */
8171  f = upb_msgdef_itof(m, 6);
8172  submsg = upb_msg_mutable(msg, f, d->arena).msg;
8174  return;
8175  default:
8176  UPB_UNREACHABLE();
8177  }
8178 
8179  upb_msg_set(msg, f, val, d->arena);
8180 }
8181 
8182 static upb_strview jsondec_mask(jsondec *d, const char *buf, const char *end) {
8183  /* FieldMask fields grow due to inserted '_' characters, so we can't do the
8184  * transform in place. */
8185  const char *ptr = buf;
8186  upb_strview ret;
8187  char *out;
8188 
8189  ret.size = end - ptr;
8190  while (ptr < end) {
8191  ret.size += (*ptr >= 'A' && *ptr <= 'Z');
8192  ptr++;
8193  }
8194 
8195  out = upb_arena_malloc(d->arena, ret.size);
8196  ptr = buf;
8197  ret.data = out;
8198 
8199  while (ptr < end) {
8200  char ch = *ptr++;
8201  if (ch >= 'A' && ch <= 'Z') {
8202  *out++ = '_';
8203  *out++ = ch + 32;
8204  } else if (ch == '_') {
8205  jsondec_err(d, "field mask may not contain '_'");
8206  } else {
8207  *out++ = ch;
8208  }
8209  }
8210 
8211  return ret;
8212 }
8213 
8214 static void jsondec_fieldmask(jsondec *d, upb_msg *msg, const upb_msgdef *m) {
8215  /* repeated string paths = 1; */
8216  const upb_fielddef *paths_f = upb_msgdef_itof(m, 1);
8217  upb_array *arr = upb_msg_mutable(msg, paths_f, d->arena).array;
8219  const char *ptr = str.data;
8220  const char *end = ptr + str.size;
8221  upb_msgval val;
8222 
8223  while (ptr < end) {
8224  const char *elem_end = memchr(ptr, ',', end - ptr);
8225  if (elem_end) {
8226  val.str_val = jsondec_mask(d, ptr, elem_end);
8227  ptr = elem_end + 1;
8228  } else {
8229  val.str_val = jsondec_mask(d, ptr, end);
8230  ptr = end;
8231  }
8232  upb_array_append(arr, val, d->arena);
8233  }
8234 }
8235 
8236 static void jsondec_anyfield(jsondec *d, upb_msg *msg, const upb_msgdef *m) {
8238  /* For regular types: {"@type": "[user type]", "f1": <V1>, "f2": <V2>}
8239  * where f1, f2, etc. are the normal fields of this type. */
8240  jsondec_field(d, msg, m);
8241  } else {
8242  /* For well-known types: {"@type": "[well-known type]", "value": <X>}
8243  * where <X> is whatever encoding the WKT normally uses. */
8246  if (!jsondec_streql(str, "value")) {
8247  jsondec_err(d, "Key for well-known type must be 'value'");
8248  }
8249  jsondec_wellknown(d, msg, m);
8250  }
8251 }
8252 
8254  const upb_msgdef *m) {
8255  const upb_fielddef *type_url_f = upb_msgdef_itof(m, 1);
8256  const upb_msgdef *type_m;
8258  const char *end = type_url.data + type_url.size;
8259  const char *ptr = end;
8260  upb_msgval val;
8261 
8262  val.str_val = type_url;
8263  upb_msg_set(msg, type_url_f, val, d->arena);
8264 
8265  /* Find message name after the last '/' */
8266  while (ptr > type_url.data && *--ptr != '/') {}
8267 
8268  if (ptr == type_url.data || ptr == end) {
8269  jsondec_err(d, "Type url must have at least one '/' and non-empty host");
8270  }
8271 
8272  ptr++;
8273  type_m = upb_symtab_lookupmsg2(d->any_pool, ptr, end - ptr);
8274 
8275  if (!type_m) {
8276  jsondec_err(d, "Type was not found");
8277  }
8278 
8279  return type_m;
8280 }
8281 
8282 static void jsondec_any(jsondec *d, upb_msg *msg, const upb_msgdef *m) {
8283  /* string type_url = 1;
8284  * bytes value = 2; */
8285  const upb_fielddef *value_f = upb_msgdef_itof(m, 2);
8286  upb_msg *any_msg;
8287  const upb_msgdef *any_m = NULL;
8288  const char *pre_type_data = NULL;
8289  const char *pre_type_end = NULL;
8290  upb_msgval encoded;
8291 
8293 
8294  /* Scan looking for "@type", which is not necessarily first. */
8295  while (!any_m && jsondec_objnext(d)) {
8296  const char *start = d->ptr;
8299  if (jsondec_streql(name, "@type")) {
8300  any_m = jsondec_typeurl(d, msg, m);
8301  if (pre_type_data) {
8302  pre_type_end = start;
8303  while (*pre_type_end != ',') pre_type_end--;
8304  }
8305  } else {
8306  if (!pre_type_data) pre_type_data = start;
8307  jsondec_skipval(d);
8308  }
8309  }
8310 
8311  if (!any_m) {
8312  jsondec_err(d, "Any object didn't contain a '@type' field");
8313  }
8314 
8315  any_msg = upb_msg_new(any_m, d->arena);
8316 
8317  if (pre_type_data) {
8318  size_t len = pre_type_end - pre_type_data + 1;
8319  char *tmp = upb_arena_malloc(d->arena, len);
8320  const char *saved_ptr = d->ptr;
8321  const char *saved_end = d->end;
8322  memcpy(tmp, pre_type_data, len - 1);
8323  tmp[len - 1] = '}';
8324  d->ptr = tmp;
8325  d->end = tmp + len;
8326  d->is_first = true;
8327  while (jsondec_objnext(d)) {
8328  jsondec_anyfield(d, any_msg, any_m);
8329  }
8330  d->ptr = saved_ptr;
8331  d->end = saved_end;
8332  }
8333 
8334  while (jsondec_objnext(d)) {
8335  jsondec_anyfield(d, any_msg, any_m);
8336  }
8337 
8338  jsondec_objend(d);
8339 
8340  encoded.str_val.data = upb_encode(any_msg, upb_msgdef_layout(any_m), d->arena,
8341  &encoded.str_val.size);
8342  upb_msg_set(msg, value_f, encoded, d->arena);
8343 }
8344 
8345 static void jsondec_wrapper(jsondec *d, upb_msg *msg, const upb_msgdef *m) {
8346  const upb_fielddef *value_f = upb_msgdef_itof(m, 1);
8347  upb_msgval val = jsondec_value(d, value_f);
8348  upb_msg_set(msg, value_f, val, d->arena);
8349 }
8350 
8351 static void jsondec_wellknown(jsondec *d, upb_msg *msg, const upb_msgdef *m) {
8352  switch (upb_msgdef_wellknowntype(m)) {
8353  case UPB_WELLKNOWN_ANY:
8354  jsondec_any(d, msg, m);
8355  break;
8357  jsondec_fieldmask(d, msg, m);
8358  break;
8360  jsondec_duration(d, msg, m);
8361  break;
8363  jsondec_timestamp(d, msg, m);
8364  break;
8365  case UPB_WELLKNOWN_VALUE:
8367  break;
8369  jsondec_listvalue(d, msg, m);
8370  break;
8371  case UPB_WELLKNOWN_STRUCT:
8372  jsondec_struct(d, msg, m);
8373  break;
8383  jsondec_wrapper(d, msg, m);
8384  break;
8385  default:
8386  UPB_UNREACHABLE();
8387  }
8388 }
8389 
8390 bool upb_json_decode(const char *buf, size_t size, upb_msg *msg,
8391  const upb_msgdef *m, const upb_symtab *any_pool,
8393  jsondec d;
8394 
8395  if (size == 0) return true;
8396 
8397  d.ptr = buf;
8398  d.end = buf + size;
8399  d.arena = arena;
8400  d.any_pool = any_pool;
8401  d.status = status;
8402  d.options = options;
8403  d.depth = 64;
8404  d.line = 1;
8405  d.line_begin = d.ptr;
8406  d.debug_field = NULL;
8407  d.is_first = false;
8408 
8409  if (UPB_SETJMP(d.err)) return false;
8410 
8411  jsondec_tomsg(&d, msg, m);
8412  return true;
8413 }
8414 
8417 #include <ctype.h>
8418 #include <float.h>
8419 #include <inttypes.h>
8420 #include <math.h>
8421 #include <setjmp.h>
8422 #include <stdarg.h>
8423 #include <stdio.h>
8424 #include <string.h>
8425 
8426 
8427 /* Must be last. */
8428 
8429 typedef struct {
8430  char *buf, *ptr, *end;
8431  size_t overflow;
8432  int indent_depth;
8433  int options;
8434  const upb_symtab *ext_pool;
8435  jmp_buf err;
8436  upb_status *status;
8437  upb_arena *arena;
8438 } jsonenc;
8439 
8440 static void jsonenc_msg(jsonenc *e, const upb_msg *msg, const upb_msgdef *m);
8441 static void jsonenc_scalar(jsonenc *e, upb_msgval val, const upb_fielddef *f);
8442 static void jsonenc_msgfield(jsonenc *e, const upb_msg *msg,
8443  const upb_msgdef *m);
8444 static void jsonenc_msgfields(jsonenc *e, const upb_msg *msg,
8445  const upb_msgdef *m, bool first);
8446 static void jsonenc_value(jsonenc *e, const upb_msg *msg, const upb_msgdef *m);
8447 
8448 UPB_NORETURN static void jsonenc_err(jsonenc *e, const char *msg) {
8449  upb_status_seterrmsg(e->status, msg);
8450  longjmp(e->err, 1);
8451 }
8452 
8453 UPB_PRINTF(2, 3)
8454 UPB_NORETURN static void jsonenc_errf(jsonenc *e, const char *fmt, ...) {
8455  va_list argp;
8456  va_start(argp, fmt);
8457  upb_status_vseterrf(e->status, fmt, argp);
8458  va_end(argp);
8459  longjmp(e->err, 1);
8460 }
8461 
8463  /* Create lazily, since it's only needed for Any */
8464  if (!e->arena) {
8465  e->arena = upb_arena_new();
8466  }
8467  return e->arena;
8468 }
8469 
8470 static void jsonenc_putbytes(jsonenc *e, const void *data, size_t len) {
8471  size_t have = e->end - e->ptr;
8472  if (UPB_LIKELY(have >= len)) {
8473  memcpy(e->ptr, data, len);
8474  e->ptr += len;
8475  } else {
8476  if (have) {
8477  memcpy(e->ptr, data, have);
8478  e->ptr += have;
8479  }
8480  e->overflow += (len - have);
8481  }
8482 }
8483 
8484 static void jsonenc_putstr(jsonenc *e, const char *str) {
8485  jsonenc_putbytes(e, str, strlen(str));
8486 }
8487 
8488 UPB_PRINTF(2, 3)
8489 static void jsonenc_printf(jsonenc *e, const char *fmt, ...) {
8490  size_t n;
8491  size_t have = e->end - e->ptr;
8492  va_list args;
8493 
8494  va_start(args, fmt);
8495  n = vsnprintf(e->ptr, have, fmt, args);
8496  va_end(args);
8497 
8498  if (UPB_LIKELY(have > n)) {
8499  e->ptr += n;
8500  } else {
8501  e->ptr = UPB_PTRADD(e->ptr, have);
8502  e->overflow += (n - have);
8503  }
8504 }
8505 
8506 static void jsonenc_nanos(jsonenc *e, int32_t nanos) {
8507  int digits = 9;
8508 
8509  if (nanos == 0) return;
8510  if (nanos < 0 || nanos >= 1000000000) {
8511  jsonenc_err(e, "error formatting timestamp as JSON: invalid nanos");
8512  }
8513 
8514  while (nanos % 1000 == 0) {
8515  nanos /= 1000;
8516  digits -= 3;
8517  }
8518 
8519  jsonenc_printf(e, ".%.*" PRId32, digits, nanos);
8520 }
8521 
8522 static void jsonenc_timestamp(jsonenc *e, const upb_msg *msg,
8523  const upb_msgdef *m) {
8524  const upb_fielddef *seconds_f = upb_msgdef_itof(m, 1);
8525  const upb_fielddef *nanos_f = upb_msgdef_itof(m, 2);
8526  int64_t seconds = upb_msg_get(msg, seconds_f).int64_val;
8527  int32_t nanos = upb_msg_get(msg, nanos_f).int32_val;
8528  int L, N, I, J, K, hour, min, sec;
8529 
8530  if (seconds < -62135596800) {
8531  jsonenc_err(e,
8532  "error formatting timestamp as JSON: minimum acceptable value "
8533  "is 0001-01-01T00:00:00Z");
8534  } else if (seconds > 253402300799) {
8535  jsonenc_err(e,
8536  "error formatting timestamp as JSON: maximum acceptable value "
8537  "is 9999-12-31T23:59:59Z");
8538  }
8539 
8540  /* Julian Day -> Y/M/D, Algorithm from:
8541  * Fliegel, H. F., and Van Flandern, T. C., "A Machine Algorithm for
8542  * Processing Calendar Dates," Communications of the Association of
8543  * Computing Machines, vol. 11 (1968), p. 657. */
8544  L = (int)(seconds / 86400) + 68569 + 2440588;
8545  N = 4 * L / 146097;
8546  L = L - (146097 * N + 3) / 4;
8547  I = 4000 * (L + 1) / 1461001;
8548  L = L - 1461 * I / 4 + 31;
8549  J = 80 * L / 2447;
8550  K = L - 2447 * J / 80;
8551  L = J / 11;
8552  J = J + 2 - 12 * L;
8553  I = 100 * (N - 49) + I + L;
8554 
8555  sec = seconds % 60;
8556  min = (seconds / 60) % 60;
8557  hour = (seconds / 3600) % 24;
8558 
8559  jsonenc_printf(e, "\"%04d-%02d-%02dT%02d:%02d:%02d", I, J, K, hour, min, sec);
8560  jsonenc_nanos(e, nanos);
8561  jsonenc_putstr(e, "Z\"");
8562 }
8563 
8564 static void jsonenc_duration(jsonenc *e, const upb_msg *msg, const upb_msgdef *m) {
8565  const upb_fielddef *seconds_f = upb_msgdef_itof(m, 1);
8566  const upb_fielddef *nanos_f = upb_msgdef_itof(m, 2);
8567  int64_t seconds = upb_msg_get(msg, seconds_f).int64_val;
8568  int32_t nanos = upb_msg_get(msg, nanos_f).int32_val;
8569 
8570  if (seconds > 315576000000 || seconds < -315576000000 ||
8571  (seconds < 0) != (nanos < 0)) {
8572  jsonenc_err(e, "bad duration");
8573  }
8574 
8575  if (nanos < 0) {
8576  nanos = -nanos;
8577  }
8578 
8579  jsonenc_printf(e, "\"%" PRId64, seconds);
8580  jsonenc_nanos(e, nanos);
8581  jsonenc_putstr(e, "s\"");
8582 }
8583 
8584 static void jsonenc_enum(int32_t val, const upb_fielddef *f, jsonenc *e) {
8585  const upb_enumdef *e_def = upb_fielddef_enumsubdef(f);
8586 
8587  if (strcmp(upb_enumdef_fullname(e_def), "google.protobuf.NullValue") == 0) {
8588  jsonenc_putstr(e, "null");
8589  } else {
8590  const char *name = upb_enumdef_iton(e_def, val);
8591 
8592  if (name) {
8593  jsonenc_printf(e, "\"%s\"", name);
8594  } else {
8595  jsonenc_printf(e, "%" PRId32, val);
8596  }
8597  }
8598 }
8599 
8601  /* This is the regular base64, not the "web-safe" version. */
8602  static const char base64[] =
8603  "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
8604  const unsigned char *ptr = (unsigned char*)str.data;
8605  const unsigned char *end = UPB_PTRADD(ptr, str.size);
8606  char buf[4];
8607 
8608  jsonenc_putstr(e, "\"");
8609 
8610  while (end - ptr >= 3) {
8611  buf[0] = base64[ptr[0] >> 2];
8612  buf[1] = base64[((ptr[0] & 0x3) << 4) | (ptr[1] >> 4)];
8613  buf[2] = base64[((ptr[1] & 0xf) << 2) | (ptr[2] >> 6)];
8614  buf[3] = base64[ptr[2] & 0x3f];
8615  jsonenc_putbytes(e, buf, 4);
8616  ptr += 3;
8617  }
8618 
8619  switch (end - ptr) {
8620  case 2:
8621  buf[0] = base64[ptr[0] >> 2];
8622  buf[1] = base64[((ptr[0] & 0x3) << 4) | (ptr[1] >> 4)];
8623  buf[2] = base64[(ptr[1] & 0xf) << 2];
8624  buf[3] = '=';
8625  jsonenc_putbytes(e, buf, 4);
8626  break;
8627  case 1:
8628  buf[0] = base64[ptr[0] >> 2];
8629  buf[1] = base64[((ptr[0] & 0x3) << 4)];
8630  buf[2] = '=';
8631  buf[3] = '=';
8632  jsonenc_putbytes(e, buf, 4);
8633  break;
8634  }
8635 
8636  jsonenc_putstr(e, "\"");
8637 }
8638 
8640  const char *ptr = str.data;
8641  const char *end = UPB_PTRADD(ptr, str.size);
8642 
8643  while (ptr < end) {
8644  switch (*ptr) {
8645  case '\n':
8646  jsonenc_putstr(e, "\\n");
8647  break;
8648  case '\r':
8649  jsonenc_putstr(e, "\\r");
8650  break;
8651  case '\t':
8652  jsonenc_putstr(e, "\\t");
8653  break;
8654  case '\"':
8655  jsonenc_putstr(e, "\\\"");
8656  break;
8657  case '\f':
8658  jsonenc_putstr(e, "\\f");
8659  break;
8660  case '\b':
8661  jsonenc_putstr(e, "\\b");
8662  break;
8663  case '\\':
8664  jsonenc_putstr(e, "\\\\");
8665  break;
8666  default:
8667  if ((uint8_t)*ptr < 0x20) {
8668  jsonenc_printf(e, "\\u%04x", (int)(uint8_t)*ptr);
8669  } else {
8670  /* This could be a non-ASCII byte. We rely on the string being valid
8671  * UTF-8. */
8672  jsonenc_putbytes(e, ptr, 1);
8673  }
8674  break;
8675  }
8676  ptr++;
8677  }
8678 }
8679 
8681  jsonenc_putstr(e, "\"");
8682  jsonenc_stringbody(e, str);
8683  jsonenc_putstr(e, "\"");
8684 }
8685 
8686 static void jsonenc_double(jsonenc *e, const char *fmt, double val) {
8687  if (val == INFINITY) {
8688  jsonenc_putstr(e, "\"Infinity\"");
8689  } else if (val == -INFINITY) {
8690  jsonenc_putstr(e, "\"-Infinity\"");
8691  } else if (val != val) {
8692  jsonenc_putstr(e, "\"NaN\"");
8693  } else {
8694  char *p = e->ptr;
8695  jsonenc_printf(e, fmt, val);
8696 
8697  /* printf() is dependent on locales; sadly there is no easy and portable way
8698  * to avoid this. This little post-processing step will translate 1,2 -> 1.2
8699  * since JSON needs the latter. Arguably a hack, but it is simple and the
8700  * alternatives are far more complicated, platform-dependent, and/or larger
8701  * in code size. */
8702  for (char *end = e->ptr; p < end; p++) {
8703  if (*p == ',') *p = '.';
8704  }
8705  }
8706 }
8707 
8708 static void jsonenc_wrapper(jsonenc *e, const upb_msg *msg,
8709  const upb_msgdef *m) {
8710  const upb_fielddef *val_f = upb_msgdef_itof(m, 1);
8711  upb_msgval val = upb_msg_get(msg, val_f);
8712  jsonenc_scalar(e, val, val_f);
8713 }
8714 
8716  /* Find last '/', if any. */
8717  const char *end = type_url.data + type_url.size;
8718  const char *ptr = end;
8719  const upb_msgdef *ret;
8720 
8721  if (!e->ext_pool) {
8722  jsonenc_err(e, "Tried to encode Any, but no symtab was provided");
8723  }
8724 
8725  if (type_url.size == 0) goto badurl;
8726 
8727  while (true) {
8728  if (--ptr == type_url.data) {
8729  /* Type URL must contain at least one '/', with host before. */
8730  goto badurl;
8731  }
8732  if (*ptr == '/') {
8733  ptr++;
8734  break;
8735  }
8736  }
8737 
8738  ret = upb_symtab_lookupmsg2(e->ext_pool, ptr, end - ptr);
8739 
8740  if (!ret) {
8741  jsonenc_errf(e, "Couldn't find Any type: %.*s", (int)(end - ptr), ptr);
8742  }
8743 
8744  return ret;
8745 
8746 badurl:
8747  jsonenc_errf(
8748  e, "Bad type URL: " UPB_STRVIEW_FORMAT, UPB_STRVIEW_ARGS(type_url));
8749 }
8750 
8751 static void jsonenc_any(jsonenc *e, const upb_msg *msg, const upb_msgdef *m) {
8752  const upb_fielddef *type_url_f = upb_msgdef_itof(m, 1);
8753  const upb_fielddef *value_f = upb_msgdef_itof(m, 2);
8754  upb_strview type_url = upb_msg_get(msg, type_url_f).str_val;
8755  upb_strview value = upb_msg_get(msg, value_f).str_val;
8756  const upb_msgdef *any_m = jsonenc_getanymsg(e, type_url);
8757  const upb_msglayout *any_layout = upb_msgdef_layout(any_m);
8759  upb_msg *any = upb_msg_new(any_m, arena);
8760 
8761  if (!upb_decode(value.data, value.size, any, any_layout, arena)) {
8762  jsonenc_err(e, "Error decoding message in Any");
8763  }
8764 
8765  jsonenc_putstr(e, "{\"@type\":");
8767 
8769  /* Regular messages: {"@type": "...","foo": 1, "bar": 2} */
8770  jsonenc_msgfields(e, any, any_m, false);
8771  } else {
8772  /* Well-known type: {"@type": "...","value": <well-known encoding>} */
8773  jsonenc_putstr(e, ",\"value\":");
8774  jsonenc_msgfield(e, any, any_m);
8775  }
8776 
8777  jsonenc_putstr(e, "}");
8778 }
8779 
8780 static void jsonenc_putsep(jsonenc *e, const char *str, bool *first) {
8781  if (*first) {
8782  *first = false;
8783  } else {
8784  jsonenc_putstr(e, str);
8785  }
8786 }
8787 
8789  const char *ptr = path.data;
8790  const char *end = ptr + path.size;
8791 
8792  while (ptr < end) {
8793  char ch = *ptr;
8794 
8795  if (ch >= 'A' && ch <= 'Z') {
8796  jsonenc_err(e, "Field mask element may not have upper-case letter.");
8797  } else if (ch == '_') {
8798  if (ptr == end - 1 || *(ptr + 1) < 'a' || *(ptr + 1) > 'z') {
8799  jsonenc_err(e, "Underscore must be followed by a lowercase letter.");
8800  }
8801  ch = *++ptr - 32;
8802  }
8803 
8804  jsonenc_putbytes(e, &ch, 1);
8805  ptr++;
8806  }
8807 }
8808 
8809 static void jsonenc_fieldmask(jsonenc *e, const upb_msg *msg,
8810  const upb_msgdef *m) {
8811  const upb_fielddef *paths_f = upb_msgdef_itof(m, 1);
8812  const upb_array *paths = upb_msg_get(msg, paths_f).array_val;
8813  bool first = true;
8814  size_t i, n = 0;
8815 
8816  if (paths) n = upb_array_size(paths);
8817 
8818  jsonenc_putstr(e, "\"");
8819 
8820  for (i = 0; i < n; i++) {
8821  jsonenc_putsep(e, ",", &first);
8822  jsonenc_fieldpath(e, upb_array_get(paths, i).str_val);
8823  }
8824 
8825  jsonenc_putstr(e, "\"");
8826 }
8827 
8828 static void jsonenc_struct(jsonenc *e, const upb_msg *msg,
8829  const upb_msgdef *m) {
8830  const upb_fielddef *fields_f = upb_msgdef_itof(m, 1);
8831  const upb_map *fields = upb_msg_get(msg, fields_f).map_val;
8832  const upb_msgdef *entry_m = upb_fielddef_msgsubdef(fields_f);
8833  const upb_fielddef *value_f = upb_msgdef_itof(entry_m, 2);
8834  size_t iter = UPB_MAP_BEGIN;
8835  bool first = true;
8836 
8837  jsonenc_putstr(e, "{");
8838 
8839  if (fields) {
8840  while (upb_mapiter_next(fields, &iter)) {
8843 
8844  jsonenc_putsep(e, ",", &first);
8845  jsonenc_string(e, key.str_val);
8846  jsonenc_putstr(e, ":");
8847  jsonenc_value(e, val.msg_val, upb_fielddef_msgsubdef(value_f));
8848  }
8849  }
8850 
8851  jsonenc_putstr(e, "}");
8852 }
8853 
8854 static void jsonenc_listvalue(jsonenc *e, const upb_msg *msg,
8855  const upb_msgdef *m) {
8856  const upb_fielddef *values_f = upb_msgdef_itof(m, 1);
8857  const upb_msgdef *values_m = upb_fielddef_msgsubdef(values_f);
8858  const upb_array *values = upb_msg_get(msg, values_f).array_val;
8859  size_t i;
8860  bool first = true;
8861 
8862  jsonenc_putstr(e, "[");
8863 
8864  if (values) {
8865  const size_t size = upb_array_size(values);
8866  for (i = 0; i < size; i++) {
8868 
8869  jsonenc_putsep(e, ",", &first);
8870  jsonenc_value(e, elem.msg_val, values_m);
8871  }
8872  }
8873 
8874  jsonenc_putstr(e, "]");
8875 }
8876 
8877 static void jsonenc_value(jsonenc *e, const upb_msg *msg, const upb_msgdef *m) {
8878  /* TODO(haberman): do we want a reflection method to get oneof case? */
8879  size_t iter = UPB_MSG_BEGIN;
8880  const upb_fielddef *f;
8881  upb_msgval val;
8882 
8883  if (!upb_msg_next(msg, m, NULL, &f, &val, &iter)) {
8884  jsonenc_err(e, "No value set in Value proto");
8885  }
8886 
8887  switch (upb_fielddef_number(f)) {
8888  case 1:
8889  jsonenc_putstr(e, "null");
8890  break;
8891  case 2:
8892  jsonenc_double(e, "%.17g", val.double_val);
8893  break;
8894  case 3:
8895  jsonenc_string(e, val.str_val);
8896  break;
8897  case 4:
8898  jsonenc_putstr(e, val.bool_val ? "true" : "false");
8899  break;
8900  case 5:
8902  break;
8903  case 6:
8905  break;
8906  }
8907 }
8908 
8909 static void jsonenc_msgfield(jsonenc *e, const upb_msg *msg,
8910  const upb_msgdef *m) {
8911  switch (upb_msgdef_wellknowntype(m)) {
8913  jsonenc_msg(e, msg, m);
8914  break;
8915  case UPB_WELLKNOWN_ANY:
8916  jsonenc_any(e, msg, m);
8917  break;
8919  jsonenc_fieldmask(e, msg, m);
8920  break;
8922  jsonenc_duration(e, msg, m);
8923  break;
8925  jsonenc_timestamp(e, msg, m);
8926  break;
8936  jsonenc_wrapper(e, msg, m);
8937  break;
8938  case UPB_WELLKNOWN_VALUE:
8939  jsonenc_value(e, msg, m);
8940  break;
8942  jsonenc_listvalue(e, msg, m);
8943  break;
8944  case UPB_WELLKNOWN_STRUCT:
8945  jsonenc_struct(e, msg, m);
8946  break;
8947  }
8948 }
8949 
8950 static void jsonenc_scalar(jsonenc *e, upb_msgval val, const upb_fielddef *f) {
8951  switch (upb_fielddef_type(f)) {
8952  case UPB_TYPE_BOOL:
8953  jsonenc_putstr(e, val.bool_val ? "true" : "false");
8954  break;
8955  case UPB_TYPE_FLOAT:
8956  jsonenc_double(e, "%.9g", val.float_val);
8957  break;
8958  case UPB_TYPE_DOUBLE:
8959  jsonenc_double(e, "%.17g", val.double_val);
8960  break;
8961  case UPB_TYPE_INT32:
8962  jsonenc_printf(e, "%" PRId32, val.int32_val);
8963  break;
8964  case UPB_TYPE_UINT32:
8965  jsonenc_printf(e, "%" PRIu32, val.uint32_val);
8966  break;
8967  case UPB_TYPE_INT64:
8968  jsonenc_printf(e, "\"%" PRId64 "\"", val.int64_val);
8969  break;
8970  case UPB_TYPE_UINT64:
8971  jsonenc_printf(e, "\"%" PRIu64 "\"", val.uint64_val);
8972  break;
8973  case UPB_TYPE_STRING:
8974  jsonenc_string(e, val.str_val);
8975  break;
8976  case UPB_TYPE_BYTES:
8977  jsonenc_bytes(e, val.str_val);
8978  break;
8979  case UPB_TYPE_ENUM:
8980  jsonenc_enum(val.int32_val, f, e);
8981  break;
8982  case UPB_TYPE_MESSAGE:
8984  break;
8985  }
8986 }
8987 
8988 static void jsonenc_mapkey(jsonenc *e, upb_msgval val, const upb_fielddef *f) {
8989  jsonenc_putstr(e, "\"");
8990 
8991  switch (upb_fielddef_type(f)) {
8992  case UPB_TYPE_BOOL:
8993  jsonenc_putstr(e, val.bool_val ? "true" : "false");
8994  break;
8995  case UPB_TYPE_INT32:
8996  jsonenc_printf(e, "%" PRId32, val.int32_val);
8997  break;
8998  case UPB_TYPE_UINT32:
8999  jsonenc_printf(e, "%" PRIu32, val.uint32_val);
9000  break;
9001  case UPB_TYPE_INT64:
9002  jsonenc_printf(e, "%" PRId64, val.int64_val);
9003  break;
9004  case UPB_TYPE_UINT64:
9005  jsonenc_printf(e, "%" PRIu64, val.uint64_val);
9006  break;
9007  case UPB_TYPE_STRING:
9008  jsonenc_stringbody(e, val.str_val);
9009  break;
9010  default:
9011  UPB_UNREACHABLE();
9012  }
9013 
9014  jsonenc_putstr(e, "\":");
9015 }
9016 
9017 static void jsonenc_array(jsonenc *e, const upb_array *arr,
9018  const upb_fielddef *f) {
9019  size_t i;
9020  size_t size = arr ? upb_array_size(arr) : 0;
9021  bool first = true;
9022 
9023  jsonenc_putstr(e, "[");
9024 
9025  for (i = 0; i < size; i++) {
9026  jsonenc_putsep(e, ",", &first);
9027  jsonenc_scalar(e, upb_array_get(arr, i), f);
9028  }
9029 
9030  jsonenc_putstr(e, "]");
9031 }
9032 
9033 static void jsonenc_map(jsonenc *e, const upb_map *map, const upb_fielddef *f) {
9034  const upb_msgdef *entry = upb_fielddef_msgsubdef(f);
9035  const upb_fielddef *key_f = upb_msgdef_itof(entry, 1);
9036  const upb_fielddef *val_f = upb_msgdef_itof(entry, 2);
9037  size_t iter = UPB_MAP_BEGIN;
9038  bool first = true;
9039 
9040  jsonenc_putstr(e, "{");
9041 
9042  if (map) {
9043  while (upb_mapiter_next(map, &iter)) {
9044  jsonenc_putsep(e, ",", &first);
9045  jsonenc_mapkey(e, upb_mapiter_key(map, iter), key_f);
9047  }
9048  }
9049 
9050  jsonenc_putstr(e, "}");
9051 }
9052 
9053 static void jsonenc_fieldval(jsonenc *e, const upb_fielddef *f,
9054  upb_msgval val, bool *first) {
9055  const char *name;
9056 
9057  if (e->options & UPB_JSONENC_PROTONAMES) {
9059  } else {
9061  }
9062 
9063  jsonenc_putsep(e, ",", first);
9064  jsonenc_printf(e, "\"%s\":", name);
9065 
9066  if (upb_fielddef_ismap(f)) {
9067  jsonenc_map(e, val.map_val, f);
9068  } else if (upb_fielddef_isseq(f)) {
9069  jsonenc_array(e, val.array_val, f);
9070  } else {
9071  jsonenc_scalar(e, val, f);
9072  }
9073 }
9074 
9075 static void jsonenc_msgfields(jsonenc *e, const upb_msg *msg,
9076  const upb_msgdef *m, bool first) {
9077  upb_msgval val;
9078  const upb_fielddef *f;
9079 
9080  if (e->options & UPB_JSONENC_EMITDEFAULTS) {
9081  /* Iterate over all fields. */
9082  int i = 0;
9083  int n = upb_msgdef_fieldcount(m);
9084  for (i = 0; i < n; i++) {
9085  f = upb_msgdef_field(m, i);
9088  }
9089  }
9090  } else {
9091  /* Iterate over non-empty fields. */
9092  size_t iter = UPB_MSG_BEGIN;
9093  while (upb_msg_next(msg, m, e->ext_pool, &f, &val, &iter)) {
9094  jsonenc_fieldval(e, f, val, &first);
9095  }
9096  }
9097 }
9098 
9099 static void jsonenc_msg(jsonenc *e, const upb_msg *msg, const upb_msgdef *m) {
9100  jsonenc_putstr(e, "{");
9101  jsonenc_msgfields(e, msg, m, true);
9102  jsonenc_putstr(e, "}");
9103 }
9104 
9105 static size_t jsonenc_nullz(jsonenc *e, size_t size) {
9106  size_t ret = e->ptr - e->buf + e->overflow;
9107 
9108  if (size > 0) {
9109  if (e->ptr == e->end) e->ptr--;
9110  *e->ptr = '\0';
9111  }
9112 
9113  return ret;
9114 }
9115 
9116 size_t upb_json_encode(const upb_msg *msg, const upb_msgdef *m,
9117  const upb_symtab *ext_pool, int options, char *buf,
9118  size_t size, upb_status *status) {
9119  jsonenc e;
9120 
9121  e.buf = buf;
9122  e.ptr = buf;
9123  e.end = UPB_PTRADD(buf, size);
9124  e.overflow = 0;
9125  e.options = options;
9126  e.ext_pool = ext_pool;
9127  e.status = status;
9128  e.arena = NULL;
9129 
9130  if (setjmp(e.err)) return -1;
9131 
9132  jsonenc_msgfield(&e, msg, m);
9133  if (e.arena) upb_arena_free(e.arena);
9134  return jsonenc_nullz(&e, size);
9135 }
9136 
9138 /* See port_def.inc. This should #undef all macros #defined there. */
9139 
9140 #undef UPB_SIZE
9141 #undef UPB_PTR_AT
9142 #undef UPB_READ_ONEOF
9143 #undef UPB_WRITE_ONEOF
9144 #undef UPB_MAPTYPE_STRING
9145 #undef UPB_INLINE
9146 #undef UPB_ALIGN_UP
9147 #undef UPB_ALIGN_DOWN
9148 #undef UPB_ALIGN_MALLOC
9149 #undef UPB_ALIGN_OF
9150 #undef UPB_LIKELY
9151 #undef UPB_UNLIKELY
9152 #undef UPB_FORCEINLINE
9153 #undef UPB_NOINLINE
9154 #undef UPB_NORETURN
9155 #undef UPB_PRINTF
9156 #undef UPB_MAX
9157 #undef UPB_MIN
9158 #undef UPB_UNUSED
9159 #undef UPB_ASSUME
9160 #undef UPB_ASSERT
9161 #undef UPB_UNREACHABLE
9162 #undef UPB_SETJMP
9163 #undef UPB_LONGJMP
9164 #undef UPB_PTRADD
9165 #undef UPB_MUSTTAIL
9166 #undef UPB_FASTTABLE_SUPPORTED
9167 #undef UPB_FASTTABLE
9168 #undef UPB_FASTTABLE_INIT
9169 #undef UPB_POISON_MEMORY_REGION
9170 #undef UPB_UNPOISON_MEMORY_REGION
9171 #undef UPB_ASAN
decode_readstr
static const char * decode_readstr(upb_decstate *d, const char *ptr, int size, upb_strview *str)
Definition: ruby-upb.c:577
jsonenc_wrapper
static void jsonenc_wrapper(jsonenc *e, const upb_msg *msg, const upb_msgdef *m)
Definition: ruby-upb.c:8708
xds_interop_client.str
str
Definition: xds_interop_client.py:487
decode_tomsg
static const char * decode_tomsg(upb_decstate *d, const char *ptr, upb_msg *msg, upb_msglayout const *const *submsgs, const upb_msglayout_field *field, wireval *val, int op)
Definition: ruby-upb.c:756
upb_inttable_iter_setdone
void upb_inttable_iter_setdone(upb_inttable_iter *i)
Definition: ruby-upb.c:2649
jsondec_skipws
static void jsondec_skipws(jsondec *d)
Definition: ruby-upb.c:7040
upb_syntax_t
upb_syntax_t
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.h:2971
ptr
char * ptr
Definition: abseil-cpp/absl/base/internal/low_level_alloc_test.cc:45
jsondec_streql
static bool jsondec_streql(upb_strview str, const char *lit)
Definition: ruby-upb.c:7006
UPB_UNLIKELY
#define UPB_UNLIKELY(x)
Definition: ruby-upb.c:104
google_protobuf_EnumValueOptions__fields
static const upb_msglayout_field google_protobuf_EnumValueOptions__fields[2]
Definition: ruby-upb.c:4329
upb_map_entry::k
union upb_map_entry::@434 k
jsondec_tsdigits
static int jsondec_tsdigits(jsondec *d, const char **ptr, size_t digits, const char *after)
Definition: ruby-upb.c:7945
wireval::uint64_val
uint64_t uint64_val
Definition: php-upb.c:395
absl::time_internal::cctz::seconds
std::chrono::duration< std::int_fast64_t > seconds
Definition: abseil-cpp/absl/time/internal/cctz/include/cctz/time_zone.h:40
layouts
static const upb_msglayout * layouts[27]
Definition: php-upb.c:4496
UPB_DTYPE_DOUBLE
@ UPB_DTYPE_DOUBLE
Definition: php-upb.h:554
ctx::arena
upb_Arena * arena
Definition: conformance_upb.c:84
google_protobuf_FieldDescriptorProto_oneof_index
UPB_INLINE int32_t google_protobuf_FieldDescriptorProto_oneof_index(const google_protobuf_FieldDescriptorProto *msg)
Definition: descriptor.upb.h:1012
decode_reserve
static bool decode_reserve(upb_decstate *d, upb_array *arr, size_t elem)
Definition: ruby-upb.c:439
UPB_SYNTAX_PROTO2
@ UPB_SYNTAX_PROTO2
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.h:2972
upb_decode
bool upb_decode(const char *buf, size_t size, void *msg, const upb_msglayout *l, upb_arena *arena)
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.c:742
encode_scalarfield
static void encode_scalarfield(upb_encstate *e, const char *msg, const upb_msglayout *m, const upb_msglayout_field *f)
Definition: ruby-upb.c:1395
realloc_internal
static bool realloc_internal(upb_msg *msg, size_t need, upb_arena *arena)
Definition: ruby-upb.c:1501
upb_mutmsgval::msg
upb_msg * msg
Definition: php-upb.h:4628
_upb_lg2ceilsize
UPB_INLINE int _upb_lg2ceilsize(int x)
Definition: php-upb.h:609
UPB_TYPE_UINT64
@ UPB_TYPE_UINT64
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.h:487
deps
static _upb_DefPool_Init * deps[4]
Definition: certs.upbdefs.c:72
upb_msgdef_numoneofs
int upb_msgdef_numoneofs(const upb_msgdef *m)
Definition: ruby-upb.c:5040
upb_arena_allocblock
static bool upb_arena_allocblock(upb_arena *a, size_t size)
Definition: ruby-upb.c:2794
google_protobuf_FieldOptions_msginit
const upb_msglayout google_protobuf_FieldOptions_msginit
Definition: ruby-upb.c:4289
mem_block::cleanups
uint32_t cleanups
Definition: php-upb.c:2752
google_protobuf_FileDescriptorSet__fields
static const upb_msglayout_field google_protobuf_FileDescriptorSet__fields[1]
Definition: ruby-upb.c:3991
upb_oneofdef::synthetic
bool synthetic
Definition: php-upb.c:4924
_upb_symtab_bytesloaded
size_t _upb_symtab_bytesloaded(const upb_symtab *s)
Definition: ruby-upb.c:6588
upb_arena_malloc
UPB_INLINE void * upb_arena_malloc(upb_arena *a, size_t size)
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.h:383
decode_verifyutf8
static void decode_verifyutf8(upb_decstate *d, const char *buf, int len)
Definition: ruby-upb.c:435
dst
static const char dst[]
Definition: test-fs-copyfile.c:37
field_rank
uint32_t field_rank(const upb_fielddef *f)
Definition: ruby-upb.c:4623
upb_fielddef_isstring
bool upb_fielddef_isstring(const upb_fielddef *f)
Definition: ruby-upb.c:4922
encode_bytes
static void encode_bytes(upb_encstate *e, const void *data, size_t len)
Definition: ruby-upb.c:1079
_upb_fasttable_entry
Definition: php-upb.h:1128
test_server.argp
argp
Definition: test_server.py:33
jsonenc_map
static void jsonenc_map(jsonenc *e, const upb_map *map, const upb_fielddef *f)
Definition: ruby-upb.c:9033
jsondec_mask
static upb_strview jsondec_mask(jsondec *d, const char *buf, const char *end)
Definition: ruby-upb.c:8182
google_protobuf_MethodOptions_submsgs
static const upb_msglayout *const google_protobuf_MethodOptions_submsgs[1]
Definition: ruby-upb.c:4355
vsnprintf
int __cdecl vsnprintf(char *buffer, size_t count, const char *format, va_list argptr)
Definition: libc.cpp:135
MIN_DENSITY
static const double MIN_DENSITY
Definition: ruby-upb.c:1871
gen_build_yaml.out
dictionary out
Definition: src/benchmark/gen_build_yaml.py:24
_upb_clearhas_field
UPB_INLINE void _upb_clearhas_field(const upb_msg *msg, const upb_msglayout_field *f)
Definition: php-upb.h:1296
check_ident
static void check_ident(symtab_addctx *ctx, upb_strview name, bool full)
Definition: ruby-upb.c:5364
upb_msgdef::map_entry
bool map_entry
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.c:2978
upb_arena
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.c:2252
_upb_extreg_get
const upb_msglayout_field * _upb_extreg_get(const upb_extreg *r, const upb_msglayout *l, uint32_t num)
Definition: ruby-upb.c:1835
google_protobuf_FieldDescriptorProto_proto3_optional
UPB_INLINE bool google_protobuf_FieldDescriptorProto_proto3_optional(const google_protobuf_FieldDescriptorProto *msg)
Definition: descriptor.upb.h:1032
upb_msglayout_field::offset
uint16_t offset
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.h:558
encode_varint
static UPB_FORCEINLINE void encode_varint(upb_encstate *e, uint64_t val)
Definition: ruby-upb.c:1108
regen-readme.it
it
Definition: regen-readme.py:15
jsonenc_getanymsg
static const upb_msgdef * jsonenc_getanymsg(jsonenc *e, upb_strview type_url)
Definition: ruby-upb.c:8715
UPB_DEFTYPE_FIELD
@ UPB_DEFTYPE_FIELD
Definition: ruby-upb.c:4573
upb_status_seterrf
void upb_status_seterrf(upb_status *status, const char *fmt,...)
Definition: ruby-upb.c:2693
jsondec_codepoint
static uint32_t jsondec_codepoint(jsondec *d)
Definition: ruby-upb.c:7289
google_protobuf_FileDescriptorSet_msginit
const upb_msglayout google_protobuf_FileDescriptorSet_msginit
Definition: ruby-upb.c:3995
jsondec_wellknownvalue
static void jsondec_wellknownvalue(jsondec *d, upb_msg *msg, const upb_msgdef *m)
Definition: ruby-upb.c:8127
upb_fielddef_layout
const upb_msglayout_field * upb_fielddef_layout(const upb_fielddef *f)
Definition: ruby-upb.c:4914
_upb_lg2ceil
UPB_INLINE int _upb_lg2ceil(int x)
Definition: php-upb.h:598
encode_tag
static void encode_tag(upb_encstate *e, uint32_t field_number, uint8_t wire_type)
Definition: ruby-upb.c:1131
JD_ARRAY
@ JD_ARRAY
Definition: ruby-upb.c:6997
upb_msgdef_oneofcount
int upb_msgdef_oneofcount(const upb_msgdef *m)
Definition: ruby-upb.c:5052
google_protobuf_FileDescriptorProto_dependency
UPB_INLINE upb_StringView const * google_protobuf_FileDescriptorProto_dependency(const google_protobuf_FileDescriptorProto *msg, size_t *len)
Definition: descriptor.upb.h:272
google_protobuf_FieldDescriptorProto_options
const UPB_INLINE google_protobuf_FieldOptions * google_protobuf_FieldDescriptorProto_options(const google_protobuf_FieldDescriptorProto *msg)
Definition: descriptor.upb.h:1002
upb_label_t
upb_label_t
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.h:491
upb_symtab_lookupmsg2
const upb_msgdef * upb_symtab_lookupmsg2(const upb_symtab *s, const char *sym, size_t len)
Definition: ruby-upb.c:5295
upb_msglayout::fields
const upb_msglayout_field * fields
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.h:567
upb_msgdef_realoneofcount
int upb_msgdef_realoneofcount(const upb_msgdef *m)
Definition: ruby-upb.c:5056
jsonenc_arena
static upb_arena * jsonenc_arena(jsonenc *e)
Definition: ruby-upb.c:8462
upb_oneofdef_ntof
const upb_fielddef * upb_oneofdef_ntof(const upb_oneofdef *o, const char *name, size_t length)
Definition: ruby-upb.c:5182
shortdefname
static const char * shortdefname(const char *fullname)
Definition: ruby-upb.c:4607
ctx
Definition: benchmark-async.c:30
google_protobuf_FieldDescriptorProto_msginit
const upb_msglayout google_protobuf_FieldDescriptorProto_msginit
Definition: ruby-upb.c:4119
const
#define const
Definition: bloaty/third_party/zlib/zconf.h:230
jsondec_arrstart
static void jsondec_arrstart(jsondec *d)
Definition: ruby-upb.c:7152
upb_roundup_pow2
static size_t upb_roundup_pow2(size_t bytes)
Definition: ruby-upb.c:1034
makefullname
static const char * makefullname(symtab_addctx *ctx, const char *prefix, upb_strview name)
Definition: ruby-upb.c:5659
upb_strtable_init
bool upb_strtable_init(upb_strtable *t, size_t expected_size, upb_arena *a)
Definition: ruby-upb.c:2280
upb_fielddef_label
upb_label_t upb_fielddef_label(const upb_fielddef *f)
Definition: ruby-upb.c:4790
UPB_TYPE_FLOAT
@ UPB_TYPE_FLOAT
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.h:476
UPB_WELLKNOWN_STRINGVALUE
@ UPB_WELLKNOWN_STRINGVALUE
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.h:2994
UPB_WELLKNOWN_DOUBLEVALUE
@ UPB_WELLKNOWN_DOUBLEVALUE
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.h:2987
upb_msgval::array_val
const upb_array * array_val
Definition: php-upb.h:4622
upb_mapiter_next
bool upb_mapiter_next(const upb_map *map, size_t *iter)
Definition: ruby-upb.c:6936
_upb_array_tagptr
UPB_INLINE uintptr_t _upb_array_tagptr(void *ptr, int elem_size_lg2)
Definition: php-upb.h:1345
memset
return memset(p, 0, total)
upb_filedef_symtab
const upb_symtab * upb_filedef_symtab(const upb_filedef *f)
Definition: ruby-upb.c:5261
UPB_SIZE
#define UPB_SIZE(size32, size64)
Definition: ruby-upb.c:65
upb_msg_field_next
void upb_msg_field_next(upb_msg_field_iter *iter)
Definition: ruby-upb.c:5098
upb_symtab_lookupmsg
const upb_msgdef * upb_symtab_lookupmsg(const upb_symtab *s, const char *sym)
Definition: ruby-upb.c:5289
encode_scalar
static void encode_scalar(upb_encstate *e, const void *_field_mem, const upb_msglayout *m, const upb_msglayout_field *f, bool skip_zero_value)
Definition: ruby-upb.c:1156
upb_status
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.h:197
file
const grpc_generator::File * file
Definition: python_private_generator.h:38
jsonenc_errf
static UPB_NORETURN void jsonenc_errf(jsonenc *e, const char *fmt,...)
Definition: ruby-upb.c:8454
UPB_DTYPE_SFIXED32
@ UPB_DTYPE_SFIXED32
Definition: php-upb.h:568
upb_symtab_addfile
const upb_filedef * upb_symtab_addfile(upb_symtab *s, const google_protobuf_FileDescriptorProto *file_proto, upb_status *status)
Definition: ruby-upb.c:6533
upb_arena_addblock
static void upb_arena_addblock(upb_arena *a, upb_arena *root, void *ptr, size_t size)
Definition: ruby-upb.c:2774
upb_filedef::ext_count
int ext_count
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.c:3015
UPB_DESCRIPTOR_TYPE_STRING
@ UPB_DESCRIPTOR_TYPE_STRING
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.h:507
google_protobuf_EnumDescriptorProto_submsgs
static const upb_msglayout *const google_protobuf_EnumDescriptorProto_submsgs[3]
Definition: ruby-upb.c:4140
google_protobuf_FieldOptions_lazy
UPB_INLINE bool google_protobuf_FieldOptions_lazy(const google_protobuf_FieldOptions *msg)
Definition: descriptor.upb.h:2156
upb_cleanup_func
void upb_cleanup_func(void *ud)
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.h:362
upb_msglayout_field::descriptortype
uint8_t descriptortype
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.h:561
upb_filedef::exts
const upb_fielddef * exts
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.c:3010
upb_msgdef::well_known_type
upb_wellknowntype_t well_known_type
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.c:2979
upb_extreg
Definition: php-upb.c:1793
upb_fielddef::msgdef
const upb_msgdef * msgdef
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.c:2936
upb_tabent_isempty
UPB_INLINE bool upb_tabent_isempty(const upb_tabent *e)
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.h:871
upb_msgval::map_val
const upb_map * map_val
Definition: php-upb.h:4620
is_pow2
static bool is_pow2(uint64_t v)
Definition: ruby-upb.c:1873
upb_msgval::uint64_val
uint64_t uint64_val
Definition: php-upb.h:4619
_upb_sortedmap::end
int end
Definition: php-upb.h:1697
uint16_t
unsigned short uint16_t
Definition: stdint-msvc2008.h:79
encode_double
static void encode_double(upb_encstate *e, double d)
Definition: ruby-upb.c:1117
DECODE_NOGROUP
#define DECODE_NOGROUP
Definition: php-upb.h:1770
_upb_sortedmap::start
int start
Definition: php-upb.h:1695
upb_msgdef_numfields
int upb_msgdef_numfields(const upb_msgdef *m)
Definition: ruby-upb.c:5036
jsondec_typeurl
static const upb_msgdef * jsondec_typeurl(jsondec *d, upb_msg *msg, const upb_msgdef *m)
Definition: ruby-upb.c:8253
upb_msgdef_numrealoneofs
int upb_msgdef_numrealoneofs(const upb_msgdef *m)
Definition: ruby-upb.c:5044
google_protobuf_ExtensionRangeOptions__fields
static const upb_msglayout_field google_protobuf_ExtensionRangeOptions__fields[1]
Definition: ruby-upb.c:4091
encode_zz32
static uint32_t encode_zz32(int32_t n)
Definition: ruby-upb.c:1022
upb_filedef::msgs
const upb_msgdef * msgs
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.c:3008
WyhashMix
static uint64_t WyhashMix(uint64_t v0, uint64_t v1)
Definition: ruby-upb.c:2174
upb_filedef_name
const char * upb_filedef_name(const upb_filedef *f)
Definition: ruby-upb.c:5217
upb_fielddef_defaultstr
const char * upb_fielddef_defaultstr(const upb_fielddef *f, size_t *len)
Definition: ruby-upb.c:4892
jsondec_parselit
static void jsondec_parselit(jsondec *d, const char *lit)
Definition: ruby-upb.c:7065
upb_msgdef::field_count
int field_count
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.c:2974
decode_msg
static const char * decode_msg(upb_decstate *d, const char *ptr, upb_msg *msg, const upb_msglayout *layout)
Definition: ruby-upb.c:827
xds_manager.f1
f1
Definition: xds_manager.py:42
memblock_reserve
static const size_t memblock_reserve
Definition: ruby-upb.c:2761
_upb_be_swap64
UPB_INLINE uint64_t _upb_be_swap64(uint64_t val)
Definition: php-upb.h:590
OP_BYTES
#define OP_BYTES
Definition: ruby-upb.c:322
decode_poplimit
UPB_INLINE void decode_poplimit(upb_decstate *d, const char *ptr, int saved_delta)
Definition: php-upb.h:1908
google_protobuf_EnumValueDescriptorProto
struct google_protobuf_EnumValueDescriptorProto google_protobuf_EnumValueDescriptorProto
Definition: descriptor.upb.h:60
decode_vret
Definition: php-upb.c:447
test
Definition: spinlock_test.cc:36
upb_map_entry::v
union upb_map_entry::@435 v
jsondec_seqnext
static bool jsondec_seqnext(jsondec *d, char end_ch)
Definition: ruby-upb.c:7143
y
const double y
Definition: bloaty/third_party/googletest/googlemock/test/gmock-matchers_test.cc:3611
jsondec_unixtime
static int64_t jsondec_unixtime(int y, int m, int d, int h, int min, int s)
Definition: ruby-upb.c:7997
upb_filedef_phpprefix
const char * upb_filedef_phpprefix(const upb_filedef *f)
Definition: ruby-upb.c:5225
upb_oneofdef_numfields
int upb_oneofdef_numfields(const upb_oneofdef *o)
Definition: ruby-upb.c:5170
upb_value
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.h:681
upb_def_init
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.h:3769
google_protobuf_FieldOptions__fields
static const upb_msglayout_field google_protobuf_FieldOptions__fields[7]
Definition: ruby-upb.c:4279
ext
void * ext
Definition: x509v3.h:87
upb_oneofdef::itof
upb_inttable itof
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.c:2997
_upb_mapsorter
Definition: php-upb.h:1688
google_protobuf_FieldDescriptorProto_default_value
UPB_INLINE upb_StringView google_protobuf_FieldDescriptorProto_default_value(const google_protobuf_FieldDescriptorProto *msg)
Definition: descriptor.upb.h:993
OP_FIXPCK_LG2
#define OP_FIXPCK_LG2(n)
Definition: ruby-upb.c:325
INT64_MAX
#define INT64_MAX
Definition: stdint-msvc2008.h:139
upb_fieldtype_t
upb_fieldtype_t
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.h:472
insert
static void insert(upb_table *t, lookupkey_t key, upb_tabkey tabkey, upb_value val, uint32_t hash, hashfunc_t *hashfunc, eqlfunc_t *eql)
Definition: ruby-upb.c:2017
upb_status_errmsg
const char * upb_status_errmsg(const upb_status *status)
Definition: ruby-upb.c:2684
jsonenc_printf
static void jsonenc_printf(jsonenc *e, const char *fmt,...)
Definition: ruby-upb.c:8489
jsondec_anyfield
static void jsondec_anyfield(jsondec *d, upb_msg *msg, const upb_msgdef *m)
Definition: ruby-upb.c:8236
string.h
copy
static int copy(grpc_slice_buffer *input, grpc_slice_buffer *output)
Definition: message_compress.cc:145
options
double_dict options[]
Definition: capstone_test.c:55
upb_fielddef::full_name
const char * full_name
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.c:2937
upb_msgdef_itof
const upb_fielddef * upb_msgdef_itof(const upb_msgdef *m, uint32_t i)
Definition: ruby-upb.c:4980
upb_oneofdef::fields
const upb_fielddef ** fields
Definition: php-upb.c:4925
_upb_map_next
UPB_INLINE void * _upb_map_next(const upb_map *map, size_t *iter)
Definition: php-upb.h:1578
upb_mutmsgval
Definition: php-upb.h:4626
jsondec_partialbase64
static char * jsondec_partialbase64(jsondec *d, const char *ptr, const char *end, char *out)
Definition: ruby-upb.c:7505
seed
static const uint8_t seed[20]
Definition: dsa_test.cc:79
upb_arena_alloc
UPB_INLINE upb_alloc * upb_arena_alloc(upb_arena *a)
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.h:379
buf
voidpf void * buf
Definition: bloaty/third_party/zlib/contrib/minizip/ioapi.h:136
streql_view
static bool streql_view(upb_strview view, const char *b)
Definition: ruby-upb.c:5655
google_protobuf_ServiceOptions_submsgs
static const upb_msglayout *const google_protobuf_ServiceOptions_submsgs[1]
Definition: ruby-upb.c:4340
UPB_ALIGN_DOWN
#define UPB_ALIGN_DOWN(size, align)
Definition: ruby-upb.c:94
upb_extreg::arena
upb_arena * arena
Definition: php-upb.c:1794
UPB_WIRE_TYPE_END_GROUP
@ UPB_WIRE_TYPE_END_GROUP
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.h:465
google_protobuf_EnumDescriptorProto_value
const UPB_INLINE google_protobuf_EnumValueDescriptorProto *const * google_protobuf_EnumDescriptorProto_value(const google_protobuf_EnumDescriptorProto *msg, size_t *len)
Definition: descriptor.upb.h:1206
elem
Timer elem
Definition: event_engine/iomgr_event_engine/timer_heap_test.cc:109
JD_NUMBER
@ JD_NUMBER
Definition: ruby-upb.c:6997
upb_symtab_lookupfile
const upb_filedef * upb_symtab_lookupfile(const upb_symtab *s, const char *name)
Definition: ruby-upb.c:5308
upb_fielddef::packed_
bool packed_
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.c:2957
_upb_sethas_field
UPB_INLINE void _upb_sethas_field(const upb_msg *msg, const upb_msglayout_field *f)
Definition: php-upb.h:1291
UPB_WELLKNOWN_UNSPECIFIED
@ UPB_WELLKNOWN_UNSPECIFIED
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.h:2981
binary_size.new_size
def new_size
Definition: binary_size.py:124
UINT64_MAX
#define UINT64_MAX
Definition: stdint-msvc2008.h:143
error_ref_leak.err
err
Definition: error_ref_leak.py:35
google_protobuf_FileOptions_msginit
const upb_msglayout google_protobuf_FileOptions_msginit
Definition: ruby-upb.c:4251
upb_fielddef_ismap
bool upb_fielddef_ismap(const upb_fielddef *f)
Definition: ruby-upb.c:4935
upb_msg_get
upb_msgval upb_msg_get(const upb_msg *msg, const upb_fielddef *f)
Definition: ruby-upb.c:6705
jsonenc_bytes
static void jsonenc_bytes(jsonenc *e, upb_strview str)
Definition: ruby-upb.c:8600
_UPB_MODE_SCALAR
@ _UPB_MODE_SCALAR
Definition: php-upb.h:1099
UPB_DESCRIPTOR_TYPE_FIXED32
@ UPB_DESCRIPTOR_TYPE_FIXED32
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.h:505
google_protobuf_UninterpretedOption_NamePart_msginit
const upb_msglayout google_protobuf_UninterpretedOption_NamePart_msginit
Definition: ruby-upb.c:4396
upb_tabent
struct _upb_tabent upb_tabent
upb_arena::freelist_tail
mem_block * freelist_tail
Definition: php-upb.h:1763
google_protobuf_DescriptorProto_name
UPB_INLINE upb_StringView google_protobuf_DescriptorProto_name(const google_protobuf_DescriptorProto *msg)
Definition: descriptor.upb.h:504
UINT32_MAX
#define UINT32_MAX
Definition: stdint-msvc2008.h:142
google_protobuf_FieldDescriptorProto__fields
static const upb_msglayout_field google_protobuf_FieldDescriptorProto__fields[11]
Definition: ruby-upb.c:4105
google_protobuf_DescriptorProto_msginit
const upb_msglayout google_protobuf_DescriptorProto_msginit
Definition: ruby-upb.c:4054
div_round_up
static size_t div_round_up(size_t n, size_t d)
Definition: ruby-upb.c:5396
upb_msgdef_ntoo
const upb_oneofdef * upb_msgdef_ntoo(const upb_msgdef *m, const char *name, size_t len)
Definition: ruby-upb.c:4997
file
Definition: bloaty/third_party/zlib/examples/gzappend.c:170
google_protobuf_FileOptions_php_namespace
UPB_INLINE upb_StringView google_protobuf_FileOptions_php_namespace(const google_protobuf_FileOptions *msg)
Definition: descriptor.upb.h:1842
UPB_DESCRIPTOR_TYPE_SFIXED64
@ UPB_DESCRIPTOR_TYPE_SFIXED64
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.h:514
jsondec_strfield
static upb_msgval jsondec_strfield(jsondec *d, const upb_fielddef *f)
Definition: ruby-upb.c:7743
google_protobuf_FileDescriptorProto_options
const UPB_INLINE google_protobuf_FileOptions * google_protobuf_FileDescriptorProto_options(const google_protobuf_FileDescriptorProto *msg)
Definition: descriptor.upb.h:317
absl::hash_internal::k2
static const uint64_t k2
Definition: abseil-cpp/absl/hash/internal/city.cc:55
upb_arena::block_alloc
upb_alloc * block_alloc
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.c:2259
upb_msgdef_file
const upb_filedef * upb_msgdef_file(const upb_msgdef *m)
Definition: ruby-upb.c:4968
status
absl::Status status
Definition: rls.cc:251
makejsonname
static char * makejsonname(symtab_addctx *ctx, const char *name)
Definition: ruby-upb.c:5748
fixed64_ok
static const unsigned fixed64_ok
Definition: ruby-upb.c:315
UPB_PRINTF
#define UPB_PRINTF(str, first_vararg)
Definition: ruby-upb.c:122
intkey
static lookupkey_t intkey(uintptr_t key)
Definition: ruby-upb.c:1922
create_fielddef
static void create_fielddef(symtab_addctx *ctx, const char *prefix, upb_msgdef *m, const google_protobuf_FieldDescriptorProto *field_proto)
Definition: ruby-upb.c:5967
_upb_map_get
UPB_INLINE bool _upb_map_get(const upb_map *map, const void *key, size_t key_size, void *val, size_t val_size)
Definition: php-upb.h:1567
kWyhashSalt
const uint64_t kWyhashSalt[5]
Definition: ruby-upb.c:2259
decode_munge
static void decode_munge(int type, wireval *val)
Definition: ruby-upb.c:501
UPB_TYPE_UINT32
@ UPB_TYPE_UINT32
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.h:478
extreg_key
static void extreg_key(char *buf, const upb_msglayout *l, uint32_t fieldnum)
Definition: ruby-upb.c:1800
jsondec_string
static upb_strview jsondec_string(jsondec *d)
Definition: ruby-upb.c:7370
UPB_LONGJMP
#define UPB_LONGJMP(buf, val)
Definition: ruby-upb.c:164
ctx
static struct test_ctx ctx
Definition: test-ipc-send-recv.c:65
upb_arena_init
upb_arena * upb_arena_init(void *mem, size_t n, upb_alloc *alloc)
Definition: ruby-upb.c:2844
upb_tabstr
UPB_INLINE char * upb_tabstr(upb_tabkey key, uint32_t *len)
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.h:789
setup.name
name
Definition: setup.py:542
upb_symtab::bytes_loaded
size_t bytes_loaded
Definition: php-upb.c:4953
jsondec_bool
static upb_msgval jsondec_bool(jsondec *d, const upb_fielddef *f)
Definition: ruby-upb.c:7782
google_protobuf_ServiceOptions_msginit
const upb_msglayout google_protobuf_ServiceOptions_msginit
Definition: ruby-upb.c:4349
upb_fielddef_fullname
const char * upb_fielddef_fullname(const upb_fielddef *f)
Definition: ruby-upb.c:4743
OP_STRING
#define OP_STRING
Definition: ruby-upb.c:321
upb_strtable_remove
bool upb_strtable_remove(upb_strtable *t, const char *key, size_t len, upb_value *val)
Definition: ruby-upb.c:2338
UPB_DESCRIPTOR_TYPE_GROUP
@ UPB_DESCRIPTOR_TYPE_GROUP
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.h:508
jsondec_wsch
static void jsondec_wsch(jsondec *d, char ch)
Definition: ruby-upb.c:7074
check_documentation.path
path
Definition: check_documentation.py:57
google_protobuf_EnumOptions__fields
static const upb_msglayout_field google_protobuf_EnumOptions__fields[3]
Definition: ruby-upb.c:4313
google_protobuf_FieldDescriptorProto_number
UPB_INLINE int32_t google_protobuf_FieldDescriptorProto_number(const google_protobuf_FieldDescriptorProto *msg)
Definition: descriptor.upb.h:953
a
int a
Definition: abseil-cpp/absl/container/internal/hash_policy_traits_test.cc:88
upb_msg_field_begin
void upb_msg_field_begin(upb_msg_field_iter *iter, const upb_msgdef *m)
Definition: ruby-upb.c:5094
UPB_DESCRIPTOR_TYPE_BYTES
@ UPB_DESCRIPTOR_TYPE_BYTES
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.h:510
_upb_tag_arrptr
UPB_INLINE uintptr_t _upb_tag_arrptr(void *ptr, int elem_size_lg2)
Definition: php-upb.h:1354
upb_fielddef::sub
union upb_fielddef::@207 sub
UPB_DTYPE_FIXED64
@ UPB_DTYPE_FIXED64
Definition: php-upb.h:559
upb_fielddef_packed
bool upb_fielddef_packed(const upb_fielddef *f)
Definition: ruby-upb.c:4806
upb_inttable_iter_value
upb_value upb_inttable_iter_value(const upb_inttable_iter *i)
Definition: ruby-upb.c:2643
decode_totable
UPB_INLINE intptr_t decode_totable(const upb_msglayout *tablep)
Definition: php-upb.h:1820
_upb_mapsorter_cmpu32
static int _upb_mapsorter_cmpu32(const void *_a, const void *_b)
Definition: ruby-upb.c:1704
xds_manager.p
p
Definition: xds_manager.py:60
upb_inttable::t
upb_table t
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.h:849
upb_msg_has
bool upb_msg_has(const upb_msg *msg, const upb_fielddef *f)
Definition: ruby-upb.c:6677
desctype_to_elem_size_lg2
static const uint8_t desctype_to_elem_size_lg2[]
Definition: ruby-upb.c:266
upb_arena_doalloc
static void * upb_arena_doalloc(upb_alloc *alloc, void *ptr, size_t oldsize, size_t size)
Definition: ruby-upb.c:2810
findentry
static const upb_tabent * findentry(const upb_table *t, lookupkey_t key, uint32_t hash, eqlfunc_t *eql)
Definition: ruby-upb.c:1985
_upb_mapsorter_cmpstr
static int _upb_mapsorter_cmpstr(const void *_a, const void *_b)
Definition: ruby-upb.c:1716
jsondec_strtoint64
static int64_t jsondec_strtoint64(jsondec *d, upb_strview str)
Definition: ruby-upb.c:7623
parse_default
static void parse_default(symtab_addctx *ctx, const char *str, size_t len, upb_fielddef *f)
Definition: ruby-upb.c:5828
decode_totablep
const UPB_INLINE upb_msglayout * decode_totablep(intptr_t table)
Definition: php-upb.h:1824
jsonenc
Definition: php-upb.c:8814
upb_symtab_lookupenum
const upb_enumdef * upb_symtab_lookupenum(const upb_symtab *s, const char *sym)
Definition: ruby-upb.c:5302
upb_cleanup_has_initial_block
static bool upb_cleanup_has_initial_block(uintptr_t cleanup_metadata)
Definition: ruby-upb.c:2734
cmp_fields
int cmp_fields(const void *p1, const void *p2)
Definition: ruby-upb.c:4632
google_protobuf_FieldDescriptorProto_extendee
UPB_INLINE upb_StringView google_protobuf_FieldDescriptorProto_extendee(const google_protobuf_FieldDescriptorProto *msg)
Definition: descriptor.upb.h:943
google_protobuf_DescriptorProto_oneof_decl
const UPB_INLINE google_protobuf_OneofDescriptorProto *const * google_protobuf_DescriptorProto_oneof_decl(const google_protobuf_DescriptorProto *msg, size_t *len)
Definition: descriptor.upb.h:567
_upb_msg_discardunknown
bool _upb_msg_discardunknown(upb_msg *msg, const upb_msgdef *m, int depth)
Definition: ruby-upb.c:6819
strviewdup
static char * strviewdup(symtab_addctx *ctx, upb_strview view)
Definition: ruby-upb.c:5647
z
Uncopyable z
Definition: bloaty/third_party/googletest/googlemock/test/gmock-matchers_test.cc:3612
decode_err
static UPB_NORETURN void decode_err(upb_decstate *d)
Definition: ruby-upb.c:402
encode_fixed32
static void encode_fixed32(upb_encstate *e, uint32_t val)
Definition: ruby-upb.c:1090
upb_msgval::str_val
upb_strview str_val
Definition: php-upb.h:4623
upb_strview::data
const char * data
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.h:258
google_protobuf_UninterpretedOption_NamePart__fields
static const upb_msglayout_field google_protobuf_UninterpretedOption_NamePart__fields[2]
Definition: ruby-upb.c:4391
encode_fixed64
static void encode_fixed64(upb_encstate *e, uint64_t val)
Definition: ruby-upb.c:1085
google_protobuf_OneofDescriptorProto
struct google_protobuf_OneofDescriptorProto google_protobuf_OneofDescriptorProto
Definition: descriptor.upb.h:57
uint8_t
unsigned char uint8_t
Definition: stdint-msvc2008.h:78
upb_symtab_filecount
int upb_symtab_filecount(const upb_symtab *s)
Definition: ruby-upb.c:5321
setup.k
k
Definition: third_party/bloaty/third_party/capstone/bindings/python/setup.py:42
upb_symtab_lookupfile2
const upb_filedef * upb_symtab_lookupfile2(const upb_symtab *s, const char *name, size_t len)
Definition: ruby-upb.c:5314
google_protobuf_EnumValueDescriptorProto_name
UPB_INLINE upb_StringView google_protobuf_EnumValueDescriptorProto_name(const google_protobuf_EnumValueDescriptorProto *msg)
Definition: descriptor.upb.h:1384
upb_fielddef_issubmsg
bool upb_fielddef_issubmsg(const upb_fielddef *f)
Definition: ruby-upb.c:4918
map
zval * map
Definition: php/ext/google/protobuf/encode_decode.c:480
upb_enumdef::full_name
const char * full_name
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.c:2986
upb_msgdef::file
const upb_filedef * file
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.c:2963
_upb_getoneofcase_field
UPB_INLINE uint32_t _upb_getoneofcase_field(const upb_msg *msg, const upb_msglayout_field *f)
Definition: php-upb.h:1321
upb_fielddef_jsonname
const char * upb_fielddef_jsonname(const upb_fielddef *f)
Definition: ruby-upb.c:4814
upb_alloc_global
upb_alloc upb_alloc_global
Definition: ruby-upb.c:2743
upb_fielddef_checkintfmt
bool upb_fielddef_checkintfmt(int32_t fmt)
Definition: ruby-upb.c:4956
upb_arena::cleanup_metadata
uintptr_t cleanup_metadata
Definition: php-upb.h:1749
google_protobuf_DescriptorProto__fields
static const upb_msglayout_field google_protobuf_DescriptorProto__fields[10]
Definition: ruby-upb.c:4041
upb_oneofdef_itof
const upb_fielddef * upb_oneofdef_itof(const upb_oneofdef *o, uint32_t num)
Definition: ruby-upb.c:5189
upb_msg
void upb_msg
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.h:548
UPB_JSONENC_PROTONAMES
@ UPB_JSONENC_PROTONAMES
Definition: php-upb.h:4806
upb_fielddef_number
uint32_t upb_fielddef_number(const upb_fielddef *f)
Definition: ruby-upb.c:4794
google_protobuf_EnumDescriptorProto_EnumReservedRange_msginit
const upb_msglayout google_protobuf_EnumDescriptorProto_EnumReservedRange_msginit
Definition: ruby-upb.c:4165
jsondec_null
static void jsondec_null(jsondec *d)
Definition: ruby-upb.c:7083
google_protobuf_MethodOptions__fields
static const upb_msglayout_field google_protobuf_MethodOptions__fields[3]
Definition: ruby-upb.c:4359
decode_top
static bool decode_top(struct upb_decstate *d, const char *buf, void *msg, const upb_msglayout *l)
Definition: ruby-upb.c:941
upb_utf8_offsets
const uint8_t upb_utf8_offsets[]
Definition: ruby-upb.c:421
google_protobuf_FieldDescriptorProto
struct google_protobuf_FieldDescriptorProto google_protobuf_FieldDescriptorProto
Definition: descriptor.upb.h:56
_upb_msg_getorcreateext
upb_msg_ext * _upb_msg_getorcreateext(upb_msg *msg, const upb_msglayout_ext *e, upb_arena *arena)
Definition: ruby-upb.c:1589
_upb_mapsorter_getkeys
static void _upb_mapsorter_getkeys(const void *_a, const void *_b, void *a_key, void *b_key, size_t size)
Definition: ruby-upb.c:1676
google_protobuf_OneofOptions__fields
static const upb_msglayout_field google_protobuf_OneofOptions__fields[1]
Definition: ruby-upb.c:4299
arena
grpc_core::ScopedArenaPtr arena
Definition: binder_transport_test.cc:237
upb_mapiter_key
upb_msgval upb_mapiter_key(const upb_map *map, size_t iter)
Definition: ruby-upb.c:6949
_upb_decode
bool _upb_decode(const char *buf, size_t size, void *msg, const upb_msglayout *l, const upb_extreg *extreg, int options, upb_arena *arena)
Definition: ruby-upb.c:949
google_protobuf_OneofOptions_submsgs
static const upb_msglayout *const google_protobuf_OneofOptions_submsgs[1]
Definition: ruby-upb.c:4295
UPB_WELLKNOWN_VALUE
@ UPB_WELLKNOWN_VALUE
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.h:2997
python_utils.port_server.stderr
stderr
Definition: port_server.py:51
upb_oneofdef_field
const upb_fielddef * upb_oneofdef_field(const upb_oneofdef *o, int i)
Definition: ruby-upb.c:5165
decode_togroup
static const UPB_FORCEINLINE char * decode_togroup(upb_decstate *d, const char *ptr, upb_msg *submsg, upb_msglayout const *const *submsgs, const upb_msglayout_field *field)
Definition: ruby-upb.c:624
jsondec_objend
static void jsondec_objend(jsondec *d)
Definition: ruby-upb.c:7171
UPB_WELLKNOWN_UINT32VALUE
@ UPB_WELLKNOWN_UINT32VALUE
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.h:2992
UPB_LIKELY
#define UPB_LIKELY(x)
Definition: ruby-upb.c:103
block
Block * block
Definition: protobuf/src/google/protobuf/descriptor.cc:1041
UPB_WIRE_TYPE_32BIT
@ UPB_WIRE_TYPE_32BIT
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.h:466
fill_fieldlayout
static void fill_fieldlayout(upb_msglayout_field *field, const upb_fielddef *f)
Definition: ruby-upb.c:5466
UPB_WELLKNOWN_UINT64VALUE
@ UPB_WELLKNOWN_UINT64VALUE
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.h:2990
UPB_DTYPE_SFIXED64
@ UPB_DTYPE_SFIXED64
Definition: php-upb.h:569
streql
static bool streql(upb_tabkey k1, lookupkey_t k2)
Definition: ruby-upb.c:2274
upb_inttable_insert
bool upb_inttable_insert(upb_inttable *t, uintptr_t key, upb_value val, upb_arena *a)
Definition: ruby-upb.c:2462
_upb_msg_new
upb_msg * _upb_msg_new(const upb_msglayout *l, upb_arena *a)
Definition: ruby-upb.c:1492
o
UnboundConversion o
Definition: third_party/abseil-cpp/absl/strings/internal/str_format/parser_test.cc:97
hash
uint64_t hash
Definition: ring_hash.cc:284
upb_encstate
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.c:782
encode_mapentry
static void encode_mapentry(upb_encstate *e, uint32_t number, const upb_msglayout *layout, const upb_map_entry *ent)
Definition: ruby-upb.c:1350
google_protobuf_SourceCodeInfo_Location_msginit
const upb_msglayout google_protobuf_SourceCodeInfo_Location_msginit
Definition: ruby-upb.c:4424
UPB_DTYPE_FIXED32
@ UPB_DTYPE_FIXED32
Definition: php-upb.h:560
UPB_WIRE_TYPE_VARINT
@ UPB_WIRE_TYPE_VARINT
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.h:461
uint32_t
unsigned int uint32_t
Definition: stdint-msvc2008.h:80
field_number_cmp
static int field_number_cmp(const void *p1, const void *p2)
Definition: ruby-upb.c:5443
upb_msg_iter_field
upb_fielddef * upb_msg_iter_field(const upb_msg_field_iter *iter)
Definition: ruby-upb.c:5104
decode_tag
static const UPB_FORCEINLINE char * decode_tag(upb_decstate *d, const char *ptr, uint32_t *val)
Definition: ruby-upb.c:485
upb_strtable_lookup
UPB_INLINE bool upb_strtable_lookup(const upb_strtable *t, const char *key, upb_value *v)
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.h:965
_upb_msg_getext
const upb_msg_ext * _upb_msg_getext(const upb_msg *msg, const upb_msglayout_ext *e)
Definition: ruby-upb.c:1572
UPB_ALIGN_OF
#define UPB_ALIGN_OF(type)
Definition: ruby-upb.c:96
TAG
#define TAG(wire_type)
UPB_WIRE_TYPE_DELIMITED
@ UPB_WIRE_TYPE_DELIMITED
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.h:463
google_protobuf_EnumDescriptorProto_name
UPB_INLINE upb_StringView google_protobuf_EnumDescriptorProto_name(const google_protobuf_EnumDescriptorProto *msg)
Definition: descriptor.upb.h:1197
for
for(map_begin_internal(intern, &it);!map_done(&it);map_next(&it))
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/map.c:207
upb_table::count
size_t count
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.h:819
upb_strtable_begin
void upb_strtable_begin(upb_strtable_iter *i, const upb_strtable *t)
Definition: ruby-upb.c:2347
upb_msglayout_place
static uint32_t upb_msglayout_place(upb_msglayout *l, size_t size)
Definition: ruby-upb.c:5434
upb_global_allocfunc
static void * upb_global_allocfunc(upb_alloc *alloc, void *ptr, size_t oldsize, size_t size)
Definition: ruby-upb.c:2718
UPB_TYPE_BYTES
@ UPB_TYPE_BYTES
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.h:482
upb_symtab::arena
upb_arena * arena
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.c:3019
upb_msgdef_field
const upb_fielddef * upb_msgdef_field(const upb_msgdef *m, int i)
Definition: ruby-upb.c:5064
UPB_ENCODE_SKIPUNKNOWN
@ UPB_ENCODE_SKIPUNKNOWN
Definition: php-upb.h:1945
cleanup_ent::ud
void * ud
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.c:2283
upb_oneofdef
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.c:2992
ULL
#define ULL(x)
Definition: bloaty/third_party/protobuf/src/google/protobuf/io/coded_stream_unittest.cc:57
google_protobuf_FieldDescriptorProto_has_extendee
UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_extendee(const google_protobuf_FieldDescriptorProto *msg)
Definition: descriptor.upb.h:936
upb_fielddef_defaultuint32
uint32_t upb_fielddef_defaultuint32(const upb_fielddef *f)
Definition: ruby-upb.c:4872
upb_array_append
bool upb_array_append(upb_array *arr, upb_msgval val, upb_arena *arena)
Definition: ruby-upb.c:6895
jsondec_msg
static upb_msgval jsondec_msg(jsondec *d, const upb_fielddef *f)
Definition: ruby-upb.c:7852
jsondec_value
static upb_msgval jsondec_value(jsondec *d, const upb_fielddef *f)
Definition: ruby-upb.c:7918
google_protobuf_MessageOptions_msginit
const upb_msglayout google_protobuf_MessageOptions_msginit
Definition: ruby-upb.c:4269
upb_filedef::dep_count
int dep_count
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.c:3012
UPB_TYPE_ENUM
@ UPB_TYPE_ENUM
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.h:479
google_protobuf_EnumValueDescriptorProto_msginit
const upb_msglayout google_protobuf_EnumValueDescriptorProto_msginit
Definition: ruby-upb.c:4181
UPB_MSG_BEGIN
#define UPB_MSG_BEGIN
Definition: php-upb.h:4679
upb_msg_iter_oneof
const upb_oneofdef * upb_msg_iter_oneof(const upb_msg_oneof_iter *iter)
Definition: ruby-upb.c:5138
encode_fixedarray
static void encode_fixedarray(upb_encstate *e, const upb_array *arr, size_t elem_size, uint32_t tag)
Definition: ruby-upb.c:1136
findentry_mutable
static upb_tabent * findentry_mutable(upb_table *t, lookupkey_t key, uint32_t hash, eqlfunc_t *eql)
Definition: ruby-upb.c:1998
_upb_array_ptr
UPB_INLINE void * _upb_array_ptr(upb_array *arr)
Definition: php-upb.h:1350
UPB_JSONDEC_IGNOREUNKNOWN
@ UPB_JSONDEC_IGNOREUNKNOWN
Definition: php-upb.h:4778
google_protobuf_FieldDescriptorProto_has_oneof_index
UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_oneof_index(const google_protobuf_FieldDescriptorProto *msg)
Definition: descriptor.upb.h:1005
upb_fielddef_defaultint32
int32_t upb_fielddef_defaultint32(const upb_fielddef *f)
Definition: ruby-upb.c:4862
google_protobuf_UninterpretedOption_msginit
const upb_msglayout google_protobuf_UninterpretedOption_msginit
Definition: ruby-upb.c:4385
memcpy
memcpy(mem, inblock.get(), min(CONTAINING_RECORD(inblock.get(), MEMBLOCK, data) ->size, size))
jsondec_peek
static int jsondec_peek(jsondec *d)
Definition: ruby-upb.c:7131
symtab_resolve
static const void * symtab_resolve(symtab_addctx *ctx, const upb_fielddef *f, const char *base, upb_strview sym, upb_deftype_t type)
Definition: ruby-upb.c:5766
upb_oneofdef_index
uint32_t upb_oneofdef_index(const upb_oneofdef *o)
Definition: ruby-upb.c:5174
upb_msg_getinternal_const
static const upb_msg_internal * upb_msg_getinternal_const(const upb_msg *msg)
Definition: ruby-upb.c:1487
in
const char * in
Definition: third_party/abseil-cpp/absl/strings/internal/str_format/parser_test.cc:391
WRITE
#define WRITE(byte)
upb_msg_discardunknown
bool upb_msg_discardunknown(upb_msg *msg, const upb_msgdef *m, int maxdepth)
Definition: ruby-upb.c:6865
start
static uint64_t start
Definition: benchmark-pound.c:74
decode_varint64
static const UPB_FORCEINLINE char * decode_varint64(upb_decstate *d, const char *ptr, uint64_t *val)
Definition: ruby-upb.c:470
UPB_ALIGN_UP
#define UPB_ALIGN_UP(size, align)
Definition: ruby-upb.c:93
google_protobuf_OneofDescriptorProto__fields
static const upb_msglayout_field google_protobuf_OneofDescriptorProto__fields[2]
Definition: ruby-upb.c:4129
upb_msg_internal
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.c:1141
UINT8_MAX
#define UINT8_MAX
Definition: stdint-msvc2008.h:140
upb_fielddef_enumsubdef
const upb_enumdef * upb_fielddef_enumsubdef(const upb_fielddef *f)
Definition: ruby-upb.c:4910
jsondec_buftoint64
static const char * jsondec_buftoint64(jsondec *d, const char *ptr, const char *end, int64_t *val)
Definition: ruby-upb.c:7595
c
void c(T a)
Definition: miscompile_with_no_unique_address_test.cc:40
upb_json_encode
size_t 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)
Definition: ruby-upb.c:9116
UPB_DESCRIPTOR_TYPE_MESSAGE
@ UPB_DESCRIPTOR_TYPE_MESSAGE
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.h:509
_upb_fieldtype_to_sizelg2
static const char _upb_fieldtype_to_sizelg2[12]
Definition: ruby-upb.c:6644
upb_fielddef_name
const char * upb_fielddef_name(const upb_fielddef *f)
Definition: ruby-upb.c:4810
autogen_x86imm.f
f
Definition: autogen_x86imm.py:9
upb_msgval_sizeof
static size_t upb_msgval_sizeof(upb_fieldtype_t type)
Definition: ruby-upb.c:5400
asyncio_get_stats.args
args
Definition: asyncio_get_stats.py:40
upb_strtable_resize
bool upb_strtable_resize(upb_strtable *t, size_t size_lg2, upb_arena *a)
Definition: ruby-upb.c:2294
jsonenc_putstr
static void jsonenc_putstr(jsonenc *e, const char *str)
Definition: ruby-upb.c:8484
upb_symtab::files
upb_strtable files
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.c:3021
a2
T::first_type a2
Definition: abseil-cpp/absl/container/internal/hash_function_defaults_test.cc:307
jsondec_isvalue
static bool jsondec_isvalue(const upb_fielddef *f)
Definition: ruby-upb.c:7016
benchmark.syntax
syntax
Definition: benchmark.py:90
upb_msgdef_isnumberwrapper
bool upb_msgdef_isnumberwrapper(const upb_msgdef *m)
Definition: ruby-upb.c:5082
xds_interop_client.int
int
Definition: xds_interop_client.py:113
_upb_map_set
UPB_INLINE bool _upb_map_set(upb_map *map, const void *key, size_t key_size, void *val, size_t val_size, upb_arena *a)
Definition: php-upb.h:1588
invalid
@ invalid
Definition: base64_test.cc:39
i1
int i1
Definition: abseil-cpp/absl/container/btree_test.cc:2772
UPB_UNUSED
#define UPB_UNUSED(var)
Definition: ruby-upb.c:128
absl::move
constexpr absl::remove_reference_t< T > && move(T &&t) noexcept
Definition: abseil-cpp/absl/utility/utility.h:221
end
char * end
Definition: abseil-cpp/absl/strings/internal/str_format/float_conversion.cc:1008
upb_enumdef_default
int32_t upb_enumdef_default(const upb_enumdef *e)
Definition: ruby-upb.c:4700
google_protobuf_FileOptions_has_php_namespace
UPB_INLINE bool google_protobuf_FileOptions_has_php_namespace(const google_protobuf_FileOptions *msg)
Definition: descriptor.upb.h:1835
UPB_DTYPE_BYTES
@ UPB_DTYPE_BYTES
Definition: php-upb.h:565
jsondec_tryskipdigits
static bool jsondec_tryskipdigits(jsondec *d)
Definition: ruby-upb.c:7186
upb_mapiter_done
bool upb_mapiter_done(const upb_map *map, size_t iter)
Definition: ruby-upb.c:6940
decode_vret::ptr
const char * ptr
Definition: php-upb.c:448
gen_stats_data.found
bool found
Definition: gen_stats_data.py:61
jsondec_field
static void jsondec_field(jsondec *d, upb_msg *msg, const upb_msgdef *m)
Definition: ruby-upb.c:7862
upb_msg_sizeof
static size_t upb_msg_sizeof(const upb_msglayout *l)
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.c:1157
gen_synthetic_protos.label
label
Definition: gen_synthetic_protos.py:102
int64_t
signed __int64 int64_t
Definition: stdint-msvc2008.h:89
upb_realloc
UPB_INLINE void * upb_realloc(upb_alloc *alloc, void *ptr, size_t oldsize, size_t size)
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.h:308
Wyhash
uint64_t Wyhash(const void *data, size_t len, uint64_t seed, const uint64_t salt[])
Definition: ruby-upb.c:2180
google_protobuf_EnumValueDescriptorProto_submsgs
static const upb_msglayout *const google_protobuf_EnumValueDescriptorProto_submsgs[1]
Definition: ruby-upb.c:4171
upb_map_clear
void upb_map_clear(upb_map *map)
Definition: ruby-upb.c:6923
jsondec_map
static void jsondec_map(jsondec *d, upb_msg *msg, const upb_fielddef *f)
Definition: ruby-upb.c:7827
upb_inttable_done
bool upb_inttable_done(const upb_inttable_iter *i)
Definition: ruby-upb.c:2627
google_protobuf_UninterpretedOption_submsgs
static const upb_msglayout *const google_protobuf_UninterpretedOption_submsgs[1]
Definition: ruby-upb.c:4371
UPB_WELLKNOWN_DURATION
@ UPB_WELLKNOWN_DURATION
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.h:2984
upb_cleanup_pointer
static uint32_t * upb_cleanup_pointer(uintptr_t cleanup_metadata)
Definition: ruby-upb.c:2730
upb_map_size
size_t upb_map_size(const upb_map *map)
Definition: ruby-upb.c:6915
_upb_sortedmap::pos
int pos
Definition: php-upb.h:1696
encode_err
static UPB_NORETURN void encode_err(upb_encstate *e)
Definition: ruby-upb.c:1042
tag
static void * tag(intptr_t t)
Definition: bad_client.cc:318
max
int max
Definition: bloaty/third_party/zlib/examples/enough.c:170
upb_fielddef::uint
uint64_t uint
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.c:2940
google_protobuf_FieldDescriptorProto_label
UPB_INLINE int32_t google_protobuf_FieldDescriptorProto_label(const google_protobuf_FieldDescriptorProto *msg)
Definition: descriptor.upb.h:963
SIZE_MAX
#define SIZE_MAX
Definition: stdint-msvc2008.h:206
jsonenc_value
static void jsonenc_value(jsonenc *e, const upb_msg *msg, const upb_msgdef *m)
Definition: ruby-upb.c:8877
root
RefCountedPtr< grpc_tls_certificate_provider > root
Definition: xds_server_config_fetcher.cc:223
google_protobuf_FieldOptions
struct google_protobuf_FieldOptions google_protobuf_FieldOptions
Definition: descriptor.upb.h:65
overhead
static const size_t overhead
Definition: ruby-upb.c:1485
google_protobuf_EnumDescriptorProto_msginit
const upb_msglayout google_protobuf_EnumDescriptorProto_msginit
Definition: ruby-upb.c:4154
ruby-upb.h
upb_enumdef_fullname
const char * upb_enumdef_fullname(const upb_enumdef *e)
Definition: ruby-upb.c:4688
upb_inthash
static uint32_t upb_inthash(uintptr_t key)
Definition: ruby-upb.c:1933
_upb_tabent::val
upb_tabval val
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.h:809
wireval::size
uint32_t size
Definition: php-upb.c:396
google_protobuf_OneofOptions_msginit
const upb_msglayout google_protobuf_OneofOptions_msginit
Definition: ruby-upb.c:4303
upb_symtab::syms
upb_strtable syms
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.c:3020
jsonenc_putsep
static void jsonenc_putsep(jsonenc *e, const char *str, bool *first)
Definition: ruby-upb.c:8780
google_protobuf_EnumValueOptions_msginit
const upb_msglayout google_protobuf_EnumValueOptions_msginit
Definition: ruby-upb.c:4334
UPB_WELLKNOWN_FLOATVALUE
@ UPB_WELLKNOWN_FLOATVALUE
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.h:2988
upb_msgdef_name
const char * upb_msgdef_name(const upb_msgdef *m)
Definition: ruby-upb.c:4972
upb_table::size_lg2
uint8_t size_lg2
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.h:822
upb_oneofdef::full_name
const char * full_name
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.c:2994
upb_fielddef::lazy_
bool lazy_
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.c:2956
jsondec_base64_tablelookup
static unsigned int jsondec_base64_tablelookup(const char ch)
Definition: ruby-upb.c:7460
upb_filedef_phpnamespace
const char * upb_filedef_phpnamespace(const upb_filedef *f)
Definition: ruby-upb.c:5229
UPB_FORCEINLINE
#define UPB_FORCEINLINE
Definition: ruby-upb.c:119
google_protobuf_FileDescriptorProto_syntax
UPB_INLINE upb_StringView google_protobuf_FileDescriptorProto_syntax(const google_protobuf_FileDescriptorProto *msg)
Definition: descriptor.upb.h:348
google_protobuf_FileOptions_submsgs
static const upb_msglayout *const google_protobuf_FileOptions_submsgs[1]
Definition: ruby-upb.c:4223
upb_DefPool::syms
upb_strtable syms
Definition: upb/upb/def.c:219
decode_verifyutf8_inl
UPB_INLINE bool decode_verifyutf8_inl(const char *buf, int len)
Definition: php-upb.h:1798
google_protobuf_FileDescriptorProto_has_name
UPB_INLINE bool google_protobuf_FileDescriptorProto_has_name(const google_protobuf_FileDescriptorProto *msg)
Definition: descriptor.upb.h:249
upb_inttable_count
size_t upb_inttable_count(const upb_inttable *t)
Definition: ruby-upb.c:2419
upb_array::len
size_t len
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.h:580
strcopy
static upb_tabkey strcopy(lookupkey_t k2, upb_arena *a)
Definition: ruby-upb.c:2119
setup.v
v
Definition: third_party/bloaty/third_party/capstone/bindings/python/setup.py:42
upb_inttable_iter
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.h:1113
_upb_map_new
upb_map * _upb_map_new(upb_arena *a, size_t key_size, size_t value_size)
Definition: ruby-upb.c:1662
UPB_PTR_AT
#define UPB_PTR_AT(msg, ofs, type)
Definition: ruby-upb.c:71
google_protobuf_FileDescriptorProto_msginit
const upb_msglayout google_protobuf_FileDescriptorProto_msginit
Definition: ruby-upb.c:4025
upb_filedef_enumcount
int upb_filedef_enumcount(const upb_filedef *f)
Definition: ruby-upb.c:5245
upb_oneofdef_fieldcount
int upb_oneofdef_fieldcount(const upb_oneofdef *o)
Definition: ruby-upb.c:5161
jsonenc_stringbody
static void jsonenc_stringbody(jsonenc *e, upb_strview str)
Definition: ruby-upb.c:8639
google_protobuf_FileDescriptorProto_extension
const UPB_INLINE google_protobuf_FieldDescriptorProto *const * google_protobuf_FileDescriptorProto_extension(const google_protobuf_FileDescriptorProto *msg, size_t *len)
Definition: descriptor.upb.h:308
UPB_DESCRIPTOR_TYPE_SINT32
@ UPB_DESCRIPTOR_TYPE_SINT32
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.h:515
UPB_WELLKNOWN_TIMESTAMP
@ UPB_WELLKNOWN_TIMESTAMP
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.h:2985
upb_arrhas
static bool upb_arrhas(upb_tabval key)
Definition: ruby-upb.c:1941
upb_fielddef::defaultval
union upb_fielddef::@206 defaultval
google_protobuf_OneofDescriptorProto_submsgs
static const upb_msglayout *const google_protobuf_OneofDescriptorProto_submsgs[1]
Definition: ruby-upb.c:4125
upb_fielddef_index
uint32_t upb_fielddef_index(const upb_fielddef *f)
Definition: ruby-upb.c:4786
jsondec_wrapper
static void jsondec_wrapper(jsondec *d, upb_msg *msg, const upb_msgdef *m)
Definition: ruby-upb.c:8345
_upb_map_fromvalue
UPB_INLINE void _upb_map_fromvalue(upb_value val, void *out, size_t size)
Definition: php-upb.h:1552
upb_arena::freelist
mem_block * freelist
Definition: php-upb.h:1763
upb_status_clear
void upb_status_clear(upb_status *status)
Definition: ruby-upb.c:2676
upb_fielddef::json_name
const char * json_name
Definition: php-upb.c:4864
google_protobuf_OneofDescriptorProto_name
UPB_INLINE upb_StringView google_protobuf_OneofDescriptorProto_name(const google_protobuf_OneofDescriptorProto *msg)
Definition: descriptor.upb.h:1128
upb_fielddef_containingoneof
const upb_oneofdef * upb_fielddef_containingoneof(const upb_fielddef *f)
Definition: ruby-upb.c:4826
google_protobuf_DescriptorProto_ReservedRange__fields
static const upb_msglayout_field google_protobuf_DescriptorProto_ReservedRange__fields[2]
Definition: ruby-upb.c:4076
inthash
static uint32_t inthash(upb_tabkey key)
Definition: ruby-upb.c:2394
upb_oneofdef_name
const char * upb_oneofdef_name(const upb_oneofdef *o)
Definition: ruby-upb.c:5153
jsondec_wellknown
static void jsondec_wellknown(jsondec *d, upb_msg *msg, const upb_msgdef *m)
Definition: ruby-upb.c:8351
upb_filedef::msg_count
int msg_count
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.c:3013
MessageLayout::fields
MessageField * fields
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/protobuf.h:938
upb_inttable_lookup
bool upb_inttable_lookup(const upb_inttable *t, uintptr_t key, upb_value *v)
Definition: ruby-upb.c:2502
_upb_map_clear
UPB_INLINE void _upb_map_clear(upb_map *map)
Definition: php-upb.h:1604
upb_json_decode
bool 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)
Definition: ruby-upb.c:8390
upb_strdup2
char * upb_strdup2(const char *s, size_t len, upb_arena *a)
Definition: ruby-upb.c:1889
uint64_t
unsigned __int64 uint64_t
Definition: stdint-msvc2008.h:90
OP_SCALAR_LG2
#define OP_SCALAR_LG2(n)
Definition: ruby-upb.c:320
upb_array::data
void * data
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.h:579
decode_tryfastdispatch
static UPB_FORCEINLINE bool decode_tryfastdispatch(upb_decstate *d, const char **ptr, upb_msg *msg, const upb_msglayout *layout)
Definition: ruby-upb.c:813
upb_tabkey
uintptr_t upb_tabkey
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.h:787
cleanup_ent
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.c:2280
upb_msgval::float_val
float float_val
Definition: php-upb.h:4614
upb_inttable
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.h:848
_upb_map_size
UPB_INLINE size_t _upb_map_size(const upb_map *map)
Definition: php-upb.h:1563
upb_enumdef::ntoi
upb_strtable ntoi
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.c:2987
CASE
#define CASE(ctype, type, wtype, encodeval)
upb_enumdef_name
const char * upb_enumdef_name(const upb_enumdef *e)
Definition: ruby-upb.c:4692
upb_fielddef::unresolved
const google_protobuf_FieldDescriptorProto * unresolved
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.c:2950
def
int def(FILE *source, FILE *dest, int level)
Definition: bloaty/third_party/zlib/examples/zpipe.c:36
upb_fielddef_checklabel
bool upb_fielddef_checklabel(int32_t label)
Definition: ruby-upb.c:4954
UPB_DESCRIPTOR_TYPE_UINT32
@ UPB_DESCRIPTOR_TYPE_UINT32
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.h:511
upb_fielddef_isextension
bool upb_fielddef_isextension(const upb_fielddef *f)
Definition: ruby-upb.c:4798
upb_mutmsgval::array
upb_array * array
Definition: php-upb.h:4629
google_protobuf_SourceCodeInfo__fields
static const upb_msglayout_field google_protobuf_SourceCodeInfo__fields[1]
Definition: ruby-upb.c:4406
google_protobuf_DescriptorProto_extension
const UPB_INLINE google_protobuf_FieldDescriptorProto *const * google_protobuf_DescriptorProto_extension(const google_protobuf_DescriptorProto *msg, size_t *len)
Definition: descriptor.upb.h:549
done
struct tab * done
Definition: bloaty/third_party/zlib/examples/enough.c:176
upb_filedef_package
const char * upb_filedef_package(const upb_filedef *f)
Definition: ruby-upb.c:5221
UPB_MIN
#define UPB_MIN(x, y)
Definition: ruby-upb.c:126
jsonenc_err
static UPB_NORETURN void jsonenc_err(jsonenc *e, const char *msg)
Definition: ruby-upb.c:8448
upb_fielddef::layout_index
uint16_t layout_index
Definition: php-upb.c:4881
upb_fielddef::type_
upb_descriptortype_t type_
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.c:2958
delim_ops
static const int8_t delim_ops[37]
Definition: ruby-upb.c:350
google_protobuf_FileOptions__fields
static const upb_msglayout_field google_protobuf_FileOptions__fields[21]
Definition: ruby-upb.c:4227
upb_msgdef_syntax
upb_syntax_t upb_msgdef_syntax(const upb_msgdef *m)
Definition: ruby-upb.c:4976
jsonenc_timestamp
static void jsonenc_timestamp(jsonenc *e, const upb_msg *msg, const upb_msgdef *m)
Definition: ruby-upb.c:8522
jsondec_arrend
static void jsondec_arrend(jsondec *d)
Definition: ruby-upb.c:7157
google_protobuf_EnumDescriptorProto
struct google_protobuf_EnumDescriptorProto google_protobuf_EnumDescriptorProto
Definition: descriptor.upb.h:58
_upb_msg_new_inl
UPB_INLINE upb_msg * _upb_msg_new_inl(const upb_msglayout *l, upb_arena *a)
Definition: php-upb.h:1209
JD_NULL
@ JD_NULL
Definition: ruby-upb.c:6997
UPB_DESCRIPTOR_TYPE_FIXED64
@ UPB_DESCRIPTOR_TYPE_FIXED64
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.h:504
upb_deftype_t
upb_deftype_t
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.c:3025
upb_symtab
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.c:3018
upb_enumdef::defaultval
int32_t defaultval
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.c:2989
upb_enum_next
void upb_enum_next(upb_enum_iter *iter)
Definition: ruby-upb.c:4714
upb_msgval::double_val
double double_val
Definition: php-upb.h:4615
UPB_LABEL_OPTIONAL
@ UPB_LABEL_OPTIONAL
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.h:492
upb_extreg_new
upb_extreg * upb_extreg_new(upb_arena *arena)
Definition: ruby-upb.c:1805
jsondec_timestamp
static void jsondec_timestamp(jsondec *d, upb_msg *msg, const upb_msgdef *m)
Definition: ruby-upb.c:8001
upb_tabval
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.h:798
upb_arena_new
UPB_INLINE upb_arena * upb_arena_new(void)
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.h:392
absl::compare_internal::value_type
int8_t value_type
Definition: abseil-cpp/absl/types/compare.h:45
number
int32_t number
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/protobuf.h:850
upb_msglayout::submsgs
const struct upb_msglayout *const * submsgs
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.h:566
google_protobuf_FileOptions_php_class_prefix
UPB_INLINE upb_StringView google_protobuf_FileOptions_php_class_prefix(const google_protobuf_FileOptions *msg)
Definition: descriptor.upb.h:1832
jsondec_tomsg
static void jsondec_tomsg(jsondec *d, upb_msg *msg, const upb_msgdef *m)
Definition: ruby-upb.c:7844
upb_msgdef::fields
const upb_fielddef * fields
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.c:2972
upb_arena
struct upb_arena upb_arena
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.h:365
arena_findroot
static upb_arena * arena_findroot(upb_arena *a)
Definition: ruby-upb.c:2763
fastdecode_loadtag
UPB_INLINE uint32_t fastdecode_loadtag(const char *ptr)
Definition: php-upb.h:1888
google_protobuf_DescriptorProto_ExtensionRange_submsgs
static const upb_msglayout *const google_protobuf_DescriptorProto_ExtensionRange_submsgs[1]
Definition: ruby-upb.c:4060
jsondec_base64
static size_t jsondec_base64(jsondec *d, upb_strview str)
Definition: ruby-upb.c:7533
UPB_DESCRIPTOR_TYPE_FLOAT
@ UPB_DESCRIPTOR_TYPE_FLOAT
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.h:500
intptr_t
_W64 signed int intptr_t
Definition: stdint-msvc2008.h:118
upb_fielddef_isseq
bool upb_fielddef_isseq(const upb_fielddef *f)
Definition: ruby-upb.c:4927
google_protobuf_FileDescriptorProto__fields
static const upb_msglayout_field google_protobuf_FileDescriptorProto__fields[12]
Definition: ruby-upb.c:4010
jsonenc_fieldmask
static void jsonenc_fieldmask(jsonenc *e, const upb_msg *msg, const upb_msgdef *m)
Definition: ruby-upb.c:8809
upb_umul128
static uint64_t upb_umul128(uint64_t v0, uint64_t v1, uint64_t *out_high)
Definition: ruby-upb.c:2149
_upb_extreg_add
bool _upb_extreg_add(upb_extreg *r, const upb_msglayout_ext *e, size_t count)
Definition: ruby-upb.c:1813
_upb_array_resize_fallback
void * _upb_array_resize_fallback(upb_array **arr_ptr, size_t size, int elem_size_lg2, upb_arena *arena)
Definition: ruby-upb.c:1637
mon
static const char *const mon[12]
Definition: a_strex.c:515
UPB_DESCRIPTOR_TYPE_SINT64
@ UPB_DESCRIPTOR_TYPE_SINT64
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.h:516
upb_gfree
UPB_INLINE void upb_gfree(void *ptr)
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.h:344
upb_fielddef_defaultfloat
float upb_fielddef_defaultfloat(const upb_fielddef *f)
Definition: ruby-upb.c:4882
x
int x
Definition: bloaty/third_party/googletest/googlemock/test/gmock-matchers_test.cc:3610
remove_filedef
static void remove_filedef(upb_symtab *s, upb_filedef *file)
Definition: ruby-upb.c:6475
google_protobuf_GeneratedCodeInfo__fields
static const upb_msglayout_field google_protobuf_GeneratedCodeInfo__fields[1]
Definition: ruby-upb.c:4434
decode_toarray
static const char * decode_toarray(upb_decstate *d, const char *ptr, upb_msg *msg, upb_msglayout const *const *submsgs, const upb_msglayout_field *field, wireval *val, int op)
Definition: ruby-upb.c:632
UPB_LABEL_REQUIRED
@ UPB_LABEL_REQUIRED
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.h:493
google_protobuf_FileDescriptorProto_has_package
UPB_INLINE bool google_protobuf_FileDescriptorProto_has_package(const google_protobuf_FileDescriptorProto *msg)
Definition: descriptor.upb.h:259
mem_block
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.c:2272
gen_synthetic_protos.base
base
Definition: gen_synthetic_protos.py:31
data
char data[kBufferLength]
Definition: abseil-cpp/absl/strings/internal/str_format/float_conversion.cc:1006
google_protobuf_UninterpretedOption__fields
static const upb_msglayout_field google_protobuf_UninterpretedOption__fields[7]
Definition: ruby-upb.c:4375
UPB_MUSTTAIL
#define UPB_MUSTTAIL
Definition: ruby-upb.c:181
UPB_STRVIEW_FORMAT
#define UPB_STRVIEW_FORMAT
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.h:279
upb_array
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.h:578
upb_status_seterrmsg
void upb_status_seterrmsg(upb_status *status, const char *msg)
Definition: ruby-upb.c:2686
jsondec_objnext
static bool jsondec_objnext(jsondec *d)
Definition: ruby-upb.c:7176
UPB_MAX
#define UPB_MAX(x, y)
Definition: ruby-upb.c:125
unpack_def
static const void * unpack_def(upb_value v, upb_deftype_t type)
Definition: ruby-upb.c:4584
UPB_STRVIEW_ARGS
#define UPB_STRVIEW_ARGS(view)
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.h:280
upb_fielddef
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.c:2934
_upb_getmode
UPB_INLINE upb_fieldmode _upb_getmode(const upb_msglayout_field *field)
Definition: php-upb.h:1107
inteql
static bool inteql(upb_tabkey k1, lookupkey_t k2)
Definition: ruby-upb.c:2396
create_msgdef
static void create_msgdef(symtab_addctx *ctx, const char *prefix, const google_protobuf_DescriptorProto *msg_proto)
Definition: ruby-upb.c:6186
UPB_PB_VARINT_MAX_LEN
#define UPB_PB_VARINT_MAX_LEN
Definition: ruby-upb.c:1008
upb_filedef::syntax
upb_syntax_t syntax
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.c:3005
upb_msgdef::real_oneof_count
int real_oneof_count
Definition: php-upb.c:4903
UPB_DECODE_ALIAS
@ UPB_DECODE_ALIAS
Definition: php-upb.h:696
upb_decstate
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.c:183
upb_msgdef_ntof
const upb_fielddef * upb_msgdef_ntof(const upb_msgdef *m, const char *name, size_t len)
Definition: ruby-upb.c:4986
decode_isdonefallback
const UPB_NOINLINE char * decode_isdonefallback(upb_decstate *d, const char *ptr, int overrun)
Definition: ruby-upb.c:568
jsondec_array
static void jsondec_array(jsondec *d, upb_msg *msg, const upb_fielddef *f)
Definition: ruby-upb.c:7816
_upb_symtab_addfile
static const upb_filedef * _upb_symtab_addfile(upb_symtab *s, const google_protobuf_FileDescriptorProto *file_proto, const upb_msglayout **layouts, upb_status *status)
Definition: ruby-upb.c:6491
upb_oneofdef_issynthetic
bool upb_oneofdef_issynthetic(const upb_oneofdef *o)
Definition: ruby-upb.c:5178
jsondec_object
static void jsondec_object(jsondec *d, upb_msg *msg, const upb_msgdef *m)
Definition: ruby-upb.c:7910
upb_map_new
upb_map * upb_map_new(upb_arena *a, upb_fieldtype_t key_type, upb_fieldtype_t value_type)
Definition: ruby-upb.c:6909
uintptr_t
_W64 unsigned int uintptr_t
Definition: stdint-msvc2008.h:119
upb_filedef
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.c:3000
bm_speedup.scale
def scale(a, mul)
Definition: bm_speedup.py:24
upb_strtable_clear
void upb_strtable_clear(upb_strtable *t)
Definition: ruby-upb.c:2288
a1
T::first_type a1
Definition: abseil-cpp/absl/container/internal/hash_function_defaults_test.cc:305
_upb_arenahas
UPB_INLINE size_t _upb_arenahas(upb_arena *a)
Definition: php-upb.h:446
jsonenc_scalar
static void jsonenc_scalar(jsonenc *e, upb_msgval val, const upb_fielddef *f)
Definition: ruby-upb.c:8950
tests.google.protobuf.internal.message_test.cmp
cmp
Definition: bloaty/third_party/protobuf/python/compatibility_tests/v2.5.0/tests/google/protobuf/internal/message_test.py:61
mem_block::next
struct mem_block * next
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.c:2273
min
#define min(a, b)
Definition: qsort.h:83
desctype_to_mapsize
static const uint8_t desctype_to_mapsize[]
Definition: ruby-upb.c:289
UPB_SETJMP
#define UPB_SETJMP(buf)
Definition: ruby-upb.c:163
decode_longvarint64
static UPB_NOINLINE decode_vret decode_longvarint64(const char *ptr, uint64_t val)
Definition: ruby-upb.c:453
upb_malloc
UPB_INLINE void * upb_malloc(upb_alloc *alloc, size_t size)
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.h:303
upb_msg_oneof_done
bool upb_msg_oneof_done(const upb_msg_oneof_iter *iter)
Definition: ruby-upb.c:5134
b
uint64_t b
Definition: abseil-cpp/absl/container/internal/layout_test.cc:53
google_protobuf_FieldDescriptorProto_type_name
UPB_INLINE upb_StringView google_protobuf_FieldDescriptorProto_type_name(const google_protobuf_FieldDescriptorProto *msg)
Definition: descriptor.upb.h:983
upb_msgdef::layout
const upb_msglayout * layout
Definition: php-upb.c:4891
upb_inttable_replace
bool upb_inttable_replace(upb_inttable *t, uintptr_t key, upb_value val)
Definition: ruby-upb.c:2509
UPB_MAP_BEGIN
#define UPB_MAP_BEGIN
Definition: php-upb.h:574
_upb_sortedmap_next
UPB_INLINE bool _upb_sortedmap_next(_upb_mapsorter *s, const upb_map *map, _upb_sortedmap *sorted, upb_map_entry *ent)
Definition: php-upb.h:1717
upb_msgdef_lookupname
bool upb_msgdef_lookupname(const upb_msgdef *m, const char *name, size_t len, const upb_fielddef **f, const upb_oneofdef **o)
Definition: ruby-upb.c:5008
g
struct @717 g
google_protobuf_DescriptorProto_options
const UPB_INLINE google_protobuf_MessageOptions * google_protobuf_DescriptorProto_options(const google_protobuf_DescriptorProto *msg)
Definition: descriptor.upb.h:558
upb_inttable_next
void upb_inttable_next(upb_inttable_iter *iter)
Definition: ruby-upb.c:2612
google_protobuf_FileDescriptorProto_has_syntax
UPB_INLINE bool google_protobuf_FileDescriptorProto_has_syntax(const google_protobuf_FileDescriptorProto *msg)
Definition: descriptor.upb.h:341
UPB_DESCRIPTOR_TYPE_UINT64
@ UPB_DESCRIPTOR_TYPE_UINT64
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.h:502
newstr
static str_t * newstr(symtab_addctx *ctx, const char *data, size_t len)
Definition: ruby-upb.c:5819
layout
MessageLayout * layout
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/protobuf.h:809
upb_fielddef::boolean
bool boolean
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.c:2943
upb_enumdef::file
const upb_filedef * file
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.c:2985
_upb_mapsorter_popmap
UPB_INLINE void _upb_mapsorter_popmap(_upb_mapsorter *s, _upb_sortedmap *sorted)
Definition: php-upb.h:1713
d
static const fe d
Definition: curve25519_tables.h:19
upb_oneofdef::parent
const upb_msgdef * parent
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.c:2993
qsort
void qsort(void *a, size_t n, size_t es, int(*cmp)(const void *, const void *))
Definition: qsort.h:130
_upb_array_resize
UPB_INLINE bool _upb_array_resize(upb_array *arr, size_t size, upb_arena *arena)
Definition: php-upb.h:1387
UPB_TYPE_INT32
@ UPB_TYPE_INT32
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.h:477
google_protobuf_FieldOptions_has_packed
UPB_INLINE bool google_protobuf_FieldOptions_has_packed(const google_protobuf_FieldOptions *msg)
Definition: descriptor.upb.h:2129
jsondec_tryparsech
static bool jsondec_tryparsech(jsondec *d, char ch)
Definition: ruby-upb.c:7059
upb_fielddef::proto3_optional_
bool proto3_optional_
Definition: php-upb.c:4885
UPB_PTRADD
#define UPB_PTRADD(ptr, ofs)
Definition: ruby-upb.c:168
n
int n
Definition: abseil-cpp/absl/container/btree_test.cc:1080
int_arrent
static upb_tabval int_arrent(const upb_inttable_iter *i)
Definition: ruby-upb.c:2600
jsondec_err
static UPB_NORETURN void jsondec_err(jsondec *d, const char *msg)
Definition: ruby-upb.c:7023
google_protobuf_DescriptorProto_ExtensionRange__fields
static const upb_msglayout_field google_protobuf_DescriptorProto_ExtensionRange__fields[3]
Definition: ruby-upb.c:4064
google_protobuf_FileOptions_has_php_class_prefix
UPB_INLINE bool google_protobuf_FileOptions_has_php_class_prefix(const google_protobuf_FileOptions *msg)
Definition: descriptor.upb.h:1825
_upb_hasbit_field
UPB_INLINE bool _upb_hasbit_field(const upb_msg *msg, const upb_msglayout_field *f)
Definition: php-upb.h:1286
_upb_mapsorter_destroy
UPB_INLINE void _upb_mapsorter_destroy(_upb_mapsorter *s)
Definition: php-upb.h:1706
encode_varint64
static UPB_NOINLINE size_t encode_varint64(uint64_t val, char *buf)
Definition: ruby-upb.c:1011
google_protobuf_FileDescriptorProto_enum_type
const UPB_INLINE google_protobuf_EnumDescriptorProto *const * google_protobuf_FileDescriptorProto_enum_type(const google_protobuf_FileDescriptorProto *msg, size_t *len)
Definition: descriptor.upb.h:290
stdint.h
getjsonname
size_t getjsonname(const char *name, char *buf, size_t len)
Definition: ruby-upb.c:5710
upb_mutmsgval::map
upb_map * map
Definition: php-upb.h:4627
assign_msg_wellknowntype
static void assign_msg_wellknowntype(upb_msgdef *m)
Definition: ruby-upb.c:4642
upb_wellknowntype_t
upb_wellknowntype_t
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.h:2980
setup.idx
idx
Definition: third_party/bloaty/third_party/capstone/bindings/python/setup.py:197
UPB_WELLKNOWN_INT32VALUE
@ UPB_WELLKNOWN_INT32VALUE
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.h:2991
pack_def
static upb_value pack_def(const void *ptr, upb_deftype_t type)
Definition: ruby-upb.c:4589
_UPB_MODE_ARRAY
@ _UPB_MODE_ARRAY
Definition: php-upb.h:1098
after
IntAfterTypedTestSuiteP after
Definition: googletest/googletest/test/gtest-typed-test_test.cc:375
msg
std::string msg
Definition: client_interceptors_end2end_test.cc:372
upb_strtable_lookup2
bool upb_strtable_lookup2(const upb_strtable *t, const char *key, size_t len, upb_value *v)
Definition: ruby-upb.c:2332
upb_msgdef_mapentry
bool upb_msgdef_mapentry(const upb_msgdef *m)
Definition: ruby-upb.c:5074
upb_array_size
size_t upb_array_size(const upb_array *arr)
Definition: ruby-upb.c:6875
upb_fielddef::index_
uint32_t index_
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.c:2953
jsondec_entrysep
static void jsondec_entrysep(jsondec *d)
Definition: ruby-upb.c:7085
OP_SUBMSG
#define OP_SUBMSG
Definition: ruby-upb.c:323
jsonenc_struct
static void jsonenc_struct(jsonenc *e, const upb_msg *msg, const upb_msgdef *m)
Definition: ruby-upb.c:8828
upb_msg_whichoneof
const upb_fielddef * upb_msg_whichoneof(const upb_msg *msg, const upb_oneofdef *o)
Definition: ruby-upb.c:6690
upb_msg_oneof_iter_isequal
bool upb_msg_oneof_iter_isequal(const upb_msg_oneof_iter *iter1, const upb_msg_oneof_iter *iter2)
Definition: ruby-upb.c:5146
UPB_TABVALUE_EMPTY_INIT
#define UPB_TABVALUE_EMPTY_INIT
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.h:802
count_types_in_msg
static void count_types_in_msg(const google_protobuf_DescriptorProto *msg_proto, upb_filedef *file)
Definition: ruby-upb.c:6257
between
static bool between(int32_t x, int32_t low, int32_t high)
Definition: ruby-upb.c:4950
upb_status_setoom
static void upb_status_setoom(upb_status *status)
Definition: ruby-upb.c:4638
upb_msgdef_fullname
const char * upb_msgdef_fullname(const upb_msgdef *m)
Definition: ruby-upb.c:4964
JD_FALSE
@ JD_FALSE
Definition: ruby-upb.c:6997
jsonenc_msgfield
static void jsonenc_msgfield(jsonenc *e, const upb_msg *msg, const upb_msgdef *m)
Definition: ruby-upb.c:8909
google_benchmark.example.empty
def empty(state)
Definition: example.py:31
google_protobuf_ServiceDescriptorProto_msginit
const upb_msglayout google_protobuf_ServiceDescriptorProto_msginit
Definition: ruby-upb.c:4198
upb_msgdef::ntof
upb_strtable ntof
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.c:2970
upb_inttable_init
bool upb_inttable_init(upb_inttable *t, upb_arena *a)
Definition: ruby-upb.c:2458
google_protobuf_FieldDescriptorProto_json_name
UPB_INLINE upb_StringView google_protobuf_FieldDescriptorProto_json_name(const google_protobuf_FieldDescriptorProto *msg)
Definition: descriptor.upb.h:1022
upb_msg_next
bool 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)
Definition: ruby-upb.c:6779
upb_msgval::bool_val
bool bool_val
Definition: php-upb.h:4613
_upb_mapsorter_cmpi32
static int _upb_mapsorter_cmpi32(const void *_a, const void *_b)
Definition: ruby-upb.c:1698
UPB_DESCRIPTOR_TYPE_DOUBLE
@ UPB_DESCRIPTOR_TYPE_DOUBLE
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.h:499
upb_fielddef_defaultbool
bool upb_fielddef_defaultbool(const upb_fielddef *f)
Definition: ruby-upb.c:4877
upb_msg_internaldata
Definition: php-upb.h:1175
_upb_msg_getraw
static upb_msgval _upb_msg_getraw(const upb_msg *msg, const upb_fielddef *f)
Definition: ruby-upb.c:6669
arena_initslow
upb_arena * arena_initslow(void *mem, size_t n, upb_alloc *alloc)
Definition: ruby-upb.c:2818
google_protobuf_EnumDescriptorProto__fields
static const upb_msglayout_field google_protobuf_EnumDescriptorProto__fields[5]
Definition: ruby-upb.c:4146
upb_oneof_next
void upb_oneof_next(upb_oneof_iter *iter)
Definition: ruby-upb.c:5199
UPB_WELLKNOWN_FIELDMASK
@ UPB_WELLKNOWN_FIELDMASK
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.h:2983
google_protobuf_FieldDescriptorProto_has_json_name
UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_json_name(const google_protobuf_FieldDescriptorProto *msg)
Definition: descriptor.upb.h:1015
jsondec_int
static upb_msgval jsondec_int(jsondec *d, const upb_fielddef *f)
Definition: ruby-upb.c:7635
upb_msg_field_done
bool upb_msg_field_done(const upb_msg_field_iter *iter)
Definition: ruby-upb.c:5100
OP_VARPCK_LG2
#define OP_VARPCK_LG2(n)
Definition: ruby-upb.c:326
count_types_in_file
static void count_types_in_file(const google_protobuf_FileDescriptorProto *file_proto, upb_filedef *file)
Definition: ruby-upb.c:6276
get_field_size
static size_t get_field_size(const upb_msglayout_field *f)
Definition: ruby-upb.c:6603
upb_msgdef_wellknowntype
upb_wellknowntype_t upb_msgdef_wellknowntype(const upb_msgdef *m)
Definition: ruby-upb.c:5078
streql2
static bool streql2(const char *a, size_t n, const char *b)
Definition: ruby-upb.c:5651
UPB_WELLKNOWN_BYTESVALUE
@ UPB_WELLKNOWN_BYTESVALUE
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.h:2995
mem
void * mem
Definition: libc.cpp:91
google_protobuf_ServiceDescriptorProto_submsgs
static const upb_msglayout *const google_protobuf_ServiceDescriptorProto_submsgs[2]
Definition: ruby-upb.c:4187
upb_oneof_done
bool upb_oneof_done(upb_oneof_iter *iter)
Definition: ruby-upb.c:5203
upb_msg_getinternal
static upb_msg_internal * upb_msg_getinternal(upb_msg *msg)
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.c:1161
upb_msg_getunknown
const char * upb_msg_getunknown(const upb_msg *msg, size_t *len)
Definition: ruby-upb.c:1549
google_protobuf_DescriptorProto_ExtensionRange_msginit
const upb_msglayout google_protobuf_DescriptorProto_ExtensionRange_msginit
Definition: ruby-upb.c:4070
_upb_tabent::next
const struct _upb_tabent * next
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.h:815
init
static bool init(upb_table *t, uint8_t size_lg2, upb_arena *a)
Definition: ruby-upb.c:1950
value
const char * value
Definition: hpack_parser_table.cc:165
UPB_UNREACHABLE
#define UPB_UNREACHABLE()
Definition: ruby-upb.c:155
VARINT_CASE
#define VARINT_CASE(ctype, encode)
symtab
upb_symtab * symtab
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/protobuf.h:774
encode_float
static void encode_float(upb_encstate *e, float d)
Definition: ruby-upb.c:1124
mutable_array
static upb_tabval * mutable_array(upb_inttable *t)
Definition: ruby-upb.c:2400
fixed32_ok
static const unsigned fixed32_ok
Definition: ruby-upb.c:311
upb_map_set
bool upb_map_set(upb_map *map, upb_msgval key, upb_msgval val, upb_arena *arena)
Definition: ruby-upb.c:6927
upb_map_get
bool upb_map_get(const upb_map *map, upb_msgval key, upb_msgval *val)
Definition: ruby-upb.c:6919
upb_enumdef_iton
const char * upb_enumdef_iton(const upb_enumdef *def, int32_t num)
Definition: ruby-upb.c:4727
jsondec_skipval
static void jsondec_skipval(jsondec *d)
Definition: ruby-upb.c:7422
symtab_alloc
void * symtab_alloc(symtab_addctx *ctx, size_t bytes)
Definition: ruby-upb.c:5358
upb_free
UPB_INLINE void upb_free(upb_alloc *alloc, void *ptr)
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.h:314
upb_descriptortype_t
upb_descriptortype_t
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.h:498
shortname
static const char * shortname(const char *longname)
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.c:8087
google_protobuf_SourceCodeInfo_Location__fields
static const upb_msglayout_field google_protobuf_SourceCodeInfo_Location__fields[5]
Definition: ruby-upb.c:4416
upb_msg_field_iter_setdone
void upb_msg_field_iter_setdone(upb_msg_field_iter *iter)
Definition: ruby-upb.c:5108
create_enumdef
static void create_enumdef(symtab_addctx *ctx, const char *prefix, const google_protobuf_EnumDescriptorProto *enum_proto)
Definition: ruby-upb.c:6131
INT64_MIN
#define INT64_MIN
Definition: stdint-msvc2008.h:138
TAGBYTES
#define TAGBYTES(card)
Definition: php-upb.h:2076
upb_msg_field_iter_isequal
bool upb_msg_field_iter_isequal(const upb_msg_field_iter *iter1, const upb_msg_field_iter *iter2)
Definition: ruby-upb.c:5112
upb_msg_new
upb_msg * upb_msg_new(const upb_msgdef *m, upb_arena *a)
Definition: ruby-upb.c:6661
google_protobuf_DescriptorProto_enum_type
const UPB_INLINE google_protobuf_EnumDescriptorProto *const * google_protobuf_DescriptorProto_enum_type(const google_protobuf_DescriptorProto *msg, size_t *len)
Definition: descriptor.upb.h:531
testing::internal::fmt
GTEST_API_ const char * fmt
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest.h:1808
ares::byte
unsigned char byte
Definition: ares-test.h:33
_upb_be_swap32
UPB_INLINE uint32_t _upb_be_swap32(uint32_t val)
Definition: php-upb.h:581
upb_DefPool::arena
upb_Arena * arena
Definition: upb/upb/def.c:218
build_filedef
static void build_filedef(symtab_addctx *ctx, upb_filedef *file, const google_protobuf_FileDescriptorProto *file_proto)
Definition: ruby-upb.c:6344
decode_isdonefallback_inl
const UPB_INLINE char * decode_isdonefallback_inl(upb_decstate *d, const char *ptr, int overrun)
Definition: php-upb.h:1829
_upb_map_delete
UPB_INLINE bool _upb_map_delete(upb_map *map, const void *key, size_t key_size)
Definition: php-upb.h:1599
google_protobuf_MethodOptions_msginit
const upb_msglayout google_protobuf_MethodOptions_msginit
Definition: ruby-upb.c:4365
upb_filedef_enum
const upb_enumdef * upb_filedef_enum(const upb_filedef *f, int i)
Definition: ruby-upb.c:5257
INT32_MIN
#define INT32_MIN
Definition: stdint-msvc2008.h:136
jsondec_fieldmask
static void jsondec_fieldmask(jsondec *d, upb_msg *msg, const upb_msgdef *m)
Definition: ruby-upb.c:8214
upb_msg_oneof_iter_setdone
void upb_msg_oneof_iter_setdone(upb_msg_oneof_iter *iter)
Definition: ruby-upb.c:5142
upb_strtable_insert
bool upb_strtable_insert(upb_strtable *t, const char *k, size_t len, upb_value v, upb_arena *a)
Definition: ruby-upb.c:2310
google_protobuf_SourceCodeInfo_msginit
const upb_msglayout google_protobuf_SourceCodeInfo_msginit
Definition: ruby-upb.c:4410
upb_msgdef::oneof_count
int oneof_count
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.c:2975
upb_fielddef_file
const upb_filedef * upb_fielddef_file(const upb_fielddef *f)
Definition: ruby-upb.c:4818
upb_filedef::phpprefix
const char * phpprefix
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.c:3003
google_protobuf_ExtensionRangeOptions_msginit
const upb_msglayout google_protobuf_ExtensionRangeOptions_msginit
Definition: ruby-upb.c:4095
google_protobuf_FieldDescriptorProto_has_type_name
UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_type_name(const google_protobuf_FieldDescriptorProto *msg)
Definition: descriptor.upb.h:976
upb_filedef_msgcount
int upb_filedef_msgcount(const upb_filedef *f)
Definition: ruby-upb.c:5237
upb_value::val
uint64_t val
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.h:682
encode_zz64
static uint64_t encode_zz64(int64_t n)
Definition: ruby-upb.c:1023
upb_oneofdef::ntof
upb_strtable ntof
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.c:2996
UPB_DESCRIPTOR_TYPE_SFIXED32
@ UPB_DESCRIPTOR_TYPE_SFIXED32
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.h:513
upb_msglayout
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.h:565
mem_block::size
size_t size
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.c:2274
upb_map_delete
bool upb_map_delete(upb_map *map, upb_msgval key)
Definition: ruby-upb.c:6932
upb_arena_addcleanup
bool upb_arena_addcleanup(upb_arena *a, void *ud, upb_cleanup_func *func)
Definition: ruby-upb.c:2898
upb_msgval
Definition: php-upb.h:4612
fastdecode_generic
const char * fastdecode_generic(struct upb_decstate *d, const char *ptr, upb_msg *msg, intptr_t table, uint64_t hasbits, uint64_t data)
Definition: ruby-upb.c:933
field
const FieldDescriptor * field
Definition: bloaty/third_party/protobuf/src/google/protobuf/compiler/parser_unittest.cc:2692
google_protobuf_DescriptorProto_ReservedRange_msginit
const upb_msglayout google_protobuf_DescriptorProto_ReservedRange_msginit
Definition: ruby-upb.c:4081
func
const EVP_CIPHER *(* func)(void)
Definition: cipher_extra.c:73
upb_gmalloc
UPB_INLINE void * upb_gmalloc(size_t size)
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.h:336
check
static void check(upb_inttable *t)
Definition: ruby-upb.c:2423
jsonenc_listvalue
static void jsonenc_listvalue(jsonenc *e, const upb_msg *msg, const upb_msgdef *m)
Definition: ruby-upb.c:8854
UPB_UNPOISON_MEMORY_REGION
#define UPB_UNPOISON_MEMORY_REGION(addr, size)
Definition: ruby-upb.c:253
key
const char * key
Definition: hpack_parser_table.cc:164
upb_msgdef::oneofs
const upb_oneofdef * oneofs
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.c:2973
upb_inttable::array_size
size_t array_size
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.h:851
__asan_unpoison_memory_region
static void __asan_unpoison_memory_region(const void *addr, size_t size)
Definition: mem.c:83
upb_msg_ext
Definition: php-upb.h:1243
upb_fielddef_checktype
bool upb_fielddef_checktype(int32_t type)
Definition: ruby-upb.c:4955
jsonenc_nanos
static void jsonenc_nanos(jsonenc *e, int32_t nanos)
Definition: ruby-upb.c:8506
decode_tomap
static const char * decode_tomap(upb_decstate *d, const char *ptr, upb_msg *msg, upb_msglayout const *const *submsgs, const upb_msglayout_field *field, wireval *val)
Definition: ruby-upb.c:722
upb_arena_free
void upb_arena_free(upb_arena *a)
Definition: ruby-upb.c:2893
UPB_DEFTYPE_MSG
@ UPB_DEFTYPE_MSG
Definition: ruby-upb.c:4576
N
#define N
Definition: sync_test.cc:37
UPB_TYPE_STRING
@ UPB_TYPE_STRING
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.h:481
google_protobuf_EnumValueDescriptorProto__fields
static const upb_msglayout_field google_protobuf_EnumValueDescriptorProto__fields[3]
Definition: ruby-upb.c:4175
upb_enumdef::iton
upb_inttable iton
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.c:2988
ctx::symtab
const upb_DefPool * symtab
Definition: conformance_upb.c:85
I
#define I(b, c, d)
Definition: md5.c:120
bytes
uint8 bytes[10]
Definition: bloaty/third_party/protobuf/src/google/protobuf/io/coded_stream_unittest.cc:153
UPB_DESCRIPTOR_TYPE_ENUM
@ UPB_DESCRIPTOR_TYPE_ENUM
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.h:512
google_protobuf_FileDescriptorProto_message_type
const UPB_INLINE google_protobuf_DescriptorProto *const * google_protobuf_FileDescriptorProto_message_type(const google_protobuf_FileDescriptorProto *msg, size_t *len)
Definition: descriptor.upb.h:281
create_oneofdef
static void create_oneofdef(symtab_addctx *ctx, upb_msgdef *m, const google_protobuf_OneofDescriptorProto *oneof_proto)
Definition: ruby-upb.c:5798
_upb_msg_getexts
const upb_msg_ext * _upb_msg_getexts(const upb_msg *msg, size_t *count)
Definition: ruby-upb.c:1560
jsonenc_nullz
static size_t jsonenc_nullz(jsonenc *e, size_t size)
Definition: ruby-upb.c:9105
UPB_STATUS_MAX_MESSAGE
#define UPB_STATUS_MAX_MESSAGE
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.h:195
table_hash
static uint32_t table_hash(const char *p, size_t n)
Definition: ruby-upb.c:2264
jsonenc_fieldpath
static void jsonenc_fieldpath(jsonenc *e, upb_strview path)
Definition: ruby-upb.c:8788
google_protobuf_FieldOptions_packed
UPB_INLINE bool google_protobuf_FieldOptions_packed(const google_protobuf_FieldOptions *msg)
Definition: descriptor.upb.h:2136
upb_enumdef
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.c:2984
upb_enum_done
bool upb_enum_done(upb_enum_iter *iter)
Definition: ruby-upb.c:4715
_upb_mapsorter_init
UPB_INLINE void _upb_mapsorter_init(_upb_mapsorter *s)
Definition: php-upb.h:1700
wireval::uint32_val
uint32_t uint32_val
Definition: php-upb.c:394
upb_strtable_iter_setdone
void upb_strtable_iter_setdone(upb_strtable_iter *i)
Definition: ruby-upb.c:2376
google_protobuf_EnumValueOptions_submsgs
static const upb_msglayout *const google_protobuf_EnumValueOptions_submsgs[1]
Definition: ruby-upb.c:4325
UPB_POISON_MEMORY_REGION
#define UPB_POISON_MEMORY_REGION(addr, size)
Definition: ruby-upb.c:251
upb_fielddef::number_
uint32_t number_
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.c:2952
upb_msgdef_oneof
const upb_oneofdef * upb_msgdef_oneof(const upb_msgdef *m, int i)
Definition: ruby-upb.c:5069
count
int * count
Definition: bloaty/third_party/googletest/googlemock/test/gmock_stress_test.cc:96
upb_inttable_sizedinit
bool upb_inttable_sizedinit(upb_inttable *t, size_t asize, int hsize_lg2, upb_arena *a)
Definition: ruby-upb.c:2439
UPB_DTYPE_FLOAT
@ UPB_DTYPE_FLOAT
Definition: php-upb.h:555
assign_layout_indices
static void assign_layout_indices(const upb_msgdef *m, upb_msglayout *l, upb_msglayout_field *fields)
Definition: ruby-upb.c:5449
upb_strtable::t
upb_table t
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.h:845
google_protobuf_FieldDescriptorProto_has_name
UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_name(const google_protobuf_FieldDescriptorProto *msg)
Definition: descriptor.upb.h:926
upb_oneofdef_containingtype
const upb_msgdef * upb_oneofdef_containingtype(const upb_oneofdef *o)
Definition: ruby-upb.c:5157
nullz
static void nullz(upb_status *status)
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.c:2187
symtab_oomerr
UPB_NORETURN static UPB_NOINLINE void symtab_oomerr(symtab_addctx *ctx)
Definition: ruby-upb.c:5353
google_protobuf_OneofDescriptorProto_msginit
const upb_msglayout google_protobuf_OneofDescriptorProto_msginit
Definition: ruby-upb.c:4134
google_protobuf_EnumOptions_msginit
const upb_msglayout google_protobuf_EnumOptions_msginit
Definition: ruby-upb.c:4319
UPB_LABEL_REPEATED
@ UPB_LABEL_REPEATED
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.h:494
upb_inttable_compact
void upb_inttable_compact(upb_inttable *t, upb_arena *a)
Definition: ruby-upb.c:2537
upb_status_vappenderrf
void upb_status_vappenderrf(upb_status *status, const char *fmt, va_list args)
Definition: ruby-upb.c:2707
lookup
static bool lookup(const upb_table *t, lookupkey_t key, upb_value *v, uint32_t hash, eqlfunc_t *eql)
Definition: ruby-upb.c:2003
_upb_value_setval
UPB_INLINE void _upb_value_setval(upb_value *v, uint64_t val, upb_ctype_t ctype)
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.h:706
_upb_array_realloc
bool _upb_array_realloc(upb_array *arr, size_t min_size, upb_arena *arena)
Definition: ruby-upb.c:1604
inttable_val
static upb_tabval * inttable_val(upb_inttable *t, uintptr_t key)
Definition: ruby-upb.c:2404
upb_strtable_done
bool upb_strtable_done(const upb_strtable_iter *i)
Definition: ruby-upb.c:2356
google_protobuf_MethodDescriptorProto_msginit
const upb_msglayout google_protobuf_MethodDescriptorProto_msginit
Definition: ruby-upb.c:4217
upb_inttable_begin
void upb_inttable_begin(upb_inttable_iter *i, const upb_inttable *t)
Definition: ruby-upb.c:2605
in_oneof
static bool in_oneof(const upb_msglayout_field *field)
Definition: ruby-upb.c:6665
google_protobuf_ExtensionRangeOptions_submsgs
static const upb_msglayout *const google_protobuf_ExtensionRangeOptions_submsgs[1]
Definition: ruby-upb.c:4087
google_protobuf_DescriptorProto_field
const UPB_INLINE google_protobuf_FieldDescriptorProto *const * google_protobuf_DescriptorProto_field(const google_protobuf_DescriptorProto *msg, size_t *len)
Definition: descriptor.upb.h:513
encode_array
static void encode_array(upb_encstate *e, const upb_msg *msg, const upb_msglayout *m, const upb_msglayout_field *f)
Definition: ruby-upb.c:1245
varint_ops
static const int8_t varint_ops[19]
Definition: ruby-upb.c:328
str_tabent
static const upb_tabent * str_tabent(const upb_strtable_iter *i)
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.c:1632
jsondec_number
static double jsondec_number(jsondec *d)
Definition: ruby-upb.c:7205
_upb_tabent
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.h:807
JD_TRUE
@ JD_TRUE
Definition: ruby-upb.c:6997
upb_table
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.h:818
upb_msg_fielddefsize
static uint8_t upb_msg_fielddefsize(const upb_fielddef *f)
Definition: ruby-upb.c:5422
UPB_DEFTYPE_ENUM
@ UPB_DEFTYPE_ENUM
Definition: ruby-upb.c:4577
index
int index
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/protobuf.h:1184
UPB_JSONENC_EMITDEFAULTS
@ UPB_JSONENC_EMITDEFAULTS
Definition: php-upb.h:4802
upb_arena::refcount
uint32_t refcount
Definition: php-upb.h:1759
upb_array_get
upb_msgval upb_array_get(const upb_array *arr, size_t i)
Definition: ruby-upb.c:6879
int_tabent
static const upb_tabent * int_tabent(const upb_inttable_iter *i)
Definition: ruby-upb.c:2595
_upb_mapsorter_pushmap
bool _upb_mapsorter_pushmap(_upb_mapsorter *s, upb_descriptortype_t key_type, const upb_map *map, _upb_sortedmap *sorted)
Definition: ruby-upb.c:1725
ret
UniquePtr< SSL_SESSION > ret
Definition: ssl_x509.cc:1029
upb_enumdef_numvals
int upb_enumdef_numvals(const upb_enumdef *e)
Definition: ruby-upb.c:4705
upb_msg_oneof_begin
void upb_msg_oneof_begin(upb_msg_oneof_iter *iter, const upb_msgdef *m)
Definition: ruby-upb.c:5117
google_protobuf_FieldDescriptorProto_name
UPB_INLINE upb_StringView google_protobuf_FieldDescriptorProto_name(const google_protobuf_FieldDescriptorProto *msg)
Definition: descriptor.upb.h:933
google_protobuf_MethodDescriptorProto__fields
static const upb_msglayout_field google_protobuf_MethodDescriptorProto__fields[6]
Definition: ruby-upb.c:4208
UPB_DTYPE_STRING
@ UPB_DTYPE_STRING
Definition: php-upb.h:562
google_protobuf_FieldDescriptorProto_submsgs
static const upb_msglayout *const google_protobuf_FieldDescriptorProto_submsgs[1]
Definition: ruby-upb.c:4101
google_protobuf_MethodDescriptorProto_submsgs
static const upb_msglayout *const google_protobuf_MethodDescriptorProto_submsgs[1]
Definition: ruby-upb.c:4204
upb_ok
bool upb_ok(const upb_status *status)
Definition: ruby-upb.c:2682
_upb_symtab_loaddefinit
bool _upb_symtab_loaddefinit(upb_symtab *s, const upb_def_init *init)
Definition: ruby-upb.c:6542
UPB_DEFTYPE_FIELD_JSONNAME
@ UPB_DEFTYPE_FIELD_JSONNAME
Definition: ruby-upb.c:4581
UPB_NOINLINE
#define UPB_NOINLINE
Definition: ruby-upb.c:120
upb_enumdef_ntoi
bool upb_enumdef_ntoi(const upb_enumdef *def, const char *name, size_t len, int32_t *num)
Definition: ruby-upb.c:4717
profile_analyzer.fields
list fields
Definition: profile_analyzer.py:266
L
lua_State * L
Definition: upb/upb/bindings/lua/main.c:35
jsondec_struct
static void jsondec_struct(jsondec *d, upb_msg *msg, const upb_msgdef *m)
Definition: ruby-upb.c:8107
google_protobuf_GeneratedCodeInfo_msginit
const upb_msglayout google_protobuf_GeneratedCodeInfo_msginit
Definition: ruby-upb.c:4438
fix_build_deps.r
r
Definition: fix_build_deps.py:491
encode_message
static void encode_message(upb_encstate *e, const upb_msg *msg, const upb_msglayout *m, size_t *size)
Definition: ruby-upb.c:1412
upb_fielddef::is_extension_
bool is_extension_
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.c:2955
UPB_INLINE
#define UPB_INLINE
Definition: ruby-upb.c:90
jsondec_errf
static UPB_NORETURN void jsondec_errf(jsondec *d, const char *fmt,...)
Definition: ruby-upb.c:7030
first
StrT first
Definition: cxa_demangle.cpp:4884
upb_msgval::msg_val
const upb_msg * msg_val
Definition: php-upb.h:4621
jsondec_uint
static upb_msgval jsondec_uint(jsondec *d, const upb_fielddef *f)
Definition: ruby-upb.c:7671
google_protobuf_EnumValueDescriptorProto_number
UPB_INLINE int32_t google_protobuf_EnumValueDescriptorProto_number(const google_protobuf_EnumValueDescriptorProto *msg)
Definition: descriptor.upb.h:1394
google_protobuf_FileDescriptorProto_name
UPB_INLINE upb_StringView google_protobuf_FileDescriptorProto_name(const google_protobuf_FileDescriptorProto *msg)
Definition: descriptor.upb.h:256
google_protobuf_EnumOptions_submsgs
static const upb_msglayout *const google_protobuf_EnumOptions_submsgs[1]
Definition: ruby-upb.c:4309
_upb_msg_addunknown
bool _upb_msg_addunknown(upb_msg *msg, const char *data, size_t len, upb_arena *arena)
Definition: ruby-upb.c:1533
ARRAY_SIZE
#define ARRAY_SIZE(x)
Definition: ruby-upb.c:1863
upb_filedef_depcount
int upb_filedef_depcount(const upb_filedef *f)
Definition: ruby-upb.c:5241
upb_msgdef_lookupjsonname
const upb_fielddef * upb_msgdef_lookupjsonname(const upb_msgdef *m, const char *name, size_t len)
Definition: ruby-upb.c:5021
UPB_ASSUME
#define UPB_ASSUME(expr)
Definition: ruby-upb.c:141
google_protobuf_FieldOptions_submsgs
static const upb_msglayout *const google_protobuf_FieldOptions_submsgs[1]
Definition: ruby-upb.c:4275
jsonenc_putbytes
static void jsonenc_putbytes(jsonenc *e, const void *data, size_t len)
Definition: ruby-upb.c:8470
upb_fielddef_containingtype
const upb_msgdef * upb_fielddef_containingtype(const upb_fielddef *f)
Definition: ruby-upb.c:4822
upb_inttable_iter_isequal
bool upb_inttable_iter_isequal(const upb_inttable_iter *i1, const upb_inttable_iter *i2)
Definition: ruby-upb.c:2655
_upb_mapsorter_cmpi64
static int _upb_mapsorter_cmpi64(const void *_a, const void *_b)
Definition: ruby-upb.c:1686
values
std::array< int64_t, Size > values
Definition: abseil-cpp/absl/container/btree_benchmark.cc:608
UPB_DESCRIPTOR_TYPE_INT64
@ UPB_DESCRIPTOR_TYPE_INT64
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.h:501
upb_inttable_remove
bool upb_inttable_remove(upb_inttable *t, uintptr_t key, upb_value *val)
Definition: ruby-upb.c:2516
jsondec_escape
static char jsondec_escape(jsondec *d)
Definition: ruby-upb.c:7266
prefix
static const char prefix[]
Definition: head_of_line_blocking.cc:28
upb_tabstrview
UPB_INLINE upb_strview upb_tabstrview(upb_tabkey key)
Definition: php-upb.h:864
strkey2
static lookupkey_t strkey2(const char *str, size_t len)
Definition: ruby-upb.c:1915
upb_enum_begin
void upb_enum_begin(upb_enum_iter *i, const upb_enumdef *e)
Definition: ruby-upb.c:4709
xds_manager.num
num
Definition: xds_manager.py:56
regen-readme.line
line
Definition: regen-readme.py:30
UPB_MAPENTRY_VALUE
#define UPB_MAPENTRY_VALUE
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.h:3310
UPB_DESCRIPTOR_TYPE_BOOL
@ UPB_DESCRIPTOR_TYPE_BOOL
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.h:506
jsondec_false
static void jsondec_false(jsondec *d)
Definition: ruby-upb.c:7082
UPB_MAPTYPE_STRING
#define UPB_MAPTYPE_STRING
Definition: ruby-upb.c:82
UPB_MAX_FIELDNUMBER
#define UPB_MAX_FIELDNUMBER
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.h:3006
upb_mapiter_value
upb_msgval upb_mapiter_value(const upb_map *map, size_t iter)
Definition: ruby-upb.c:6958
absl::hash_internal::k1
static const uint64_t k1
Definition: abseil-cpp/absl/hash/internal/city.cc:54
parse
static void parse(const char *s)
Definition: debug/trace.cc:121
type_url
string * type_url
Definition: bloaty/third_party/protobuf/conformance/conformance_cpp.cc:72
upb_inttable_iter_key
uintptr_t upb_inttable_iter_key(const upb_inttable_iter *i)
Definition: ruby-upb.c:2638
ok
bool ok
Definition: async_end2end_test.cc:197
emptyent
static upb_tabent * emptyent(upb_table *t, upb_tabent *e)
Definition: ruby-upb.c:1968
jsonenc_enum
static void jsonenc_enum(int32_t val, const upb_fielddef *f, jsonenc *e)
Definition: ruby-upb.c:8584
decode_isdone
UPB_INLINE bool decode_isdone(upb_decstate *d, const char **ptr)
Definition: php-upb.h:1859
UPB_WIRE_TYPE_64BIT
@ UPB_WIRE_TYPE_64BIT
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.h:462
state
Definition: bloaty/third_party/zlib/contrib/blast/blast.c:41
UPB_SYNTAX_PROTO3
@ UPB_SYNTAX_PROTO3
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.h:2973
set_default_default
static void set_default_default(symtab_addctx *ctx, upb_fielddef *f)
Definition: ruby-upb.c:5940
google_protobuf_EnumDescriptorProto_EnumReservedRange__fields
static const upb_msglayout_field google_protobuf_EnumDescriptorProto_EnumReservedRange__fields[2]
Definition: ruby-upb.c:4160
jsondec_resize
static void jsondec_resize(jsondec *d, char **buf, char **end, char **buf_end)
Definition: ruby-upb.c:7358
upb_fielddef_realcontainingoneof
const upb_oneofdef * upb_fielddef_realcontainingoneof(const upb_fielddef *f)
Definition: ruby-upb.c:4830
strhash
static uint32_t strhash(upb_tabkey key)
Definition: ruby-upb.c:2268
upb_msg_clearfield
void upb_msg_clearfield(upb_msg *msg, const upb_fielddef *f)
Definition: ruby-upb.c:6760
absl::Status::ok
ABSL_MUST_USE_RESULT bool ok() const
Definition: third_party/abseil-cpp/absl/status/status.h:802
UPB_TYPE_MESSAGE
@ UPB_TYPE_MESSAGE
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.h:483
UPB_PARSE_PARAMS
#define UPB_PARSE_PARAMS
Definition: php-upb.h:2012
jsondec
Definition: php-upb.c:7368
upb_DefPool::files
upb_strtable files
Definition: upb/upb/def.c:220
_upb_arena_slowmalloc
void * _upb_arena_slowmalloc(upb_arena *a, size_t size)
Definition: ruby-upb.c:2804
upb_strtable
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.h:844
upb_fielddef_lazy
bool upb_fielddef_lazy(const upb_fielddef *f)
Definition: ruby-upb.c:4802
make_layout
static void make_layout(symtab_addctx *ctx, const upb_msgdef *m)
Definition: ruby-upb.c:5492
upb_strtable_iter_key
upb_strview upb_strtable_iter_key(const upb_strtable_iter *i)
Definition: ruby-upb.c:2362
upb_fielddef::enumdef
const upb_enumdef * enumdef
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.c:2949
upb_fielddef_isprimitive
bool upb_fielddef_isprimitive(const upb_fielddef *f)
Definition: ruby-upb.c:4931
google_protobuf_FieldDescriptorProto_has_options
UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_options(const google_protobuf_FieldDescriptorProto *msg)
Definition: descriptor.upb.h:996
UPB_DTYPE_GROUP
@ UPB_DTYPE_GROUP
Definition: php-upb.h:563
google_protobuf_MessageOptions_submsgs
static const upb_msglayout *const google_protobuf_MessageOptions_submsgs[1]
Definition: ruby-upb.c:4257
encode_map
static void encode_map(upb_encstate *e, const upb_msg *msg, const upb_msglayout *m, const upb_msglayout_field *f)
Definition: ruby-upb.c:1364
_upb_array_constptr
const UPB_INLINE void * _upb_array_constptr(const upb_array *arr)
Definition: php-upb.h:1340
upb_tabval::val
uint64_t val
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.h:799
jsondec_arrnext
static bool jsondec_arrnext(jsondec *d)
Definition: ruby-upb.c:7162
google_protobuf_FileDescriptorSet_submsgs
static const upb_msglayout *const google_protobuf_FileDescriptorSet_submsgs[1]
Definition: ruby-upb.c:3987
decode_tosubmsg
static const UPB_FORCEINLINE char * decode_tosubmsg(upb_decstate *d, const char *ptr, upb_msg *submsg, upb_msglayout const *const *submsgs, const upb_msglayout_field *field, int size)
Definition: ruby-upb.c:592
upb_filedef_msg
const upb_msgdef * upb_filedef_msg(const upb_filedef *f, int i)
Definition: ruby-upb.c:5253
upb_fielddef::label_
upb_label_t label_
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.c:2959
upb_isbetween
static bool upb_isbetween(char c, char low, char high)
Definition: ruby-upb.c:4595
upb_status_vseterrf
void upb_status_vseterrf(upb_status *status, const char *fmt, va_list args)
Definition: ruby-upb.c:2700
UPB_NORETURN
#define UPB_NORETURN
Definition: ruby-upb.c:121
google_protobuf_ServiceDescriptorProto__fields
static const upb_msglayout_field google_protobuf_ServiceDescriptorProto__fields[3]
Definition: ruby-upb.c:4192
google_protobuf_MessageOptions_map_entry
UPB_INLINE bool google_protobuf_MessageOptions_map_entry(const google_protobuf_MessageOptions *msg)
Definition: descriptor.upb.h:2046
cleanup_ent::cleanup
upb_cleanup_func * cleanup
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.c:2282
google_protobuf_GeneratedCodeInfo_submsgs
static const upb_msglayout *const google_protobuf_GeneratedCodeInfo_submsgs[1]
Definition: ruby-upb.c:4430
getorcreate_array
static upb_array * getorcreate_array(upb_array **arr_ptr, int elem_size_lg2, upb_arena *arena)
Definition: ruby-upb.c:1626
upb_enumdef_file
const upb_filedef * upb_enumdef_file(const upb_enumdef *e)
Definition: ruby-upb.c:4696
_upb_mapsorter_cmpbool
static int _upb_mapsorter_cmpbool(const void *_a, const void *_b)
Definition: ruby-upb.c:1710
google_protobuf_FileDescriptorProto_submsgs
static const upb_msglayout *const google_protobuf_FileDescriptorProto_submsgs[6]
Definition: ruby-upb.c:4001
upb_msglayout_ext
Definition: php-upb.h:1148
upb_filedef::deps
const upb_filedef ** deps
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.c:3007
_upb_value_val
static upb_value _upb_value_val(uint64_t val)
Definition: ruby-upb.c:1875
upb_fielddef_hassubdef
bool upb_fielddef_hassubdef(const upb_fielddef *f)
Definition: ruby-upb.c:4940
upb_fielddef_haspresence
bool upb_fielddef_haspresence(const upb_fielddef *f)
Definition: ruby-upb.c:4944
jsondec_listvalue
static void jsondec_listvalue(jsondec *d, upb_msg *msg, const upb_msgdef *m)
Definition: ruby-upb.c:8091
hashfunc_t
uint32_t hashfunc_t(upb_tabkey key)
Definition: ruby-upb.c:1928
jsondec_true
static void jsondec_true(jsondec *d)
Definition: ruby-upb.c:7081
upb_encode_ex
char * upb_encode_ex(const void *msg, const upb_msglayout *l, int options, upb_arena *arena, size_t *size)
Definition: ruby-upb.c:1447
upb_filedef::phpnamespace
const char * phpnamespace
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.c:3004
upb_msgdef_layout
const upb_msglayout * upb_msgdef_layout(const upb_msgdef *m)
Definition: ruby-upb.c:5060
_UPB_MODE_MAP
@ _UPB_MODE_MAP
Definition: php-upb.h:1097
upb_array_new
upb_array * upb_array_new(upb_arena *a, upb_fieldtype_t type)
Definition: ruby-upb.c:6871
JD_OBJECT
@ JD_OBJECT
Definition: ruby-upb.c:6997
UPB_WELLKNOWN_STRUCT
@ UPB_WELLKNOWN_STRUCT
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.h:2999
upb_msg_set
void upb_msg_set(upb_msg *msg, const upb_fielddef *f, upb_msgval val, upb_arena *a)
Definition: ruby-upb.c:6747
UPB_WELLKNOWN_BOOLVALUE
@ UPB_WELLKNOWN_BOOLVALUE
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.h:2996
internal
Definition: benchmark/test/output_test_helper.cc:20
UnalignedLoad32
static uint32_t UnalignedLoad32(const void *p)
Definition: ruby-upb.c:2137
symtab_addctx
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.c:3740
table
uint8_t table[256]
Definition: hpack_parser.cc:456
upb_fielddef_msgsubdef
const upb_msgdef * upb_fielddef_msgsubdef(const upb_fielddef *f)
Definition: ruby-upb.c:4906
upb_fielddef_default
upb_msgval upb_fielddef_default(const upb_fielddef *f)
Definition: ruby-upb.c:4835
jsondec_duration
static void jsondec_duration(jsondec *d, upb_msg *msg, const upb_msgdef *m)
Definition: ruby-upb.c:8063
upb_msg_oneof_next
void upb_msg_oneof_next(upb_msg_oneof_iter *iter)
Definition: ruby-upb.c:5126
google_protobuf_GeneratedCodeInfo_Annotation__fields
static const upb_msglayout_field google_protobuf_GeneratedCodeInfo_Annotation__fields[4]
Definition: ruby-upb.c:4444
iter
Definition: test_winkernel.cpp:47
upb_msgval::int32_val
int32_t int32_val
Definition: php-upb.h:4616
google_protobuf_FieldDescriptorProto_type
UPB_INLINE int32_t google_protobuf_FieldDescriptorProto_type(const google_protobuf_FieldDescriptorProto *msg)
Definition: descriptor.upb.h:973
google_protobuf_FieldDescriptorProto_has_default_value
UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_default_value(const google_protobuf_FieldDescriptorProto *msg)
Definition: descriptor.upb.h:986
upb_strview
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.h:257
_upb_mapsorter_cmpu64
static int _upb_mapsorter_cmpu64(const void *_a, const void *_b)
Definition: ruby-upb.c:1692
jsondec_any
static void jsondec_any(jsondec *d, upb_msg *msg, const upb_msgdef *m)
Definition: ruby-upb.c:8282
jsondec_epochdays
int jsondec_epochdays(int y, int m, int d)
Definition: ruby-upb.c:7986
_upb_sortedmap
Definition: php-upb.h:1694
xds_manager.f2
f2
Definition: xds_manager.py:85
google_protobuf_ServiceOptions__fields
static const upb_msglayout_field google_protobuf_ServiceOptions__fields[2]
Definition: ruby-upb.c:4344
i2
int i2
Definition: abseil-cpp/absl/container/btree_test.cc:2773
jsonenc_msgfields
static void jsonenc_msgfields(jsonenc *e, const upb_msg *msg, const upb_msgdef *m, bool first)
Definition: ruby-upb.c:9075
upb_fielddef_checkdescriptortype
bool upb_fielddef_checkdescriptortype(int32_t type)
Definition: ruby-upb.c:4958
str_t
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.c:2920
upb_cleanup_metadata
static uintptr_t upb_cleanup_metadata(uint32_t *cleanup, bool has_initial_block)
Definition: ruby-upb.c:2738
rm
static bool rm(upb_table *t, lookupkey_t key, upb_value *val, upb_tabkey *removed, uint32_t hash, eqlfunc_t *eql)
Definition: ruby-upb.c:2062
upb_array::size
size_t size
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.h:581
google_protobuf_SourceCodeInfo_submsgs
static const upb_msglayout *const google_protobuf_SourceCodeInfo_submsgs[1]
Definition: ruby-upb.c:4402
UPB_WIRE_TYPE_START_GROUP
@ UPB_WIRE_TYPE_START_GROUP
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.h:464
jsonenc_msg
static void jsonenc_msg(jsonenc *e, const upb_msg *msg, const upb_msgdef *m)
Definition: ruby-upb.c:9099
upb_getentry
static const upb_tabent * upb_getentry(const upb_table *t, uint32_t hash)
Definition: ruby-upb.c:1937
fastdecode_err
const char * fastdecode_err(upb_decstate *d)
Definition: ruby-upb.c:412
upb_filedef::enum_count
int enum_count
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.c:3014
int8_t
signed char int8_t
Definition: stdint-msvc2008.h:75
asyncio_get_stats.type
type
Definition: asyncio_get_stats.py:37
jsondec_isnullvalue
static bool jsondec_isnullvalue(const upb_fielddef *f)
Definition: ruby-upb.c:7010
ch
char ch
Definition: bloaty/third_party/googletest/googlemock/test/gmock-matchers_test.cc:3621
len
int len
Definition: abseil-cpp/absl/base/internal/low_level_alloc_test.cc:46
upb_fielddef_defaultint64
int64_t upb_fielddef_defaultint64(const upb_fielddef *f)
Definition: ruby-upb.c:4857
upb_deftype_t
upb_deftype_t
Definition: ruby-upb.c:4572
autogen_x86imm.tmp
tmp
Definition: autogen_x86imm.py:12
cleanup
Definition: cleanup.py:1
_upb_repeated_or_map
UPB_INLINE bool _upb_repeated_or_map(const upb_msglayout_field *field)
Definition: php-upb.h:1111
upb_msg_clear
void upb_msg_clear(upb_msg *msg, const upb_msgdef *m)
Definition: ruby-upb.c:6775
intrin.h
upb_filedef::enums
const upb_enumdef * enums
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.c:3009
jsonenc_double
static void jsonenc_double(jsonenc *e, const char *fmt, double val)
Definition: ruby-upb.c:8686
encode_growbuffer
static UPB_NOINLINE void encode_growbuffer(upb_encstate *e, size_t bytes)
Definition: ruby-upb.c:1047
decode_pushlimit
UPB_INLINE int decode_pushlimit(upb_decstate *d, const char *ptr, int size)
Definition: php-upb.h:1898
UPB_MAXARRSIZE
#define UPB_MAXARRSIZE
Definition: ruby-upb.c:1860
UPB_DESCRIPTOR_TYPE_INT32
@ UPB_DESCRIPTOR_TYPE_INT32
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.h:503
upb_oneof_begin
void upb_oneof_begin(upb_oneof_iter *iter, const upb_oneofdef *o)
Definition: ruby-upb.c:5195
decode_group
static const UPB_FORCEINLINE char * decode_group(upb_decstate *d, const char *ptr, upb_msg *submsg, const upb_msglayout *subl, uint32_t number)
Definition: ruby-upb.c:609
jsonenc_array
static void jsonenc_array(jsonenc *e, const upb_array *arr, const upb_fielddef *f)
Definition: ruby-upb.c:9017
google_protobuf_DescriptorProto
struct google_protobuf_DescriptorProto google_protobuf_DescriptorProto
Definition: descriptor.upb.h:52
EXTREG_KEY_SIZE
#define EXTREG_KEY_SIZE
Definition: ruby-upb.c:1798
upb_map_entry
Definition: php-upb.h:1499
upb_msgdef::full_name
const char * full_name
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.c:2964
file::name
char * name
Definition: bloaty/third_party/zlib/examples/gzappend.c:176
upb_fielddef::str
str_t * str
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.c:2944
_upb_isle
UPB_INLINE bool _upb_isle(void)
Definition: php-upb.h:576
run_grpclb_interop_tests.l
dictionary l
Definition: run_grpclb_interop_tests.py:410
jsondec_double
static upb_msgval jsondec_double(jsondec *d, const upb_fielddef *f)
Definition: ruby-upb.c:7707
size
voidpf void uLong size
Definition: bloaty/third_party/zlib/contrib/minizip/ioapi.h:136
upb_filedef::package
const char * package
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.c:3002
upb_strtable_iter
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.h:1086
upb_enum_iter_number
int32_t upb_enum_iter_number(upb_enum_iter *iter)
Definition: ruby-upb.c:4736
_upb_tabent::key
upb_tabkey key
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.h:808
google_protobuf_DescriptorProto_nested_type
const UPB_INLINE google_protobuf_DescriptorProto *const * google_protobuf_DescriptorProto_nested_type(const google_protobuf_DescriptorProto *msg, size_t *len)
Definition: descriptor.upb.h:522
upb_msg_mutable
upb_mutmsgval upb_msg_mutable(upb_msg *msg, const upb_fielddef *f, upb_arena *a)
Definition: ruby-upb.c:6713
length
std::size_t length
Definition: abseil-cpp/absl/time/internal/test_util.cc:57
key_type
upb_fieldtype_t key_type
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/protobuf.h:1071
_upb_symtab_arena
upb_arena * _upb_symtab_arena(const upb_symtab *s)
Definition: ruby-upb.c:6592
upb_msgdef::itof
upb_inttable itof
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.c:2969
resolve_fielddef
static void resolve_fielddef(symtab_addctx *ctx, const char *prefix, upb_fielddef *f)
Definition: ruby-upb.c:6294
upb_filedef_dep
const upb_filedef * upb_filedef_dep(const upb_filedef *f, int i)
Definition: ruby-upb.c:5249
chkdefaulttype
static void chkdefaulttype(const upb_fielddef *f, int ctype)
Definition: ruby-upb.c:4852
upb_enum_iter_name
const char * upb_enum_iter_name(upb_enum_iter *iter)
Definition: ruby-upb.c:4732
encode_longvarint
static UPB_NOINLINE void encode_longvarint(upb_encstate *e, uint64_t val)
Definition: ruby-upb.c:1096
INT32_MAX
#define INT32_MAX
Definition: stdint-msvc2008.h:137
regress.m
m
Definition: regress/regress.py:25
mkowners.depth
depth
Definition: mkowners.py:114
int32_t
signed int int32_t
Definition: stdint-msvc2008.h:77
upb_alloc
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.h:299
MAX_LOAD
static const double MAX_LOAD
Definition: ruby-upb.c:1866
upb_map_entry::val
upb_value val
Definition: php-upb.h:1503
upb_encode
char * upb_encode(const void *msg, const upb_msglayout *m, upb_arena *arena, size_t *size)
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.c:1105
upb_oneof_iter_setdone
void upb_oneof_iter_setdone(upb_oneof_iter *iter)
Definition: ruby-upb.c:5211
isfull
static bool isfull(upb_table *t)
Definition: ruby-upb.c:1946
_upb_map_fromkey
UPB_INLINE void _upb_map_fromkey(upb_strview key, void *out, size_t size)
Definition: php-upb.h:1531
upb_extreg::exts
upb_strtable exts
Definition: php-upb.c:1795
_UPB_MODE_IS_PACKED
@ _UPB_MODE_IS_PACKED
Definition: php-upb.h:1104
__asan_poison_memory_region
static void __asan_poison_memory_region(const void *addr, size_t size)
Definition: mem.c:82
lookupkey_t
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.c:1324
UPB_WELLKNOWN_INT64VALUE
@ UPB_WELLKNOWN_INT64VALUE
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.h:2989
upb_msglayout_field
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.h:556
jsonenc_mapkey
static void jsonenc_mapkey(jsonenc *e, upb_msgval val, const upb_fielddef *f)
Definition: ruby-upb.c:8988
upb_fielddef::sint
int64_t sint
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.c:2939
upb_msgdef_iswrapper
bool upb_msgdef_iswrapper(const upb_msgdef *m)
Definition: ruby-upb.c:5088
eqlfunc_t
bool eqlfunc_t(upb_tabkey k1, lookupkey_t k2)
Definition: ruby-upb.c:1929
google_protobuf_FileDescriptorProto_parse_ex
UPB_INLINE google_protobuf_FileDescriptorProto * google_protobuf_FileDescriptorProto_parse_ex(const char *buf, size_t size, const upb_ExtensionRegistry *extreg, int options, upb_Arena *arena)
Definition: descriptor.upb.h:231
jsondec_objstart
static void jsondec_objstart(jsondec *d)
Definition: ruby-upb.c:7166
UPB_ENCODE_DETERMINISTIC
@ UPB_ENCODE_DETERMINISTIC
Definition: php-upb.h:1942
google_protobuf_DescriptorProto_submsgs
static const upb_msglayout *const google_protobuf_DescriptorProto_submsgs[7]
Definition: ruby-upb.c:4031
demo_pb2._b
int _b
Definition: demo_pb2.py:6
upb_fielddef::file
const upb_filedef * file
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.c:2935
UPB_DEFTYPE_ONEOF
@ UPB_DEFTYPE_ONEOF
Definition: ruby-upb.c:4580
upb_fielddef_descriptortype
upb_descriptortype_t upb_fielddef_descriptortype(const upb_fielddef *f)
Definition: ruby-upb.c:4782
google_protobuf_FileDescriptorProto
struct google_protobuf_FileDescriptorProto google_protobuf_FileDescriptorProto
Definition: descriptor.upb.h:51
inttable_val_const
static const upb_tabval * inttable_val_const(const upb_inttable *t, uintptr_t key)
Definition: ruby-upb.c:2414
jsondec_skipdigits
static void jsondec_skipdigits(jsondec *d)
Definition: ruby-upb.c:7199
upb_array_resize
bool upb_array_resize(upb_array *arr, size_t size, upb_arena *arena)
Definition: ruby-upb.c:6903
op
static grpc_op * op
Definition: test/core/fling/client.cc:47
upb_filedef::name
const char * name
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.c:3001
upb_oneof_iter_field
upb_fielddef * upb_oneof_iter_field(const upb_oneof_iter *iter)
Definition: ruby-upb.c:5207
upb_fielddef_defaultuint64
uint64_t upb_fielddef_defaultuint64(const upb_fielddef *f)
Definition: ruby-upb.c:4867
jsonenc_duration
static void jsonenc_duration(jsonenc *e, const upb_msg *msg, const upb_msgdef *m)
Definition: ruby-upb.c:8564
jsondec_strtouint64
static uint64_t jsondec_strtouint64(jsondec *d, upb_strview str)
Definition: ruby-upb.c:7614
upb_strtable_iter_value
upb_value upb_strtable_iter_value(const upb_strtable_iter *i)
Definition: ruby-upb.c:2371
_upb_array_new
UPB_INLINE upb_array * _upb_array_new(upb_arena *a, size_t init_size, int elem_size_lg2)
Definition: php-upb.h:1360
UPB_MAPENTRY_KEY
#define UPB_MAPENTRY_KEY
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.h:3309
JD_STRING
@ JD_STRING
Definition: ruby-upb.c:6997
UPB_TYPE_DOUBLE
@ UPB_TYPE_DOUBLE
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.h:485
jsondec_nanos
static int jsondec_nanos(jsondec *d, const char **ptr, const char *end)
Definition: ruby-upb.c:7965
upb_array_set
void upb_array_set(upb_array *arr, size_t i, upb_msgval val)
Definition: ruby-upb.c:6888
google_protobuf_FileOptions
struct google_protobuf_FileOptions google_protobuf_FileOptions
Definition: descriptor.upb.h:63
jsonenc_any
static void jsonenc_any(jsonenc *e, const upb_msg *msg, const upb_msgdef *m)
Definition: ruby-upb.c:8751
_upb_msg_discardunknown_shallow
void _upb_msg_discardunknown_shallow(upb_msg *msg)
Definition: ruby-upb.c:1542
jsondec_unicode
static size_t jsondec_unicode(jsondec *d, char *out)
Definition: ruby-upb.c:7316
next
static size_t next(const upb_table *t, size_t i)
Definition: ruby-upb.c:2101
google_protobuf_MessageOptions
struct google_protobuf_MessageOptions google_protobuf_MessageOptions
Definition: descriptor.upb.h:64
CHK_OOM
#define CHK_OOM(x)
Definition: ruby-upb.c:5332
google_protobuf_MessageOptions__fields
static const upb_msglayout_field google_protobuf_MessageOptions__fields[5]
Definition: ruby-upb.c:4261
upb_strview::size
size_t size
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.h:259
upb_isalphanum
static bool upb_isalphanum(char c)
Definition: ruby-upb.c:4603
symtab_add
static void symtab_add(symtab_addctx *ctx, const char *name, upb_value v)
Definition: ruby-upb.c:5755
upb_fielddef_type
upb_fieldtype_t upb_fielddef_type(const upb_fielddef *f)
Definition: ruby-upb.c:4747
jsonenc_fieldval
static void jsonenc_fieldval(jsonenc *e, const upb_fielddef *f, upb_msgval val, bool *first)
Definition: ruby-upb.c:9053
jsonenc_string
static void jsonenc_string(jsonenc *e, upb_strview str)
Definition: ruby-upb.c:8680
UPB_TYPE_BOOL
@ UPB_TYPE_BOOL
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.h:474
log2ceil
static int log2ceil(uint64_t v)
Definition: ruby-upb.c:1881
addr
struct sockaddr_in addr
Definition: libuv/docs/code/tcp-echo-server/main.c:10
upb_table_size
UPB_INLINE size_t upb_table_size(const upb_table *t)
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.h:863
upb_fielddef::dbl
double dbl
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.c:2941
UPB_TYPE_INT64
@ UPB_TYPE_INT64
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.h:486
if
if(p->owned &&p->wrapped !=NULL)
Definition: call.c:42
upb_oneofdef::field_count
int field_count
Definition: php-upb.c:4923
_upb_oneofcase_field
UPB_INLINE uint32_t * _upb_oneofcase_field(upb_msg *msg, const upb_msglayout_field *f)
Definition: php-upb.h:1316
binary_size.old_size
old_size
Definition: binary_size.py:125
alloc
std::allocator< int > alloc
Definition: abseil-cpp/absl/container/internal/hash_policy_traits_test.cc:87
_upb_fieldtype_to_mapsize
static char _upb_fieldtype_to_mapsize[12]
Definition: ruby-upb.c:6629
google_protobuf_GeneratedCodeInfo_Annotation_msginit
const upb_msglayout google_protobuf_GeneratedCodeInfo_Annotation_msginit
Definition: ruby-upb.c:4451
errno.h
upb_msgdef
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.c:2962
upb_strtable_count
UPB_INLINE size_t upb_strtable_count(const upb_strtable *t)
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.h:919
jsondec_buftouint64
static const char * jsondec_buftouint64(jsondec *d, const char *ptr, const char *end, uint64_t *val)
Definition: ruby-upb.c:7577
upb_strtable_iter_isequal
bool upb_strtable_iter_isequal(const upb_strtable_iter *i1, const upb_strtable_iter *i2)
Definition: ruby-upb.c:2381
finalize_oneofs
static void finalize_oneofs(symtab_addctx *ctx, upb_msgdef *m)
Definition: ruby-upb.c:5675
wireval
Definition: php-upb.c:392
jsondec_rawpeek
static int jsondec_rawpeek(jsondec *d)
Definition: ruby-upb.c:7090
upb_find_field
static const upb_msglayout_field * upb_find_field(const upb_msglayout *l, uint32_t field_number, int *last_field_index)
Definition: ruby-upb.c:526
upb_fielddef::flt
float flt
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.c:2942
wireval::bool_val
bool bool_val
Definition: php-upb.c:393
_upb_msg_clear
void _upb_msg_clear(upb_msg *msg, const upb_msglayout *l)
Definition: ruby-upb.c:1496
upb_fielddef_defaultdouble
double upb_fielddef_defaultdouble(const upb_fielddef *f)
Definition: ruby-upb.c:4887
i
uint64_t i
Definition: abseil-cpp/absl/container/btree_benchmark.cc:230
UnalignedLoad64
static uint64_t UnalignedLoad64(const void *p)
Definition: ruby-upb.c:2131
UPB_WELLKNOWN_LISTVALUE
@ UPB_WELLKNOWN_LISTVALUE
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.h:2998
state
static struct rpc_state state
Definition: bad_server_response_test.cc:87
upb_msgval::int64_val
int64_t int64_val
Definition: php-upb.h:4617
arena_dofree
static void arena_dofree(upb_arena *a)
Definition: ruby-upb.c:2870
upb_msgval::uint32_val
uint32_t uint32_val
Definition: php-upb.h:4618
UPB_WELLKNOWN_ANY
@ UPB_WELLKNOWN_ANY
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.h:2982
encode_reserve
static UPB_FORCEINLINE void encode_reserve(upb_encstate *e, size_t bytes)
Definition: ruby-upb.c:1069
upb_arena::parent
struct upb_arena * parent
Definition: php-upb.h:1760
upb_symtab_new
upb_symtab * upb_symtab_new(void)
Definition: ruby-upb.c:5270
getentry_mutable
static upb_tabent * getentry_mutable(upb_table *t, uint32_t hash)
Definition: ruby-upb.c:1981
upb_arena_fuse
bool upb_arena_fuse(upb_arena *a1, upb_arena *a2)
Definition: ruby-upb.c:2919
upb_isletter
static bool upb_isletter(char c)
Definition: ruby-upb.c:4599
cleanup_ent
struct cleanup_ent cleanup_ent
upb_symtab_free
void upb_symtab_free(upb_symtab *s)
Definition: ruby-upb.c:5265
jsondec_push
static void jsondec_push(jsondec *d)
Definition: ruby-upb.c:7136
upb_msgdef_fieldcount
int upb_msgdef_fieldcount(const upb_msgdef *m)
Definition: ruby-upb.c:5048
begin
static size_t begin(const upb_table *t)
Definition: ruby-upb.c:2110
upb_arena_realloc
UPB_INLINE void * upb_arena_realloc(upb_arena *a, void *ptr, size_t oldsize, size_t size)
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.h:387
_upb_array_append_fallback
bool _upb_array_append_fallback(upb_array **arr_ptr, const void *value, int elem_size_lg2, upb_arena *arena)
Definition: ruby-upb.c:1644
upb_filedef::symtab
const upb_symtab * symtab
Definition: php-upb.c:4940
UPB_ASSERT
#define UPB_ASSERT(expr)
Definition: ruby-upb.c:149
upb_filedef_syntax
upb_syntax_t upb_filedef_syntax(const upb_filedef *f)
Definition: ruby-upb.c:5233
decode_newsubmsg
static upb_msg * decode_newsubmsg(upb_decstate *d, upb_msglayout const *const *submsgs, const upb_msglayout_field *field)
Definition: ruby-upb.c:560
decode_vret::val
uint64_t val
Definition: php-upb.c:449
upb_strtable_next
void upb_strtable_next(upb_strtable_iter *i)
Definition: ruby-upb.c:2352
upb_fielddef::oneof
const upb_oneofdef * oneof
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.c:2946
jsondec_enum
static upb_msgval jsondec_enum(jsondec *d, const upb_fielddef *f)
Definition: ruby-upb.c:7752
upb_map
Definition: php-upb.h:1487


grpc
Author(s):
autogenerated on Thu Mar 13 2025 03:01:13