php/ext/google/protobuf/upb.c
Go to the documentation of this file.
1 /* Amalgamated source file */
2 #include "upb.h"
3 
4 #ifndef UINTPTR_MAX
5 #error must include stdint.h first
6 #endif
7 
8 #if UINTPTR_MAX == 0xffffffff
9 #define UPB_SIZE(size32, size64) size32
10 #else
11 #define UPB_SIZE(size32, size64) size64
12 #endif
13 
14 #define UPB_FIELD_AT(msg, fieldtype, offset) \
15  *(fieldtype*)((const char*)(msg) + offset)
16 
17 #define UPB_READ_ONEOF(msg, fieldtype, offset, case_offset, case_val, default) \
18  UPB_FIELD_AT(msg, int, case_offset) == case_val \
19  ? UPB_FIELD_AT(msg, fieldtype, offset) \
20  : default
21 
22 #define UPB_WRITE_ONEOF(msg, fieldtype, offset, value, case_offset, case_val) \
23  UPB_FIELD_AT(msg, int, case_offset) = case_val; \
24  UPB_FIELD_AT(msg, fieldtype, offset) = value;
25 /* This file was generated by upbc (the upb compiler) from the input
26  * file:
27  *
28  * google/protobuf/descriptor.proto
29  *
30  * Do not edit -- your changes will be discarded when the file is
31  * regenerated. */
32 
33 #include <stddef.h>
34 
35 
38 };
39 
41  {1, UPB_SIZE(0, 0), 0, 0, 11, 3},
42 };
43 
47  UPB_SIZE(4, 8), 1, false,
48 };
49 
57 };
58 
60  {1, UPB_SIZE(4, 8), 1, 0, 9, 1},
61  {2, UPB_SIZE(12, 24), 2, 0, 9, 1},
62  {3, UPB_SIZE(36, 72), 0, 0, 9, 3},
63  {4, UPB_SIZE(40, 80), 0, 0, 11, 3},
64  {5, UPB_SIZE(44, 88), 0, 1, 11, 3},
65  {6, UPB_SIZE(48, 96), 0, 4, 11, 3},
66  {7, UPB_SIZE(52, 104), 0, 2, 11, 3},
67  {8, UPB_SIZE(28, 56), 4, 3, 11, 1},
68  {9, UPB_SIZE(32, 64), 5, 5, 11, 1},
69  {10, UPB_SIZE(56, 112), 0, 0, 5, 3},
70  {11, UPB_SIZE(60, 120), 0, 0, 5, 3},
71  {12, UPB_SIZE(20, 40), 3, 0, 9, 1},
72 };
73 
77  UPB_SIZE(64, 128), 12, false,
78 };
79 
88 };
89 
91  {1, UPB_SIZE(4, 8), 1, 0, 9, 1},
92  {2, UPB_SIZE(16, 32), 0, 4, 11, 3},
93  {3, UPB_SIZE(20, 40), 0, 0, 11, 3},
94  {4, UPB_SIZE(24, 48), 0, 3, 11, 3},
95  {5, UPB_SIZE(28, 56), 0, 1, 11, 3},
96  {6, UPB_SIZE(32, 64), 0, 4, 11, 3},
97  {7, UPB_SIZE(12, 24), 2, 5, 11, 1},
98  {8, UPB_SIZE(36, 72), 0, 6, 11, 3},
99  {9, UPB_SIZE(40, 80), 0, 2, 11, 3},
100  {10, UPB_SIZE(44, 88), 0, 0, 9, 3},
101 };
102 
106  UPB_SIZE(48, 96), 10, false,
107 };
108 
111 };
112 
114  {1, UPB_SIZE(4, 4), 1, 0, 5, 1},
115  {2, UPB_SIZE(8, 8), 2, 0, 5, 1},
116  {3, UPB_SIZE(12, 16), 3, 0, 11, 1},
117 };
118 
122  UPB_SIZE(16, 24), 3, false,
123 };
124 
126  {1, UPB_SIZE(4, 4), 1, 0, 5, 1},
127  {2, UPB_SIZE(8, 8), 2, 0, 5, 1},
128 };
129 
131  NULL,
133  UPB_SIZE(12, 12), 2, false,
134 };
135 
138 };
139 
141  {999, UPB_SIZE(0, 0), 0, 0, 11, 3},
142 };
143 
147  UPB_SIZE(4, 8), 1, false,
148 };
149 
152 };
153 
155  {1, UPB_SIZE(32, 32), 5, 0, 9, 1},
156  {2, UPB_SIZE(40, 48), 6, 0, 9, 1},
157  {3, UPB_SIZE(24, 24), 3, 0, 5, 1},
158  {4, UPB_SIZE(8, 8), 1, 0, 14, 1},
159  {5, UPB_SIZE(16, 16), 2, 0, 14, 1},
160  {6, UPB_SIZE(48, 64), 7, 0, 9, 1},
161  {7, UPB_SIZE(56, 80), 8, 0, 9, 1},
162  {8, UPB_SIZE(72, 112), 10, 0, 11, 1},
163  {9, UPB_SIZE(28, 28), 4, 0, 5, 1},
164  {10, UPB_SIZE(64, 96), 9, 0, 9, 1},
165 };
166 
170  UPB_SIZE(80, 128), 10, false,
171 };
172 
175 };
176 
178  {1, UPB_SIZE(4, 8), 1, 0, 9, 1},
179  {2, UPB_SIZE(12, 24), 2, 0, 11, 1},
180 };
181 
185  UPB_SIZE(16, 32), 2, false,
186 };
187 
192 };
193 
195  {1, UPB_SIZE(4, 8), 1, 0, 9, 1},
196  {2, UPB_SIZE(16, 32), 0, 2, 11, 3},
197  {3, UPB_SIZE(12, 24), 2, 1, 11, 1},
198  {4, UPB_SIZE(20, 40), 0, 0, 11, 3},
199  {5, UPB_SIZE(24, 48), 0, 0, 9, 3},
200 };
201 
205  UPB_SIZE(32, 64), 5, false,
206 };
207 
209  {1, UPB_SIZE(4, 4), 1, 0, 5, 1},
210  {2, UPB_SIZE(8, 8), 2, 0, 5, 1},
211 };
212 
214  NULL,
216  UPB_SIZE(12, 12), 2, false,
217 };
218 
221 };
222 
224  {1, UPB_SIZE(8, 8), 2, 0, 9, 1},
225  {2, UPB_SIZE(4, 4), 1, 0, 5, 1},
226  {3, UPB_SIZE(16, 24), 3, 0, 11, 1},
227 };
228 
232  UPB_SIZE(24, 32), 3, false,
233 };
234 
238 };
239 
241  {1, UPB_SIZE(4, 8), 1, 0, 9, 1},
242  {2, UPB_SIZE(16, 32), 0, 0, 11, 3},
243  {3, UPB_SIZE(12, 24), 2, 1, 11, 1},
244 };
245 
249  UPB_SIZE(24, 48), 3, false,
250 };
251 
254 };
255 
257  {1, UPB_SIZE(4, 8), 3, 0, 9, 1},
258  {2, UPB_SIZE(12, 24), 4, 0, 9, 1},
259  {3, UPB_SIZE(20, 40), 5, 0, 9, 1},
260  {4, UPB_SIZE(28, 56), 6, 0, 11, 1},
261  {5, UPB_SIZE(1, 1), 1, 0, 8, 1},
262  {6, UPB_SIZE(2, 2), 2, 0, 8, 1},
263 };
264 
268  UPB_SIZE(32, 64), 6, false,
269 };
270 
273 };
274 
276  {1, UPB_SIZE(28, 32), 11, 0, 9, 1},
277  {8, UPB_SIZE(36, 48), 12, 0, 9, 1},
278  {9, UPB_SIZE(8, 8), 1, 0, 14, 1},
279  {10, UPB_SIZE(16, 16), 2, 0, 8, 1},
280  {11, UPB_SIZE(44, 64), 13, 0, 9, 1},
281  {16, UPB_SIZE(17, 17), 3, 0, 8, 1},
282  {17, UPB_SIZE(18, 18), 4, 0, 8, 1},
283  {18, UPB_SIZE(19, 19), 5, 0, 8, 1},
284  {20, UPB_SIZE(20, 20), 6, 0, 8, 1},
285  {23, UPB_SIZE(21, 21), 7, 0, 8, 1},
286  {27, UPB_SIZE(22, 22), 8, 0, 8, 1},
287  {31, UPB_SIZE(23, 23), 9, 0, 8, 1},
288  {36, UPB_SIZE(52, 80), 14, 0, 9, 1},
289  {37, UPB_SIZE(60, 96), 15, 0, 9, 1},
290  {39, UPB_SIZE(68, 112), 16, 0, 9, 1},
291  {40, UPB_SIZE(76, 128), 17, 0, 9, 1},
292  {41, UPB_SIZE(84, 144), 18, 0, 9, 1},
293  {42, UPB_SIZE(24, 24), 10, 0, 8, 1},
294  {999, UPB_SIZE(92, 160), 0, 0, 11, 3},
295 };
296 
300  UPB_SIZE(96, 176), 19, false,
301 };
302 
305 };
306 
308  {1, UPB_SIZE(1, 1), 1, 0, 8, 1},
309  {2, UPB_SIZE(2, 2), 2, 0, 8, 1},
310  {3, UPB_SIZE(3, 3), 3, 0, 8, 1},
311  {7, UPB_SIZE(4, 4), 4, 0, 8, 1},
312  {999, UPB_SIZE(8, 8), 0, 0, 11, 3},
313 };
314 
318  UPB_SIZE(12, 16), 5, false,
319 };
320 
323 };
324 
326  {1, UPB_SIZE(8, 8), 1, 0, 14, 1},
327  {2, UPB_SIZE(24, 24), 3, 0, 8, 1},
328  {3, UPB_SIZE(25, 25), 4, 0, 8, 1},
329  {5, UPB_SIZE(26, 26), 5, 0, 8, 1},
330  {6, UPB_SIZE(16, 16), 2, 0, 14, 1},
331  {10, UPB_SIZE(27, 27), 6, 0, 8, 1},
332  {999, UPB_SIZE(28, 32), 0, 0, 11, 3},
333 };
334 
338  UPB_SIZE(32, 40), 7, false,
339 };
340 
343 };
344 
346  {999, UPB_SIZE(0, 0), 0, 0, 11, 3},
347 };
348 
352  UPB_SIZE(4, 8), 1, false,
353 };
354 
357 };
358 
360  {2, UPB_SIZE(1, 1), 1, 0, 8, 1},
361  {3, UPB_SIZE(2, 2), 2, 0, 8, 1},
362  {999, UPB_SIZE(4, 8), 0, 0, 11, 3},
363 };
364 
368  UPB_SIZE(8, 16), 3, false,
369 };
370 
373 };
374 
376  {1, UPB_SIZE(1, 1), 1, 0, 8, 1},
377  {999, UPB_SIZE(4, 8), 0, 0, 11, 3},
378 };
379 
383  UPB_SIZE(8, 16), 2, false,
384 };
385 
388 };
389 
391  {33, UPB_SIZE(1, 1), 1, 0, 8, 1},
392  {999, UPB_SIZE(4, 8), 0, 0, 11, 3},
393 };
394 
398  UPB_SIZE(8, 16), 2, false,
399 };
400 
403 };
404 
406  {33, UPB_SIZE(16, 16), 2, 0, 8, 1},
407  {34, UPB_SIZE(8, 8), 1, 0, 14, 1},
408  {999, UPB_SIZE(20, 24), 0, 0, 11, 3},
409 };
410 
414  UPB_SIZE(24, 32), 3, false,
415 };
416 
419 };
420 
422  {2, UPB_SIZE(56, 80), 0, 0, 11, 3},
423  {3, UPB_SIZE(32, 32), 4, 0, 9, 1},
424  {4, UPB_SIZE(8, 8), 1, 0, 4, 1},
425  {5, UPB_SIZE(16, 16), 2, 0, 3, 1},
426  {6, UPB_SIZE(24, 24), 3, 0, 1, 1},
427  {7, UPB_SIZE(40, 48), 5, 0, 12, 1},
428  {8, UPB_SIZE(48, 64), 6, 0, 9, 1},
429 };
430 
434  UPB_SIZE(64, 96), 7, false,
435 };
436 
438  {1, UPB_SIZE(4, 8), 2, 0, 9, 2},
439  {2, UPB_SIZE(1, 1), 1, 0, 8, 2},
440 };
441 
443  NULL,
445  UPB_SIZE(16, 32), 2, false,
446 };
447 
450 };
451 
453  {1, UPB_SIZE(0, 0), 0, 0, 11, 3},
454 };
455 
459  UPB_SIZE(4, 8), 1, false,
460 };
461 
463  {1, UPB_SIZE(20, 40), 0, 0, 5, 3},
464  {2, UPB_SIZE(24, 48), 0, 0, 5, 3},
465  {3, UPB_SIZE(4, 8), 1, 0, 9, 1},
466  {4, UPB_SIZE(12, 24), 2, 0, 9, 1},
467  {6, UPB_SIZE(28, 56), 0, 0, 9, 3},
468 };
469 
471  NULL,
473  UPB_SIZE(32, 64), 5, false,
474 };
475 
478 };
479 
481  {1, UPB_SIZE(0, 0), 0, 0, 11, 3},
482 };
483 
487  UPB_SIZE(4, 8), 1, false,
488 };
489 
491  {1, UPB_SIZE(20, 32), 0, 0, 5, 3},
492  {2, UPB_SIZE(12, 16), 3, 0, 9, 1},
493  {3, UPB_SIZE(4, 4), 1, 0, 5, 1},
494  {4, UPB_SIZE(8, 8), 2, 0, 5, 1},
495 };
496 
498  NULL,
500  UPB_SIZE(24, 48), 4, false,
501 };
502 
503 
504 
505 #include <string.h>
506 
507 /* Maps descriptor type -> upb field type. */
508 const uint8_t upb_desctype_to_fieldtype[] = {
509  UPB_WIRE_TYPE_END_GROUP, /* ENDGROUP */
510  UPB_TYPE_DOUBLE, /* DOUBLE */
511  UPB_TYPE_FLOAT, /* FLOAT */
512  UPB_TYPE_INT64, /* INT64 */
513  UPB_TYPE_UINT64, /* UINT64 */
514  UPB_TYPE_INT32, /* INT32 */
515  UPB_TYPE_UINT64, /* FIXED64 */
516  UPB_TYPE_UINT32, /* FIXED32 */
517  UPB_TYPE_BOOL, /* BOOL */
518  UPB_TYPE_STRING, /* STRING */
519  UPB_TYPE_MESSAGE, /* GROUP */
520  UPB_TYPE_MESSAGE, /* MESSAGE */
521  UPB_TYPE_BYTES, /* BYTES */
522  UPB_TYPE_UINT32, /* UINT32 */
523  UPB_TYPE_ENUM, /* ENUM */
524  UPB_TYPE_INT32, /* SFIXED32 */
525  UPB_TYPE_INT64, /* SFIXED64 */
526  UPB_TYPE_INT32, /* SINT32 */
527  UPB_TYPE_INT64, /* SINT64 */
528 };
529 
530 /* Data pertaining to the parse. */
531 typedef struct {
532  /* Current decoding pointer. Points to the beginning of a field until we
533  * have finished decoding the whole field. */
534  const char *ptr;
535 } upb_decstate;
536 
537 /* Data pertaining to a single message frame. */
538 typedef struct {
539  const char *limit;
540  int32_t group_number; /* 0 if we are not parsing a group. */
541 
542  /* These members are unset for an unknown group frame. */
543  char *msg;
544  const upb_msglayout *m;
545 } upb_decframe;
546 
547 #define CHK(x) if (!(x)) { return false; }
548 
549 static bool upb_skip_unknowngroup(upb_decstate *d, int field_number,
550  const char *limit);
551 static bool upb_decode_message(upb_decstate *d, const char *limit,
552  int group_number, char *msg,
553  const upb_msglayout *l);
554 
555 static bool upb_decode_varint(const char **ptr, const char *limit,
556  uint64_t *val) {
557  uint8_t byte;
558  int bitpos = 0;
559  const char *p = *ptr;
560  *val = 0;
561 
562  do {
563  CHK(bitpos < 70 && p < limit);
564  byte = *p;
565  *val |= (uint64_t)(byte & 0x7F) << bitpos;
566  p++;
567  bitpos += 7;
568  } while (byte & 0x80);
569 
570  *ptr = p;
571  return true;
572 }
573 
574 static bool upb_decode_varint32(const char **ptr, const char *limit,
575  uint32_t *val) {
576  uint64_t u64;
577  CHK(upb_decode_varint(ptr, limit, &u64) && u64 <= UINT32_MAX);
578  *val = u64;
579  return true;
580 }
581 
582 static bool upb_decode_64bit(const char **ptr, const char *limit,
583  uint64_t *val) {
584  CHK(limit - *ptr >= 8);
585  memcpy(val, *ptr, 8);
586  *ptr += 8;
587  return true;
588 }
589 
590 static bool upb_decode_32bit(const char **ptr, const char *limit,
591  uint32_t *val) {
592  CHK(limit - *ptr >= 4);
593  memcpy(val, *ptr, 4);
594  *ptr += 4;
595  return true;
596 }
597 
598 static bool upb_decode_tag(const char **ptr, const char *limit,
599  int *field_number, int *wire_type) {
600  uint32_t tag = 0;
601  CHK(upb_decode_varint32(ptr, limit, &tag));
602  *field_number = tag >> 3;
603  *wire_type = tag & 7;
604  return true;
605 }
606 
607 static int32_t upb_zzdecode_32(uint32_t n) {
608  return (n >> 1) ^ -(int32_t)(n & 1);
609 }
610 
611 static int64_t upb_zzdecode_64(uint64_t n) {
612  return (n >> 1) ^ -(int64_t)(n & 1);
613 }
614 
615 static bool upb_decode_string(const char **ptr, const char *limit,
616  upb_strview *val) {
617  uint32_t len;
618 
619  CHK(upb_decode_varint32(ptr, limit, &len) &&
620  len < INT32_MAX &&
621  limit - *ptr >= (int32_t)len);
622 
623  *val = upb_strview_make(*ptr, len);
624  *ptr += len;
625  return true;
626 }
627 
628 static void upb_set32(void *msg, size_t ofs, uint32_t val) {
629  memcpy((char*)msg + ofs, &val, sizeof(val));
630 }
631 
633  const char *start) {
634  upb_msg_addunknown(frame->msg, start, d->ptr - start);
635  return true;
636 }
637 
639  int field_number, int wire_type) {
640  switch (wire_type) {
641  case UPB_WIRE_TYPE_VARINT: {
642  uint64_t val;
643  return upb_decode_varint(&d->ptr, frame->limit, &val);
644  }
645  case UPB_WIRE_TYPE_32BIT: {
646  uint32_t val;
647  return upb_decode_32bit(&d->ptr, frame->limit, &val);
648  }
649  case UPB_WIRE_TYPE_64BIT: {
650  uint64_t val;
651  return upb_decode_64bit(&d->ptr, frame->limit, &val);
652  }
655  return upb_decode_string(&d->ptr, frame->limit, &val);
656  }
658  return upb_skip_unknowngroup(d, field_number, frame->limit);
660  CHK(field_number == frame->group_number);
661  frame->limit = d->ptr;
662  return true;
663  }
664  return false;
665 }
666 
667 static bool upb_array_grow(upb_array *arr, size_t elements) {
668  size_t needed = arr->len + elements;
669  size_t new_size = UPB_MAX(arr->size, 8);
670  size_t new_bytes;
671  size_t old_bytes;
672  void *new_data;
673  upb_alloc *alloc = upb_arena_alloc(arr->arena);
674 
675  while (new_size < needed) {
676  new_size *= 2;
677  }
678 
679  old_bytes = arr->len * arr->element_size;
680  new_bytes = new_size * arr->element_size;
681  new_data = upb_realloc(alloc, arr->data, old_bytes, new_bytes);
682  CHK(new_data);
683 
684  arr->data = new_data;
685  arr->size = new_size;
686  return true;
687 }
688 
689 static void *upb_array_reserve(upb_array *arr, size_t elements) {
690  if (arr->size - arr->len < elements) {
691  CHK(upb_array_grow(arr, elements));
692  }
693  return (char*)arr->data + (arr->len * arr->element_size);
694 }
695 
696 static void *upb_array_add(upb_array *arr, size_t elements) {
697  void *ret = upb_array_reserve(arr, elements);
698  arr->len += elements;
699  return ret;
700 }
701 
703  const upb_msglayout_field *field) {
705  return *(upb_array**)&frame->msg[field->offset];
706 }
707 
709  const upb_msglayout_field *field) {
710  upb_array *arr = upb_getarr(frame, field);
711 
712  if (!arr) {
714  arr = upb_array_new(type, upb_msg_arena(frame->msg));
715  if (!arr) {
716  return NULL;
717  }
718  *(upb_array**)&frame->msg[field->offset] = arr;
719  }
720 
721  return arr;
722 }
723 
724 static void upb_sethasbit(upb_decframe *frame,
725  const upb_msglayout_field *field) {
726  int32_t hasbit = field->presence;
727  UPB_ASSERT(field->presence > 0);
728  frame->msg[hasbit / 8] |= (1 << (hasbit % 8));
729 }
730 
731 static void upb_setoneofcase(upb_decframe *frame,
732  const upb_msglayout_field *field) {
733  UPB_ASSERT(field->presence < 0);
734  upb_set32(frame->msg, ~field->presence, field->number);
735 }
736 
738  const upb_msglayout_field *field) {
739  char *field_mem = frame->msg + field->offset;
740  upb_array *arr;
741 
742  if (field->label == UPB_LABEL_REPEATED) {
743  arr = upb_getorcreatearr(frame, field);
744  field_mem = upb_array_reserve(arr, 1);
745  }
746 
747  return field_mem;
748 }
749 
751  const upb_msglayout_field *field) {
752  if (field->label == UPB_LABEL_REPEATED) {
753  upb_array *arr = upb_getarr(frame, field);
754  UPB_ASSERT(arr->len < arr->size);
755  arr->len++;
756  } else if (field->presence < 0) {
757  upb_setoneofcase(frame, field);
758  } else if (field->presence > 0) {
759  upb_sethasbit(frame, field);
760  }
761 }
762 
764  const char *limit,
765  const upb_msglayout_field *field,
766  int group_number) {
767  char *submsg_slot = upb_decode_prepareslot(frame, field);
768  char *submsg = *(void **)submsg_slot;
769  const upb_msglayout *subm;
770 
771  subm = frame->m->submsgs[field->submsg_index];
772  UPB_ASSERT(subm);
773 
774  if (!submsg) {
775  submsg = upb_msg_new(subm, upb_msg_arena(frame->msg));
776  CHK(submsg);
777  *(void**)submsg_slot = submsg;
778  }
779 
780  upb_decode_message(d, limit, group_number, submsg, subm);
781 
782  return true;
783 }
784 
786  const char *field_start,
787  const upb_msglayout_field *field) {
788  uint64_t val;
789  void *field_mem;
790 
791  field_mem = upb_decode_prepareslot(frame, field);
792  CHK(field_mem);
793  CHK(upb_decode_varint(&d->ptr, frame->limit, &val));
794 
795  switch ((upb_descriptortype_t)field->descriptortype) {
798  memcpy(field_mem, &val, sizeof(val));
799  break;
803  uint32_t val32 = val;
804  memcpy(field_mem, &val32, sizeof(val32));
805  break;
806  }
808  bool valbool = val != 0;
809  memcpy(field_mem, &valbool, sizeof(valbool));
810  break;
811  }
813  int32_t decoded = upb_zzdecode_32(val);
814  memcpy(field_mem, &decoded, sizeof(decoded));
815  break;
816  }
818  int64_t decoded = upb_zzdecode_64(val);
819  memcpy(field_mem, &decoded, sizeof(decoded));
820  break;
821  }
822  default:
823  return upb_append_unknown(d, frame, field_start);
824  }
825 
827  return true;
828 }
829 
831  const char *field_start,
832  const upb_msglayout_field *field) {
833  void *field_mem;
834  uint64_t val;
835 
836  field_mem = upb_decode_prepareslot(frame, field);
837  CHK(field_mem);
838  CHK(upb_decode_64bit(&d->ptr, frame->limit, &val));
839 
840  switch ((upb_descriptortype_t)field->descriptortype) {
844  memcpy(field_mem, &val, sizeof(val));
845  break;
846  default:
847  return upb_append_unknown(d, frame, field_start);
848  }
849 
851  return true;
852 }
853 
855  const char *field_start,
856  const upb_msglayout_field *field) {
857  void *field_mem;
858  uint32_t val;
859 
860  field_mem = upb_decode_prepareslot(frame, field);
861  CHK(field_mem);
862  CHK(upb_decode_32bit(&d->ptr, frame->limit, &val));
863 
864  switch ((upb_descriptortype_t)field->descriptortype) {
868  memcpy(field_mem, &val, sizeof(val));
869  break;
870  default:
871  return upb_append_unknown(d, frame, field_start);
872  }
873 
875  return true;
876 }
877 
879  int elem_size) {
880  int elements = data.size / elem_size;
881  void *field_mem;
882 
883  CHK((size_t)(elements * elem_size) == data.size);
884  field_mem = upb_array_add(arr, elements);
885  CHK(field_mem);
886  memcpy(field_mem, data.data, data.size);
887  return true;
888 }
889 
891  const char *field_start,
892  const upb_msglayout_field *field,
893  upb_strview val) {
894  upb_array *arr = upb_getorcreatearr(frame, field);
895 
896 #define VARINT_CASE(ctype, decode) { \
897  const char *ptr = val.data; \
898  const char *limit = ptr + val.size; \
899  while (ptr < limit) { \
900  uint64_t val; \
901  void *field_mem; \
902  ctype decoded; \
903  CHK(upb_decode_varint(&ptr, limit, &val)); \
904  decoded = (decode)(val); \
905  field_mem = upb_array_add(arr, 1); \
906  CHK(field_mem); \
907  memcpy(field_mem, &decoded, sizeof(ctype)); \
908  } \
909  return true; \
910 }
911 
912  switch ((upb_descriptortype_t)field->descriptortype) {
915  void *field_mem = upb_array_add(arr, 1);
916  CHK(field_mem);
917  memcpy(field_mem, &val, sizeof(val));
918  return true;
919  }
923  return upb_decode_fixedpacked(arr, val, sizeof(int32_t));
927  return upb_decode_fixedpacked(arr, val, sizeof(int64_t));
931  /* TODO: proto2 enum field that isn't in the enum. */
932  VARINT_CASE(uint32_t, uint32_t);
935  VARINT_CASE(uint64_t, uint64_t);
937  VARINT_CASE(bool, bool);
939  VARINT_CASE(int32_t, upb_zzdecode_32);
941  VARINT_CASE(int64_t, upb_zzdecode_64);
943  const upb_msglayout *subm;
944  char *submsg;
945  void *field_mem;
946 
947  CHK(val.size <= (size_t)(frame->limit - val.data));
948  d->ptr -= val.size;
949 
950  /* Create elemente message. */
951  subm = frame->m->submsgs[field->submsg_index];
952  UPB_ASSERT(subm);
953 
954  submsg = upb_msg_new(subm, upb_msg_arena(frame->msg));
955  CHK(submsg);
956 
957  field_mem = upb_array_add(arr, 1);
958  CHK(field_mem);
959  *(void**)field_mem = submsg;
960 
961  return upb_decode_message(
962  d, val.data + val.size, frame->group_number, submsg, subm);
963  }
965  return upb_append_unknown(d, frame, field_start);
966  }
967 #undef VARINT_CASE
968  UPB_UNREACHABLE();
969 }
970 
972  const char *field_start,
973  const upb_msglayout_field *field) {
975 
976  CHK(upb_decode_string(&d->ptr, frame->limit, &val));
977 
978  if (field->label == UPB_LABEL_REPEATED) {
979  return upb_decode_toarray(d, frame, field_start, field, val);
980  } else {
981  switch ((upb_descriptortype_t)field->descriptortype) {
984  void *field_mem = upb_decode_prepareslot(frame, field);
985  CHK(field_mem);
986  memcpy(field_mem, &val, sizeof(val));
987  break;
988  }
990  CHK(val.size <= (size_t)(frame->limit - val.data));
991  d->ptr -= val.size;
992  CHK(upb_decode_submsg(d, frame, val.data + val.size, field, 0));
993  break;
994  default:
995  /* TODO(haberman): should we accept the last element of a packed? */
996  return upb_append_unknown(d, frame, field_start);
997  }
999  return true;
1000  }
1001 }
1002 
1004  uint32_t field_number) {
1005  /* Lots of optimization opportunities here. */
1006  int i;
1007  for (i = 0; i < l->field_count; i++) {
1008  if (l->fields[i].number == field_number) {
1009  return &l->fields[i];
1010  }
1011  }
1012 
1013  return NULL; /* Unknown field. */
1014 }
1015 
1016 static bool upb_decode_field(upb_decstate *d, upb_decframe *frame) {
1017  int field_number;
1018  int wire_type;
1019  const char *field_start = d->ptr;
1020  const upb_msglayout_field *field;
1021 
1022  CHK(upb_decode_tag(&d->ptr, frame->limit, &field_number, &wire_type));
1023  field = upb_find_field(frame->m, field_number);
1024 
1025  if (field) {
1026  switch (wire_type) {
1027  case UPB_WIRE_TYPE_VARINT:
1028  return upb_decode_varintfield(d, frame, field_start, field);
1029  case UPB_WIRE_TYPE_32BIT:
1030  return upb_decode_32bitfield(d, frame, field_start, field);
1031  case UPB_WIRE_TYPE_64BIT:
1032  return upb_decode_64bitfield(d, frame, field_start, field);
1034  return upb_decode_delimitedfield(d, frame, field_start, field);
1036  CHK(field->descriptortype == UPB_DESCRIPTOR_TYPE_GROUP);
1037  return upb_decode_submsg(d, frame, frame->limit, field, field_number);
1039  CHK(frame->group_number == field_number)
1040  frame->limit = d->ptr;
1041  return true;
1042  default:
1043  return false;
1044  }
1045  } else {
1046  CHK(field_number != 0);
1047  CHK(upb_skip_unknownfielddata(d, frame, field_number, wire_type));
1048  CHK(upb_append_unknown(d, frame, field_start));
1049  return true;
1050  }
1051 }
1052 
1053 static bool upb_skip_unknowngroup(upb_decstate *d, int field_number,
1054  const char *limit) {
1055  upb_decframe frame;
1056  frame.msg = NULL;
1057  frame.m = NULL;
1058  frame.group_number = field_number;
1059  frame.limit = limit;
1060 
1061  while (d->ptr < frame.limit) {
1062  int wire_type;
1063  int field_number;
1064 
1065  CHK(upb_decode_tag(&d->ptr, frame.limit, &field_number, &wire_type));
1066  CHK(upb_skip_unknownfielddata(d, &frame, field_number, wire_type));
1067  }
1068 
1069  return true;
1070 }
1071 
1072 static bool upb_decode_message(upb_decstate *d, const char *limit,
1073  int group_number, char *msg,
1074  const upb_msglayout *l) {
1075  upb_decframe frame;
1076  frame.group_number = group_number;
1077  frame.limit = limit;
1078  frame.msg = msg;
1079  frame.m = l;
1080 
1081  while (d->ptr < frame.limit) {
1082  CHK(upb_decode_field(d, &frame));
1083  }
1084 
1085  return true;
1086 }
1087 
1088 bool upb_decode(const char *buf, size_t size, void *msg,
1089  const upb_msglayout *l) {
1090  upb_decstate state;
1091  state.ptr = buf;
1092 
1093  return upb_decode_message(&state, buf + size, 0, msg, l);
1094 }
1095 
1096 #undef CHK
1097 
1098 
1099 #include <ctype.h>
1100 #include <errno.h>
1101 #include <stdlib.h>
1102 #include <string.h>
1103 
1104 typedef struct {
1105  size_t len;
1106  char str[1]; /* Null-terminated string data follows. */
1107 } str_t;
1108 
1109 static str_t *newstr(upb_alloc *alloc, const char *data, size_t len) {
1110  str_t *ret = upb_malloc(alloc, sizeof(*ret) + len);
1111  if (!ret) return NULL;
1112  ret->len = len;
1113  memcpy(ret->str, data, len);
1114  ret->str[len] = '\0';
1115  return ret;
1116 }
1117 
1121  const char *full_name;
1122  union {
1123  int64_t sint;
1124  uint64_t uint;
1125  double dbl;
1126  float flt;
1127  bool boolean;
1129  } defaultval;
1131  union {
1132  const upb_msgdef *msgdef;
1135  } sub;
1136  uint32_t number_;
1137  uint32_t index_;
1138  uint32_t selector_base; /* Used to index into a upb::Handlers table. */
1140  bool lazy_;
1141  bool packed_;
1144 };
1145 
1146 struct upb_msgdef {
1148  const char *full_name;
1149  uint32_t selector_count;
1151 
1152  /* Tables for looking up fields by number and name. */
1155 
1160 
1161  /* Is this a map-entry message? */
1164 
1165  /* TODO(haberman): proper extension ranges (there can be multiple). */
1166 };
1167 
1168 struct upb_enumdef {
1170  const char *full_name;
1173  int32_t defaultval;
1174 };
1175 
1178  const char *full_name;
1179  uint32_t index;
1182 };
1183 
1184 struct upb_filedef {
1185  const char *name;
1186  const char *package;
1187  const char *phpprefix;
1188  const char *phpnamespace;
1190 
1195 
1200 };
1201 
1202 struct upb_symtab {
1204  upb_strtable syms; /* full_name -> packed def ptr */
1205  upb_strtable files; /* file_name -> upb_filedef* */
1206 };
1207 
1208 /* Inside a symtab we store tagged pointers to specific def types. */
1209 typedef enum {
1214 } upb_deftype_t;
1215 
1216 static const void *unpack_def(upb_value v, upb_deftype_t type) {
1217  uintptr_t num = (uintptr_t)upb_value_getconstptr(v);
1218  return (num & 3) == type ? (const void*)(num & ~3) : NULL;
1219 }
1220 
1221 static upb_value pack_def(const void *ptr, upb_deftype_t type) {
1222  uintptr_t num = (uintptr_t)ptr | type;
1223  return upb_value_constptr((const void*)num);
1224 }
1225 
1226 /* isalpha() etc. from <ctype.h> are locale-dependent, which we don't want. */
1227 static bool upb_isbetween(char c, char low, char high) {
1228  return c >= low && c <= high;
1229 }
1230 
1231 static bool upb_isletter(char c) {
1232  return upb_isbetween(c, 'A', 'Z') || upb_isbetween(c, 'a', 'z') || c == '_';
1233 }
1234 
1235 static bool upb_isalphanum(char c) {
1236  return upb_isletter(c) || upb_isbetween(c, '0', '9');
1237 }
1238 
1239 static bool upb_isident(upb_strview name, bool full, upb_status *s) {
1240  const char *str = name.data;
1241  size_t len = name.size;
1242  bool start = true;
1243  size_t i;
1244  for (i = 0; i < len; i++) {
1245  char c = str[i];
1246  if (c == '.') {
1247  if (start || !full) {
1248  upb_status_seterrf(s, "invalid name: unexpected '.' (%s)", str);
1249  return false;
1250  }
1251  start = true;
1252  } else if (start) {
1253  if (!upb_isletter(c)) {
1255  s, "invalid name: path components must start with a letter (%s)",
1256  str);
1257  return false;
1258  }
1259  start = false;
1260  } else {
1261  if (!upb_isalphanum(c)) {
1262  upb_status_seterrf(s, "invalid name: non-alphanumeric character (%s)",
1263  str);
1264  return false;
1265  }
1266  }
1267  }
1268  return !start;
1269 }
1270 
1271 static const char *shortdefname(const char *fullname) {
1272  const char *p;
1273 
1274  if (fullname == NULL) {
1275  return NULL;
1276  } else if ((p = strrchr(fullname, '.')) == NULL) {
1277  /* No '.' in the name, return the full string. */
1278  return fullname;
1279  } else {
1280  /* Return one past the last '.'. */
1281  return p + 1;
1282  }
1283 }
1284 
1285 /* All submessage fields are lower than all other fields.
1286  * Secondly, fields are increasing in order. */
1287 uint32_t field_rank(const upb_fielddef *f) {
1288  uint32_t ret = upb_fielddef_number(f);
1289  const uint32_t high_bit = 1 << 30;
1290  UPB_ASSERT(ret < high_bit);
1291  if (!upb_fielddef_issubmsg(f))
1292  ret |= high_bit;
1293  return ret;
1294 }
1295 
1296 int cmp_fields(const void *p1, const void *p2) {
1297  const upb_fielddef *f1 = *(upb_fielddef*const*)p1;
1298  const upb_fielddef *f2 = *(upb_fielddef*const*)p2;
1299  return field_rank(f1) - field_rank(f2);
1300 }
1301 
1303  /* Sort fields. upb internally relies on UPB_TYPE_MESSAGE fields having the
1304  * lowest indexes, but we do not publicly guarantee this. */
1307  int i;
1308  uint32_t selector;
1309  int n = upb_msgdef_numfields(m);
1310  upb_fielddef **fields;
1311 
1312  if (n == 0) {
1313  m->selector_count = UPB_STATIC_SELECTOR_COUNT;
1314  m->submsg_field_count = 0;
1315  return true;
1316  }
1317 
1318  fields = upb_gmalloc(n * sizeof(*fields));
1319  if (!fields) {
1321  return false;
1322  }
1323 
1324  m->submsg_field_count = 0;
1325  for(i = 0, upb_msg_field_begin(&j, m);
1326  !upb_msg_field_done(&j);
1327  upb_msg_field_next(&j), i++) {
1329  UPB_ASSERT(f->msgdef == m);
1330  if (upb_fielddef_issubmsg(f)) {
1331  m->submsg_field_count++;
1332  }
1333  fields[i] = f;
1334  }
1335 
1336  qsort(fields, n, sizeof(*fields), cmp_fields);
1337 
1338  selector = UPB_STATIC_SELECTOR_COUNT + m->submsg_field_count;
1339  for (i = 0; i < n; i++) {
1340  upb_fielddef *f = fields[i];
1341  f->index_ = i;
1342  f->selector_base = selector + upb_handlers_selectorbaseoffset(f);
1343  selector += upb_handlers_selectorcount(f);
1344  }
1345  m->selector_count = selector;
1346 
1347 #ifndef NDEBUG
1348  {
1349  /* Verify that all selectors for the message are distinct. */
1350 #define TRY(type) \
1351  if (upb_handlers_getselector(f, type, &sel)) { upb_inttable_insert(&t, sel, v); }
1352 
1353  upb_inttable t;
1354  upb_value v;
1355  upb_selector_t sel;
1356 
1358  v = upb_value_bool(true);
1362  for(upb_msg_field_begin(&j, m);
1363  !upb_msg_field_done(&j);
1364  upb_msg_field_next(&j)) {
1366  /* These calls will assert-fail in upb_table if the value already
1367  * exists. */
1382  }
1383  upb_inttable_uninit(&t);
1384  }
1385 #undef TRY
1386 #endif
1387 
1388  for(upb_msg_oneof_begin(&k, m), i = 0;
1389  !upb_msg_oneof_done(&k);
1390  upb_msg_oneof_next(&k), i++) {
1392  o->index = i;
1393  }
1394 
1395  upb_gfree(fields);
1396  return true;
1397 }
1398 
1400  const char *name = upb_msgdef_fullname(m);
1401  if (name == NULL) {
1402  m->well_known_type = UPB_WELLKNOWN_UNSPECIFIED;
1403  return;
1404  }
1405  if (!strcmp(name, "google.protobuf.Any")) {
1406  m->well_known_type = UPB_WELLKNOWN_ANY;
1407  } else if (!strcmp(name, "google.protobuf.FieldMask")) {
1408  m->well_known_type = UPB_WELLKNOWN_FIELDMASK;
1409  } else if (!strcmp(name, "google.protobuf.Duration")) {
1410  m->well_known_type = UPB_WELLKNOWN_DURATION;
1411  } else if (!strcmp(name, "google.protobuf.Timestamp")) {
1412  m->well_known_type = UPB_WELLKNOWN_TIMESTAMP;
1413  } else if (!strcmp(name, "google.protobuf.DoubleValue")) {
1414  m->well_known_type = UPB_WELLKNOWN_DOUBLEVALUE;
1415  } else if (!strcmp(name, "google.protobuf.FloatValue")) {
1416  m->well_known_type = UPB_WELLKNOWN_FLOATVALUE;
1417  } else if (!strcmp(name, "google.protobuf.Int64Value")) {
1418  m->well_known_type = UPB_WELLKNOWN_INT64VALUE;
1419  } else if (!strcmp(name, "google.protobuf.UInt64Value")) {
1420  m->well_known_type = UPB_WELLKNOWN_UINT64VALUE;
1421  } else if (!strcmp(name, "google.protobuf.Int32Value")) {
1422  m->well_known_type = UPB_WELLKNOWN_INT32VALUE;
1423  } else if (!strcmp(name, "google.protobuf.UInt32Value")) {
1424  m->well_known_type = UPB_WELLKNOWN_UINT32VALUE;
1425  } else if (!strcmp(name, "google.protobuf.BoolValue")) {
1426  m->well_known_type = UPB_WELLKNOWN_BOOLVALUE;
1427  } else if (!strcmp(name, "google.protobuf.StringValue")) {
1428  m->well_known_type = UPB_WELLKNOWN_STRINGVALUE;
1429  } else if (!strcmp(name, "google.protobuf.BytesValue")) {
1430  m->well_known_type = UPB_WELLKNOWN_BYTESVALUE;
1431  } else if (!strcmp(name, "google.protobuf.Value")) {
1432  m->well_known_type = UPB_WELLKNOWN_VALUE;
1433  } else if (!strcmp(name, "google.protobuf.ListValue")) {
1434  m->well_known_type = UPB_WELLKNOWN_LISTVALUE;
1435  } else if (!strcmp(name, "google.protobuf.Struct")) {
1436  m->well_known_type = UPB_WELLKNOWN_STRUCT;
1437  } else {
1438  m->well_known_type = UPB_WELLKNOWN_UNSPECIFIED;
1439  }
1440 }
1441 
1442 
1443 /* upb_enumdef ****************************************************************/
1444 
1445 const char *upb_enumdef_fullname(const upb_enumdef *e) {
1446  return e->full_name;
1447 }
1448 
1449 const char *upb_enumdef_name(const upb_enumdef *e) {
1450  return shortdefname(e->full_name);
1451 }
1452 
1454  return e->file;
1455 }
1456 
1459  return e->defaultval;
1460 }
1461 
1463  return upb_strtable_count(&e->ntoi);
1464 }
1465 
1467  /* We iterate over the ntoi table, to account for duplicate numbers. */
1468  upb_strtable_begin(i, &e->ntoi);
1469 }
1470 
1472 bool upb_enum_done(upb_enum_iter *iter) { return upb_strtable_done(iter); }
1473 
1474 bool upb_enumdef_ntoi(const upb_enumdef *def, const char *name,
1475  size_t len, int32_t *num) {
1476  upb_value v;
1477  if (!upb_strtable_lookup2(&def->ntoi, name, len, &v)) {
1478  return false;
1479  }
1480  if (num) *num = upb_value_getint32(v);
1481  return true;
1482 }
1483 
1484 const char *upb_enumdef_iton(const upb_enumdef *def, int32_t num) {
1485  upb_value v;
1486  return upb_inttable_lookup32(&def->iton, num, &v) ?
1487  upb_value_getcstr(v) : NULL;
1488 }
1489 
1490 const char *upb_enum_iter_name(upb_enum_iter *iter) {
1491  return upb_strtable_iter_key(iter);
1492 }
1493 
1495  return upb_value_getint32(upb_strtable_iter_value(iter));
1496 }
1497 
1498 
1499 /* upb_fielddef ***************************************************************/
1500 
1501 const char *upb_fielddef_fullname(const upb_fielddef *f) {
1502  return f->full_name;
1503 }
1504 
1506  switch (f->type_) {
1508  return UPB_TYPE_DOUBLE;
1510  return UPB_TYPE_FLOAT;
1514  return UPB_TYPE_INT64;
1518  return UPB_TYPE_INT32;
1521  return UPB_TYPE_UINT64;
1524  return UPB_TYPE_UINT32;
1526  return UPB_TYPE_ENUM;
1528  return UPB_TYPE_BOOL;
1530  return UPB_TYPE_STRING;
1532  return UPB_TYPE_BYTES;
1535  return UPB_TYPE_MESSAGE;
1536  }
1537  UPB_UNREACHABLE();
1538 }
1539 
1541  return f->type_;
1542 }
1543 
1545  return f->index_;
1546 }
1547 
1549  return f->label_;
1550 }
1551 
1553  return f->number_;
1554 }
1555 
1557  return f->is_extension_;
1558 }
1559 
1561  return f->lazy_;
1562 }
1563 
1565  return f->packed_;
1566 }
1567 
1568 const char *upb_fielddef_name(const upb_fielddef *f) {
1569  return shortdefname(f->full_name);
1570 }
1571 
1573  return f->selector_base;
1574 }
1575 
1576 size_t upb_fielddef_getjsonname(const upb_fielddef *f, char *buf, size_t len) {
1577  const char *name = upb_fielddef_name(f);
1578  size_t src, dst = 0;
1579  bool ucase_next = false;
1580 
1581 #define WRITE(byte) \
1582  ++dst; \
1583  if (dst < len) buf[dst - 1] = byte; \
1584  else if (dst == len) buf[dst - 1] = '\0'
1585 
1586  if (!name) {
1587  WRITE('\0');
1588  return 0;
1589  }
1590 
1591  /* Implement the transformation as described in the spec:
1592  * 1. upper case all letters after an underscore.
1593  * 2. remove all underscores.
1594  */
1595  for (src = 0; name[src]; src++) {
1596  if (name[src] == '_') {
1597  ucase_next = true;
1598  continue;
1599  }
1600 
1601  if (ucase_next) {
1602  WRITE(toupper(name[src]));
1603  ucase_next = false;
1604  } else {
1605  WRITE(name[src]);
1606  }
1607  }
1608 
1609  WRITE('\0');
1610  return dst;
1611 
1612 #undef WRITE
1613 }
1614 
1616  return f->msgdef;
1617 }
1618 
1620  return f->oneof;
1621 }
1622 
1623 static void chkdefaulttype(const upb_fielddef *f, int ctype) {
1624  UPB_UNUSED(f);
1625  UPB_UNUSED(ctype);
1626 }
1627 
1630  return f->defaultval.sint;
1631 }
1632 
1635  return f->defaultval.sint;
1636 }
1637 
1640  return f->defaultval.uint;
1641 }
1642 
1645  return f->defaultval.uint;
1646 }
1647 
1650  return f->defaultval.boolean;
1651 }
1652 
1655  return f->defaultval.flt;
1656 }
1657 
1660  return f->defaultval.dbl;
1661 }
1662 
1663 const char *upb_fielddef_defaultstr(const upb_fielddef *f, size_t *len) {
1664  str_t *str = f->defaultval.str;
1668  if (str) {
1669  if (len) *len = str->len;
1670  return str->str;
1671  } else {
1672  if (len) *len = 0;
1673  return NULL;
1674  }
1675 }
1676 
1679  return f->sub.msgdef;
1680 }
1681 
1684  return f->sub.enumdef;
1685 }
1686 
1689 }
1690 
1692  return upb_fielddef_type(f) == UPB_TYPE_STRING ||
1694 }
1695 
1698 }
1699 
1702 }
1703 
1707 }
1708 
1711 }
1712 
1714  if (upb_fielddef_isseq(f)) return false;
1715  if (upb_fielddef_issubmsg(f)) return true;
1716  return f->file->syntax == UPB_SYNTAX_PROTO2;
1717 }
1718 
1719 static bool between(int32_t x, int32_t low, int32_t high) {
1720  return x >= low && x <= high;
1721 }
1722 
1723 bool upb_fielddef_checklabel(int32_t label) { return between(label, 1, 3); }
1724 bool upb_fielddef_checktype(int32_t type) { return between(type, 1, 11); }
1725 bool upb_fielddef_checkintfmt(int32_t fmt) { return between(fmt, 1, 3); }
1726 
1728  return between(type, 1, 18);
1729 }
1730 
1731 /* upb_msgdef *****************************************************************/
1732 
1733 const char *upb_msgdef_fullname(const upb_msgdef *m) {
1734  return m->full_name;
1735 }
1736 
1738  return m->file;
1739 }
1740 
1741 const char *upb_msgdef_name(const upb_msgdef *m) {
1742  return shortdefname(m->full_name);
1743 }
1744 
1746  return m->file->syntax;
1747 }
1748 
1750  return m->selector_count;
1751 }
1752 
1754  return m->submsg_field_count;
1755 }
1756 
1757 const upb_fielddef *upb_msgdef_itof(const upb_msgdef *m, uint32_t i) {
1758  upb_value val;
1759  return upb_inttable_lookup32(&m->itof, i, &val) ?
1760  upb_value_getconstptr(val) : NULL;
1761 }
1762 
1763 const upb_fielddef *upb_msgdef_ntof(const upb_msgdef *m, const char *name,
1764  size_t len) {
1765  upb_value val;
1766 
1767  if (!upb_strtable_lookup2(&m->ntof, name, len, &val)) {
1768  return NULL;
1769  }
1770 
1771  return unpack_def(val, UPB_DEFTYPE_FIELD);
1772 }
1773 
1774 const upb_oneofdef *upb_msgdef_ntoo(const upb_msgdef *m, const char *name,
1775  size_t len) {
1776  upb_value val;
1777 
1778  if (!upb_strtable_lookup2(&m->ntof, name, len, &val)) {
1779  return NULL;
1780  }
1781 
1782  return unpack_def(val, UPB_DEFTYPE_ONEOF);
1783 }
1784 
1785 bool upb_msgdef_lookupname(const upb_msgdef *m, const char *name, size_t len,
1786  const upb_fielddef **f, const upb_oneofdef **o) {
1787  upb_value val;
1788 
1789  if (!upb_strtable_lookup2(&m->ntof, name, len, &val)) {
1790  return false;
1791  }
1792 
1795  UPB_ASSERT((*o != NULL) ^ (*f != NULL)); /* Exactly one of the two should be set. */
1796  return true;
1797 }
1798 
1800  /* The number table contains only fields. */
1801  return upb_inttable_count(&m->itof);
1802 }
1803 
1805  /* The name table includes oneofs, and the number table does not. */
1806  return upb_strtable_count(&m->ntof) - upb_inttable_count(&m->itof);
1807 }
1808 
1810  return m->map_entry;
1811 }
1812 
1814  return m->well_known_type;
1815 }
1816 
1819  return type >= UPB_WELLKNOWN_DOUBLEVALUE &&
1821 }
1822 
1824  upb_inttable_begin(iter, &m->itof);
1825 }
1826 
1828 
1830  return upb_inttable_done(iter);
1831 }
1832 
1834  return (upb_fielddef *)upb_value_getconstptr(upb_inttable_iter_value(iter));
1835 }
1836 
1839 }
1840 
1842  const upb_msg_field_iter * iter2) {
1843  return upb_inttable_iter_isequal(iter1, iter2);
1844 }
1845 
1847  upb_strtable_begin(iter, &m->ntof);
1848  /* We need to skip past any initial fields. */
1849  while (!upb_strtable_done(iter) &&
1851  upb_strtable_next(iter);
1852  }
1853 }
1854 
1856  /* We need to skip past fields to return only oneofs. */
1857  do {
1858  upb_strtable_next(iter);
1859  } while (!upb_strtable_done(iter) &&
1861 }
1862 
1864  return upb_strtable_done(iter);
1865 }
1866 
1869 }
1870 
1873 }
1874 
1876  const upb_msg_oneof_iter *iter2) {
1877  return upb_strtable_iter_isequal(iter1, iter2);
1878 }
1879 
1880 /* upb_oneofdef ***************************************************************/
1881 
1882 const char *upb_oneofdef_name(const upb_oneofdef *o) {
1883  return shortdefname(o->full_name);
1884 }
1885 
1887  return o->parent;
1888 }
1889 
1891  return upb_strtable_count(&o->ntof);
1892 }
1893 
1894 uint32_t upb_oneofdef_index(const upb_oneofdef *o) {
1895  return o->index;
1896 }
1897 
1899  const char *name, size_t length) {
1900  upb_value val;
1901  return upb_strtable_lookup2(&o->ntof, name, length, &val) ?
1902  upb_value_getptr(val) : NULL;
1903 }
1904 
1905 const upb_fielddef *upb_oneofdef_itof(const upb_oneofdef *o, uint32_t num) {
1906  upb_value val;
1907  return upb_inttable_lookup32(&o->itof, num, &val) ?
1908  upb_value_getptr(val) : NULL;
1909 }
1910 
1912  upb_inttable_begin(iter, &o->itof);
1913 }
1914 
1916  upb_inttable_next(iter);
1917 }
1918 
1920  return upb_inttable_done(iter);
1921 }
1922 
1924  return (upb_fielddef *)upb_value_getconstptr(upb_inttable_iter_value(iter));
1925 }
1926 
1929 }
1930 
1931 /* Code to build defs from descriptor protos. *********************************/
1932 
1933 /* There is a question of how much validation to do here. It will be difficult
1934  * to perfectly match the amount of validation performed by proto2. But since
1935  * this code is used to directly build defs from Ruby (for example) we do need
1936  * to validate important constraints like uniqueness of names and numbers. */
1937 
1938 #define CHK(x) if (!(x)) { return false; }
1939 #define CHK_OOM(x) if (!(x)) { upb_status_setoom(ctx->status); return false; }
1940 
1941 typedef struct {
1943  upb_filedef *file; /* File we are building. */
1944  upb_alloc *alloc; /* Allocate defs here. */
1945  upb_alloc *tmp; /* Alloc for addtab and any other tmp data. */
1946  upb_strtable *addtab; /* full_name -> packed def ptr for new defs. */
1947  upb_status *status; /* Record errors here. */
1948 } symtab_addctx;
1949 
1950 static char* strviewdup(const symtab_addctx *ctx, upb_strview view) {
1951  return upb_strdup2(view.data, view.size, ctx->alloc);
1952 }
1953 
1954 static bool streql2(const char *a, size_t n, const char *b) {
1955  return n == strlen(b) && memcmp(a, b, n) == 0;
1956 }
1957 
1958 static bool streql_view(upb_strview view, const char *b) {
1959  return streql2(view.data, view.size, b);
1960 }
1961 
1962 static const char *makefullname(const symtab_addctx *ctx, const char *prefix,
1963  upb_strview name) {
1964  if (prefix) {
1965  /* ret = prefix + '.' + name; */
1966  size_t n = strlen(prefix);
1967  char *ret = upb_malloc(ctx->alloc, n + name.size + 2);
1968  CHK_OOM(ret);
1969  strcpy(ret, prefix);
1970  ret[n] = '.';
1971  memcpy(&ret[n + 1], name.data, name.size);
1972  ret[n + 1 + name.size] = '\0';
1973  return ret;
1974  } else {
1975  return strviewdup(ctx, name);
1976  }
1977 }
1978 
1979 static bool symtab_add(const symtab_addctx *ctx, const char *name,
1980  upb_value v) {
1981  upb_value tmp;
1982  if (upb_strtable_lookup(ctx->addtab, name, &tmp) ||
1983  upb_strtable_lookup(&ctx->symtab->syms, name, &tmp)) {
1984  upb_status_seterrf(ctx->status, "duplicate symbol '%s'", name);
1985  return false;
1986  }
1987 
1988  CHK_OOM(upb_strtable_insert3(ctx->addtab, name, strlen(name), v, ctx->tmp));
1989  return true;
1990 }
1991 
1992 /* Given a symbol and the base symbol inside which it is defined, find the
1993  * symbol's definition in t. */
1994 static bool resolvename(const upb_strtable *t, const upb_fielddef *f,
1995  const char *base, upb_strview sym,
1996  upb_deftype_t type, upb_status *status,
1997  const void **def) {
1998  if(sym.size == 0) return NULL;
1999  if(sym.data[0] == '.') {
2000  /* Symbols starting with '.' are absolute, so we do a single lookup.
2001  * Slice to omit the leading '.' */
2002  upb_value v;
2003  if (!upb_strtable_lookup2(t, sym.data + 1, sym.size - 1, &v)) {
2004  return false;
2005  }
2006 
2007  *def = unpack_def(v, type);
2008 
2009  if (!*def) {
2010  upb_status_seterrf(status,
2011  "type mismatch when resolving field %s, name %s",
2012  f->full_name, sym.data);
2013  return false;
2014  }
2015 
2016  return true;
2017  } else {
2018  /* Remove components from base until we find an entry or run out.
2019  * TODO: This branch is totally broken, but currently not used. */
2020  (void)base;
2021  UPB_ASSERT(false);
2022  return false;
2023  }
2024 }
2025 
2026 const void *symtab_resolve(const symtab_addctx *ctx, const upb_fielddef *f,
2027  const char *base, upb_strview sym,
2028  upb_deftype_t type) {
2029  const void *ret;
2030  if (!resolvename(ctx->addtab, f, base, sym, type, ctx->status, &ret) &&
2031  !resolvename(&ctx->symtab->syms, f, base, sym, type, ctx->status, &ret)) {
2032  if (upb_ok(ctx->status)) {
2033  upb_status_seterrf(ctx->status, "couldn't resolve name '%s'", sym.data);
2034  }
2035  return false;
2036  }
2037  return ret;
2038 }
2039 
2040 static bool create_oneofdef(
2041  const symtab_addctx *ctx, upb_msgdef *m,
2042  const google_protobuf_OneofDescriptorProto *oneof_proto) {
2043  upb_oneofdef *o;
2045  upb_value v;
2046 
2047  o = (upb_oneofdef*)&m->oneofs[m->oneof_count++];
2048  o->parent = m;
2049  o->full_name = makefullname(ctx, m->full_name, name);
2050 
2052  CHK_OOM(symtab_add(ctx, o->full_name, v));
2053  CHK_OOM(upb_strtable_insert3(&m->ntof, name.data, name.size, v, ctx->alloc));
2054 
2057 
2058  return true;
2059 }
2060 
2061 static bool parse_default(const symtab_addctx *ctx, const char *str, size_t len,
2062  upb_fielddef *f) {
2063  char *end;
2064  char nullz[64];
2065  errno = 0;
2066 
2067  switch (upb_fielddef_type(f)) {
2068  case UPB_TYPE_INT32:
2069  case UPB_TYPE_INT64:
2070  case UPB_TYPE_UINT32:
2071  case UPB_TYPE_UINT64:
2072  case UPB_TYPE_DOUBLE:
2073  case UPB_TYPE_FLOAT:
2074  /* Standard C number parsing functions expect null-terminated strings. */
2075  if (len >= sizeof(nullz) - 1) {
2076  return false;
2077  }
2078  memcpy(nullz, str, len);
2079  nullz[len] = '\0';
2080  str = nullz;
2081  break;
2082  default:
2083  break;
2084  }
2085 
2086  switch (upb_fielddef_type(f)) {
2087  case UPB_TYPE_INT32: {
2088  long val = strtol(str, &end, 0);
2089  CHK(val <= INT32_MAX && val >= INT32_MIN && errno != ERANGE && !*end);
2090  f->defaultval.sint = val;
2091  break;
2092  }
2093  case UPB_TYPE_ENUM: {
2094  const upb_enumdef *e = f->sub.enumdef;
2095  int32_t val;
2096  CHK(upb_enumdef_ntoi(e, str, len, &val));
2097  f->defaultval.sint = val;
2098  break;
2099  }
2100  case UPB_TYPE_INT64: {
2101  /* XXX: Need to write our own strtoll, since it's not available in c89. */
2102  long long val = strtol(str, &end, 0);
2103  CHK(val <= INT64_MAX && val >= INT64_MIN && errno != ERANGE && !*end);
2104  f->defaultval.sint = val;
2105  break;
2106  }
2107  case UPB_TYPE_UINT32: {
2108  unsigned long val = strtoul(str, &end, 0);
2109  CHK(val <= UINT32_MAX && errno != ERANGE && !*end);
2110  f->defaultval.uint = val;
2111  break;
2112  }
2113  case UPB_TYPE_UINT64: {
2114  /* XXX: Need to write our own strtoull, since it's not available in c89. */
2115  unsigned long long val = strtoul(str, &end, 0);
2116  CHK(val <= UINT64_MAX && errno != ERANGE && !*end);
2117  f->defaultval.uint = val;
2118  break;
2119  }
2120  case UPB_TYPE_DOUBLE: {
2121  double val = strtod(str, &end);
2122  CHK(errno != ERANGE && !*end);
2123  f->defaultval.dbl = val;
2124  break;
2125  }
2126  case UPB_TYPE_FLOAT: {
2127  /* XXX: Need to write our own strtof, since it's not available in c89. */
2128  float val = strtod(str, &end);
2129  CHK(errno != ERANGE && !*end);
2130  f->defaultval.flt = val;
2131  break;
2132  }
2133  case UPB_TYPE_BOOL: {
2134  if (streql2(str, len, "false")) {
2135  f->defaultval.boolean = false;
2136  } else if (streql2(str, len, "true")) {
2137  f->defaultval.boolean = true;
2138  } else {
2139  return false;
2140  }
2141  }
2142  case UPB_TYPE_STRING:
2143  f->defaultval.str = newstr(ctx->alloc, str, len);
2144  break;
2145  case UPB_TYPE_BYTES:
2146  /* XXX: need to interpret the C-escaped value. */
2147  f->defaultval.str = newstr(ctx->alloc, str, len);
2148  break;
2149  case UPB_TYPE_MESSAGE:
2150  /* Should not have a default value. */
2151  return false;
2152  }
2153  return true;
2154 }
2155 
2157  switch (upb_fielddef_type(f)) {
2158  case UPB_TYPE_INT32:
2159  case UPB_TYPE_INT64:
2160  case UPB_TYPE_ENUM:
2161  f->defaultval.sint = 0;
2162  break;
2163  case UPB_TYPE_UINT64:
2164  case UPB_TYPE_UINT32:
2165  f->defaultval.uint = 0;
2166  break;
2167  case UPB_TYPE_DOUBLE:
2168  case UPB_TYPE_FLOAT:
2169  f->defaultval.dbl = 0;
2170  break;
2171  case UPB_TYPE_STRING:
2172  case UPB_TYPE_BYTES:
2173  f->defaultval.str = newstr(ctx->alloc, NULL, 0);
2174  break;
2175  case UPB_TYPE_BOOL:
2176  f->defaultval.boolean = false;
2177  break;
2178  case UPB_TYPE_MESSAGE:
2179  break;
2180  }
2181 }
2182 
2183 static bool create_fielddef(
2184  const symtab_addctx *ctx, const char *prefix, upb_msgdef *m,
2185  const google_protobuf_FieldDescriptorProto *field_proto) {
2186  upb_alloc *alloc = ctx->alloc;
2187  upb_fielddef *f;
2189  upb_strview name;
2190  const char *full_name;
2191  const char *shortname;
2192  uint32_t field_number;
2193 
2195  upb_status_seterrmsg(ctx->status, "field has no name");
2196  return false;
2197  }
2198 
2200  CHK(upb_isident(name, false, ctx->status));
2201  full_name = makefullname(ctx, prefix, name);
2202  shortname = shortdefname(full_name);
2203 
2204  field_number = google_protobuf_FieldDescriptorProto_number(field_proto);
2205 
2206  if (field_number == 0 || field_number > UPB_MAX_FIELDNUMBER) {
2207  upb_status_seterrf(ctx->status, "invalid field number (%u)", field_number);
2208  return false;
2209  }
2210 
2211  if (m) {
2212  /* direct message field. */
2213  upb_value v, packed_v;
2214 
2215  f = (upb_fielddef*)&m->fields[m->field_count++];
2216  f->msgdef = m;
2217  f->is_extension_ = false;
2218 
2219  packed_v = pack_def(f, UPB_DEFTYPE_FIELD);
2220  v = upb_value_constptr(f);
2221 
2222  if (!upb_strtable_insert3(&m->ntof, name.data, name.size, packed_v, alloc)) {
2223  upb_status_seterrf(ctx->status, "duplicate field name (%s)", shortname);
2224  return false;
2225  }
2226 
2227  if (!upb_inttable_insert2(&m->itof, field_number, v, alloc)) {
2228  upb_status_seterrf(ctx->status, "duplicate field number (%u)",
2229  field_number);
2230  return false;
2231  }
2232  } else {
2233  /* extension field. */
2234  f = (upb_fielddef*)&ctx->file->exts[ctx->file->ext_count];
2235  f->is_extension_ = true;
2236  CHK_OOM(symtab_add(ctx, full_name, pack_def(f, UPB_DEFTYPE_FIELD)));
2237  }
2238 
2239  f->full_name = full_name;
2240  f->file = ctx->file;
2241  f->type_ = (int)google_protobuf_FieldDescriptorProto_type(field_proto);
2242  f->label_ = (int)google_protobuf_FieldDescriptorProto_label(field_proto);
2243  f->number_ = field_number;
2244  f->oneof = NULL;
2245 
2246  /* We can't resolve the subdef or (in the case of extensions) the containing
2247  * message yet, because it may not have been defined yet. We stash a pointer
2248  * to the field_proto until later when we can properly resolve it. */
2249  f->sub.unresolved = field_proto;
2250 
2251  if (f->label_ == UPB_LABEL_REQUIRED && f->file->syntax == UPB_SYNTAX_PROTO3) {
2252  upb_status_seterrf(ctx->status, "proto3 fields cannot be required (%s)",
2253  f->full_name);
2254  return false;
2255  }
2256 
2258  int oneof_index =
2260  upb_oneofdef *oneof;
2261  upb_value v = upb_value_constptr(f);
2262 
2265  "fields in oneof must have OPTIONAL label (%s)",
2266  f->full_name);
2267  return false;
2268  }
2269 
2270  if (!m) {
2272  "oneof_index provided for extension field (%s)",
2273  f->full_name);
2274  return false;
2275  }
2276 
2277  if (oneof_index >= m->oneof_count) {
2278  upb_status_seterrf(ctx->status, "oneof_index out of range (%s)",
2279  f->full_name);
2280  return false;
2281  }
2282 
2283  oneof = (upb_oneofdef*)&m->oneofs[oneof_index];
2284  f->oneof = oneof;
2285 
2286  CHK(upb_inttable_insert2(&oneof->itof, f->number_, v, alloc));
2287  CHK(upb_strtable_insert3(&oneof->ntof, name.data, name.size, v, alloc));
2288  } else {
2289  f->oneof = NULL;
2290  }
2291 
2296  } else {
2297  f->lazy_ = false;
2298  f->packed_ = false;
2299  }
2300 
2301  return true;
2302 }
2303 
2304 static bool create_enumdef(
2305  const symtab_addctx *ctx, const char *prefix,
2306  const google_protobuf_EnumDescriptorProto *enum_proto) {
2307  upb_enumdef *e;
2309  upb_strview name;
2310  size_t i, n;
2311 
2313  CHK(upb_isident(name, false, ctx->status));
2314 
2315  e = (upb_enumdef*)&ctx->file->enums[ctx->file->enum_count++];
2316  e->full_name = makefullname(ctx, prefix, name);
2318 
2321 
2322  e->file = ctx->file;
2323  e->defaultval = 0;
2324 
2326 
2327  if (n == 0) {
2329  "enums must contain at least one value (%s)",
2330  e->full_name);
2331  return false;
2332  }
2333 
2334  for (i = 0; i < n; i++) {
2337  char *name2 = strviewdup(ctx, name);
2339  upb_value v = upb_value_int32(num);
2340 
2341  if (i == 0 && e->file->syntax == UPB_SYNTAX_PROTO3 && num != 0) {
2343  "for proto3, the first enum value must be zero (%s)",
2344  e->full_name);
2345  return false;
2346  }
2347 
2348  if (upb_strtable_lookup(&e->ntoi, name2, NULL)) {
2349  upb_status_seterrf(ctx->status, "duplicate enum label '%s'", name2);
2350  return false;
2351  }
2352 
2353  CHK_OOM(name2)
2354  CHK_OOM(
2355  upb_strtable_insert3(&e->ntoi, name2, strlen(name2), v, ctx->alloc));
2356 
2357  if (!upb_inttable_lookup(&e->iton, num, NULL)) {
2358  upb_value v = upb_value_cstr(name2);
2359  CHK_OOM(upb_inttable_insert2(&e->iton, num, v, ctx->alloc));
2360  }
2361  }
2362 
2363  upb_inttable_compact2(&e->iton, ctx->alloc);
2364 
2365  return true;
2366 }
2367 
2368 static bool create_msgdef(const symtab_addctx *ctx, const char *prefix,
2369  const google_protobuf_DescriptorProto *msg_proto) {
2370  upb_msgdef *m;
2372  const google_protobuf_OneofDescriptorProto *const *oneofs;
2375  const google_protobuf_DescriptorProto *const *msgs;
2376  size_t i, n;
2377  upb_strview name;
2378 
2380  CHK(upb_isident(name, false, ctx->status));
2381 
2382  m = (upb_msgdef*)&ctx->file->msgs[ctx->file->msg_count++];
2383  m->full_name = makefullname(ctx, prefix, name);
2384  CHK_OOM(symtab_add(ctx, m->full_name, pack_def(m, UPB_DEFTYPE_MSG)));
2385 
2388 
2389  m->file = ctx->file;
2390  m->map_entry = false;
2391 
2393 
2394  if (options) {
2396  }
2397 
2398  oneofs = google_protobuf_DescriptorProto_oneof_decl(msg_proto, &n);
2399  m->oneof_count = 0;
2400  m->oneofs = upb_malloc(ctx->alloc, sizeof(*m->oneofs) * n);
2401  for (i = 0; i < n; i++) {
2402  CHK(create_oneofdef(ctx, m, oneofs[i]));
2403  }
2404 
2406  m->field_count = 0;
2407  m->fields = upb_malloc(ctx->alloc, sizeof(*m->fields) * n);
2408  for (i = 0; i < n; i++) {
2409  CHK(create_fielddef(ctx, m->full_name, m, fields[i]));
2410  }
2411 
2412  CHK(assign_msg_indices(m, ctx->status));
2414  upb_inttable_compact2(&m->itof, ctx->alloc);
2415 
2416  /* This message is built. Now build nested messages and enums. */
2417 
2419  for (i = 0; i < n; i++) {
2420  CHK(create_enumdef(ctx, m->full_name, enums[i]));
2421  }
2422 
2424  for (i = 0; i < n; i++) {
2425  CHK(create_msgdef(ctx, m->full_name, msgs[i]));
2426  }
2427 
2428  return true;
2429 }
2430 
2431 typedef struct {
2435 } decl_counts;
2436 
2438  decl_counts *counts) {
2439  const google_protobuf_DescriptorProto *const *msgs;
2440  size_t i, n;
2441 
2442  counts->msg_count++;
2443 
2445  for (i = 0; i < n; i++) {
2446  count_types_in_msg(msgs[i], counts);
2447  }
2448 
2450  counts->enum_count += n;
2451 
2453  counts->ext_count += n;
2454 }
2455 
2457  const google_protobuf_FileDescriptorProto *file_proto,
2458  decl_counts *counts) {
2459  const google_protobuf_DescriptorProto *const *msgs;
2460  size_t i, n;
2461 
2463  for (i = 0; i < n; i++) {
2464  count_types_in_msg(msgs[i], counts);
2465  }
2466 
2468  counts->enum_count += n;
2469 
2471  counts->ext_count += n;
2472 }
2473 
2474 static bool resolve_fielddef(const symtab_addctx *ctx, const char *prefix,
2475  upb_fielddef *f) {
2476  upb_strview name;
2477  const google_protobuf_FieldDescriptorProto *field_proto = f->sub.unresolved;
2478 
2479  if (f->is_extension_) {
2482  "extension for field '%s' had no extendee",
2483  f->full_name);
2484  return false;
2485  }
2486 
2488  f->msgdef = symtab_resolve(ctx, f, prefix, name, UPB_DEFTYPE_MSG);
2489  CHK(f->msgdef);
2490  }
2491 
2492  if ((upb_fielddef_issubmsg(f) || f->type_ == UPB_DESCRIPTOR_TYPE_ENUM) &&
2494  upb_status_seterrf(ctx->status, "field '%s' is missing type name",
2495  f->full_name);
2496  return false;
2497  }
2498 
2500 
2501  if (upb_fielddef_issubmsg(f)) {
2502  f->sub.msgdef = symtab_resolve(ctx, f, prefix, name, UPB_DEFTYPE_MSG);
2503  CHK(f->sub.msgdef);
2504  } else if (f->type_ == UPB_DESCRIPTOR_TYPE_ENUM) {
2505  f->sub.enumdef = symtab_resolve(ctx, f, prefix, name, UPB_DEFTYPE_ENUM);
2506  CHK(f->sub.enumdef);
2507  }
2508 
2509  /* Have to delay resolving of the default value until now because of the enum
2510  * case, since enum defaults are specified with a label. */
2512  upb_strview defaultval =
2514 
2515  if (f->file->syntax == UPB_SYNTAX_PROTO3) {
2517  "proto3 fields cannot have explicit defaults (%s)",
2518  f->full_name);
2519  return false;
2520  }
2521 
2522  if (upb_fielddef_issubmsg(f)) {
2524  "message fields cannot have explicit defaults (%s)",
2525  f->full_name);
2526  return false;
2527  }
2528 
2529  if (!parse_default(ctx, defaultval.data, defaultval.size, f)) {
2531  "couldn't parse default '" UPB_STRVIEW_FORMAT
2532  "' for field (%s)",
2533  UPB_STRVIEW_ARGS(defaultval), f->full_name);
2534  return false;
2535  }
2536  } else {
2537  set_default_default(ctx, f);
2538  }
2539 
2540  return true;
2541 }
2542 
2543 static bool build_filedef(
2544  const symtab_addctx *ctx, upb_filedef *file,
2545  const google_protobuf_FileDescriptorProto *file_proto) {
2546  upb_alloc *alloc = ctx->alloc;
2547  const google_protobuf_FileOptions *file_options_proto;
2548  const google_protobuf_DescriptorProto *const *msgs;
2550  const google_protobuf_FieldDescriptorProto *const *exts;
2551  const upb_strview* strs;
2552  size_t i, n;
2553  decl_counts counts = {0};
2554 
2555  count_types_in_file(file_proto, &counts);
2556 
2557  file->msgs = upb_malloc(alloc, sizeof(*file->msgs) * counts.msg_count);
2558  file->enums = upb_malloc(alloc, sizeof(*file->enums) * counts.enum_count);
2559  file->exts = upb_malloc(alloc, sizeof(*file->exts) * counts.ext_count);
2560 
2561  CHK_OOM(counts.msg_count == 0 || file->msgs);
2562  CHK_OOM(counts.enum_count == 0 || file->enums);
2563  CHK_OOM(counts.ext_count == 0 || file->exts);
2564 
2565  /* We increment these as defs are added. */
2566  file->msg_count = 0;
2567  file->enum_count = 0;
2568  file->ext_count = 0;
2569 
2571  upb_status_seterrmsg(ctx->status, "File has no name");
2572  return false;
2573  }
2574 
2575  file->name =
2577  file->phpprefix = NULL;
2578  file->phpnamespace = NULL;
2579 
2581  upb_strview package =
2582  google_protobuf_FileDescriptorProto_package(file_proto);
2583  CHK(upb_isident(package, true, ctx->status));
2584  file->package = strviewdup(ctx, package);
2585  } else {
2586  file->package = NULL;
2587  }
2588 
2590  upb_strview syntax =
2592 
2593  if (streql_view(syntax, "proto2")) {
2594  file->syntax = UPB_SYNTAX_PROTO2;
2595  } else if (streql_view(syntax, "proto3")) {
2596  file->syntax = UPB_SYNTAX_PROTO3;
2597  } else {
2598  upb_status_seterrf(ctx->status, "Invalid syntax '%s'", syntax);
2599  return false;
2600  }
2601  } else {
2602  file->syntax = UPB_SYNTAX_PROTO2;
2603  }
2604 
2605  /* Read options. */
2606  file_options_proto = google_protobuf_FileDescriptorProto_options(file_proto);
2607  if (file_options_proto) {
2608  if (google_protobuf_FileOptions_has_php_class_prefix(file_options_proto)) {
2609  file->phpprefix = strviewdup(
2610  ctx,
2611  google_protobuf_FileOptions_php_class_prefix(file_options_proto));
2612  }
2613  if (google_protobuf_FileOptions_has_php_namespace(file_options_proto)) {
2614  file->phpnamespace = strviewdup(
2615  ctx, google_protobuf_FileOptions_php_namespace(file_options_proto));
2616  }
2617  }
2618 
2619  /* Verify dependencies. */
2621  file->deps = upb_malloc(alloc, sizeof(*file->deps) * n) ;
2622  CHK_OOM(n == 0 || file->deps);
2623 
2624  for (i = 0; i < n; i++) {
2625  upb_strview dep_name = strs[i];
2626  upb_value v;
2627  if (!upb_strtable_lookup2(&ctx->symtab->files, dep_name.data,
2628  dep_name.size, &v)) {
2630  "Depends on file '" UPB_STRVIEW_FORMAT
2631  "', but it has not been loaded",
2632  UPB_STRVIEW_ARGS(dep_name));
2633  return false;
2634  }
2635  file->deps[i] = upb_value_getconstptr(v);
2636  }
2637 
2638  /* Create messages. */
2640  for (i = 0; i < n; i++) {
2641  CHK(create_msgdef(ctx, file->package, msgs[i]));
2642  }
2643 
2644  /* Create enums. */
2646  for (i = 0; i < n; i++) {
2647  CHK(create_enumdef(ctx, file->package, enums[i]));
2648  }
2649 
2650  /* Create extensions. */
2651  exts = google_protobuf_FileDescriptorProto_extension(file_proto, &n);
2652  file->exts = upb_malloc(alloc, sizeof(*file->exts) * n);
2653  CHK_OOM(n == 0 || file->exts);
2654  for (i = 0; i < n; i++) {
2655  CHK(create_fielddef(ctx, file->package, NULL, exts[i]));
2656  }
2657 
2658  /* Now that all names are in the table, resolve references. */
2659  for (i = 0; i < file->ext_count; i++) {
2660  CHK(resolve_fielddef(ctx, file->package, (upb_fielddef*)&file->exts[i]));
2661  }
2662 
2663  for (i = 0; i < file->msg_count; i++) {
2664  const upb_msgdef *m = &file->msgs[i];
2665  int j;
2666  for (j = 0; j < m->field_count; j++) {
2667  CHK(resolve_fielddef(ctx, m->full_name, (upb_fielddef*)&m->fields[j]));
2668  }
2669  }
2670 
2671  return true;
2672  }
2673 
2675  upb_status *status) {
2676  const upb_filedef *file = ctx->file;
2677  upb_alloc *alloc = upb_arena_alloc(s->arena);
2678  upb_strtable_iter iter;
2679 
2680  CHK_OOM(upb_strtable_insert3(&s->files, file->name, strlen(file->name),
2681  upb_value_constptr(file), alloc));
2682 
2683  upb_strtable_begin(&iter, ctx->addtab);
2684  for (; !upb_strtable_done(&iter); upb_strtable_next(&iter)) {
2685  const char *key = upb_strtable_iter_key(&iter);
2686  size_t keylen = upb_strtable_iter_keylength(&iter);
2688  CHK_OOM(upb_strtable_insert3(&s->syms, key, keylen, value, alloc));
2689  }
2690 
2691  return true;
2692 }
2693 
2694 /* upb_filedef ****************************************************************/
2695 
2696 const char *upb_filedef_name(const upb_filedef *f) {
2697  return f->name;
2698 }
2699 
2700 const char *upb_filedef_package(const upb_filedef *f) {
2701  return f->package;
2702 }
2703 
2704 const char *upb_filedef_phpprefix(const upb_filedef *f) {
2705  return f->phpprefix;
2706 }
2707 
2709  return f->phpnamespace;
2710 }
2711 
2713  return f->syntax;
2714 }
2715 
2717  return f->msg_count;
2718 }
2719 
2721  return f->dep_count;
2722 }
2723 
2725  return f->enum_count;
2726 }
2727 
2729  return i < 0 || i >= f->dep_count ? NULL : f->deps[i];
2730 }
2731 
2733  return i < 0 || i >= f->msg_count ? NULL : &f->msgs[i];
2734 }
2735 
2737  return i < 0 || i >= f->enum_count ? NULL : &f->enums[i];
2738 }
2739 
2741  upb_arena_free(s->arena);
2742  upb_gfree(s);
2743 }
2744 
2746  upb_symtab *s = upb_gmalloc(sizeof(*s));
2747  upb_alloc *alloc;
2748 
2749  if (!s) {
2750  return NULL;
2751  }
2752 
2753  s->arena = upb_arena_new();
2754  alloc = upb_arena_alloc(s->arena);
2755 
2756  if (!upb_strtable_init2(&s->syms, UPB_CTYPE_CONSTPTR, alloc) ||
2757  !upb_strtable_init2(&s->files, UPB_CTYPE_CONSTPTR, alloc)) {
2758  upb_arena_free(s->arena);
2759  upb_gfree(s);
2760  s = NULL;
2761  }
2762  return s;
2763 }
2764 
2765 const upb_msgdef *upb_symtab_lookupmsg(const upb_symtab *s, const char *sym) {
2766  upb_value v;
2767  return upb_strtable_lookup(&s->syms, sym, &v) ?
2769 }
2770 
2771 const upb_msgdef *upb_symtab_lookupmsg2(const upb_symtab *s, const char *sym,
2772  size_t len) {
2773  upb_value v;
2774  return upb_strtable_lookup2(&s->syms, sym, len, &v) ?
2776 }
2777 
2778 const upb_enumdef *upb_symtab_lookupenum(const upb_symtab *s, const char *sym) {
2779  upb_value v;
2780  return upb_strtable_lookup(&s->syms, sym, &v) ?
2782 }
2783 
2784 const upb_filedef *upb_symtab_lookupfile(const upb_symtab *s, const char *name) {
2785  upb_value v;
2786  return upb_strtable_lookup(&s->files, name, &v) ? upb_value_getconstptr(v)
2787  : NULL;
2788 }
2789 
2791  upb_symtab *s, const google_protobuf_FileDescriptorProto *file_proto,
2792  upb_status *status) {
2793  upb_arena *tmparena = upb_arena_new();
2794  upb_strtable addtab;
2795  upb_alloc *alloc = upb_arena_alloc(s->arena);
2796  upb_filedef *file = upb_malloc(alloc, sizeof(*file));
2797  bool ok;
2798  symtab_addctx ctx;
2799 
2800  ctx.file = file;
2801  ctx.symtab = s;
2802  ctx.alloc = alloc;
2803  ctx.tmp = upb_arena_alloc(tmparena);
2804  ctx.addtab = &addtab;
2805  ctx.status = status;
2806 
2807  ok = file &&
2808  upb_strtable_init2(&addtab, UPB_CTYPE_CONSTPTR, ctx.tmp) &&
2809  build_filedef(&ctx, file, file_proto) &&
2810  upb_symtab_addtotabs(s, &ctx, status);
2811 
2812  upb_arena_free(tmparena);
2813  return ok ? file : NULL;
2814 }
2815 
2816 /* Include here since we want most of this file to be stdio-free. */
2817 #include <stdio.h>
2818 
2820  /* Since this function should never fail (it would indicate a bug in upb) we
2821  * print errors to stderr instead of returning error status to the user. */
2822  upb_def_init **deps = init->deps;
2824  upb_arena *arena;
2825  upb_status status;
2826 
2827  upb_status_clear(&status);
2828 
2829  if (upb_strtable_lookup(&s->files, init->filename, NULL)) {
2830  return true;
2831  }
2832 
2833  arena = upb_arena_new();
2834 
2835  for (; *deps; deps++) {
2836  if (!_upb_symtab_loaddefinit(s, *deps)) goto err;
2837  }
2838 
2840  init->descriptor.data, init->descriptor.size, arena);
2841 
2842  if (!file) {
2844  &status,
2845  "Failed to parse compiled-in descriptor for file '%s'. This should "
2846  "never happen.",
2847  init->filename);
2848  goto err;
2849  }
2850 
2851  if (!upb_symtab_addfile(s, file, &status)) goto err;
2852 
2853  upb_arena_free(arena);
2854  return true;
2855 
2856 err:
2857  fprintf(stderr, "Error loading compiled-in descriptor: %s\n",
2858  upb_status_errmsg(&status));
2859  upb_arena_free(arena);
2860  return false;
2861 }
2862 
2863 #undef CHK
2864 #undef CHK_OOM
2865 /* We encode backwards, to avoid pre-computing lengths (one-pass encode). */
2866 
2867 #include <string.h>
2868 
2869 #define UPB_PB_VARINT_MAX_LEN 10
2870 #define CHK(x) do { if (!(x)) { return false; } } while(0)
2871 
2872 /* Maps descriptor type -> upb field type. */
2873 static const uint8_t upb_desctype_to_fieldtype2[] = {
2874  UPB_WIRE_TYPE_END_GROUP, /* ENDGROUP */
2875  UPB_TYPE_DOUBLE, /* DOUBLE */
2876  UPB_TYPE_FLOAT, /* FLOAT */
2877  UPB_TYPE_INT64, /* INT64 */
2878  UPB_TYPE_UINT64, /* UINT64 */
2879  UPB_TYPE_INT32, /* INT32 */
2880  UPB_TYPE_UINT64, /* FIXED64 */
2881  UPB_TYPE_UINT32, /* FIXED32 */
2882  UPB_TYPE_BOOL, /* BOOL */
2883  UPB_TYPE_STRING, /* STRING */
2884  UPB_TYPE_MESSAGE, /* GROUP */
2885  UPB_TYPE_MESSAGE, /* MESSAGE */
2886  UPB_TYPE_BYTES, /* BYTES */
2887  UPB_TYPE_UINT32, /* UINT32 */
2888  UPB_TYPE_ENUM, /* ENUM */
2889  UPB_TYPE_INT32, /* SFIXED32 */
2890  UPB_TYPE_INT64, /* SFIXED64 */
2891  UPB_TYPE_INT32, /* SINT32 */
2892  UPB_TYPE_INT64, /* SINT64 */
2893 };
2894 
2895 static size_t upb_encode_varint(uint64_t val, char *buf) {
2896  size_t i;
2897  if (val < 128) { buf[0] = val; return 1; }
2898  i = 0;
2899  while (val) {
2900  uint8_t byte = val & 0x7fU;
2901  val >>= 7;
2902  if (val) byte |= 0x80U;
2903  buf[i++] = byte;
2904  }
2905  return i;
2906 }
2907 
2908 static uint32_t upb_zzencode_32(int32_t n) { return (n << 1) ^ (n >> 31); }
2909 static uint64_t upb_zzencode_64(int64_t n) { return (n << 1) ^ (n >> 63); }
2910 
2911 typedef struct {
2913  char *buf, *ptr, *limit;
2914 } upb_encstate;
2915 
2916 static size_t upb_roundup_pow2(size_t bytes) {
2917  size_t ret = 128;
2918  while (ret < bytes) {
2919  ret *= 2;
2920  }
2921  return ret;
2922 }
2923 
2924 static bool upb_encode_growbuffer(upb_encstate *e, size_t bytes) {
2925  size_t old_size = e->limit - e->buf;
2926  size_t new_size = upb_roundup_pow2(bytes + (e->limit - e->ptr));
2927  char *new_buf = upb_realloc(e->alloc, e->buf, old_size, new_size);
2928  CHK(new_buf);
2929 
2930  /* We want previous data at the end, realloc() put it at the beginning. */
2931  memmove(new_buf + new_size - old_size, e->buf, old_size);
2932 
2933  e->ptr = new_buf + new_size - (e->limit - e->ptr);
2934  e->limit = new_buf + new_size;
2935  e->buf = new_buf;
2936  return true;
2937 }
2938 
2939 /* Call to ensure that at least "bytes" bytes are available for writing at
2940  * e->ptr. Returns false if the bytes could not be allocated. */
2941 static bool upb_encode_reserve(upb_encstate *e, size_t bytes) {
2942  CHK(UPB_LIKELY((size_t)(e->ptr - e->buf) >= bytes) ||
2944 
2945  e->ptr -= bytes;
2946  return true;
2947 }
2948 
2949 /* Writes the given bytes to the buffer, handling reserve/advance. */
2950 static bool upb_put_bytes(upb_encstate *e, const void *data, size_t len) {
2951  CHK(upb_encode_reserve(e, len));
2952  memcpy(e->ptr, data, len);
2953  return true;
2954 }
2955 
2956 static bool upb_put_fixed64(upb_encstate *e, uint64_t val) {
2957  /* TODO(haberman): byte-swap for big endian. */
2958  return upb_put_bytes(e, &val, sizeof(uint64_t));
2959 }
2960 
2961 static bool upb_put_fixed32(upb_encstate *e, uint32_t val) {
2962  /* TODO(haberman): byte-swap for big endian. */
2963  return upb_put_bytes(e, &val, sizeof(uint32_t));
2964 }
2965 
2966 static bool upb_put_varint(upb_encstate *e, uint64_t val) {
2967  size_t len;
2968  char *start;
2970  len = upb_encode_varint(val, e->ptr);
2972  memmove(start, e->ptr, len);
2973  e->ptr = start;
2974  return true;
2975 }
2976 
2977 static bool upb_put_double(upb_encstate *e, double d) {
2978  uint64_t u64;
2979  UPB_ASSERT(sizeof(double) == sizeof(uint64_t));
2980  memcpy(&u64, &d, sizeof(uint64_t));
2981  return upb_put_fixed64(e, u64);
2982 }
2983 
2984 static bool upb_put_float(upb_encstate *e, float d) {
2985  uint32_t u32;
2986  UPB_ASSERT(sizeof(float) == sizeof(uint32_t));
2987  memcpy(&u32, &d, sizeof(uint32_t));
2988  return upb_put_fixed32(e, u32);
2989 }
2990 
2991 static uint32_t upb_readcase(const char *msg, const upb_msglayout_field *f) {
2992  uint32_t ret;
2993  uint32_t offset = ~f->presence;
2994  memcpy(&ret, msg + offset, sizeof(ret));
2995  return ret;
2996 }
2997 
2998 static bool upb_readhasbit(const char *msg, const upb_msglayout_field *f) {
2999  uint32_t hasbit = f->presence;
3000  UPB_ASSERT(f->presence > 0);
3001  return msg[hasbit / 8] & (1 << (hasbit % 8));
3002 }
3003 
3004 static bool upb_put_tag(upb_encstate *e, int field_number, int wire_type) {
3005  return upb_put_varint(e, (field_number << 3) | wire_type);
3006 }
3007 
3008 static bool upb_put_fixedarray(upb_encstate *e, const upb_array *arr,
3009  size_t size) {
3010  size_t bytes = arr->len * size;
3011  return upb_put_bytes(e, arr->data, bytes) && upb_put_varint(e, bytes);
3012 }
3013 
3014 bool upb_encode_message(upb_encstate *e, const char *msg,
3015  const upb_msglayout *m, size_t *size);
3016 
3017 static bool upb_encode_array(upb_encstate *e, const char *field_mem,
3018  const upb_msglayout *m,
3019  const upb_msglayout_field *f) {
3020  const upb_array *arr = *(const upb_array**)field_mem;
3021 
3022  if (arr == NULL || arr->len == 0) {
3023  return true;
3024  }
3025 
3026  UPB_ASSERT(arr->type == upb_desctype_to_fieldtype2[f->descriptortype]);
3027 
3028 #define VARINT_CASE(ctype, encode) { \
3029  ctype *start = arr->data; \
3030  ctype *ptr = start + arr->len; \
3031  size_t pre_len = e->limit - e->ptr; \
3032  do { \
3033  ptr--; \
3034  CHK(upb_put_varint(e, encode)); \
3035  } while (ptr != start); \
3036  CHK(upb_put_varint(e, e->limit - e->ptr - pre_len)); \
3037 } \
3038 break; \
3039 do { ; } while(0)
3040 
3041  switch (f->descriptortype) {
3043  CHK(upb_put_fixedarray(e, arr, sizeof(double)));
3044  break;
3046  CHK(upb_put_fixedarray(e, arr, sizeof(float)));
3047  break;
3050  CHK(upb_put_fixedarray(e, arr, sizeof(uint64_t)));
3051  break;
3054  CHK(upb_put_fixedarray(e, arr, sizeof(uint32_t)));
3055  break;
3058  VARINT_CASE(uint64_t, *ptr);
3060  VARINT_CASE(uint32_t, *ptr);
3063  VARINT_CASE(int32_t, (int64_t)*ptr);
3065  VARINT_CASE(bool, *ptr);
3067  VARINT_CASE(int32_t, upb_zzencode_32(*ptr));
3069  VARINT_CASE(int64_t, upb_zzencode_64(*ptr));
3072  upb_strview *start = arr->data;
3073  upb_strview *ptr = start + arr->len;
3074  do {
3075  ptr--;
3076  CHK(upb_put_bytes(e, ptr->data, ptr->size) &&
3077  upb_put_varint(e, ptr->size) &&
3078  upb_put_tag(e, f->number, UPB_WIRE_TYPE_DELIMITED));
3079  } while (ptr != start);
3080  return true;
3081  }
3083  void **start = arr->data;
3084  void **ptr = start + arr->len;
3085  const upb_msglayout *subm = m->submsgs[f->submsg_index];
3086  do {
3087  size_t size;
3088  ptr--;
3089  CHK(upb_put_tag(e, f->number, UPB_WIRE_TYPE_END_GROUP) &&
3090  upb_encode_message(e, *ptr, subm, &size) &&
3091  upb_put_tag(e, f->number, UPB_WIRE_TYPE_START_GROUP));
3092  } while (ptr != start);
3093  return true;
3094  }
3096  void **start = arr->data;
3097  void **ptr = start + arr->len;
3098  const upb_msglayout *subm = m->submsgs[f->submsg_index];
3099  do {
3100  size_t size;
3101  ptr--;
3102  CHK(upb_encode_message(e, *ptr, subm, &size) &&
3103  upb_put_varint(e, size) &&
3104  upb_put_tag(e, f->number, UPB_WIRE_TYPE_DELIMITED));
3105  } while (ptr != start);
3106  return true;
3107  }
3108  }
3109 #undef VARINT_CASE
3110 
3111  /* We encode all primitive arrays as packed, regardless of what was specified
3112  * in the .proto file. Could special case 1-sized arrays. */
3113  CHK(upb_put_tag(e, f->number, UPB_WIRE_TYPE_DELIMITED));
3114  return true;
3115 }
3116 
3117 static bool upb_encode_scalarfield(upb_encstate *e, const char *field_mem,
3118  const upb_msglayout *m,
3119  const upb_msglayout_field *f,
3120  bool skip_zero_value) {
3121 #define CASE(ctype, type, wire_type, encodeval) do { \
3122  ctype val = *(ctype*)field_mem; \
3123  if (skip_zero_value && val == 0) { \
3124  return true; \
3125  } \
3126  return upb_put_ ## type(e, encodeval) && \
3127  upb_put_tag(e, f->number, wire_type); \
3128 } while(0)
3129 
3130  switch (f->descriptortype) {
3132  CASE(double, double, UPB_WIRE_TYPE_64BIT, val);
3134  CASE(float, float, UPB_WIRE_TYPE_32BIT, val);
3137  CASE(uint64_t, varint, UPB_WIRE_TYPE_VARINT, val);
3139  CASE(uint32_t, varint, UPB_WIRE_TYPE_VARINT, val);
3142  CASE(int32_t, varint, UPB_WIRE_TYPE_VARINT, (int64_t)val);
3145  CASE(uint64_t, fixed64, UPB_WIRE_TYPE_64BIT, val);
3148  CASE(uint32_t, fixed32, UPB_WIRE_TYPE_32BIT, val);
3150  CASE(bool, varint, UPB_WIRE_TYPE_VARINT, val);
3152  CASE(int32_t, varint, UPB_WIRE_TYPE_VARINT, upb_zzencode_32(val));
3154  CASE(int64_t, varint, UPB_WIRE_TYPE_VARINT, upb_zzencode_64(val));
3157  upb_strview view = *(upb_strview*)field_mem;
3158  if (skip_zero_value && view.size == 0) {
3159  return true;
3160  }
3161  return upb_put_bytes(e, view.data, view.size) &&
3162  upb_put_varint(e, view.size) &&
3163  upb_put_tag(e, f->number, UPB_WIRE_TYPE_DELIMITED);
3164  }
3166  size_t size;
3167  void *submsg = *(void **)field_mem;
3168  const upb_msglayout *subm = m->submsgs[f->submsg_index];
3169  if (submsg == NULL) {
3170  return true;
3171  }
3172  return upb_put_tag(e, f->number, UPB_WIRE_TYPE_END_GROUP) &&
3173  upb_encode_message(e, submsg, subm, &size) &&
3175  }
3177  size_t size;
3178  void *submsg = *(void **)field_mem;
3179  const upb_msglayout *subm = m->submsgs[f->submsg_index];
3180  if (submsg == NULL) {
3181  return true;
3182  }
3183  return upb_encode_message(e, submsg, subm, &size) &&
3184  upb_put_varint(e, size) &&
3185  upb_put_tag(e, f->number, UPB_WIRE_TYPE_DELIMITED);
3186  }
3187  }
3188 #undef CASE
3189  UPB_UNREACHABLE();
3190 }
3191 
3192 bool upb_encode_message(upb_encstate *e, const char *msg,
3193  const upb_msglayout *m, size_t *size) {
3194  int i;
3195  size_t pre_len = e->limit - e->ptr;
3196  const char *unknown;
3197  size_t unknown_size;
3198 
3199  for (i = m->field_count - 1; i >= 0; i--) {
3200  const upb_msglayout_field *f = &m->fields[i];
3201 
3202  if (f->label == UPB_LABEL_REPEATED) {
3203  CHK(upb_encode_array(e, msg + f->offset, m, f));
3204  } else {
3205  bool skip_empty = false;
3206  if (f->presence == 0) {
3207  /* Proto3 presence. */
3208  skip_empty = true;
3209  } else if (f->presence > 0) {
3210  /* Proto2 presence: hasbit. */
3211  if (!upb_readhasbit(msg, f)) {
3212  continue;
3213  }
3214  } else {
3215  /* Field is in a oneof. */
3216  if (upb_readcase(msg, f) != f->number) {
3217  continue;
3218  }
3219  }
3220  CHK(upb_encode_scalarfield(e, msg + f->offset, m, f, skip_empty));
3221  }
3222  }
3223 
3224  unknown = upb_msg_getunknown(msg, &unknown_size);
3225 
3226  if (unknown) {
3227  upb_put_bytes(e, unknown, unknown_size);
3228  }
3229 
3230  *size = (e->limit - e->ptr) - pre_len;
3231  return true;
3232 }
3233 
3234 char *upb_encode(const void *msg, const upb_msglayout *m, upb_arena *arena,
3235  size_t *size) {
3236  upb_encstate e;
3237  e.alloc = upb_arena_alloc(arena);
3238  e.buf = NULL;
3239  e.limit = NULL;
3240  e.ptr = NULL;
3241 
3242  if (!upb_encode_message(&e, msg, m, size)) {
3243  *size = 0;
3244  return NULL;
3245  }
3246 
3247  *size = e.limit - e.ptr;
3248 
3249  if (*size == 0) {
3250  static char ch;
3251  return &ch;
3252  } else {
3253  UPB_ASSERT(e.ptr);
3254  return e.ptr;
3255  }
3256 }
3257 
3258 #undef CHK
3259 /*
3260 ** TODO(haberman): it's unclear whether a lot of the consistency checks should
3261 ** UPB_ASSERT() or return false.
3262 */
3263 
3264 
3265 #include <string.h>
3266 
3267 
3268 
3271  const upb_msgdef *msg;
3273  const void *top_closure_type;
3274  upb_handlers_tabent table[1]; /* Dynamically-sized field handler array. */
3275 };
3276 
3277 static void *upb_calloc(upb_arena *arena, size_t size) {
3278  void *mem = upb_malloc(upb_arena_alloc(arena), size);
3279  if (mem) {
3280  memset(mem, 0, size);
3281  }
3282  return mem;
3283 }
3284 
3285 /* Defined for the sole purpose of having a unique pointer value for
3286  * UPB_NO_CLOSURE. */
3288 
3289 /* Given a selector for a STARTSUBMSG handler, resolves to a pointer to the
3290  * subhandlers for this submessage field. */
3291 #define SUBH(h, selector) (h->sub[selector])
3292 
3293 /* The selector for a submessage field is the field index. */
3294 #define SUBH_F(h, f) SUBH(h, upb_fielddef_index(f))
3295 
3296 static int32_t trygetsel(upb_handlers *h, const upb_fielddef *f,
3298  upb_selector_t sel;
3299  bool ok;
3300 
3301  ok = upb_handlers_getselector(f, type, &sel);
3302 
3304  UPB_ASSERT(ok);
3305 
3306  return sel;
3307 }
3308 
3311  int32_t sel = trygetsel(h, f, type);
3312  UPB_ASSERT(sel >= 0);
3313  return sel;
3314 }
3315 
3316 static const void **returntype(upb_handlers *h, const upb_fielddef *f,
3318  return &h->table[handlers_getsel(h, f, type)].attr.return_closure_type;
3319 }
3320 
3321 static bool doset(upb_handlers *h, int32_t sel, const upb_fielddef *f,
3323  const upb_handlerattr *attr) {
3325  const void *closure_type;
3326  const void **context_closure_type;
3327 
3328  UPB_ASSERT(!h->table[sel].func);
3329 
3330  if (attr) {
3331  set_attr = *attr;
3332  }
3333 
3334  /* Check that the given closure type matches the closure type that has been
3335  * established for this context (if any). */
3336  closure_type = set_attr.closure_type;
3337 
3338  if (type == UPB_HANDLER_STRING) {
3339  context_closure_type = returntype(h, f, UPB_HANDLER_STARTSTR);
3340  } else if (f && upb_fielddef_isseq(f) &&
3342  type != UPB_HANDLER_ENDSEQ) {
3343  context_closure_type = returntype(h, f, UPB_HANDLER_STARTSEQ);
3344  } else {
3345  context_closure_type = &h->top_closure_type;
3346  }
3347 
3348  if (closure_type && *context_closure_type &&
3349  closure_type != *context_closure_type) {
3350  return false;
3351  }
3352 
3353  if (closure_type)
3354  *context_closure_type = closure_type;
3355 
3356  /* If this is a STARTSEQ or STARTSTR handler, check that the returned pointer
3357  * matches any pre-existing expectations about what type is expected. */
3359  const void *return_type = set_attr.return_closure_type;
3360  const void *table_return_type = h->table[sel].attr.return_closure_type;
3361  if (return_type && table_return_type && return_type != table_return_type) {
3362  return false;
3363  }
3364 
3365  if (table_return_type && !return_type) {
3366  set_attr.return_closure_type = table_return_type;
3367  }
3368  }
3369 
3370  h->table[sel].func = (upb_func*)func;
3371  h->table[sel].attr = set_attr;
3372  return true;
3373 }
3374 
3375 /* Returns the effective closure type for this handler (which will propagate
3376  * from outer frames if this frame has no START* handler). Not implemented for
3377  * UPB_HANDLER_STRING at the moment since this is not needed. Returns NULL is
3378  * the effective closure type is unspecified (either no handler was registered
3379  * to specify it or the handler that was registered did not specify the closure
3380  * type). */
3383  const void *ret;
3384  upb_selector_t sel;
3385 
3387  ret = h->top_closure_type;
3388 
3389  if (upb_fielddef_isseq(f) &&
3391  type != UPB_HANDLER_ENDSEQ &&
3392  h->table[sel = handlers_getsel(h, f, UPB_HANDLER_STARTSEQ)].func) {
3393  ret = h->table[sel].attr.return_closure_type;
3394  }
3395 
3396  if (type == UPB_HANDLER_STRING &&
3397  h->table[sel = handlers_getsel(h, f, UPB_HANDLER_STARTSTR)].func) {
3398  ret = h->table[sel].attr.return_closure_type;
3399  }
3400 
3401  /* The effective type of the submessage; not used yet.
3402  * if (type == SUBMESSAGE &&
3403  * h->table[sel = handlers_getsel(h, f, UPB_HANDLER_STARTSUBMSG)].func) {
3404  * ret = h->table[sel].attr.return_closure_type;
3405  * } */
3406 
3407  return ret;
3408 }
3409 
3410 /* Checks whether the START* handler specified by f & type is missing even
3411  * though it is required to convert the established type of an outer frame
3412  * ("closure_type") into the established type of an inner frame (represented in
3413  * the return closure type of this handler's attr. */
3415  upb_status *status) {
3416  const void *closure_type;
3417  const upb_handlerattr *attr;
3418  const void *return_closure_type;
3419 
3421  if (h->table[sel].func) return true;
3422  closure_type = effective_closure_type(h, f, type);
3423  attr = &h->table[sel].attr;
3424  return_closure_type = attr->return_closure_type;
3425  if (closure_type && return_closure_type &&
3426  closure_type != return_closure_type) {
3427  return false;
3428  }
3429  return true;
3430 }
3431 
3433  upb_handlercache *cache,
3434  upb_arena *arena) {
3435  int extra;
3436  upb_handlers *h;
3437 
3438  extra = sizeof(upb_handlers_tabent) * (upb_msgdef_selectorcount(md) - 1);
3439  h = upb_calloc(arena, sizeof(*h) + extra);
3440  if (!h) return NULL;
3441 
3442  h->cache = cache;
3443  h->msg = md;
3444 
3445  if (upb_msgdef_submsgfieldcount(md) > 0) {
3446  size_t bytes = upb_msgdef_submsgfieldcount(md) * sizeof(*h->sub);
3447  h->sub = upb_calloc(arena, bytes);
3448  if (!h->sub) return NULL;
3449  } else {
3450  h->sub = 0;
3451  }
3452 
3453  /* calloc() above initialized all handlers to NULL. */
3454  return h;
3455 }
3456 
3457 /* Public interface ***********************************************************/
3458 
3459 #define SETTER(name, handlerctype, handlertype) \
3460  bool upb_handlers_set##name(upb_handlers *h, const upb_fielddef *f, \
3461  handlerctype func, \
3462  const upb_handlerattr *attr) { \
3463  int32_t sel = trygetsel(h, f, handlertype); \
3464  return doset(h, sel, f, handlertype, (upb_func *)func, attr); \
3465  }
3466 
3481 
3482 #undef SETTER
3483 
3485  const upb_handlerattr *attr) {
3487  (upb_func *)func, attr);
3488 }
3489 
3491  const upb_handlerattr *attr) {
3493  (upb_func *)func, attr);
3494 }
3495 
3497  const upb_handlerattr *attr) {
3499  (upb_func *)func, attr);
3500 }
3501 
3503  const upb_handlers *sub) {
3504  UPB_ASSERT(sub);
3506  if (SUBH_F(h, f)) return false; /* Can't reset. */
3508  return false;
3509  }
3510  SUBH_F(h, f) = sub;
3511  return true;
3512 }
3513 
3515  const upb_fielddef *f) {
3517  return SUBH_F(h, f);
3518 }
3519 
3521  const void **handler_data) {
3522  upb_func *ret = (upb_func *)h->table[s].func;
3523  if (ret && handler_data) {
3524  *handler_data = h->table[s].attr.handler_data;
3525  }
3526  return ret;
3527 }
3528 
3530  upb_handlerattr *attr) {
3531  if (!upb_handlers_gethandler(h, sel, NULL))
3532  return false;
3533  *attr = h->table[sel].attr;
3534  return true;
3535 }
3536 
3538  upb_selector_t sel) {
3539  /* STARTSUBMSG selector in sel is the field's selector base. */
3540  return SUBH(h, sel - UPB_STATIC_SELECTOR_COUNT);
3541 }
3542 
3543 const upb_msgdef *upb_handlers_msgdef(const upb_handlers *h) { return h->msg; }
3544 
3546  return upb_handlercache_addcleanup(h->cache, p, func);
3547 }
3548 
3550  switch (upb_fielddef_type(f)) {
3551  case UPB_TYPE_INT32:
3552  case UPB_TYPE_ENUM: return UPB_HANDLER_INT32;
3553  case UPB_TYPE_INT64: return UPB_HANDLER_INT64;
3554  case UPB_TYPE_UINT32: return UPB_HANDLER_UINT32;
3555  case UPB_TYPE_UINT64: return UPB_HANDLER_UINT64;
3556  case UPB_TYPE_FLOAT: return UPB_HANDLER_FLOAT;
3557  case UPB_TYPE_DOUBLE: return UPB_HANDLER_DOUBLE;
3558  case UPB_TYPE_BOOL: return UPB_HANDLER_BOOL;
3559  default: UPB_ASSERT(false); return -1; /* Invalid input. */
3560  }
3561 }
3562 
3564  upb_selector_t *s) {
3565  uint32_t selector_base = upb_fielddef_selectorbase(f);
3566  switch (type) {
3567  case UPB_HANDLER_INT32:
3568  case UPB_HANDLER_INT64:
3569  case UPB_HANDLER_UINT32:
3570  case UPB_HANDLER_UINT64:
3571  case UPB_HANDLER_FLOAT:
3572  case UPB_HANDLER_DOUBLE:
3573  case UPB_HANDLER_BOOL:
3574  if (!upb_fielddef_isprimitive(f) ||
3576  return false;
3577  *s = selector_base;
3578  break;
3579  case UPB_HANDLER_STRING:
3580  if (upb_fielddef_isstring(f)) {
3581  *s = selector_base;
3582  } else if (upb_fielddef_lazy(f)) {
3583  *s = selector_base + 3;
3584  } else {
3585  return false;
3586  }
3587  break;
3588  case UPB_HANDLER_STARTSTR:
3590  *s = selector_base + 1;
3591  } else {
3592  return false;
3593  }
3594  break;
3595  case UPB_HANDLER_ENDSTR:
3597  *s = selector_base + 2;
3598  } else {
3599  return false;
3600  }
3601  break;
3602  case UPB_HANDLER_STARTSEQ:
3603  if (!upb_fielddef_isseq(f)) return false;
3604  *s = selector_base - 2;
3605  break;
3606  case UPB_HANDLER_ENDSEQ:
3607  if (!upb_fielddef_isseq(f)) return false;
3608  *s = selector_base - 1;
3609  break;
3611  if (!upb_fielddef_issubmsg(f)) return false;
3612  /* Selectors for STARTSUBMSG are at the beginning of the table so that the
3613  * selector can also be used as an index into the "sub" array of
3614  * subhandlers. The indexes for the two into these two tables are the
3615  * same, except that in the handler table the static selectors come first. */
3617  break;
3618  case UPB_HANDLER_ENDSUBMSG:
3619  if (!upb_fielddef_issubmsg(f)) return false;
3620  *s = selector_base;
3621  break;
3622  }
3624  return true;
3625 }
3626 
3628  return upb_fielddef_isseq(f) ? 2 : 0;
3629 }
3630 
3632  uint32_t ret = 1;
3633  if (upb_fielddef_isseq(f)) ret += 2; /* STARTSEQ/ENDSEQ */
3634  if (upb_fielddef_isstring(f)) ret += 2; /* [STRING]/STARTSTR/ENDSTR */
3635  if (upb_fielddef_issubmsg(f)) {
3636  /* ENDSUBMSG (STARTSUBMSG is at table beginning) */
3637  ret += 0;
3638  if (upb_fielddef_lazy(f)) {
3639  /* STARTSTR/ENDSTR/STRING (for lazy) */
3640  ret += 3;
3641  }
3642  }
3643  return ret;
3644 }
3645 
3646 /* upb_handlercache ***********************************************************/
3647 
3650  upb_inttable tab; /* maps upb_msgdef* -> upb_handlers*. */
3652  const void *closure;
3653 };
3654 
3656  const upb_msgdef *md) {
3658  upb_value v;
3659  upb_handlers *h;
3660 
3661  if (upb_inttable_lookupptr(&c->tab, md, &v)) {
3662  return upb_value_getptr(v);
3663  }
3664 
3665  h = upb_handlers_new(md, c, c->arena);
3666  v = upb_value_ptr(h);
3667 
3668  if (!h) return NULL;
3669  if (!upb_inttable_insertptr(&c->tab, md, v)) return NULL;
3670 
3671  c->callback(c->closure, h);
3672 
3673  /* For each submessage field, get or create a handlers object and set it as
3674  * the subhandlers. */
3675  for(upb_msg_field_begin(&i, md);
3676  !upb_msg_field_done(&i);
3677  upb_msg_field_next(&i)) {
3679 
3680  if (upb_fielddef_issubmsg(f)) {
3681  const upb_msgdef *subdef = upb_fielddef_msgsubdef(f);
3682  const upb_handlers *sub_mh = upb_handlercache_get(c, subdef);
3683 
3684  if (!sub_mh) return NULL;
3685 
3686  upb_handlers_setsubhandlers(h, f, sub_mh);
3687  }
3688  }
3689 
3690  return h;
3691 }
3692 
3693 
3695  const void *closure) {
3696  upb_handlercache *cache = upb_gmalloc(sizeof(*cache));
3697 
3698  if (!cache) return NULL;
3699 
3700  cache->arena = upb_arena_new();
3701 
3702  cache->callback = callback;
3703  cache->closure = closure;
3704 
3705  if (!upb_inttable_init(&cache->tab, UPB_CTYPE_PTR)) goto oom;
3706 
3707  return cache;
3708 
3709 oom:
3710  upb_gfree(cache);
3711  return NULL;
3712 }
3713 
3715  upb_inttable_uninit(&cache->tab);
3716  upb_arena_free(cache->arena);
3717  upb_gfree(cache);
3718 }
3719 
3721  upb_handlerfree *func) {
3722  return upb_arena_addcleanup(c->arena, p, func);
3723 }
3724 
3725 /* upb_byteshandler ***********************************************************/
3726 
3728  upb_startstr_handlerfunc *func, void *d) {
3729  h->table[UPB_STARTSTR_SELECTOR].func = (upb_func*)func;
3730  h->table[UPB_STARTSTR_SELECTOR].attr.handler_data = d;
3731  return true;
3732 }
3733 
3735  upb_string_handlerfunc *func, void *d) {
3736  h->table[UPB_STRING_SELECTOR].func = (upb_func*)func;
3737  h->table[UPB_STRING_SELECTOR].attr.handler_data = d;
3738  return true;
3739 }
3740 
3742  upb_endfield_handlerfunc *func, void *d) {
3743  h->table[UPB_ENDSTR_SELECTOR].func = (upb_func*)func;
3744  h->table[UPB_ENDSTR_SELECTOR].attr.handler_data = d;
3745  return true;
3746 }
3747 
3750 typedef struct {
3751  size_t offset;
3752  int32_t hasbit;
3754 
3755 /* Fallback implementation if the handler is not specialized by the producer. */
3756 #define MSG_WRITER(type, ctype) \
3757  bool upb_msg_set ## type (void *c, const void *hd, ctype val) { \
3758  uint8_t *m = c; \
3759  const upb_msg_handlerdata *d = hd; \
3760  if (d->hasbit > 0) \
3761  *(uint8_t*)&m[d->hasbit / 8] |= 1 << (d->hasbit % 8); \
3762  *(ctype*)&m[d->offset] = val; \
3763  return true; \
3764  } \
3765 
3766 MSG_WRITER(double, double)
3767 MSG_WRITER(float, float)
3768 MSG_WRITER(int32, int32_t)
3769 MSG_WRITER(int64, int64_t)
3770 MSG_WRITER(uint32, uint32_t)
3771 MSG_WRITER(uint64, uint64_t)
3772 MSG_WRITER(bool, bool)
3773 
3775  size_t offset, int32_t hasbit) {
3777  bool ok;
3778 
3779  upb_msg_handlerdata *d = upb_gmalloc(sizeof(*d));
3780  if (!d) return false;
3781  d->offset = offset;
3782  d->hasbit = hasbit;
3783 
3784  attr.handler_data = d;
3785  attr.alwaysok = true;
3787 
3788 #define TYPE(u, l) \
3789  case UPB_TYPE_##u: \
3790  ok = upb_handlers_set##l(h, f, upb_msg_set##l, &attr); break;
3791 
3792  ok = false;
3793 
3794  switch (upb_fielddef_type(f)) {
3795  TYPE(INT64, int64);
3796  TYPE(INT32, int32);
3797  TYPE(ENUM, int32);
3798  TYPE(UINT64, uint64);
3799  TYPE(UINT32, uint32);
3800  TYPE(DOUBLE, double);
3801  TYPE(FLOAT, float);
3802  TYPE(BOOL, bool);
3803  default: UPB_ASSERT(false); break;
3804  }
3805 #undef TYPE
3806 
3807  return ok;
3808 }
3809 
3811  upb_selector_t s,
3813  size_t *offset,
3814  int32_t *hasbit) {
3815  const upb_msg_handlerdata *d;
3816  const void *p;
3818 
3819  if ((upb_int64_handlerfunc*)f == upb_msg_setint64) {
3820  *type = UPB_TYPE_INT64;
3821  } else if ((upb_int32_handlerfunc*)f == upb_msg_setint32) {
3822  *type = UPB_TYPE_INT32;
3823  } else if ((upb_uint64_handlerfunc*)f == upb_msg_setuint64) {
3824  *type = UPB_TYPE_UINT64;
3825  } else if ((upb_uint32_handlerfunc*)f == upb_msg_setuint32) {
3826  *type = UPB_TYPE_UINT32;
3827  } else if ((upb_double_handlerfunc*)f == upb_msg_setdouble) {
3828  *type = UPB_TYPE_DOUBLE;
3829  } else if ((upb_float_handlerfunc*)f == upb_msg_setfloat) {
3830  *type = UPB_TYPE_FLOAT;
3831  } else if ((upb_bool_handlerfunc*)f == upb_msg_setbool) {
3832  *type = UPB_TYPE_BOOL;
3833  } else {
3834  return false;
3835  }
3836 
3837  d = p;
3838  *offset = d->offset;
3839  *hasbit = d->hasbit;
3840  return true;
3841 }
3842 
3843 #include <string.h>
3844 
3846  return type == UPB_TYPE_BOOL || type == UPB_TYPE_INT32 ||
3849 }
3850 
3851 #define PTR_AT(msg, ofs, type) (type*)((char*)msg + ofs)
3852 #define VOIDPTR_AT(msg, ofs) PTR_AT(msg, ofs, void)
3853 #define ENCODE_MAX_NESTING 64
3854 #define CHECK_TRUE(x) if (!(x)) { return false; }
3855 
3858 /* These functions will generate real memcpy() calls on ARM sadly, because
3859  * the compiler assumes they might not be aligned. */
3860 
3861 static upb_msgval upb_msgval_read(const void *p, size_t ofs,
3862  uint8_t size) {
3863  upb_msgval val;
3864  p = (char*)p + ofs;
3865  memcpy(&val, p, size);
3866  return val;
3867 }
3868 
3869 static void upb_msgval_write(void *p, size_t ofs, upb_msgval val,
3870  uint8_t size) {
3871  p = (char*)p + ofs;
3872  memcpy(p, &val, size);
3873 }
3874 
3876  switch (type) {
3877  case UPB_TYPE_DOUBLE:
3878  case UPB_TYPE_INT64:
3879  case UPB_TYPE_UINT64:
3880  return 8;
3881  case UPB_TYPE_ENUM:
3882  case UPB_TYPE_INT32:
3883  case UPB_TYPE_UINT32:
3884  case UPB_TYPE_FLOAT:
3885  return 4;
3886  case UPB_TYPE_BOOL:
3887  return 1;
3888  case UPB_TYPE_MESSAGE:
3889  return sizeof(void*);
3890  case UPB_TYPE_BYTES:
3891  case UPB_TYPE_STRING:
3892  return sizeof(upb_strview);
3893  }
3894  UPB_UNREACHABLE();
3895 }
3896 
3898  if (field->label == UPB_LABEL_REPEATED) {
3899  return sizeof(void*);
3900  } else {
3901  return upb_msgval_sizeof(upb_desctype_to_fieldtype[field->descriptortype]);
3902  }
3903 }
3904 
3905 /* TODO(haberman): this is broken right now because upb_msgval can contain
3906  * a char* / size_t pair, which is too big for a upb_value. To fix this
3907  * we'll probably need to dynamically allocate a upb_msgval and store a
3908  * pointer to that in the tables for extensions/maps. */
3910  upb_value ret;
3911  UPB_UNUSED(val);
3912  memset(&ret, 0, sizeof(upb_value)); /* XXX */
3913  return ret;
3914 }
3915 
3917  upb_msgval ret;
3918  UPB_UNUSED(val);
3919  memset(&ret, 0, sizeof(upb_msgval)); /* XXX */
3920  return ret;
3921 }
3922 
3924  switch (type) {
3925  case UPB_TYPE_FLOAT: return UPB_CTYPE_FLOAT;
3926  case UPB_TYPE_DOUBLE: return UPB_CTYPE_DOUBLE;
3927  case UPB_TYPE_BOOL: return UPB_CTYPE_BOOL;
3928  case UPB_TYPE_BYTES:
3929  case UPB_TYPE_MESSAGE:
3930  case UPB_TYPE_STRING: return UPB_CTYPE_CONSTPTR;
3931  case UPB_TYPE_ENUM:
3932  case UPB_TYPE_INT32: return UPB_CTYPE_INT32;
3933  case UPB_TYPE_UINT32: return UPB_CTYPE_UINT32;
3934  case UPB_TYPE_INT64: return UPB_CTYPE_INT64;
3935  case UPB_TYPE_UINT64: return UPB_CTYPE_UINT64;
3936  default: UPB_ASSERT(false); return 0;
3937  }
3938 }
3939 
3940 
3943 /* If we always read/write as a consistent type to each address, this shouldn't
3944  * violate aliasing.
3945  */
3946 #define DEREF(msg, ofs, type) *PTR_AT(msg, ofs, type)
3947 
3948 /* Internal members of a upb_msg. We can change this without breaking binary
3949  * compatibility. We put these before the user's data. The user's upb_msg*
3950  * points after the upb_msg_internal. */
3951 
3952 /* Used when a message is not extendable. */
3953 typedef struct {
3954  /* TODO(haberman): use pointer tagging so we we are slim when known unknown
3955  * fields are not present. */
3957  char *unknown;
3958  size_t unknown_len;
3961 
3962 /* Used when a message is extendable. */
3963 typedef struct {
3967 
3968 static int upb_msg_internalsize(const upb_msglayout *l) {
3969  return sizeof(upb_msg_internal) - l->extendable * sizeof(void *);
3970 }
3971 
3973  return VOIDPTR_AT(msg, -sizeof(upb_msg_internal));
3974 }
3975 
3977  return VOIDPTR_AT(msg, -sizeof(upb_msg_internal));
3978 }
3979 
3981  upb_msg *msg, const upb_msglayout *l) {
3982  UPB_ASSERT(l->extendable);
3983  return VOIDPTR_AT(msg, -sizeof(upb_msg_internal_withext));
3984 }
3985 
3986 void upb_msg_addunknown(upb_msg *msg, const char *data, size_t len) {
3988  if (len > in->unknown_size - in->unknown_len) {
3989  upb_alloc *alloc = upb_arena_alloc(in->arena);
3990  size_t need = in->unknown_size + len;
3991  size_t newsize = UPB_MAX(in->unknown_size * 2, need);
3992  in->unknown = upb_realloc(alloc, in->unknown, in->unknown_size, newsize);
3993  in->unknown_size = newsize;
3994  }
3995  memcpy(in->unknown + in->unknown_len, data, len);
3996  in->unknown_len += len;
3997 }
3998 
3999 const char *upb_msg_getunknown(const upb_msg *msg, size_t *len) {
4001  *len = in->unknown_len;
4002  return in->unknown;
4003 }
4004 
4005 static const upb_msglayout_field *upb_msg_checkfield(int field_index,
4006  const upb_msglayout *l) {
4007  UPB_ASSERT(field_index >= 0 && field_index < l->field_count);
4008  return &l->fields[field_index];
4009 }
4010 
4012  return field->presence < 0;
4013 }
4014 
4015 static uint32_t *upb_msg_oneofcase(const upb_msg *msg, int field_index,
4016  const upb_msglayout *l) {
4017  const upb_msglayout_field *field = upb_msg_checkfield(field_index, l);
4019  return PTR_AT(msg, ~field->presence, uint32_t);
4020 }
4021 
4022 static size_t upb_msg_sizeof(const upb_msglayout *l) {
4023  return l->size + upb_msg_internalsize(l);
4024 }
4025 
4027  upb_alloc *alloc = upb_arena_alloc(a);
4028  void *mem = upb_malloc(alloc, upb_msg_sizeof(l));
4029  upb_msg_internal *in;
4030  upb_msg *msg;
4031 
4032  if (!mem) {
4033  return NULL;
4034  }
4035 
4036  msg = VOIDPTR_AT(mem, upb_msg_internalsize(l));
4037 
4038  /* Initialize normal members. */
4039  memset(msg, 0, l->size);
4040 
4041  /* Initialize internal members. */
4042  in = upb_msg_getinternal(msg);
4043  in->arena = a;
4044  in->unknown = NULL;
4045  in->unknown_len = 0;
4046  in->unknown_size = 0;
4047 
4048  if (l->extendable) {
4050  }
4051 
4052  return msg;
4053 }
4054 
4056  return upb_msg_getinternal_const(msg)->arena;
4057 }
4058 
4059 bool upb_msg_has(const upb_msg *msg,
4060  int field_index,
4061  const upb_msglayout *l) {
4062  const upb_msglayout_field *field = upb_msg_checkfield(field_index, l);
4063 
4064  UPB_ASSERT(field->presence);
4065 
4066  if (upb_msg_inoneof(field)) {
4067  /* Oneofs are set when the oneof number is set to this field. */
4068  return *upb_msg_oneofcase(msg, field_index, l) == field->number;
4069  } else {
4070  /* Other fields are set when their hasbit is set. */
4071  uint32_t hasbit = field->presence;
4072  return DEREF(msg, hasbit / 8, char) | (1 << (hasbit % 8));
4073  }
4074 }
4075 
4076 upb_msgval upb_msg_get(const upb_msg *msg, int field_index,
4077  const upb_msglayout *l) {
4078  const upb_msglayout_field *field = upb_msg_checkfield(field_index, l);
4079  int size = upb_msg_fieldsize(field);
4080  return upb_msgval_read(msg, field->offset, size);
4081 }
4082 
4083 void upb_msg_set(upb_msg *msg, int field_index, upb_msgval val,
4084  const upb_msglayout *l) {
4085  const upb_msglayout_field *field = upb_msg_checkfield(field_index, l);
4086  int size = upb_msg_fieldsize(field);
4087  upb_msgval_write(msg, field->offset, val, size);
4088 }
4089 
4090 
4093 #define DEREF_ARR(arr, i, type) ((type*)arr->data)[i]
4094 
4096  upb_alloc *alloc = upb_arena_alloc(a);
4097  upb_array *ret = upb_malloc(alloc, sizeof(upb_array));
4098 
4099  if (!ret) {
4100  return NULL;
4101  }
4102 
4103  ret->type = type;
4104  ret->data = NULL;
4105  ret->len = 0;
4106  ret->size = 0;
4108  ret->arena = a;
4109 
4110  return ret;
4111 }
4112 
4113 size_t upb_array_size(const upb_array *arr) {
4114  return arr->len;
4115 }
4116 
4118  return arr->type;
4119 }
4120 
4121 upb_msgval upb_array_get(const upb_array *arr, size_t i) {
4122  UPB_ASSERT(i < arr->len);
4123  return upb_msgval_read(arr->data, i * arr->element_size, arr->element_size);
4124 }
4125 
4126 bool upb_array_set(upb_array *arr, size_t i, upb_msgval val) {
4127  UPB_ASSERT(i <= arr->len);
4128 
4129  if (i == arr->len) {
4130  /* Extending the array. */
4131 
4132  if (i == arr->size) {
4133  /* Need to reallocate. */
4134  size_t new_size = UPB_MAX(arr->size * 2, 8);
4135  size_t new_bytes = new_size * arr->element_size;
4136  size_t old_bytes = arr->size * arr->element_size;
4137  upb_alloc *alloc = upb_arena_alloc(arr->arena);
4138  upb_msgval *new_data =
4139  upb_realloc(alloc, arr->data, old_bytes, new_bytes);
4140 
4141  if (!new_data) {
4142  return false;
4143  }
4144 
4145  arr->data = new_data;
4146  arr->size = new_size;
4147  }
4148 
4149  arr->len = i + 1;
4150  }
4151 
4152  upb_msgval_write(arr->data, i * arr->element_size, val, arr->element_size);
4153  return true;
4154 }
4155 
4156 
4159 struct upb_map {
4162  /* We may want to optimize this to use inttable where possible, for greater
4163  * efficiency and lower memory footprint. */
4166 };
4167 
4169  const char **out_key, size_t *out_len) {
4170  switch (type) {
4171  case UPB_TYPE_STRING:
4172  /* Point to string data of the input key. */
4173  *out_key = key->str.data;
4174  *out_len = key->str.size;
4175  return;
4176  case UPB_TYPE_BOOL:
4177  case UPB_TYPE_INT32:
4178  case UPB_TYPE_UINT32:
4179  case UPB_TYPE_INT64:
4180  case UPB_TYPE_UINT64:
4181  /* Point to the key itself. XXX: big-endian. */
4182  *out_key = (const char*)key;
4183  *out_len = upb_msgval_sizeof(type);
4184  return;
4185  case UPB_TYPE_BYTES:
4186  case UPB_TYPE_DOUBLE:
4187  case UPB_TYPE_ENUM:
4188  case UPB_TYPE_FLOAT:
4189  case UPB_TYPE_MESSAGE:
4190  break; /* Cannot be a map key. */
4191  }
4192  UPB_UNREACHABLE();
4193 }
4194 
4196  size_t len) {
4197  switch (type) {
4198  case UPB_TYPE_STRING:
4199  return upb_msgval_makestr(key, len);
4200  case UPB_TYPE_BOOL:
4201  case UPB_TYPE_INT32:
4202  case UPB_TYPE_UINT32:
4203  case UPB_TYPE_INT64:
4204  case UPB_TYPE_UINT64:
4206  case UPB_TYPE_BYTES:
4207  case UPB_TYPE_DOUBLE:
4208  case UPB_TYPE_ENUM:
4209  case UPB_TYPE_FLOAT:
4210  case UPB_TYPE_MESSAGE:
4211  break; /* Cannot be a map key. */
4212  }
4213  UPB_UNREACHABLE();
4214 }
4215 
4217  upb_arena *a) {
4218  upb_ctype_t vtabtype = upb_fieldtotabtype(vtype);
4219  upb_alloc *alloc = upb_arena_alloc(a);
4220  upb_map *map = upb_malloc(alloc, sizeof(upb_map));
4221 
4222  if (!map) {
4223  return NULL;
4224  }
4225 
4227  map->key_type = ktype;
4228  map->val_type = vtype;
4229  map->arena = a;
4230 
4231  if (!upb_strtable_init2(&map->strtab, vtabtype, alloc)) {
4232  return NULL;
4233  }
4234 
4235  return map;
4236 }
4237 
4238 size_t upb_map_size(const upb_map *map) {
4239  return upb_strtable_count(&map->strtab);
4240 }
4241 
4243  return map->key_type;
4244 }
4245 
4247  return map->val_type;
4248 }
4249 
4251  upb_value tabval;
4252  const char *key_str;
4253  size_t key_len;
4254  bool ret;
4255 
4256  upb_map_tokey(map->key_type, &key, &key_str, &key_len);
4257  ret = upb_strtable_lookup2(&map->strtab, key_str, key_len, &tabval);
4258  if (ret) {
4259  memcpy(val, &tabval, sizeof(tabval));
4260  }
4261 
4262  return ret;
4263 }
4264 
4266  upb_msgval *removed) {
4267  const char *key_str;
4268  size_t key_len;
4269  upb_value tabval = upb_toval(val);
4270  upb_value removedtabval;
4271  upb_alloc *a = upb_arena_alloc(map->arena);
4272 
4273  upb_map_tokey(map->key_type, &key, &key_str, &key_len);
4274 
4275  /* TODO(haberman): add overwrite operation to minimize number of lookups. */
4276  if (upb_strtable_lookup2(&map->strtab, key_str, key_len, NULL)) {
4277  upb_strtable_remove3(&map->strtab, key_str, key_len, &removedtabval, a);
4278  memcpy(&removed, &removedtabval, sizeof(removed));
4279  }
4280 
4281  return upb_strtable_insert3(&map->strtab, key_str, key_len, tabval, a);
4282 }
4283 
4285  const char *key_str;
4286  size_t key_len;
4287  upb_alloc *a = upb_arena_alloc(map->arena);
4288 
4289  upb_map_tokey(map->key_type, &key, &key_str, &key_len);
4290  return upb_strtable_remove3(&map->strtab, key_str, key_len, NULL, a);
4291 }
4292 
4293 
4296 struct upb_mapiter {
4299 };
4300 
4302  return sizeof(upb_mapiter);
4303 }
4304 
4306  upb_strtable_begin(&i->iter, &map->strtab);
4307  i->key_type = map->key_type;
4308 }
4309 
4312 
4313  if (!ret) {
4314  return NULL;
4315  }
4316 
4317  upb_mapiter_begin(ret, t);
4318  return ret;
4319 }
4320 
4322  upb_free(a, i);
4323 }
4324 
4326  upb_strtable_next(&i->iter);
4327 }
4328 
4330  return upb_strtable_done(&i->iter);
4331 }
4332 
4334  return upb_map_fromkey(i->key_type, upb_strtable_iter_key(&i->iter),
4335  upb_strtable_iter_keylength(&i->iter));
4336 }
4337 
4340 }
4341 
4343  upb_strtable_iter_setdone(&i->iter);
4344 }
4345 
4346 bool upb_mapiter_isequal(const upb_mapiter *i1, const upb_mapiter *i2) {
4347  return upb_strtable_iter_isequal(&i1->iter, &i2->iter);
4348 }
4349 
4350 
4351 static bool is_power_of_two(size_t val) {
4352  return (val & (val - 1)) == 0;
4353 }
4354 
4355 /* Align up to the given power of 2. */
4356 static size_t align_up(size_t val, size_t align) {
4357  UPB_ASSERT(is_power_of_two(align));
4358  return (val + align - 1) & ~(align - 1);
4359 }
4360 
4361 static size_t div_round_up(size_t n, size_t d) {
4362  return (n + d - 1) / d;
4363 }
4364 
4366  switch (type) {
4367  case UPB_TYPE_DOUBLE:
4368  case UPB_TYPE_INT64:
4369  case UPB_TYPE_UINT64:
4370  return 8;
4371  case UPB_TYPE_ENUM:
4372  case UPB_TYPE_INT32:
4373  case UPB_TYPE_UINT32:
4374  case UPB_TYPE_FLOAT:
4375  return 4;
4376  case UPB_TYPE_BOOL:
4377  return 1;
4378  case UPB_TYPE_MESSAGE:
4379  return sizeof(void*);
4380  case UPB_TYPE_BYTES:
4381  case UPB_TYPE_STRING:
4382  return sizeof(upb_strview);
4383  }
4384  UPB_UNREACHABLE();
4385 }
4386 
4387 static uint8_t upb_msg_fielddefsize(const upb_fielddef *f) {
4388  if (upb_fielddef_isseq(f)) {
4389  return sizeof(void*);
4390  } else {
4392  }
4393 }
4394 
4395 
4399  upb_gfree(l);
4400 }
4401 
4402 static size_t upb_msglayout_place(upb_msglayout *l, size_t size) {
4403  size_t ret;
4404 
4405  l->size = align_up(l->size, size);
4406  ret = l->size;
4407  l->size += size;
4408  return ret;
4409 }
4410 
4411 static bool upb_msglayout_init(const upb_msgdef *m,
4412  upb_msglayout *l,
4413  upb_msgfactory *factory) {
4415  upb_msg_oneof_iter oit;
4416  size_t hasbit;
4417  size_t submsg_count = 0;
4418  const upb_msglayout **submsgs;
4420 
4421  for (upb_msg_field_begin(&it, m);
4423  upb_msg_field_next(&it)) {
4424  const upb_fielddef* f = upb_msg_iter_field(&it);
4425  if (upb_fielddef_issubmsg(f)) {
4426  submsg_count++;
4427  }
4428  }
4429 
4430  memset(l, 0, sizeof(*l));
4431 
4433  submsgs = upb_gmalloc(submsg_count * sizeof(*submsgs));
4434 
4435  if ((!fields && upb_msgdef_numfields(m)) ||
4436  (!submsgs && submsg_count)) {
4437  /* OOM. */
4438  upb_gfree(fields);
4439  upb_gfree(submsgs);
4440  return false;
4441  }
4442 
4444  l->fields = fields;
4445  l->submsgs = submsgs;
4446 
4447  /* Allocate data offsets in three stages:
4448  *
4449  * 1. hasbits.
4450  * 2. regular fields.
4451  * 3. oneof fields.
4452  *
4453  * OPT: There is a lot of room for optimization here to minimize the size.
4454  */
4455 
4456  /* Allocate hasbits and set basic field attributes. */
4457  submsg_count = 0;
4458  for (upb_msg_field_begin(&it, m), hasbit = 0;
4460  upb_msg_field_next(&it)) {
4461  const upb_fielddef* f = upb_msg_iter_field(&it);
4463 
4464  field->number = upb_fielddef_number(f);
4465  field->descriptortype = upb_fielddef_descriptortype(f);
4466  field->label = upb_fielddef_label(f);
4467 
4468  if (upb_fielddef_issubmsg(f)) {
4469  const upb_msglayout *sub_layout =
4471  field->submsg_index = submsg_count++;
4472  submsgs[field->submsg_index] = sub_layout;
4473  }
4474 
4476  field->presence = (hasbit++);
4477  } else {
4478  field->presence = 0;
4479  }
4480  }
4481 
4482  /* Account for space used by hasbits. */
4483  l->size = div_round_up(hasbit, 8);
4484 
4485  /* Allocate non-oneof fields. */
4487  upb_msg_field_next(&it)) {
4488  const upb_fielddef* f = upb_msg_iter_field(&it);
4489  size_t field_size = upb_msg_fielddefsize(f);
4490  size_t index = upb_fielddef_index(f);
4491 
4493  /* Oneofs are handled separately below. */
4494  continue;
4495  }
4496 
4497  fields[index].offset = upb_msglayout_place(l, field_size);
4498  }
4499 
4500  /* Allocate oneof fields. Each oneof field consists of a uint32 for the case
4501  * and space for the actual data. */
4502  for (upb_msg_oneof_begin(&oit, m); !upb_msg_oneof_done(&oit);
4503  upb_msg_oneof_next(&oit)) {
4504  const upb_oneofdef* o = upb_msg_iter_oneof(&oit);
4505  upb_oneof_iter fit;
4506 
4507  size_t case_size = sizeof(uint32_t); /* Could potentially optimize this. */
4508  size_t field_size = 0;
4509  uint32_t case_offset;
4510  uint32_t data_offset;
4511 
4512  /* Calculate field size: the max of all field sizes. */
4513  for (upb_oneof_begin(&fit, o);
4514  !upb_oneof_done(&fit);
4515  upb_oneof_next(&fit)) {
4516  const upb_fielddef* f = upb_oneof_iter_field(&fit);
4517  field_size = UPB_MAX(field_size, upb_msg_fielddefsize(f));
4518  }
4519 
4520  /* Align and allocate case offset. */
4521  case_offset = upb_msglayout_place(l, case_size);
4522  data_offset = upb_msglayout_place(l, field_size);
4523 
4524  for (upb_oneof_begin(&fit, o);
4525  !upb_oneof_done(&fit);
4526  upb_oneof_next(&fit)) {
4527  const upb_fielddef* f = upb_oneof_iter_field(&fit);
4528  fields[upb_fielddef_index(f)].offset = data_offset;
4529  fields[upb_fielddef_index(f)].presence = ~case_offset;
4530  }
4531  }
4532 
4533  /* Size of the entire structure should be a multiple of its greatest
4534  * alignment. TODO: track overall alignment for real? */
4535  l->size = align_up(l->size, 8);
4536 
4537  return true;
4538 }
4539 
4540 
4544  const upb_symtab *symtab; /* We own a ref. */
4546 };
4547 
4549  upb_msgfactory *ret = upb_gmalloc(sizeof(*ret));
4550 
4551  ret->symtab = symtab;
4553 
4554  return ret;
4555 }
4556 
4559  upb_inttable_begin(&i, &f->layouts);
4560  for(; !upb_inttable_done(&i); upb_inttable_next(&i)) {
4561  upb_msglayout *l = upb_value_getptr(upb_inttable_iter_value(&i));
4562  upb_msglayout_free(l);
4563  }
4564 
4565  upb_inttable_uninit(&f->layouts);
4566  upb_gfree(f);
4567 }
4568 
4570  return f->symtab;
4571 }
4572 
4574  const upb_msgdef *m) {
4575  upb_value v;
4578 
4579  if (upb_inttable_lookupptr(&f->layouts, m, &v)) {
4580  UPB_ASSERT(upb_value_getptr(v));
4581  return upb_value_getptr(v);
4582  } else {
4583  /* In case of circular dependency, layout has to be inserted first. */
4584  upb_msglayout *l = upb_gmalloc(sizeof(*l));
4585  upb_msgfactory *mutable_f = (void*)f;
4586  upb_inttable_insertptr(&mutable_f->layouts, m, upb_value_ptr(l));
4587  UPB_ASSERT(l);
4588  if (!upb_msglayout_init(m, l, f)) {
4589  upb_msglayout_free(l);
4590  }
4591  return l;
4592  }
4593 }
4594 
4595 #ifndef UINTPTR_MAX
4596 #error must include stdint.h first
4597 #endif
4598 
4599 #if UINTPTR_MAX == 0xffffffff
4600 #define UPB_SIZE(size32, size64) size32
4601 #else
4602 #define UPB_SIZE(size32, size64) size64
4603 #endif
4604 
4605 #define UPB_FIELD_AT(msg, fieldtype, offset) \
4606  *(fieldtype*)((const char*)(msg) + offset)
4607 
4608 #define UPB_READ_ONEOF(msg, fieldtype, offset, case_offset, case_val, default) \
4609  UPB_FIELD_AT(msg, int, case_offset) == case_val \
4610  ? UPB_FIELD_AT(msg, fieldtype, offset) \
4611  : default
4612 
4613 #define UPB_WRITE_ONEOF(msg, fieldtype, offset, value, case_offset, case_val) \
4614  UPB_FIELD_AT(msg, int, case_offset) = case_val; \
4615  UPB_FIELD_AT(msg, fieldtype, offset) = value;
4616 
4617 #undef UPB_SIZE
4618 #undef UPB_FIELD_AT
4619 #undef UPB_READ_ONEOF
4620 #undef UPB_WRITE_ONEOF
4621 
4622 
4623 bool upb_bufsrc_putbuf(const char *buf, size_t len, upb_bytessink sink) {
4624  void *subc;
4625  bool ret;
4627  handle.buf = buf;
4628  ret = upb_bytessink_start(sink, len, &subc);
4629  if (ret && len != 0) {
4630  ret = (upb_bytessink_putbuf(sink, subc, buf, len, &handle) >= len);
4631  }
4632  if (ret) {
4633  ret = upb_bytessink_end(sink);
4634  }
4635  return ret;
4636 }
4637 /*
4638 ** upb_table Implementation
4639 **
4640 ** Implementation is heavily inspired by Lua's ltable.c.
4641 */
4642 
4643 
4644 #include <string.h>
4645 
4646 #define UPB_MAXARRSIZE 16 /* 64k. */
4647 
4648 /* From Chromium. */
4649 #define ARRAY_SIZE(x) \
4650  ((sizeof(x)/sizeof(0[x])) / ((size_t)(!(sizeof(x) % sizeof(0[x])))))
4651 
4653  UPB_UNUSED(t);
4654  UPB_UNUSED(a);
4655  UPB_ASSERT_DEBUGVAR(t->alloc == a);
4656 }
4657 
4658 static const double MAX_LOAD = 0.85;
4659 
4660 /* The minimum utilization of the array part of a mixed hash/array table. This
4661  * is a speed/memory-usage tradeoff (though it's not straightforward because of
4662  * cache effects). The lower this is, the more memory we'll use. */
4663 static const double MIN_DENSITY = 0.1;
4664 
4665 bool is_pow2(uint64_t v) { return v == 0 || (v & (v - 1)) == 0; }
4666 
4667 int log2ceil(uint64_t v) {
4668  int ret = 0;
4669  bool pow2 = is_pow2(v);
4670  while (v >>= 1) ret++;
4671  ret = pow2 ? ret : ret + 1; /* Ceiling. */
4672  return UPB_MIN(UPB_MAXARRSIZE, ret);
4673 }
4674 
4675 char *upb_strdup(const char *s, upb_alloc *a) {
4676  return upb_strdup2(s, strlen(s), a);
4677 }
4678 
4679 char *upb_strdup2(const char *s, size_t len, upb_alloc *a) {
4680  size_t n;
4681  char *p;
4682 
4683  /* Prevent overflow errors. */
4684  if (len == SIZE_MAX) return NULL;
4685  /* Always null-terminate, even if binary data; but don't rely on the input to
4686  * have a null-terminating byte since it may be a raw binary buffer. */
4687  n = len + 1;
4688  p = upb_malloc(a, n);
4689  if (p) {
4690  memcpy(p, s, len);
4691  p[len] = 0;
4692  }
4693  return p;
4694 }
4695 
4696 /* A type to represent the lookup key of either a strtable or an inttable. */
4697 typedef union {
4698  uintptr_t num;
4699  struct {
4700  const char *str;
4701  size_t len;
4702  } str;
4703 } lookupkey_t;
4704 
4705 static lookupkey_t strkey2(const char *str, size_t len) {
4706  lookupkey_t k;
4707  k.str.str = str;
4708  k.str.len = len;
4709  return k;
4710 }
4711 
4712 static lookupkey_t intkey(uintptr_t key) {
4713  lookupkey_t k;
4714  k.num = key;
4715  return k;
4716 }
4717 
4718 typedef uint32_t hashfunc_t(upb_tabkey key);
4720 
4721 /* Base table (shared code) ***************************************************/
4722 
4723 /* For when we need to cast away const. */
4725  return (upb_tabent*)t->entries;
4726 }
4727 
4728 static bool isfull(upb_table *t) {
4729  if (upb_table_size(t) == 0) {
4730  return true;
4731  } else {
4732  return ((double)(t->count + 1) / upb_table_size(t)) > MAX_LOAD;
4733  }
4734 }
4735 
4736 static bool init(upb_table *t, upb_ctype_t ctype, uint8_t size_lg2,
4737  upb_alloc *a) {
4738  size_t bytes;
4739 
4740  t->count = 0;
4741  t->ctype = ctype;
4742  t->size_lg2 = size_lg2;
4743  t->mask = upb_table_size(t) ? upb_table_size(t) - 1 : 0;
4744 #ifndef NDEBUG
4745  t->alloc = a;
4746 #endif
4747  bytes = upb_table_size(t) * sizeof(upb_tabent);
4748  if (bytes > 0) {
4749  t->entries = upb_malloc(a, bytes);
4750  if (!t->entries) return false;
4751  memset(mutable_entries(t), 0, bytes);
4752  } else {
4753  t->entries = NULL;
4754  }
4755  return true;
4756 }
4757 
4758 static void uninit(upb_table *t, upb_alloc *a) {
4759  upb_check_alloc(t, a);
4760  upb_free(a, mutable_entries(t));
4761 }
4762 
4765  while (1) { if (upb_tabent_isempty(--e)) return e; UPB_ASSERT(e > t->entries); }
4766 }
4767 
4768 static upb_tabent *getentry_mutable(upb_table *t, uint32_t hash) {
4769  return (upb_tabent*)upb_getentry(t, hash);
4770 }
4771 
4773  uint32_t hash, eqlfunc_t *eql) {
4774  const upb_tabent *e;
4775 
4776  if (t->size_lg2 == 0) return NULL;
4777  e = upb_getentry(t, hash);
4778  if (upb_tabent_isempty(e)) return NULL;
4779  while (1) {
4780  if (eql(e->key, key)) return e;
4781  if ((e = e->next) == NULL) return NULL;
4782  }
4783 }
4784 
4786  uint32_t hash, eqlfunc_t *eql) {
4787  return (upb_tabent*)findentry(t, key, hash, eql);
4788 }
4789 
4790 static bool lookup(const upb_table *t, lookupkey_t key, upb_value *v,
4791  uint32_t hash, eqlfunc_t *eql) {
4792  const upb_tabent *e = findentry(t, key, hash, eql);
4793  if (e) {
4794  if (v) {
4795  _upb_value_setval(v, e->val.val, t->ctype);
4796  }
4797  return true;
4798  } else {
4799  return false;
4800  }
4801 }
4802 
4803 /* The given key must not already exist in the table. */
4804 static void insert(upb_table *t, lookupkey_t key, upb_tabkey tabkey,
4805  upb_value val, uint32_t hash,
4806  hashfunc_t *hashfunc, eqlfunc_t *eql) {
4807  upb_tabent *mainpos_e;
4808  upb_tabent *our_e;
4809 
4810  UPB_ASSERT(findentry(t, key, hash, eql) == NULL);
4811  UPB_ASSERT_DEBUGVAR(val.ctype == t->ctype);
4812 
4813  t->count++;
4814  mainpos_e = getentry_mutable(t, hash);
4815  our_e = mainpos_e;
4816 
4817  if (upb_tabent_isempty(mainpos_e)) {
4818  /* Our main position is empty; use it. */
4819  our_e->next = NULL;
4820  } else {
4821  /* Collision. */
4822  upb_tabent *new_e = emptyent(t);
4823  /* Head of collider's chain. */
4824  upb_tabent *chain = getentry_mutable(t, hashfunc(mainpos_e->key));
4825  if (chain == mainpos_e) {
4826  /* Existing ent is in its main posisiton (it has the same hash as us, and
4827  * is the head of our chain). Insert to new ent and append to this chain. */
4828  new_e->next = mainpos_e->next;
4829  mainpos_e->next = new_e;
4830  our_e = new_e;
4831  } else {
4832  /* Existing ent is not in its main position (it is a node in some other
4833  * chain). This implies that no existing ent in the table has our hash.
4834  * Evict it (updating its chain) and use its ent for head of our chain. */
4835  *new_e = *mainpos_e; /* copies next. */
4836  while (chain->next != mainpos_e) {
4837  chain = (upb_tabent*)chain->next;
4838  UPB_ASSERT(chain);
4839  }
4840  chain->next = new_e;
4841  our_e = mainpos_e;
4842  our_e->next = NULL;
4843  }
4844  }
4845  our_e->key = tabkey;
4846  our_e->val.val = val.val;
4847  UPB_ASSERT(findentry(t, key, hash, eql) == our_e);
4848 }
4849 
4851  upb_tabkey *removed, uint32_t hash, eqlfunc_t *eql) {
4852  upb_tabent *chain = getentry_mutable(t, hash);
4853  if (upb_tabent_isempty(chain)) return false;
4854  if (eql(chain->key, key)) {
4855  /* Element to remove is at the head of its chain. */
4856  t->count--;
4857  if (val) _upb_value_setval(val, chain->val.val, t->ctype);
4858  if (removed) *removed = chain->key;
4859  if (chain->next) {
4860  upb_tabent *move = (upb_tabent*)chain->next;
4861  *chain = *move;
4862  move->key = 0; /* Make the slot empty. */
4863  } else {
4864  chain->key = 0; /* Make the slot empty. */
4865  }
4866  return true;
4867  } else {
4868  /* Element to remove is either in a non-head position or not in the
4869  * table. */
4870  while (chain->next && !eql(chain->next->key, key)) {
4871  chain = (upb_tabent*)chain->next;
4872  }
4873  if (chain->next) {
4874  /* Found element to remove. */
4875  upb_tabent *rm = (upb_tabent*)chain->next;
4876  t->count--;
4877  if (val) _upb_value_setval(val, chain->next->val.val, t->ctype);
4878  if (removed) *removed = rm->key;
4879  rm->key = 0; /* Make the slot empty. */
4880  chain->next = rm->next;
4881  return true;
4882  } else {
4883  /* Element to remove is not in the table. */
4884  return false;
4885  }
4886  }
4887 }
4888 
4889 static size_t next(const upb_table *t, size_t i) {
4890  do {
4891  if (++i >= upb_table_size(t))
4892  return SIZE_MAX;
4893  } while(upb_tabent_isempty(&t->entries[i]));
4894 
4895  return i;
4896 }
4897 
4898 static size_t begin(const upb_table *t) {
4899  return next(t, -1);
4900 }
4901 
4902 
4903 /* upb_strtable ***************************************************************/
4904 
4905 /* A simple "subclass" of upb_table that only adds a hash function for strings. */
4906 
4908  uint32_t len = (uint32_t) k2.str.len;
4909  char *str = upb_malloc(a, k2.str.len + sizeof(uint32_t) + 1);
4910  if (str == NULL) return 0;
4911  memcpy(str, &len, sizeof(uint32_t));
4912  memcpy(str + sizeof(uint32_t), k2.str.str, k2.str.len + 1);
4913  return (uintptr_t)str;
4914 }
4915 
4916 static uint32_t strhash(upb_tabkey key) {
4917  uint32_t len;
4918  char *str = upb_tabstr(key, &len);
4919  return MurmurHash2(str, len, 0);
4920 }
4921 
4923  uint32_t len;
4924  char *str = upb_tabstr(k1, &len);
4925  return len == k2.str.len && memcmp(str, k2.str.str, len) == 0;
4926 }
4927 
4929  return init(&t->t, ctype, 2, a);
4930 }
4931 
4933  size_t i;
4934  for (i = 0; i < upb_table_size(&t->t); i++)
4935  upb_free(a, (void*)t->t.entries[i].key);
4936  uninit(&t->t, a);
4937 }
4938 
4939 bool upb_strtable_resize(upb_strtable *t, size_t size_lg2, upb_alloc *a) {
4940  upb_strtable new_table;
4942 
4943  upb_check_alloc(&t->t, a);
4944 
4945  if (!init(&new_table.t, t->t.ctype, size_lg2, a))
4946  return false;
4947  upb_strtable_begin(&i, t);
4948  for ( ; !upb_strtable_done(&i); upb_strtable_next(&i)) {
4950  &new_table,
4954  a);
4955  }
4956  upb_strtable_uninit2(t, a);
4957  *t = new_table;
4958  return true;
4959 }
4960 
4961 bool upb_strtable_insert3(upb_strtable *t, const char *k, size_t len,
4962  upb_value v, upb_alloc *a) {
4963  lookupkey_t key;
4964  upb_tabkey tabkey;
4965  uint32_t hash;
4966 
4967  upb_check_alloc(&t->t, a);
4968 
4969  if (isfull(&t->t)) {
4970  /* Need to resize. New table of double the size, add old elements to it. */
4971  if (!upb_strtable_resize(t, t->t.size_lg2 + 1, a)) {
4972  return false;
4973  }
4974  }
4975 
4976  key = strkey2(k, len);
4977  tabkey = strcopy(key, a);
4978  if (tabkey == 0) return false;
4979 
4980  hash = MurmurHash2(key.str.str, key.str.len, 0);
4981  insert(&t->t, key, tabkey, v, hash, &strhash, &streql);
4982  return true;
4983 }
4984 
4985 bool upb_strtable_lookup2(const upb_strtable *t, const char *key, size_t len,
4986  upb_value *v) {
4987  uint32_t hash = MurmurHash2(key, len, 0);
4988  return lookup(&t->t, strkey2(key, len), v, hash, &streql);
4989 }
4990 
4991 bool upb_strtable_remove3(upb_strtable *t, const char *key, size_t len,
4992  upb_value *val, upb_alloc *alloc) {
4993  uint32_t hash = MurmurHash2(key, len, 0);
4994  upb_tabkey tabkey;
4995  if (rm(&t->t, strkey2(key, len), val, &tabkey, hash, &streql)) {
4996  upb_free(alloc, (void*)tabkey);
4997  return true;
4998  } else {
4999  return false;
5000  }
5001 }
5002 
5003 /* Iteration */
5004 
5005 static const upb_tabent *str_tabent(const upb_strtable_iter *i) {
5006  return &i->t->t.entries[i->index];
5007 }
5008 
5010  i->t = t;
5011  i->index = begin(&t->t);
5012 }
5013 
5015  i->index = next(&i->t->t, i->index);
5016 }
5017 
5019  if (!i->t) return true;
5020  return i->index >= upb_table_size(&i->t->t) ||
5022 }
5023 
5026  return upb_tabstr(str_tabent(i)->key, NULL);
5027 }
5028 
5030  uint32_t len;
5032  upb_tabstr(str_tabent(i)->key, &len);
5033  return len;
5034 }
5035 
5038  return _upb_value_val(str_tabent(i)->val.val, i->t->t.ctype);
5039 }
5040 
5042  i->t = NULL;
5043  i->index = SIZE_MAX;
5044 }
5045 
5047  const upb_strtable_iter *i2) {
5048  if (upb_strtable_done(i1) && upb_strtable_done(i2))
5049  return true;
5050  return i1->t == i2->t && i1->index == i2->index;
5051 }
5052 
5053 
5054 /* upb_inttable ***************************************************************/
5055 
5056 /* For inttables we use a hybrid structure where small keys are kept in an
5057  * array and large keys are put in the hash table. */
5058 
5059 static uint32_t inthash(upb_tabkey key) { return upb_inthash(key); }
5060 
5062  return k1 == k2.num;
5063 }
5064 
5066  return (upb_tabval*)t->array;
5067 }
5068 
5069 static upb_tabval *inttable_val(upb_inttable *t, uintptr_t key) {
5070  if (key < t->array_size) {
5071  return upb_arrhas(t->array[key]) ? &(mutable_array(t)[key]) : NULL;
5072  } else {
5073  upb_tabent *e =
5075  return e ? &e->val : NULL;
5076  }
5077 }
5078 
5080  uintptr_t key) {
5081  return inttable_val((upb_inttable*)t, key);
5082 }
5083 
5085  return t->t.count + t->array_count;
5086 }
5087 
5088 static void check(upb_inttable *t) {
5089  UPB_UNUSED(t);
5090 #if defined(UPB_DEBUG_TABLE) && !defined(NDEBUG)
5091  {
5092  /* This check is very expensive (makes inserts/deletes O(N)). */
5093  size_t count = 0;
5095  upb_inttable_begin(&i, t);
5096  for(; !upb_inttable_done(&i); upb_inttable_next(&i), count++) {
5098  }
5100  }
5101 #endif
5102 }
5103 
5105  size_t asize, int hsize_lg2, upb_alloc *a) {
5106  size_t array_bytes;
5107 
5108  if (!init(&t->t, ctype, hsize_lg2, a)) return false;
5109  /* Always make the array part at least 1 long, so that we know key 0
5110  * won't be in the hash part, which simplifies things. */
5111  t->array_size = UPB_MAX(1, asize);
5112  t->array_count = 0;
5113  array_bytes = t->array_size * sizeof(upb_value);
5114  t->array = upb_malloc(a, array_bytes);
5115  if (!t->array) {
5116  uninit(&t->t, a);
5117  return false;
5118  }
5119  memset(mutable_array(t), 0xff, array_bytes);
5120  check(t);
5121  return true;
5122 }
5123 
5125  return upb_inttable_sizedinit(t, ctype, 0, 4, a);
5126 }
5127 
5129  uninit(&t->t, a);
5130  upb_free(a, mutable_array(t));
5131 }
5132 
5134  upb_alloc *a) {
5135  upb_tabval tabval;
5136  tabval.val = val.val;
5137  UPB_ASSERT(upb_arrhas(tabval)); /* This will reject (uint64_t)-1. Fix this. */
5138 
5139  upb_check_alloc(&t->t, a);
5140 
5141  if (key < t->array_size) {
5142  UPB_ASSERT(!upb_arrhas(t->array[key]));
5143  t->array_count++;
5144  mutable_array(t)[key].val = val.val;
5145  } else {
5146  if (isfull(&t->t)) {
5147  /* Need to resize the hash part, but we re-use the array part. */
5148  size_t i;
5149  upb_table new_table;
5150 
5151  if (!init(&new_table, t->t.ctype, t->t.size_lg2 + 1, a)) {
5152  return false;
5153  }
5154 
5155  for (i = begin(&t->t); i < upb_table_size(&t->t); i = next(&t->t, i)) {
5156  const upb_tabent *e = &t->t.entries[i];
5157  uint32_t hash;
5158  upb_value v;
5159 
5160  _upb_value_setval(&v, e->val.val, t->t.ctype);
5161  hash = upb_inthash(e->key);
5162  insert(&new_table, intkey(e->key), e->key, v, hash, &inthash, &inteql);
5163  }
5164 
5165  UPB_ASSERT(t->t.count == new_table.count);
5166 
5167  uninit(&t->t, a);
5168  t->t = new_table;
5169  }
5170  insert(&t->t, intkey(key), key, val, upb_inthash(key), &inthash, &inteql);
5171  }
5172  check(t);
5173  return true;
5174 }
5175 
5176 bool upb_inttable_lookup(const upb_inttable *t, uintptr_t key, upb_value *v) {
5177  const upb_tabval *table_v = inttable_val_const(t, key);
5178  if (!table_v) return false;
5179  if (v) _upb_value_setval(v, table_v->val, t->t.ctype);
5180  return true;
5181 }
5182 
5184  upb_tabval *table_v = inttable_val(t, key);
5185  if (!table_v) return false;
5186  table_v->val = val.val;
5187  return true;
5188 }
5189 
5191  bool success;
5192  if (key < t->array_size) {
5193  if (upb_arrhas(t->array[key])) {
5195  t->array_count--;
5196  if (val) {
5197  _upb_value_setval(val, t->array[key].val, t->t.ctype);
5198  }
5199  mutable_array(t)[key] = empty;
5200  success = true;
5201  } else {
5202  success = false;
5203  }
5204  } else {
5205  success = rm(&t->t, intkey(key), val, NULL, upb_inthash(key), &inteql);
5206  }
5207  check(t);
5208  return success;
5209 }
5210 
5212  upb_check_alloc(&t->t, a);
5213  return upb_inttable_insert2(t, upb_inttable_count(t), val, a);
5214 }
5215 
5217  upb_value val;
5218  bool ok = upb_inttable_remove(t, upb_inttable_count(t) - 1, &val);
5219  UPB_ASSERT(ok);
5220  return val;
5221 }
5222 
5224  upb_alloc *a) {
5225  upb_check_alloc(&t->t, a);
5226  return upb_inttable_insert2(t, (uintptr_t)key, val, a);
5227 }
5228 
5229 bool upb_inttable_lookupptr(const upb_inttable *t, const void *key,
5230  upb_value *v) {
5231  return upb_inttable_lookup(t, (uintptr_t)key, v);
5232 }
5233 
5235  return upb_inttable_remove(t, (uintptr_t)key, val);
5236 }
5237 
5239  /* A power-of-two histogram of the table keys. */
5240  size_t counts[UPB_MAXARRSIZE + 1] = {0};
5241 
5242  /* The max key in each bucket. */
5243  uintptr_t max[UPB_MAXARRSIZE + 1] = {0};
5244 
5246  size_t arr_count;
5247  int size_lg2;
5248  upb_inttable new_t;
5249 
5250  upb_check_alloc(&t->t, a);
5251 
5252  upb_inttable_begin(&i, t);
5253  for (; !upb_inttable_done(&i); upb_inttable_next(&i)) {
5254  uintptr_t key = upb_inttable_iter_key(&i);
5255  int bucket = log2ceil(key);
5256  max[bucket] = UPB_MAX(max[bucket], key);
5257  counts[bucket]++;
5258  }
5259 
5260  /* Find the largest power of two that satisfies the MIN_DENSITY
5261  * definition (while actually having some keys). */
5262  arr_count = upb_inttable_count(t);
5263 
5264  for (size_lg2 = ARRAY_SIZE(counts) - 1; size_lg2 > 0; size_lg2--) {
5265  if (counts[size_lg2] == 0) {
5266  /* We can halve again without losing any entries. */
5267  continue;
5268  } else if (arr_count >= (1 << size_lg2) * MIN_DENSITY) {
5269  break;
5270  }
5271 
5272  arr_count -= counts[size_lg2];
5273  }
5274 
5275  UPB_ASSERT(arr_count <= upb_inttable_count(t));
5276 
5277  {
5278  /* Insert all elements into new, perfectly-sized table. */
5279  size_t arr_size = max[size_lg2] + 1; /* +1 so arr[max] will fit. */
5280  size_t hash_count = upb_inttable_count(t) - arr_count;
5281  size_t hash_size = hash_count ? (hash_count / MAX_LOAD) + 1 : 0;
5282  size_t hashsize_lg2 = log2ceil(hash_size);
5283 
5284  upb_inttable_sizedinit(&new_t, t->t.ctype, arr_size, hashsize_lg2, a);
5285  upb_inttable_begin(&i, t);
5286  for (; !upb_inttable_done(&i); upb_inttable_next(&i)) {
5287  uintptr_t k = upb_inttable_iter_key(&i);
5289  }
5290  UPB_ASSERT(new_t.array_size == arr_size);
5291  UPB_ASSERT(new_t.t.size_lg2 == hashsize_lg2);
5292  }
5293  upb_inttable_uninit2(t, a);
5294  *t = new_t;
5295 }
5296 
5297 /* Iteration. */
5298 
5299 static const upb_tabent *int_tabent(const upb_inttable_iter *i) {
5300  UPB_ASSERT(!i->array_part);
5301  return &i->t->t.entries[i->index];
5302 }
5303 
5305  UPB_ASSERT(i->array_part);
5306  return i->t->array[i->index];
5307 }
5308 
5310  i->t = t;
5311  i->index = -1;
5312  i->array_part = true;
5314 }
5315 
5317  const upb_inttable *t = iter->t;
5318  if (iter->array_part) {
5319  while (++iter->index < t->array_size) {
5320  if (upb_arrhas(int_arrent(iter))) {
5321  return;
5322  }
5323  }
5324  iter->array_part = false;
5325  iter->index = begin(&t->t);
5326  } else {
5327  iter->index = next(&t->t, iter->index);
5328  }
5329 }
5330 
5332  if (!i->t) return true;
5333  if (i->array_part) {
5334  return i->index >= i->t->array_size ||
5335  !upb_arrhas(int_arrent(i));
5336  } else {
5337  return i->index >= upb_table_size(&i->t->t) ||
5339  }
5340 }
5341 
5344  return i->array_part ? i->index : int_tabent(i)->key;
5345 }
5346 
5349  return _upb_value_val(
5350  i->array_part ? i->t->array[i->index].val : int_tabent(i)->val.val,
5351  i->t->t.ctype);
5352 }
5353 
5355  i->t = NULL;
5356  i->index = SIZE_MAX;
5357  i->array_part = false;
5358 }
5359 
5361  const upb_inttable_iter *i2) {
5362  if (upb_inttable_done(i1) && upb_inttable_done(i2))
5363  return true;
5364  return i1->t == i2->t && i1->index == i2->index &&
5365  i1->array_part == i2->array_part;
5366 }
5367 
5368 #if defined(UPB_UNALIGNED_READS_OK) || defined(__s390x__)
5369 /* -----------------------------------------------------------------------------
5370  * MurmurHash2, by Austin Appleby (released as public domain).
5371  * Reformatted and C99-ified by Joshua Haberman.
5372  * Note - This code makes a few assumptions about how your machine behaves -
5373  * 1. We can read a 4-byte value from any address without crashing
5374  * 2. sizeof(int) == 4 (in upb this limitation is removed by using uint32_t
5375  * And it has a few limitations -
5376  * 1. It will not work incrementally.
5377  * 2. It will not produce the same results on little-endian and big-endian
5378  * machines. */
5379 uint32_t MurmurHash2(const void *key, size_t len, uint32_t seed) {
5380  /* 'm' and 'r' are mixing constants generated offline.
5381  * They're not really 'magic', they just happen to work well. */
5382  const uint32_t m = 0x5bd1e995;
5383  const int32_t r = 24;
5384 
5385  /* Initialize the hash to a 'random' value */
5386  uint32_t h = seed ^ len;
5387 
5388  /* Mix 4 bytes at a time into the hash */
5389  const uint8_t * data = (const uint8_t *)key;
5390  while(len >= 4) {
5391  uint32_t k = *(uint32_t *)data;
5392 
5393  k *= m;
5394  k ^= k >> r;
5395  k *= m;
5396 
5397  h *= m;
5398  h ^= k;
5399 
5400  data += 4;
5401  len -= 4;
5402  }
5403 
5404  /* Handle the last few bytes of the input array */
5405  switch(len) {
5406  case 3: h ^= data[2] << 16;
5407  case 2: h ^= data[1] << 8;
5408  case 1: h ^= data[0]; h *= m;
5409  };
5410 
5411  /* Do a few final mixes of the hash to ensure the last few
5412  * bytes are well-incorporated. */
5413  h ^= h >> 13;
5414  h *= m;
5415  h ^= h >> 15;
5416 
5417  return h;
5418 }
5419 
5420 #else /* !UPB_UNALIGNED_READS_OK */
5421 
5422 /* -----------------------------------------------------------------------------
5423  * MurmurHashAligned2, by Austin Appleby
5424  * Same algorithm as MurmurHash2, but only does aligned reads - should be safer
5425  * on certain platforms.
5426  * Performance will be lower than MurmurHash2 */
5427 
5428 #define MIX(h,k,m) { k *= m; k ^= k >> r; k *= m; h *= m; h ^= k; }
5429 
5430 uint32_t MurmurHash2(const void * key, size_t len, uint32_t seed) {
5431  const uint32_t m = 0x5bd1e995;
5432  const int32_t r = 24;
5433  const uint8_t * data = (const uint8_t *)key;
5434  uint32_t h = seed ^ len;
5435  uint8_t align = (uintptr_t)data & 3;
5436 
5437  if(align && (len >= 4)) {
5438  /* Pre-load the temp registers */
5439  uint32_t t = 0, d = 0;
5440  int32_t sl;
5441  int32_t sr;
5442 
5443  switch(align) {
5444  case 1: t |= data[2] << 16;
5445  case 2: t |= data[1] << 8;
5446  case 3: t |= data[0];
5447  }
5448 
5449  t <<= (8 * align);
5450 
5451  data += 4-align;
5452  len -= 4-align;
5453 
5454  sl = 8 * (4-align);
5455  sr = 8 * align;
5456 
5457  /* Mix */
5458 
5459  while(len >= 4) {
5460  uint32_t k;
5461 
5462  d = *(uint32_t *)data;
5463  t = (t >> sr) | (d << sl);
5464 
5465  k = t;
5466 
5467  MIX(h,k,m);
5468 
5469  t = d;
5470 
5471  data += 4;
5472  len -= 4;
5473  }
5474 
5475  /* Handle leftover data in temp registers */
5476 
5477  d = 0;
5478 
5479  if(len >= align) {
5480  uint32_t k;
5481 
5482  switch(align) {
5483  case 3: d |= data[2] << 16;
5484  case 2: d |= data[1] << 8;
5485  case 1: d |= data[0];
5486  }
5487 
5488  k = (t >> sr) | (d << sl);
5489  MIX(h,k,m);
5490 
5491  data += align;
5492  len -= align;
5493 
5494  /* ----------
5495  * Handle tail bytes */
5496 
5497  switch(len) {
5498  case 3: h ^= data[2] << 16;
5499  case 2: h ^= data[1] << 8;
5500  case 1: h ^= data[0]; h *= m;
5501  };
5502  } else {
5503  switch(len) {
5504  case 3: d |= data[2] << 16;
5505  case 2: d |= data[1] << 8;
5506  case 1: d |= data[0];
5507  case 0: h ^= (t >> sr) | (d << sl); h *= m;
5508  }
5509  }
5510 
5511  h ^= h >> 13;
5512  h *= m;
5513  h ^= h >> 15;
5514 
5515  return h;
5516  } else {
5517  while(len >= 4) {
5518  uint32_t k = *(uint32_t *)data;
5519 
5520  MIX(h,k,m);
5521 
5522  data += 4;
5523  len -= 4;
5524  }
5525 
5526  /* ----------
5527  * Handle tail bytes */
5528 
5529  switch(len) {
5530  case 3: h ^= data[2] << 16;
5531  case 2: h ^= data[1] << 8;
5532  case 1: h ^= data[0]; h *= m;
5533  };
5534 
5535  h ^= h >> 13;
5536  h *= m;
5537  h ^= h >> 15;
5538 
5539  return h;
5540  }
5541 }
5542 #undef MIX
5543 
5544 #endif /* UPB_UNALIGNED_READS_OK */
5545 
5546 #include <errno.h>
5547 #include <stdarg.h>
5548 #include <stddef.h>
5549 #include <stdint.h>
5550 #include <stdio.h>
5551 #include <stdlib.h>
5552 #include <string.h>
5553 
5554 /* Guarantee null-termination and provide ellipsis truncation.
5555  * It may be tempting to "optimize" this by initializing these final
5556  * four bytes up-front and then being careful never to overwrite them,
5557  * this is safer and simpler. */
5558 static void nullz(upb_status *status) {
5559  const char *ellipsis = "...";
5560  size_t len = strlen(ellipsis);
5561  UPB_ASSERT(sizeof(status->msg) > len);
5562  memcpy(status->msg + sizeof(status->msg) - len, ellipsis, len);
5563 }
5564 
5565 /* upb_status *****************************************************************/
5566 
5568  if (!status) return;
5569  status->ok = true;
5570  status->msg[0] = '\0';
5571 }
5572 
5573 bool upb_ok(const upb_status *status) { return status->ok; }
5574 
5575 const char *upb_status_errmsg(const upb_status *status) { return status->msg; }
5576 
5577 void upb_status_seterrmsg(upb_status *status, const char *msg) {
5578  if (!status) return;
5579  status->ok = false;
5580  strncpy(status->msg, msg, sizeof(status->msg));
5581  nullz(status);
5582 }
5583 
5584 void upb_status_seterrf(upb_status *status, const char *fmt, ...) {
5585  va_list args;
5586  va_start(args, fmt);
5587  upb_status_vseterrf(status, fmt, args);
5588  va_end(args);
5589 }
5590 
5591 void upb_status_vseterrf(upb_status *status, const char *fmt, va_list args) {
5592  if (!status) return;
5593  status->ok = false;
5594  _upb_vsnprintf(status->msg, sizeof(status->msg), fmt, args);
5595  nullz(status);
5596 }
5597 
5598 /* upb_alloc ******************************************************************/
5599 
5600 static void *upb_global_allocfunc(upb_alloc *alloc, void *ptr, size_t oldsize,
5601  size_t size) {
5602  UPB_UNUSED(alloc);
5603  UPB_UNUSED(oldsize);
5604  if (size == 0) {
5605  free(ptr);
5606  return NULL;
5607  } else {
5608  return realloc(ptr, size);
5609  }
5610 }
5611 
5613 
5614 /* upb_arena ******************************************************************/
5615 
5616 /* Be conservative and choose 16 in case anyone is using SSE. */
5617 static const size_t maxalign = 16;
5618 
5619 static size_t align_up_max(size_t size) {
5620  return ((size + maxalign - 1) / maxalign) * maxalign;
5621 }
5622 
5623 struct upb_arena {
5624  /* We implement the allocator interface.
5625  * This must be the first member of upb_arena! */
5627 
5628  /* Allocator to allocate arena blocks. We are responsible for freeing these
5629  * when we are destroyed. */
5631 
5635 
5636  /* Linked list of blocks. Points to an arena_block, defined in env.c */
5637  void *block_head;
5638 
5639  /* Cleanup entries. Pointer to a cleanup_ent, defined in env.c */
5641 };
5642 
5643 typedef struct mem_block {
5644  struct mem_block *next;
5645  size_t size;
5646  size_t used;
5647  bool owned;
5648  /* Data follows. */
5649 } mem_block;
5650 
5651 typedef struct cleanup_ent {
5654  void *ud;
5655 } cleanup_ent;
5656 
5657 static void upb_arena_addblock(upb_arena *a, void *ptr, size_t size,
5658  bool owned) {
5659  mem_block *block = ptr;
5660 
5661  block->next = a->block_head;
5662  block->size = size;
5663  block->used = align_up_max(sizeof(mem_block));
5664  block->owned = owned;
5665 
5666  a->block_head = block;
5667 
5668  /* TODO(haberman): ASAN poison. */
5669 }
5670 
5672  size_t block_size = UPB_MAX(size, a->next_block_size) + sizeof(mem_block);
5673  mem_block *block = upb_malloc(a->block_alloc, block_size);
5674 
5675  if (!block) {
5676  return NULL;
5677  }
5678 
5679  upb_arena_addblock(a, block, block_size, true);
5680  a->next_block_size = UPB_MIN(block_size * 2, a->max_block_size);
5681 
5682  return block;
5683 }
5684 
5685 static void *upb_arena_doalloc(upb_alloc *alloc, void *ptr, size_t oldsize,
5686  size_t size) {
5687  upb_arena *a = (upb_arena*)alloc; /* upb_alloc is initial member. */
5688  mem_block *block = a->block_head;
5689  void *ret;
5690 
5691  if (size == 0) {
5692  return NULL; /* We are an arena, don't need individual frees. */
5693  }
5694 
5695  size = align_up_max(size);
5696 
5697  /* TODO(haberman): special-case if this is a realloc of the last alloc? */
5698 
5699  if (!block || block->size - block->used < size) {
5700  /* Slow path: have to allocate a new block. */
5701  block = upb_arena_allocblock(a, size);
5702 
5703  if (!block) {
5704  return NULL; /* Out of memory. */
5705  }
5706  }
5707 
5708  ret = (char*)block + block->used;
5709  block->used += size;
5710 
5711  if (oldsize > 0) {
5712  memcpy(ret, ptr, oldsize); /* Preserve existing data. */
5713  }
5714 
5715  /* TODO(haberman): ASAN unpoison. */
5716 
5717  a->bytes_allocated += size;
5718  return ret;
5719 }
5720 
5721 /* Public Arena API ***********************************************************/
5722 
5723 #define upb_alignof(type) offsetof (struct { char c; type member; }, member)
5724 
5725 upb_arena *upb_arena_init(void *mem, size_t n, upb_alloc *alloc) {
5726  const size_t first_block_overhead = sizeof(upb_arena) + sizeof(mem_block);
5727  upb_arena *a;
5728  bool owned = false;
5729 
5730  /* Round block size down to alignof(*a) since we will allocate the arena
5731  * itself at the end. */
5732  n &= ~(upb_alignof(upb_arena) - 1);
5733 
5734  if (n < first_block_overhead) {
5735  /* We need to malloc the initial block. */
5736  n = first_block_overhead + 256;
5737  owned = true;
5738  if (!alloc || !(mem = upb_malloc(alloc, n))) {
5739  return NULL;
5740  }
5741  }
5742 
5743  a = (void*)((char*)mem + n - sizeof(*a));
5744  n -= sizeof(*a);
5745 
5746  a->alloc.func = &upb_arena_doalloc;
5747  a->block_alloc = &upb_alloc_global;
5748  a->bytes_allocated = 0;
5749  a->next_block_size = 256;
5750  a->max_block_size = 16384;
5751  a->cleanup_head = NULL;
5752  a->block_head = NULL;
5753  a->block_alloc = alloc;
5754 
5755  upb_arena_addblock(a, mem, n, owned);
5756 
5757  return a;
5758 }
5759 
5760 #undef upb_alignof
5761 
5763  cleanup_ent *ent = a->cleanup_head;
5764  mem_block *block = a->block_head;
5765 
5766  while (ent) {
5767  ent->cleanup(ent->ud);
5768  ent = ent->next;
5769  }
5770 
5771  /* Must do this after running cleanup functions, because this will delete
5772  * the memory we store our cleanup entries in! */
5773  while (block) {
5774  /* Load first since we are deleting block. */
5775  mem_block *next = block->next;
5776 
5777  if (block->owned) {
5778  upb_free(a->block_alloc, block);
5779  }
5780 
5781  block = next;
5782  }
5783 }
5784 
5786  cleanup_ent *ent = upb_malloc(&a->alloc, sizeof(cleanup_ent));
5787  if (!ent) {
5788  return false; /* Out of memory. */
5789  }
5790 
5791  ent->cleanup = func;
5792  ent->ud = ud;
5793  ent->next = a->cleanup_head;
5794  a->cleanup_head = ent;
5795 
5796  return true;
5797 }
5798 
5800  return a->bytes_allocated;
5801 }
5802 /*
5803 ** protobuf decoder bytecode compiler
5804 **
5805 ** Code to compile a upb::Handlers into bytecode for decoding a protobuf
5806 ** according to that specific schema and destination handlers.
5807 **
5808 ** Bytecode definition is in decoder.int.h.
5809 */
5810 
5811 #include <stdarg.h>
5812 
5813 #ifdef UPB_DUMP_BYTECODE
5814 #include <stdio.h>
5815 #endif
5816 
5817 #define MAXLABEL 5
5818 #define EMPTYLABEL -1
5819 
5820 /* upb_pbdecodermethod ********************************************************/
5821 
5823  upb_inttable_uninit(&method->dispatch);
5824  upb_gfree(method);
5825 }
5826 
5827 static upb_pbdecodermethod *newmethod(const upb_handlers *dest_handlers,
5828  mgroup *group) {
5829  upb_pbdecodermethod *ret = upb_gmalloc(sizeof(*ret));
5831 
5832  ret->group = group;
5833  ret->dest_handlers_ = dest_handlers;
5835 
5836  return ret;
5837 }
5838 
5840  const upb_pbdecodermethod *m) {
5841  return m->dest_handlers_;
5842 }
5843 
5845  const upb_pbdecodermethod *m) {
5846  return &m->input_handler_;
5847 }
5848 
5850  return m->is_native_;
5851 }
5852 
5853 
5854 /* mgroup *********************************************************************/
5855 
5856 static void freegroup(mgroup *g) {
5858 
5859  upb_inttable_begin(&i, &g->methods);
5860  for(; !upb_inttable_done(&i); upb_inttable_next(&i)) {
5861  freemethod(upb_value_getptr(upb_inttable_iter_value(&i)));
5862  }
5863 
5864  upb_inttable_uninit(&g->methods);
5865  upb_gfree(g->bytecode);
5866  upb_gfree(g);
5867 }
5868 
5870  mgroup *g = upb_gmalloc(sizeof(*g));
5871  upb_inttable_init(&g->methods, UPB_CTYPE_PTR);
5872  g->bytecode = NULL;
5873  g->bytecode_end = NULL;
5874  return g;
5875 }
5876 
5877 
5878 /* bytecode compiler **********************************************************/
5879 
5880 /* Data used only at compilation time. */
5881 typedef struct {
5883 
5884  uint32_t *pc;
5885  int fwd_labels[MAXLABEL];
5886  int back_labels[MAXLABEL];
5887 
5888  /* For fields marked "lazy", parse them lazily or eagerly? */
5889  bool lazy;
5890 } compiler;
5891 
5892 static compiler *newcompiler(mgroup *group, bool lazy) {
5893  compiler *ret = upb_gmalloc(sizeof(*ret));
5894  int i;
5895 
5896  ret->group = group;
5897  ret->lazy = lazy;
5898  for (i = 0; i < MAXLABEL; i++) {
5899  ret->fwd_labels[i] = EMPTYLABEL;
5900  ret->back_labels[i] = EMPTYLABEL;
5901  }
5902  return ret;
5903 }
5904 
5905 static void freecompiler(compiler *c) {
5906  upb_gfree(c);
5907 }
5908 
5909 const size_t ptr_words = sizeof(void*) / sizeof(uint32_t);
5910 
5911 /* How many words an instruction is. */
5912 static int instruction_len(uint32_t instr) {
5913  switch (getop(instr)) {
5914  case OP_SETDISPATCH: return 1 + ptr_words;
5915  case OP_TAGN: return 3;
5916  case OP_SETBIGGROUPNUM: return 2;
5917  default: return 1;
5918  }
5919 }
5920 
5921 bool op_has_longofs(int32_t instruction) {
5922  switch (getop(instruction)) {
5923  case OP_CALL:
5924  case OP_BRANCH:
5925  case OP_CHECKDELIM:
5926  return true;
5927  /* The "tag" instructions only have 8 bytes available for the jump target,
5928  * but that is ok because these opcodes only require short jumps. */
5929  case OP_TAG1:
5930  case OP_TAG2:
5931  case OP_TAGN:
5932  return false;
5933  default:
5934  UPB_ASSERT(false);
5935  return false;
5936  }
5937 }
5938 
5939 static int32_t getofs(uint32_t instruction) {
5940  if (op_has_longofs(instruction)) {
5941  return (int32_t)instruction >> 8;
5942  } else {
5943  return (int8_t)(instruction >> 8);
5944  }
5945 }
5946 
5947 static void setofs(uint32_t *instruction, int32_t ofs) {
5948  if (op_has_longofs(*instruction)) {
5949  *instruction = getop(*instruction) | ofs << 8;
5950  } else {
5951  *instruction = (*instruction & ~0xff00) | ((ofs & 0xff) << 8);
5952  }
5953  UPB_ASSERT(getofs(*instruction) == ofs); /* Would fail in cases of overflow. */
5954 }
5955 
5956 static uint32_t pcofs(compiler *c) { return c->pc - c->group->bytecode; }
5957 
5958 /* Defines a local label at the current PC location. All previous forward
5959  * references are updated to point to this location. The location is noted
5960  * for any future backward references. */
5961 static void label(compiler *c, unsigned int label) {
5962  int val;
5963  uint32_t *codep;
5964 
5966  val = c->fwd_labels[label];
5967  codep = (val == EMPTYLABEL) ? NULL : c->group->bytecode + val;
5968  while (codep) {
5969  int ofs = getofs(*codep);
5970  setofs(codep, c->pc - codep - instruction_len(*codep));
5971  codep = ofs ? codep + ofs : NULL;
5972  }
5973  c->fwd_labels[label] = EMPTYLABEL;
5974  c->back_labels[label] = pcofs(c);
5975 }
5976 
5977 /* Creates a reference to a numbered label; either a forward reference
5978  * (positive arg) or backward reference (negative arg). For forward references
5979  * the value returned now is actually a "next" pointer into a linked list of all
5980  * instructions that use this label and will be patched later when the label is
5981  * defined with label().
5982  *
5983  * The returned value is the offset that should be written into the instruction.
5984  */
5985 static int32_t labelref(compiler *c, int label) {
5987  if (label == LABEL_DISPATCH) {
5988  /* No resolving required. */
5989  return 0;
5990  } else if (label < 0) {
5991  /* Backward local label. Relative to the next instruction. */
5992  uint32_t from = (c->pc + 1) - c->group->bytecode;
5993  return c->back_labels[-label] - from;
5994  } else {
5995  /* Forward local label: prepend to (possibly-empty) linked list. */
5996  int *lptr = &c->fwd_labels[label];
5997  int32_t ret = (*lptr == EMPTYLABEL) ? 0 : *lptr - pcofs(c);
5998  *lptr = pcofs(c);
5999  return ret;
6000  }
6001 }
6002 
6003 static void put32(compiler *c, uint32_t v) {
6004  mgroup *g = c->group;
6005  if (c->pc == g->bytecode_end) {
6006  int ofs = pcofs(c);
6007  size_t oldsize = g->bytecode_end - g->bytecode;
6008  size_t newsize = UPB_MAX(oldsize * 2, 64);
6009  /* TODO(haberman): handle OOM. */
6010  g->bytecode = upb_grealloc(g->bytecode, oldsize * sizeof(uint32_t),
6011  newsize * sizeof(uint32_t));
6012  g->bytecode_end = g->bytecode + newsize;
6013  c->pc = g->bytecode + ofs;
6014  }
6015  *c->pc++ = v;
6016 }
6017 
6018 static void putop(compiler *c, int op, ...) {
6019  va_list ap;
6020  va_start(ap, op);
6021 
6022  switch (op) {
6023  case OP_SETDISPATCH: {
6024  uintptr_t ptr = (uintptr_t)va_arg(ap, void*);
6025  put32(c, OP_SETDISPATCH);
6026  put32(c, ptr);
6027  if (sizeof(uintptr_t) > sizeof(uint32_t))
6028  put32(c, (uint64_t)ptr >> 32);
6029  break;
6030  }
6031  case OP_STARTMSG:
6032  case OP_ENDMSG:
6033  case OP_PUSHLENDELIM:
6034  case OP_POP:
6035  case OP_SETDELIM:
6036  case OP_HALT:
6037  case OP_RET:
6038  case OP_DISPATCH:
6039  put32(c, op);
6040  break;
6041  case OP_PARSE_DOUBLE:
6042  case OP_PARSE_FLOAT:
6043  case OP_PARSE_INT64:
6044  case OP_PARSE_UINT64:
6045  case OP_PARSE_INT32:
6046  case OP_PARSE_FIXED64:
6047  case OP_PARSE_FIXED32:
6048  case OP_PARSE_BOOL:
6049  case OP_PARSE_UINT32:
6050  case OP_PARSE_SFIXED32:
6051  case OP_PARSE_SFIXED64:
6052  case OP_PARSE_SINT32:
6053  case OP_PARSE_SINT64:
6054  case OP_STARTSEQ:
6055  case OP_ENDSEQ:
6056  case OP_STARTSUBMSG:
6057  case OP_ENDSUBMSG:
6058  case OP_STARTSTR:
6059  case OP_STRING:
6060  case OP_ENDSTR:
6061  case OP_PUSHTAGDELIM:
6062  put32(c, op | va_arg(ap, upb_selector_t) << 8);
6063  break;
6064  case OP_SETBIGGROUPNUM:
6065  put32(c, op);
6066  put32(c, va_arg(ap, int));
6067  break;
6068  case OP_CALL: {
6069  const upb_pbdecodermethod *method = va_arg(ap, upb_pbdecodermethod *);
6070  put32(c, op | (method->code_base.ofs - (pcofs(c) + 1)) << 8);
6071  break;
6072  }
6073  case OP_CHECKDELIM:
6074  case OP_BRANCH: {
6075  uint32_t instruction = op;
6076  int label = va_arg(ap, int);
6077  setofs(&instruction, labelref(c, label));
6078  put32(c, instruction);
6079  break;
6080  }
6081  case OP_TAG1:
6082  case OP_TAG2: {
6083  int label = va_arg(ap, int);
6084  uint64_t tag = va_arg(ap, uint64_t);
6085  uint32_t instruction = op | (tag << 16);
6086  UPB_ASSERT(tag <= 0xffff);
6087  setofs(&instruction, labelref(c, label));
6088  put32(c, instruction);
6089  break;
6090  }
6091  case OP_TAGN: {
6092  int label = va_arg(ap, int);
6093  uint64_t tag = va_arg(ap, uint64_t);
6094  uint32_t instruction = op | (upb_value_size(tag) << 16);
6095  setofs(&instruction, labelref(c, label));
6096  put32(c, instruction);
6097  put32(c, tag);
6098  put32(c, tag >> 32);
6099  break;
6100  }
6101  }
6102 
6103  va_end(ap);
6104 }
6105 
6106 #if defined(UPB_DUMP_BYTECODE)
6107 
6108 const char *upb_pbdecoder_getopname(unsigned int op) {
6109 #define QUOTE(x) #x
6110 #define EXPAND_AND_QUOTE(x) QUOTE(x)
6111 #define OPNAME(x) OP_##x
6112 #define OP(x) case OPNAME(x): return EXPAND_AND_QUOTE(OPNAME(x));
6113 #define T(x) OP(PARSE_##x)
6114  /* Keep in sync with list in decoder.int.h. */
6115  switch ((opcode)op) {
6116  T(DOUBLE) T(FLOAT) T(INT64) T(UINT64) T(INT32) T(FIXED64) T(FIXED32)
6117  T(BOOL) T(UINT32) T(SFIXED32) T(SFIXED64) T(SINT32) T(SINT64)
6118  OP(STARTMSG) OP(ENDMSG) OP(STARTSEQ) OP(ENDSEQ) OP(STARTSUBMSG)
6119  OP(ENDSUBMSG) OP(STARTSTR) OP(STRING) OP(ENDSTR) OP(CALL) OP(RET)
6120  OP(PUSHLENDELIM) OP(PUSHTAGDELIM) OP(SETDELIM) OP(CHECKDELIM)
6121  OP(BRANCH) OP(TAG1) OP(TAG2) OP(TAGN) OP(SETDISPATCH) OP(POP)
6122  OP(SETBIGGROUPNUM) OP(DISPATCH) OP(HALT)
6123  }
6124  return "<unknown op>";
6125 #undef OP
6126 #undef T
6127 }
6128 
6129 #endif
6130 
6131 #ifdef UPB_DUMP_BYTECODE
6132 
6133 static void dumpbc(uint32_t *p, uint32_t *end, FILE *f) {
6134 
6135  uint32_t *begin = p;
6136 
6137  while (p < end) {
6138  fprintf(f, "%p %8tx", p, p - begin);
6139  uint32_t instr = *p++;
6140  uint8_t op = getop(instr);
6141  fprintf(f, " %s", upb_pbdecoder_getopname(op));
6142  switch ((opcode)op) {
6143  case OP_SETDISPATCH: {
6144  const upb_inttable *dispatch;
6145  memcpy(&dispatch, p, sizeof(void*));
6146  p += ptr_words;
6147  const upb_pbdecodermethod *method =
6148  (void *)((char *)dispatch -
6149  offsetof(upb_pbdecodermethod, dispatch));
6150  fprintf(f, " %s", upb_msgdef_fullname(
6151  upb_handlers_msgdef(method->dest_handlers_)));
6152  break;
6153  }
6154  case OP_DISPATCH:
6155  case OP_STARTMSG:
6156  case OP_ENDMSG:
6157  case OP_PUSHLENDELIM:
6158  case OP_POP:
6159  case OP_SETDELIM:
6160  case OP_HALT:
6161  case OP_RET:
6162  break;
6163  case OP_PARSE_DOUBLE:
6164  case OP_PARSE_FLOAT:
6165  case OP_PARSE_INT64:
6166  case OP_PARSE_UINT64:
6167  case OP_PARSE_INT32:
6168  case OP_PARSE_FIXED64:
6169  case OP_PARSE_FIXED32:
6170  case OP_PARSE_BOOL:
6171  case OP_PARSE_UINT32:
6172  case OP_PARSE_SFIXED32:
6173  case OP_PARSE_SFIXED64:
6174  case OP_PARSE_SINT32:
6175  case OP_PARSE_SINT64:
6176  case OP_STARTSEQ:
6177  case OP_ENDSEQ:
6178  case OP_STARTSUBMSG:
6179  case OP_ENDSUBMSG:
6180  case OP_STARTSTR:
6181  case OP_STRING:
6182  case OP_ENDSTR:
6183  case OP_PUSHTAGDELIM:
6184  fprintf(f, " %d", instr >> 8);
6185  break;
6186  case OP_SETBIGGROUPNUM:
6187  fprintf(f, " %d", *p++);
6188  break;
6189  case OP_CHECKDELIM:
6190  case OP_CALL:
6191  case OP_BRANCH:
6192  fprintf(f, " =>0x%tx", p + getofs(instr) - begin);
6193  break;
6194  case OP_TAG1:
6195  case OP_TAG2: {
6196  fprintf(f, " tag:0x%x", instr >> 16);
6197  if (getofs(instr)) {
6198  fprintf(f, " =>0x%tx", p + getofs(instr) - begin);
6199  }
6200  break;
6201  }
6202  case OP_TAGN: {
6203  uint64_t tag = *p++;
6204  tag |= (uint64_t)*p++ << 32;
6205  fprintf(f, " tag:0x%llx", (long long)tag);
6206  fprintf(f, " n:%d", instr >> 16);
6207  if (getofs(instr)) {
6208  fprintf(f, " =>0x%tx", p + getofs(instr) - begin);
6209  }
6210  break;
6211  }
6212  }
6213  fputs("\n", f);
6214  }
6215 }
6216 
6217 #endif
6218 
6219 static uint64_t get_encoded_tag(const upb_fielddef *f, int wire_type) {
6220  uint32_t tag = (upb_fielddef_number(f) << 3) | wire_type;
6221  uint64_t encoded_tag = upb_vencode32(tag);
6222  /* No tag should be greater than 5 bytes. */
6223  UPB_ASSERT(encoded_tag <= 0xffffffffff);
6224  return encoded_tag;
6225 }
6226 
6227 static void putchecktag(compiler *c, const upb_fielddef *f,
6228  int wire_type, int dest) {
6229  uint64_t tag = get_encoded_tag(f, wire_type);
6230  switch (upb_value_size(tag)) {
6231  case 1:
6232  putop(c, OP_TAG1, dest, tag);
6233  break;
6234  case 2:
6235  putop(c, OP_TAG2, dest, tag);
6236  break;
6237  default:
6238  putop(c, OP_TAGN, dest, tag);
6239  break;
6240  }
6241 }
6242 
6244  upb_selector_t selector;
6245  bool ok = upb_handlers_getselector(f, type, &selector);
6246  UPB_ASSERT(ok);
6247  return selector;
6248 }
6249 
6250 /* Takes an existing, primary dispatch table entry and repacks it with a
6251  * different alternate wire type. Called when we are inserting a secondary
6252  * dispatch table entry for an alternate wire type. */
6253 static uint64_t repack(uint64_t dispatch, int new_wt2) {
6254  uint64_t ofs;
6255  uint8_t wt1;
6256  uint8_t old_wt2;
6257  upb_pbdecoder_unpackdispatch(dispatch, &ofs, &wt1, &old_wt2);
6258  UPB_ASSERT(old_wt2 == NO_WIRE_TYPE); /* wt2 should not be set yet. */
6259  return upb_pbdecoder_packdispatch(ofs, wt1, new_wt2);
6260 }
6261 
6262 /* Marks the current bytecode position as the dispatch target for this message,
6263  * field, and wire type. */
6265  const upb_fielddef *f, int wire_type) {
6266  /* Offset is relative to msg base. */
6267  uint64_t ofs = pcofs(c) - method->code_base.ofs;
6268  uint32_t fn = upb_fielddef_number(f);
6269  upb_inttable *d = &method->dispatch;
6270  upb_value v;
6271  if (upb_inttable_remove(d, fn, &v)) {
6272  /* TODO: prioritize based on packed setting in .proto file. */
6273  uint64_t repacked = repack(upb_value_getuint64(v), wire_type);
6274  upb_inttable_insert(d, fn, upb_value_uint64(repacked));
6275  upb_inttable_insert(d, fn + UPB_MAX_FIELDNUMBER, upb_value_uint64(ofs));
6276  } else {
6277  uint64_t val = upb_pbdecoder_packdispatch(ofs, wire_type, NO_WIRE_TYPE);
6278  upb_inttable_insert(d, fn, upb_value_uint64(val));
6279  }
6280 }
6281 
6282 static void putpush(compiler *c, const upb_fielddef *f) {
6284  putop(c, OP_PUSHLENDELIM);
6285  } else {
6286  uint32_t fn = upb_fielddef_number(f);
6287  if (fn >= 1 << 24) {
6288  putop(c, OP_PUSHTAGDELIM, 0);
6289  putop(c, OP_SETBIGGROUPNUM, fn);
6290  } else {
6291  putop(c, OP_PUSHTAGDELIM, fn);
6292  }
6293  }
6294 }
6295 
6297  const upb_pbdecodermethod *method,
6298  const upb_fielddef *f) {
6299  const upb_handlers *sub =
6300  upb_handlers_getsubhandlers(method->dest_handlers_, f);
6301  upb_value v;
6302  return upb_inttable_lookupptr(&c->group->methods, sub, &v)
6303  ? upb_value_getptr(v)
6304  : NULL;
6305 }
6306 
6307 static void putsel(compiler *c, opcode op, upb_selector_t sel,
6308  const upb_handlers *h) {
6309  if (upb_handlers_gethandler(h, sel, NULL)) {
6310  putop(c, op, sel);
6311  }
6312 }
6313 
6314 /* Puts an opcode to call a callback, but only if a callback actually exists for
6315  * this field and handler type. */
6316 static void maybeput(compiler *c, opcode op, const upb_handlers *h,
6318  putsel(c, op, getsel(f, type), h);
6319 }
6320 
6321 static bool haslazyhandlers(const upb_handlers *h, const upb_fielddef *f) {
6322  if (!upb_fielddef_lazy(f))
6323  return false;
6324 
6328 }
6329 
6330 
6331 /* bytecode compiler code generation ******************************************/
6332 
6333 /* Symbolic names for our local labels. */
6334 #define LABEL_LOOPSTART 1 /* Top of a repeated field loop. */
6335 #define LABEL_LOOPBREAK 2 /* To jump out of a repeated loop */
6336 #define LABEL_FIELD 3 /* Jump backward to find the most recent field. */
6337 #define LABEL_ENDMSG 4 /* To reach the OP_ENDMSG instr for this msg. */
6338 
6339 /* Generates bytecode to parse a single non-lazy message field. */
6340 static void generate_msgfield(compiler *c, const upb_fielddef *f,
6343  const upb_pbdecodermethod *sub_m = find_submethod(c, method, f);
6344  int wire_type;
6345 
6346  if (!sub_m) {
6347  /* Don't emit any code for this field at all; it will be parsed as an
6348  * unknown field.
6349  *
6350  * TODO(haberman): we should change this to parse it as a string field
6351  * instead. It will probably be faster, but more importantly, once we
6352  * start vending unknown fields, a field shouldn't be treated as unknown
6353  * just because it doesn't have subhandlers registered. */
6354  return;
6355  }
6356 
6357  label(c, LABEL_FIELD);
6358 
6359  wire_type =
6363 
6364  if (upb_fielddef_isseq(f)) {
6366  putchecktag(c, f, wire_type, LABEL_DISPATCH);
6367  dispatchtarget(c, method, f, wire_type);
6368  putop(c, OP_PUSHTAGDELIM, 0);
6370  label(c, LABEL_LOOPSTART);
6371  putpush(c, f);
6373  putop(c, OP_CALL, sub_m);
6374  putop(c, OP_POP);
6376  if (wire_type == UPB_WIRE_TYPE_DELIMITED) {
6377  putop(c, OP_SETDELIM);
6378  }
6380  putchecktag(c, f, wire_type, LABEL_LOOPBREAK);
6382  label(c, LABEL_LOOPBREAK);
6383  putop(c, OP_POP);
6385  } else {
6387  putchecktag(c, f, wire_type, LABEL_DISPATCH);
6388  dispatchtarget(c, method, f, wire_type);
6389  putpush(c, f);
6391  putop(c, OP_CALL, sub_m);
6392  putop(c, OP_POP);
6394  if (wire_type == UPB_WIRE_TYPE_DELIMITED) {
6395  putop(c, OP_SETDELIM);
6396  }
6397  }
6398 }
6399 
6400 /* Generates bytecode to parse a single string or lazy submessage field. */
6404 
6405  label(c, LABEL_FIELD);
6406  if (upb_fielddef_isseq(f)) {
6410  putop(c, OP_PUSHTAGDELIM, 0);
6412  label(c, LABEL_LOOPSTART);
6413  putop(c, OP_PUSHLENDELIM);
6415  /* Need to emit even if no handler to skip past the string. */
6418  putop(c, OP_POP);
6419  putop(c, OP_SETDELIM);
6423  label(c, LABEL_LOOPBREAK);
6424  putop(c, OP_POP);
6426  } else {
6430  putop(c, OP_PUSHLENDELIM);
6434  putop(c, OP_POP);
6435  putop(c, OP_SETDELIM);
6436  }
6437 }
6438 
6439 /* Generates bytecode to parse a single primitive field. */
6444  opcode parse_type;
6445  upb_selector_t sel;
6446  int wire_type;
6447 
6448  label(c, LABEL_FIELD);
6449 
6450  /* From a decoding perspective, ENUM is the same as INT32. */
6453 
6454  parse_type = (opcode)descriptor_type;
6455 
6456  /* TODO(haberman): generate packed or non-packed first depending on "packed"
6457  * setting in the fielddef. This will favor (in speed) whichever was
6458  * specified. */
6459 
6460  UPB_ASSERT((int)parse_type >= 0 && parse_type <= OP_MAX);
6463  if (upb_fielddef_isseq(f)) {
6467  putop(c, OP_PUSHLENDELIM);
6468  putop(c, OP_STARTSEQ, getsel(f, UPB_HANDLER_STARTSEQ)); /* Packed */
6469  label(c, LABEL_LOOPSTART);
6470  putop(c, parse_type, sel);
6473  dispatchtarget(c, method, f, wire_type);
6474  putop(c, OP_PUSHTAGDELIM, 0);
6475  putop(c, OP_STARTSEQ, getsel(f, UPB_HANDLER_STARTSEQ)); /* Non-packed */
6476  label(c, LABEL_LOOPSTART);
6477  putop(c, parse_type, sel);
6479  putchecktag(c, f, wire_type, LABEL_LOOPBREAK);
6481  label(c, LABEL_LOOPBREAK);
6482  putop(c, OP_POP); /* Packed and non-packed join. */
6484  putop(c, OP_SETDELIM); /* Could remove for non-packed by dup ENDSEQ. */
6485  } else {
6487  putchecktag(c, f, wire_type, LABEL_DISPATCH);
6488  dispatchtarget(c, method, f, wire_type);
6489  putop(c, parse_type, sel);
6490  }
6491 }
6492 
6493 /* Adds bytecode for parsing the given message to the given decoderplan,
6494  * while adding all dispatch targets to this message's dispatch table. */
6496  const upb_handlers *h;
6497  const upb_msgdef *md;
6498  uint32_t* start_pc;
6500  upb_value val;
6501 
6502  UPB_ASSERT(method);
6503 
6504  /* Clear all entries in the dispatch table. */
6505  upb_inttable_uninit(&method->dispatch);
6507 
6509  md = upb_handlers_msgdef(h);
6510 
6511  method->code_base.ofs = pcofs(c);
6512  putop(c, OP_SETDISPATCH, &method->dispatch);
6514  label(c, LABEL_FIELD);
6515  start_pc = c->pc;
6516  for(upb_msg_field_begin(&i, md);
6517  !upb_msg_field_done(&i);
6518  upb_msg_field_next(&i)) {
6519  const upb_fielddef *f = upb_msg_iter_field(&i);
6521 
6522  if (type == UPB_TYPE_MESSAGE && !(haslazyhandlers(h, f) && c->lazy)) {
6523  generate_msgfield(c, f, method);
6524  } else if (type == UPB_TYPE_STRING || type == UPB_TYPE_BYTES ||
6525  type == UPB_TYPE_MESSAGE) {
6527  } else {
6529  }
6530  }
6531 
6532  /* If there were no fields, or if no handlers were defined, we need to
6533  * generate a non-empty loop body so that we can at least dispatch for unknown
6534  * fields and check for the end of the message. */
6535  if (c->pc == start_pc) {
6536  /* Check for end-of-message. */
6538  /* Unconditionally dispatch. */
6539  putop(c, OP_DISPATCH, 0);
6540  }
6541 
6542  /* For now we just loop back to the last field of the message (or if none,
6543  * the DISPATCH opcode for the message). */
6544  putop(c, OP_BRANCH, -LABEL_FIELD);
6545 
6546  /* Insert both a label and a dispatch table entry for this end-of-msg. */
6547  label(c, LABEL_ENDMSG);
6548  val = upb_value_uint64(pcofs(c) - method->code_base.ofs);
6550 
6552  putop(c, OP_RET);
6553 
6554  upb_inttable_compact(&method->dispatch);
6555 }
6556 
6557 /* Populate "methods" with new upb_pbdecodermethod objects reachable from "h".
6558  * Returns the method for these handlers.
6559  *
6560  * Generates a new method for every destination handlers reachable from "h". */
6561 static void find_methods(compiler *c, const upb_handlers *h) {
6562  upb_value v;
6564  const upb_msgdef *md;
6566 
6567  if (upb_inttable_lookupptr(&c->group->methods, h, &v))
6568  return;
6569 
6570  method = newmethod(h, c->group);
6571  upb_inttable_insertptr(&c->group->methods, h, upb_value_ptr(method));
6572 
6573  /* Find submethods. */
6574  md = upb_handlers_msgdef(h);
6575  for(upb_msg_field_begin(&i, md);
6576  !upb_msg_field_done(&i);
6577  upb_msg_field_next(&i)) {
6578  const upb_fielddef *f = upb_msg_iter_field(&i);
6579  const upb_handlers *sub_h;
6581  (sub_h = upb_handlers_getsubhandlers(h, f)) != NULL) {
6582  /* We only generate a decoder method for submessages with handlers.
6583  * Others will be parsed as unknown fields. */
6584  find_methods(c, sub_h);
6585  }
6586  }
6587 }
6588 
6589 /* (Re-)compile bytecode for all messages in "msgs."
6590  * Overwrites any existing bytecode in "c". */
6591 static void compile_methods(compiler *c) {
6593 
6594  /* Start over at the beginning of the bytecode. */
6595  c->pc = c->group->bytecode;
6596 
6598  for(; !upb_inttable_done(&i); upb_inttable_next(&i)) {
6599  upb_pbdecodermethod *method = upb_value_getptr(upb_inttable_iter_value(&i));
6600  compile_method(c, method);
6601  }
6602 }
6603 
6606  upb_inttable_begin(&i, &g->methods);
6607  for(; !upb_inttable_done(&i); upb_inttable_next(&i)) {
6608  upb_pbdecodermethod *m = upb_value_getptr(upb_inttable_iter_value(&i));
6610 
6611  m->code_base.ptr = g->bytecode + m->code_base.ofs;
6612 
6616  }
6617 }
6618 
6619 
6620 /* TODO(haberman): allow this to be constructed for an arbitrary set of dest
6621  * handlers and other mgroups (but verify we have a transitive closure). */
6622 const mgroup *mgroup_new(const upb_handlers *dest, bool allowjit, bool lazy) {
6623  mgroup *g;
6624  compiler *c;
6625 
6626  UPB_UNUSED(allowjit);
6627 
6628  g = newgroup();
6629  c = newcompiler(g, lazy);
6630  find_methods(c, dest);
6631 
6632  /* We compile in two passes:
6633  * 1. all messages are assigned relative offsets from the beginning of the
6634  * bytecode (saved in method->code_base).
6635  * 2. forwards OP_CALL instructions can be correctly linked since message
6636  * offsets have been previously assigned.
6637  *
6638  * Could avoid the second pass by linking OP_CALL instructions somehow. */
6639  compile_methods(c);
6640  compile_methods(c);
6641  g->bytecode_end = c->pc;
6642  freecompiler(c);
6643 
6644 #ifdef UPB_DUMP_BYTECODE
6645  {
6646  FILE *f = fopen("/tmp/upb-bytecode", "w");
6647  UPB_ASSERT(f);
6648  dumpbc(g->bytecode, g->bytecode_end, stderr);
6649  dumpbc(g->bytecode, g->bytecode_end, f);
6650  fclose(f);
6651 
6652  f = fopen("/tmp/upb-bytecode.bin", "wb");
6653  UPB_ASSERT(f);
6654  fwrite(g->bytecode, 1, g->bytecode_end - g->bytecode, f);
6655  fclose(f);
6656  }
6657 #endif
6658 
6660  return g;
6661 }
6662 
6663 
6664 /* upb_pbcodecache ************************************************************/
6665 
6667  upb_pbcodecache *c = upb_gmalloc(sizeof(*c));
6668 
6669  if (!c) return NULL;
6670 
6671  c->dest = dest;
6672  c->allow_jit = true;
6673  c->lazy = false;
6674 
6675  c->arena = upb_arena_new();
6676  if (!upb_inttable_init(&c->groups, UPB_CTYPE_CONSTPTR)) return NULL;
6677 
6678  return c;
6679 }
6680 
6682  size_t i;
6683 
6684  for (i = 0; i < upb_inttable_count(&c->groups); i++) {
6685  upb_value v;
6686  bool ok = upb_inttable_lookup(&c->groups, i, &v);
6687  UPB_ASSERT(ok);
6688  freegroup((void*)upb_value_getconstptr(v));
6689  }
6690 
6692  upb_arena_free(c->arena);
6693  upb_gfree(c);
6694 }
6695 
6697  return c->allow_jit;
6698 }
6699 
6702  c->allow_jit = allow;
6703 }
6704 
6707  c->lazy = lazy;
6708 }
6709 
6711  const upb_msgdef *md) {
6712  upb_value v;
6713  bool ok;
6714  const upb_handlers *h;
6715  const mgroup *g;
6716 
6717  /* Right now we build a new DecoderMethod every time.
6718  * TODO(haberman): properly cache methods by their true key. */
6719  h = upb_handlercache_get(c->dest, md);
6720  g = mgroup_new(h, c->allow_jit, c->lazy);
6721  upb_inttable_push(&c->groups, upb_value_constptr(g));
6722 
6723  ok = upb_inttable_lookupptr(&g->methods, h, &v);
6724  UPB_ASSERT(ok);
6725  return upb_value_getptr(v);
6726 }
6727 /*
6728 ** upb::Decoder (Bytecode Decoder VM)
6729 **
6730 ** Bytecode must previously have been generated using the bytecode compiler in
6731 ** compile_decoder.c. This decoder then walks through the bytecode op-by-op to
6732 ** parse the input.
6733 **
6734 ** Decoding is fully resumable; we just keep a pointer to the current bytecode
6735 ** instruction and resume from there. A fair amount of the logic here is to
6736 ** handle the fact that values can span buffer seams and we have to be able to
6737 ** be capable of suspending/resuming from any byte in the stream. This
6738 ** sometimes requires keeping a few trailing bytes from the last buffer around
6739 ** in the "residual" buffer.
6740 */
6741 
6742 #include <inttypes.h>
6743 #include <stddef.h>
6744 
6745 #ifdef UPB_DUMP_BYTECODE
6746 #include <stdio.h>
6747 #endif
6748 
6749 #define CHECK_SUSPEND(x) if (!(x)) return upb_pbdecoder_suspend(d);
6750 
6751 /* Error messages that are shared between the bytecode and JIT decoders. */
6752 const char *kPbDecoderStackOverflow = "Nesting too deep.";
6754  "Submessage end extends past enclosing submessage.";
6755 
6756 /* Error messages shared within this file. */
6757 static const char *kUnterminatedVarint = "Unterminated varint.";
6758 
6759 /* upb_pbdecoder **************************************************************/
6760 
6762 
6763 /* A dummy character we can point to when the user passes us a NULL buffer.
6764  * We need this because in C (NULL + 0) and (NULL - NULL) are undefined
6765  * behavior, which would invalidate functions like curbufleft(). */
6766 static const char dummy_char;
6767 
6768 /* Whether an op consumes any of the input buffer. */
6769 static bool consumes_input(opcode op) {
6770  switch (op) {
6771  case OP_SETDISPATCH:
6772  case OP_STARTMSG:
6773  case OP_ENDMSG:
6774  case OP_STARTSEQ:
6775  case OP_ENDSEQ:
6776  case OP_STARTSUBMSG:
6777  case OP_ENDSUBMSG:
6778  case OP_STARTSTR:
6779  case OP_ENDSTR:
6780  case OP_PUSHTAGDELIM:
6781  case OP_POP:
6782  case OP_SETDELIM:
6783  case OP_SETBIGGROUPNUM:
6784  case OP_CHECKDELIM:
6785  case OP_CALL:
6786  case OP_RET:
6787  case OP_BRANCH:
6788  return false;
6789  default:
6790  return true;
6791  }
6792 }
6793 
6794 static size_t stacksize(upb_pbdecoder *d, size_t entries) {
6795  UPB_UNUSED(d);
6796  return entries * sizeof(upb_pbdecoder_frame);
6797 }
6798 
6799 static size_t callstacksize(upb_pbdecoder *d, size_t entries) {
6800  UPB_UNUSED(d);
6801 
6802 #ifdef UPB_USE_JIT_X64
6803  if (d->method_->is_native_) {
6804  /* Each native stack frame needs two pointers, plus we need a few frames for
6805  * the enter/exit trampolines. */
6806  size_t ret = entries * sizeof(void*) * 2;
6807  ret += sizeof(void*) * 10;
6808  return ret;
6809  }
6810 #endif
6811 
6812  return entries * sizeof(uint32_t*);
6813 }
6814 
6815 
6816 static bool in_residual_buf(const upb_pbdecoder *d, const char *p);
6817 
6818 /* It's unfortunate that we have to micro-manage the compiler with
6819  * UPB_FORCEINLINE and UPB_NOINLINE, especially since this tuning is necessarily
6820  * specific to one hardware configuration. But empirically on a Core i7,
6821  * performance increases 30-50% with these annotations. Every instance where
6822  * these appear, gcc 4.2.1 made the wrong decision and degraded performance in
6823  * benchmarks. */
6824 
6825 static void seterr(upb_pbdecoder *d, const char *msg) {
6826  upb_status_seterrmsg(d->status, msg);
6827 }
6828 
6829 void upb_pbdecoder_seterr(upb_pbdecoder *d, const char *msg) {
6830  seterr(d, msg);
6831 }
6832 
6833 
6834 /* Buffering ******************************************************************/
6835 
6836 /* We operate on one buffer at a time, which is either the user's buffer passed
6837  * to our "decode" callback or some residual bytes from the previous buffer. */
6838 
6839 /* How many bytes can be safely read from d->ptr without reading past end-of-buf
6840  * or past the current delimited end. */
6841 static size_t curbufleft(const upb_pbdecoder *d) {
6842  UPB_ASSERT(d->data_end >= d->ptr);
6843  return d->data_end - d->ptr;
6844 }
6845 
6846 /* How many bytes are available before end-of-buffer. */
6847 static size_t bufleft(const upb_pbdecoder *d) {
6848  return d->end - d->ptr;
6849 }
6850 
6851 /* Overall stream offset of d->ptr. */
6852 uint64_t offset(const upb_pbdecoder *d) {
6853  return d->bufstart_ofs + (d->ptr - d->buf);
6854 }
6855 
6856 /* How many bytes are available before the end of this delimited region. */
6857 size_t delim_remaining(const upb_pbdecoder *d) {
6858  return d->top->end_ofs - offset(d);
6859 }
6860 
6861 /* Advances d->ptr. */
6862 static void advance(upb_pbdecoder *d, size_t len) {
6863  UPB_ASSERT(curbufleft(d) >= len);
6864  d->ptr += len;
6865 }
6866 
6867 static bool in_buf(const char *p, const char *buf, const char *end) {
6868  return p >= buf && p <= end;
6869 }
6870 
6871 static bool in_residual_buf(const upb_pbdecoder *d, const char *p) {
6872  return in_buf(p, d->residual, d->residual_end);
6873 }
6874 
6875 /* Calculates the delim_end value, which is affected by both the current buffer
6876  * and the parsing stack, so must be called whenever either is updated. */
6877 static void set_delim_end(upb_pbdecoder *d) {
6878  size_t delim_ofs = d->top->end_ofs - d->bufstart_ofs;
6879  if (delim_ofs <= (size_t)(d->end - d->buf)) {
6880  d->delim_end = d->buf + delim_ofs;
6881  d->data_end = d->delim_end;
6882  } else {
6883  d->data_end = d->end;
6884  d->delim_end = NULL;
6885  }
6886 }
6887 
6888 static void switchtobuf(upb_pbdecoder *d, const char *buf, const char *end) {
6889  d->ptr = buf;
6890  d->buf = buf;
6891  d->end = end;
6892  set_delim_end(d);
6893 }
6894 
6895 static void advancetobuf(upb_pbdecoder *d, const char *buf, size_t len) {
6896  UPB_ASSERT(curbufleft(d) == 0);
6897  d->bufstart_ofs += (d->end - d->buf);
6898  switchtobuf(d, buf, buf + len);
6899 }
6900 
6901 static void checkpoint(upb_pbdecoder *d) {
6902  /* The assertion here is in the interests of efficiency, not correctness.
6903  * We are trying to ensure that we don't checkpoint() more often than
6904  * necessary. */
6905  UPB_ASSERT(d->checkpoint != d->ptr);
6906  d->checkpoint = d->ptr;
6907 }
6908 
6909 /* Skips "bytes" bytes in the stream, which may be more than available. If we
6910  * skip more bytes than are available, we return a long read count to the caller
6911  * indicating how many bytes can be skipped over before passing actual data
6912  * again. Skipped bytes can pass a NULL buffer and the decoder guarantees they
6913  * won't actually be read.
6914  */
6915 static int32_t skip(upb_pbdecoder *d, size_t bytes) {
6916  UPB_ASSERT(!in_residual_buf(d, d->ptr) || d->size_param == 0);
6917  UPB_ASSERT(d->skip == 0);
6918  if (bytes > delim_remaining(d)) {
6919  seterr(d, "Skipped value extended beyond enclosing submessage.");
6920  return upb_pbdecoder_suspend(d);
6921  } else if (bufleft(d) >= bytes) {
6922  /* Skipped data is all in current buffer, and more is still available. */
6923  advance(d, bytes);
6924  d->skip = 0;
6925  return DECODE_OK;
6926  } else {
6927  /* Skipped data extends beyond currently available buffers. */
6928  d->pc = d->last;
6929  d->skip = bytes - curbufleft(d);
6930  d->bufstart_ofs += (d->end - d->buf);
6931  d->residual_end = d->residual;
6932  switchtobuf(d, d->residual, d->residual_end);
6933  return d->size_param + d->skip;
6934  }
6935 }
6936 
6937 
6938 /* Resumes the decoder from an initial state or from a previous suspend. */
6939 int32_t upb_pbdecoder_resume(upb_pbdecoder *d, void *p, const char *buf,
6940  size_t size, const upb_bufhandle *handle) {
6941  UPB_UNUSED(p); /* Useless; just for the benefit of the JIT. */
6942 
6943  /* d->skip and d->residual_end could probably elegantly be represented
6944  * as a single variable, to more easily represent this invariant. */
6945  UPB_ASSERT(!(d->skip && d->residual_end > d->residual));
6946 
6947  /* We need to remember the original size_param, so that the value we return
6948  * is relative to it, even if we do some skipping first. */
6949  d->size_param = size;
6950  d->handle = handle;
6951 
6952  /* Have to handle this case specially (ie. not with skip()) because the user
6953  * is allowed to pass a NULL buffer here, which won't allow us to safely
6954  * calculate a d->end or use our normal functions like curbufleft(). */
6955  if (d->skip && d->skip >= size) {
6956  d->skip -= size;
6957  d->bufstart_ofs += size;
6958  buf = &dummy_char;
6959  size = 0;
6960 
6961  /* We can't just return now, because we might need to execute some ops
6962  * like CHECKDELIM, which could call some callbacks and pop the stack. */
6963  }
6964 
6965  /* We need to pretend that this was the actual buffer param, since some of the
6966  * calculations assume that d->ptr/d->buf is relative to this. */
6967  d->buf_param = buf;
6968 
6969  if (!buf) {
6970  /* NULL buf is ok if its entire span is covered by the "skip" above, but
6971  * by this point we know that "skip" doesn't cover the buffer. */
6972  seterr(d, "Passed NULL buffer over non-skippable region.");
6973  return upb_pbdecoder_suspend(d);
6974  }
6975 
6976  if (d->residual_end > d->residual) {
6977  /* We have residual bytes from the last buffer. */
6978  UPB_ASSERT(d->ptr == d->residual);
6979  } else {
6980  switchtobuf(d, buf, buf + size);
6981  }
6982 
6983  d->checkpoint = d->ptr;
6984 
6985  /* Handle skips that don't cover the whole buffer (as above). */
6986  if (d->skip) {
6987  size_t skip_bytes = d->skip;
6988  d->skip = 0;
6989  CHECK_RETURN(skip(d, skip_bytes));
6990  checkpoint(d);
6991  }
6992 
6993  /* If we're inside an unknown group, continue to parse unknown values. */
6994  if (d->top->groupnum < 0) {
6996  checkpoint(d);
6997  }
6998 
6999  return DECODE_OK;
7000 }
7001 
7002 /* Suspends the decoder at the last checkpoint, without saving any residual
7003  * bytes. If there are any unconsumed bytes, returns a short byte count. */
7005  d->pc = d->last;
7006  if (d->checkpoint == d->residual) {
7007  /* Checkpoint was in residual buf; no user bytes were consumed. */
7008  d->ptr = d->residual;
7009  return 0;
7010  } else {
7011  size_t ret = d->size_param - (d->end - d->checkpoint);
7012  UPB_ASSERT(!in_residual_buf(d, d->checkpoint));
7013  UPB_ASSERT(d->buf == d->buf_param || d->buf == &dummy_char);
7014 
7015  d->bufstart_ofs += (d->checkpoint - d->buf);
7016  d->residual_end = d->residual;
7017  switchtobuf(d, d->residual, d->residual_end);
7018  return ret;
7019  }
7020 }
7021 
7022 /* Suspends the decoder at the last checkpoint, and saves any unconsumed
7023  * bytes in our residual buffer. This is necessary if we need more user
7024  * bytes to form a complete value, which might not be contiguous in the
7025  * user's buffers. Always consumes all user bytes. */
7026 static size_t suspend_save(upb_pbdecoder *d) {
7027  /* We hit end-of-buffer before we could parse a full value.
7028  * Save any unconsumed bytes (if any) to the residual buffer. */
7029  d->pc = d->last;
7030 
7031  if (d->checkpoint == d->residual) {
7032  /* Checkpoint was in residual buf; append user byte(s) to residual buf. */
7033  UPB_ASSERT((d->residual_end - d->residual) + d->size_param <=
7034  sizeof(d->residual));
7035  if (!in_residual_buf(d, d->ptr)) {
7036  d->bufstart_ofs -= (d->residual_end - d->residual);
7037  }
7038  memcpy(d->residual_end, d->buf_param, d->size_param);
7039  d->residual_end += d->size_param;
7040  } else {
7041  /* Checkpoint was in user buf; old residual bytes not needed. */
7042  size_t save;
7043  UPB_ASSERT(!in_residual_buf(d, d->checkpoint));
7044 
7045  d->ptr = d->checkpoint;
7046  save = curbufleft(d);
7047  UPB_ASSERT(save <= sizeof(d->residual));
7048  memcpy(d->residual, d->ptr, save);
7049  d->residual_end = d->residual + save;
7050  d->bufstart_ofs = offset(d);
7051  }
7052 
7053  switchtobuf(d, d->residual, d->residual_end);
7054  return d->size_param;
7055 }
7056 
7057 /* Copies the next "bytes" bytes into "buf" and advances the stream.
7058  * Requires that this many bytes are available in the current buffer. */
7060  size_t bytes) {
7062  memcpy(buf, d->ptr, bytes);
7063  advance(d, bytes);
7064 }
7065 
7066 /* Slow path for getting the next "bytes" bytes, regardless of whether they are
7067  * available in the current buffer or not. Returns a status code as described
7068  * in decoder.int.h. */
7069 UPB_NOINLINE static int32_t getbytes_slow(upb_pbdecoder *d, void *buf,
7070  size_t bytes) {
7071  const size_t avail = curbufleft(d);
7072  consumebytes(d, buf, avail);
7073  bytes -= avail;
7074  UPB_ASSERT(bytes > 0);
7075  if (in_residual_buf(d, d->ptr)) {
7076  advancetobuf(d, d->buf_param, d->size_param);
7077  }
7078  if (curbufleft(d) >= bytes) {
7079  consumebytes(d, (char *)buf + avail, bytes);
7080  return DECODE_OK;
7081  } else if (d->data_end == d->delim_end) {
7082  seterr(d, "Submessage ended in the middle of a value or group");
7083  return upb_pbdecoder_suspend(d);
7084  } else {
7085  return suspend_save(d);
7086  }
7087 }
7088 
7089 /* Gets the next "bytes" bytes, regardless of whether they are available in the
7090  * current buffer or not. Returns a status code as described in decoder.int.h.
7091  */
7092 UPB_FORCEINLINE static int32_t getbytes(upb_pbdecoder *d, void *buf,
7093  size_t bytes) {
7094  if (curbufleft(d) >= bytes) {
7095  /* Buffer has enough data to satisfy. */
7096  consumebytes(d, buf, bytes);
7097  return DECODE_OK;
7098  } else {
7099  return getbytes_slow(d, buf, bytes);
7100  }
7101 }
7102 
7104  size_t bytes) {
7105  size_t ret = curbufleft(d);
7106  memcpy(buf, d->ptr, ret);
7107  if (in_residual_buf(d, d->ptr)) {
7108  size_t copy = UPB_MIN(bytes - ret, d->size_param);
7109  memcpy((char *)buf + ret, d->buf_param, copy);
7110  ret += copy;
7111  }
7112  return ret;
7113 }
7114 
7115 UPB_FORCEINLINE static size_t peekbytes(upb_pbdecoder *d, void *buf,
7116  size_t bytes) {
7117  if (curbufleft(d) >= bytes) {
7118  memcpy(buf, d->ptr, bytes);
7119  return bytes;
7120  } else {
7121  return peekbytes_slow(d, buf, bytes);
7122  }
7123 }
7124 
7125 
7126 /* Decoding of wire types *****************************************************/
7127 
7128 /* Slow path for decoding a varint from the current buffer position.
7129  * Returns a status code as described in decoder.int.h. */
7131  uint64_t *u64) {
7132  uint8_t byte = 0x80;
7133  int bitpos;
7134  *u64 = 0;
7135  for(bitpos = 0; bitpos < 70 && (byte & 0x80); bitpos += 7) {
7136  CHECK_RETURN(getbytes(d, &byte, 1));
7137  *u64 |= (uint64_t)(byte & 0x7F) << bitpos;
7138  }
7139  if(bitpos == 70 && (byte & 0x80)) {
7141  return upb_pbdecoder_suspend(d);
7142  }
7143  return DECODE_OK;
7144 }
7145 
7146 /* Decodes a varint from the current buffer position.
7147  * Returns a status code as described in decoder.int.h. */
7148 UPB_FORCEINLINE static int32_t decode_varint(upb_pbdecoder *d, uint64_t *u64) {
7149  if (curbufleft(d) > 0 && !(*d->ptr & 0x80)) {
7150  *u64 = *d->ptr;
7151  advance(d, 1);
7152  return DECODE_OK;
7153  } else if (curbufleft(d) >= 10) {
7154  /* Fast case. */
7156  if (r.p == NULL) {
7158  return upb_pbdecoder_suspend(d);
7159  }
7160  advance(d, r.p - d->ptr);
7161  *u64 = r.val;
7162  return DECODE_OK;
7163  } else {
7164  /* Slow case -- varint spans buffer seam. */
7165  return upb_pbdecoder_decode_varint_slow(d, u64);
7166  }
7167 }
7168 
7169 /* Decodes a 32-bit varint from the current buffer position.
7170  * Returns a status code as described in decoder.int.h. */
7171 UPB_FORCEINLINE static int32_t decode_v32(upb_pbdecoder *d, uint32_t *u32) {
7172  uint64_t u64;
7173  int32_t ret = decode_varint(d, &u64);
7174  if (ret >= 0) return ret;
7175  if (u64 > UINT32_MAX) {
7176  seterr(d, "Unterminated 32-bit varint");
7177  /* TODO(haberman) guarantee that this function return is >= 0 somehow,
7178  * so we know this path will always be treated as error by our caller.
7179  * Right now the size_t -> int32_t can overflow and produce negative values.
7180  */
7181  *u32 = 0;
7182  return upb_pbdecoder_suspend(d);
7183  }
7184  *u32 = u64;
7185  return DECODE_OK;
7186 }
7187 
7188 /* Decodes a fixed32 from the current buffer position.
7189  * Returns a status code as described in decoder.int.h.
7190  * TODO: proper byte swapping for big-endian machines. */
7191 UPB_FORCEINLINE static int32_t decode_fixed32(upb_pbdecoder *d, uint32_t *u32) {
7192  return getbytes(d, u32, 4);
7193 }
7194 
7195 /* Decodes a fixed64 from the current buffer position.
7196  * Returns a status code as described in decoder.int.h.
7197  * TODO: proper byte swapping for big-endian machines. */
7198 UPB_FORCEINLINE static int32_t decode_fixed64(upb_pbdecoder *d, uint64_t *u64) {
7199  return getbytes(d, u64, 8);
7200 }
7201 
7202 /* Non-static versions of the above functions.
7203  * These are called by the JIT for fallback paths. */
7204 int32_t upb_pbdecoder_decode_f32(upb_pbdecoder *d, uint32_t *u32) {
7205  return decode_fixed32(d, u32);
7206 }
7207 
7208 int32_t upb_pbdecoder_decode_f64(upb_pbdecoder *d, uint64_t *u64) {
7209  return decode_fixed64(d, u64);
7210 }
7211 
7212 static double as_double(uint64_t n) { double d; memcpy(&d, &n, 8); return d; }
7213 static float as_float(uint32_t n) { float f; memcpy(&f, &n, 4); return f; }
7214 
7215 /* Pushes a frame onto the decoder stack. */
7216 static bool decoder_push(upb_pbdecoder *d, uint64_t end) {
7217  upb_pbdecoder_frame *fr = d->top;
7218 
7219  if (end > fr->end_ofs) {
7221  return false;
7222  } else if (fr == d->limit) {
7224  return false;
7225  }
7226 
7227  fr++;
7228  fr->end_ofs = end;
7229  fr->dispatch = NULL;
7230  fr->groupnum = 0;
7231  d->top = fr;
7232  return true;
7233 }
7234 
7235 static bool pushtagdelim(upb_pbdecoder *d, uint32_t arg) {
7236  /* While we expect to see an "end" tag (either ENDGROUP or a non-sequence
7237  * field number) prior to hitting any enclosing submessage end, pushing our
7238  * existing delim end prevents us from continuing to parse values from a
7239  * corrupt proto that doesn't give us an END tag in time. */
7240  if (!decoder_push(d, d->top->end_ofs))
7241  return false;
7242  d->top->groupnum = arg;
7243  return true;
7244 }
7245 
7246 /* Pops a frame from the decoder stack. */
7247 static void decoder_pop(upb_pbdecoder *d) { d->top--; }
7248 
7250  uint64_t expected) {
7251  uint64_t data = 0;
7252  size_t bytes = upb_value_size(expected);
7253  size_t read = peekbytes(d, &data, bytes);
7254  if (read == bytes && data == expected) {
7255  /* Advance past matched bytes. */
7256  int32_t ok = getbytes(d, &data, read);
7257  UPB_ASSERT(ok < 0);
7258  return DECODE_OK;
7259  } else if (read < bytes && memcmp(&data, &expected, read) == 0) {
7260  return suspend_save(d);
7261  } else {
7262  return DECODE_MISMATCH;
7263  }
7264 }
7265 
7266 int32_t upb_pbdecoder_skipunknown(upb_pbdecoder *d, int32_t fieldnum,
7267  uint8_t wire_type) {
7268  if (fieldnum >= 0)
7269  goto have_tag;
7270 
7271  while (true) {
7272  uint32_t tag;
7273  CHECK_RETURN(decode_v32(d, &tag));
7274  wire_type = tag & 0x7;
7275  fieldnum = tag >> 3;
7276 
7277 have_tag:
7278  if (fieldnum == 0) {
7279  seterr(d, "Saw invalid field number (0)");
7280  return upb_pbdecoder_suspend(d);
7281  }
7282 
7283  switch (wire_type) {
7284  case UPB_WIRE_TYPE_32BIT:
7285  CHECK_RETURN(skip(d, 4));
7286  break;
7287  case UPB_WIRE_TYPE_64BIT:
7288  CHECK_RETURN(skip(d, 8));
7289  break;
7290  case UPB_WIRE_TYPE_VARINT: {
7291  uint64_t u64;
7292  CHECK_RETURN(decode_varint(d, &u64));
7293  break;
7294  }
7295  case UPB_WIRE_TYPE_DELIMITED: {
7296  uint32_t len;
7298  CHECK_RETURN(skip(d, len));
7299  break;
7300  }
7302  CHECK_SUSPEND(pushtagdelim(d, -fieldnum));
7303  break;
7305  if (fieldnum == -d->top->groupnum) {
7306  decoder_pop(d);
7307  } else if (fieldnum == d->top->groupnum) {
7308  return DECODE_ENDGROUP;
7309  } else {
7310  seterr(d, "Unmatched ENDGROUP tag.");
7311  return upb_pbdecoder_suspend(d);
7312  }
7313  break;
7314  default:
7315  seterr(d, "Invalid wire type");
7316  return upb_pbdecoder_suspend(d);
7317  }
7318 
7319  if (d->top->groupnum >= 0) {
7320  /* TODO: More code needed for handling unknown groups. */
7321  upb_sink_putunknown(d->top->sink, d->checkpoint, d->ptr - d->checkpoint);
7322  return DECODE_OK;
7323  }
7324 
7325  /* Unknown group -- continue looping over unknown fields. */
7326  checkpoint(d);
7327  }
7328 }
7329 
7330 static void goto_endmsg(upb_pbdecoder *d) {
7331  upb_value v;
7332  bool found = upb_inttable_lookup32(d->top->dispatch, DISPATCH_ENDMSG, &v);
7333  UPB_ASSERT(found);
7334  d->pc = d->top->base + upb_value_getuint64(v);
7335 }
7336 
7337 /* Parses a tag and jumps to the corresponding bytecode instruction for this
7338  * field.
7339  *
7340  * If the tag is unknown (or the wire type doesn't match), parses the field as
7341  * unknown. If the tag is a valid ENDGROUP tag, jumps to the bytecode
7342  * instruction for the end of message. */
7343 static int32_t dispatch(upb_pbdecoder *d) {
7344  upb_inttable *dispatch = d->top->dispatch;
7345  uint32_t tag;
7346  uint8_t wire_type;
7347  uint32_t fieldnum;
7348  upb_value val;
7349  int32_t retval;
7350 
7351  /* Decode tag. */
7352  CHECK_RETURN(decode_v32(d, &tag));
7353  wire_type = tag & 0x7;
7354  fieldnum = tag >> 3;
7355 
7356  /* Lookup tag. Because of packed/non-packed compatibility, we have to
7357  * check the wire type against two possibilities. */
7358  if (fieldnum != DISPATCH_ENDMSG &&
7359  upb_inttable_lookup32(dispatch, fieldnum, &val)) {
7360  uint64_t v = upb_value_getuint64(val);
7361  if (wire_type == (v & 0xff)) {
7362  d->pc = d->top->base + (v >> 16);
7363  return DECODE_OK;
7364  } else if (wire_type == ((v >> 8) & 0xff)) {
7365  bool found =
7367  UPB_ASSERT(found);
7368  d->pc = d->top->base + upb_value_getuint64(val);
7369  return DECODE_OK;
7370  }
7371  }
7372 
7373  /* We have some unknown fields (or ENDGROUP) to parse. The DISPATCH or TAG
7374  * bytecode that triggered this is preceded by a CHECKDELIM bytecode which
7375  * we need to back up to, so that when we're done skipping unknown data we
7376  * can re-check the delimited end. */
7377  d->last--; /* Necessary if we get suspended */
7378  d->pc = d->last;
7379  UPB_ASSERT(getop(*d->last) == OP_CHECKDELIM);
7380 
7381  /* Unknown field or ENDGROUP. */
7382  retval = upb_pbdecoder_skipunknown(d, fieldnum, wire_type);
7383 
7384  CHECK_RETURN(retval);
7385 
7386  if (retval == DECODE_ENDGROUP) {
7387  goto_endmsg(d);
7388  return DECODE_OK;
7389  }
7390 
7391  return DECODE_OK;
7392 }
7393 
7394 /* Callers know that the stack is more than one deep because the opcodes that
7395  * call this only occur after PUSH operations. */
7397  UPB_ASSERT(d->top != d->stack);
7398  return d->top - 1;
7399 }
7400 
7401 
7402 /* The main decoding loop *****************************************************/
7403 
7404 /* The main decoder VM function. Uses traditional bytecode dispatch loop with a
7405  * switch() statement. */
7407  const upb_bufhandle* handle) {
7408 
7409 #define VMCASE(op, code) \
7410  case op: { code; if (consumes_input(op)) checkpoint(d); break; }
7411 #define PRIMITIVE_OP(type, wt, name, convfunc, ctype) \
7412  VMCASE(OP_PARSE_ ## type, { \
7413  ctype val; \
7414  CHECK_RETURN(decode_ ## wt(d, &val)); \
7415  upb_sink_put ## name(d->top->sink, arg, (convfunc)(val)); \
7416  })
7417 
7418  while(1) {
7419  int32_t instruction;
7420  opcode op;
7421  uint32_t arg;
7422  int32_t longofs;
7423 
7424  d->last = d->pc;
7425  instruction = *d->pc++;
7426  op = getop(instruction);
7427  arg = instruction >> 8;
7428  longofs = arg;
7429  UPB_ASSERT(d->ptr != d->residual_end);
7430  UPB_UNUSED(group);
7431 #ifdef UPB_DUMP_BYTECODE
7432  fprintf(stderr, "s_ofs=%d buf_ofs=%d data_rem=%d buf_rem=%d delim_rem=%d "
7433  "%x %s (%d)\n",
7434  (int)offset(d),
7435  (int)(d->ptr - d->buf),
7436  (int)(d->data_end - d->ptr),
7437  (int)(d->end - d->ptr),
7438  (int)((d->top->end_ofs - d->bufstart_ofs) - (d->ptr - d->buf)),
7439  (int)(d->pc - 1 - group->bytecode),
7441  arg);
7442 #endif
7443  switch (op) {
7444  /* Technically, we are losing data if we see a 32-bit varint that is not
7445  * properly sign-extended. We could detect this and error about the data
7446  * loss, but proto2 does not do this, so we pass. */
7447  PRIMITIVE_OP(INT32, varint, int32, int32_t, uint64_t)
7448  PRIMITIVE_OP(INT64, varint, int64, int64_t, uint64_t)
7449  PRIMITIVE_OP(UINT32, varint, uint32, uint32_t, uint64_t)
7450  PRIMITIVE_OP(UINT64, varint, uint64, uint64_t, uint64_t)
7451  PRIMITIVE_OP(FIXED32, fixed32, uint32, uint32_t, uint32_t)
7452  PRIMITIVE_OP(FIXED64, fixed64, uint64, uint64_t, uint64_t)
7453  PRIMITIVE_OP(SFIXED32, fixed32, int32, int32_t, uint32_t)
7454  PRIMITIVE_OP(SFIXED64, fixed64, int64, int64_t, uint64_t)
7455  PRIMITIVE_OP(BOOL, varint, bool, bool, uint64_t)
7456  PRIMITIVE_OP(DOUBLE, fixed64, double, as_double, uint64_t)
7457  PRIMITIVE_OP(FLOAT, fixed32, float, as_float, uint32_t)
7458  PRIMITIVE_OP(SINT32, varint, int32, upb_zzdec_32, uint64_t)
7459  PRIMITIVE_OP(SINT64, varint, int64, upb_zzdec_64, uint64_t)
7460 
7462  d->top->base = d->pc - 1;
7463  memcpy(&d->top->dispatch, d->pc, sizeof(void*));
7464  d->pc += sizeof(void*) / sizeof(uint32_t);
7465  )
7467  CHECK_SUSPEND(upb_sink_startmsg(d->top->sink));
7468  )
7469  VMCASE(OP_ENDMSG,
7470  CHECK_SUSPEND(upb_sink_endmsg(d->top->sink, d->status));
7471  )
7473  upb_pbdecoder_frame *outer = outer_frame(d);
7474  CHECK_SUSPEND(upb_sink_startseq(outer->sink, arg, &d->top->sink));
7475  )
7476  VMCASE(OP_ENDSEQ,
7477  CHECK_SUSPEND(upb_sink_endseq(d->top->sink, arg));
7478  )
7480  upb_pbdecoder_frame *outer = outer_frame(d);
7481  CHECK_SUSPEND(upb_sink_startsubmsg(outer->sink, arg, &d->top->sink));
7482  )
7484  CHECK_SUSPEND(upb_sink_endsubmsg(d->top->sink, arg));
7485  )
7487  uint32_t len = delim_remaining(d);
7488  upb_pbdecoder_frame *outer = outer_frame(d);
7489  CHECK_SUSPEND(upb_sink_startstr(outer->sink, arg, len, &d->top->sink));
7490  if (len == 0) {
7491  d->pc++; /* Skip OP_STRING. */
7492  }
7493  )
7494  VMCASE(OP_STRING,
7495  uint32_t len = curbufleft(d);
7496  size_t n = upb_sink_putstring(d->top->sink, arg, d->ptr, len, handle);
7497  if (n > len) {
7498  if (n > delim_remaining(d)) {
7499  seterr(d, "Tried to skip past end of string.");
7500  return upb_pbdecoder_suspend(d);
7501  } else {
7502  int32_t ret = skip(d, n);
7503  /* This shouldn't return DECODE_OK, because n > len. */
7504  UPB_ASSERT(ret >= 0);
7505  return ret;
7506  }
7507  }
7508  advance(d, n);
7509  if (n < len || d->delim_end == NULL) {
7510  /* We aren't finished with this string yet. */
7511  d->pc--; /* Repeat OP_STRING. */
7512  if (n > 0) checkpoint(d);
7513  return upb_pbdecoder_suspend(d);
7514  }
7515  )
7516  VMCASE(OP_ENDSTR,
7517  CHECK_SUSPEND(upb_sink_endstr(d->top->sink, arg));
7518  )
7520  CHECK_SUSPEND(pushtagdelim(d, arg));
7521  )
7523  d->top->groupnum = *d->pc++;
7524  )
7525  VMCASE(OP_POP,
7526  UPB_ASSERT(d->top > d->stack);
7527  decoder_pop(d);
7528  )
7530  uint32_t len;
7533  set_delim_end(d);
7534  )
7536  set_delim_end(d);
7537  )
7539  /* We are guaranteed of this assert because we never allow ourselves to
7540  * consume bytes beyond data_end, which covers delim_end when non-NULL.
7541  */
7542  UPB_ASSERT(!(d->delim_end && d->ptr > d->delim_end));
7543  if (d->ptr == d->delim_end)
7544  d->pc += longofs;
7545  )
7546  VMCASE(OP_CALL,
7547  d->callstack[d->call_len++] = d->pc;
7548  d->pc += longofs;
7549  )
7550  VMCASE(OP_RET,
7551  UPB_ASSERT(d->call_len > 0);
7552  d->pc = d->callstack[--d->call_len];
7553  )
7554  VMCASE(OP_BRANCH,
7555  d->pc += longofs;
7556  )
7557  VMCASE(OP_TAG1,
7558  uint8_t expected;
7559  CHECK_SUSPEND(curbufleft(d) > 0);
7560  expected = (arg >> 8) & 0xff;
7561  if (*d->ptr == expected) {
7562  advance(d, 1);
7563  } else {
7564  int8_t shortofs;
7565  badtag:
7566  shortofs = arg;
7567  if (shortofs == LABEL_DISPATCH) {
7569  } else {
7570  d->pc += shortofs;
7571  break; /* Avoid checkpoint(). */
7572  }
7573  }
7574  )
7575  VMCASE(OP_TAG2,
7576  uint16_t expected;
7577  CHECK_SUSPEND(curbufleft(d) > 0);
7578  expected = (arg >> 8) & 0xffff;
7579  if (curbufleft(d) >= 2) {
7580  uint16_t actual;
7581  memcpy(&actual, d->ptr, 2);
7582  if (expected == actual) {
7583  advance(d, 2);
7584  } else {
7585  goto badtag;
7586  }
7587  } else {
7588  int32_t result = upb_pbdecoder_checktag_slow(d, expected);
7589  if (result == DECODE_MISMATCH) goto badtag;
7590  if (result >= 0) return result;
7591  }
7592  )
7593  VMCASE(OP_TAGN, {
7594  uint64_t expected;
7595  int32_t result;
7596  memcpy(&expected, d->pc, 8);
7597  d->pc += 2;
7598  result = upb_pbdecoder_checktag_slow(d, expected);
7599  if (result == DECODE_MISMATCH) goto badtag;
7600  if (result >= 0) return result;
7601  })
7602  VMCASE(OP_DISPATCH, {
7604  })
7605  VMCASE(OP_HALT, {
7606  return d->size_param;
7607  })
7608  }
7609  }
7610 }
7611 
7612 
7613 /* BytesHandler handlers ******************************************************/
7614 
7615 void *upb_pbdecoder_startbc(void *closure, const void *pc, size_t size_hint) {
7616  upb_pbdecoder *d = closure;
7617  UPB_UNUSED(size_hint);
7618  d->top->end_ofs = UINT64_MAX;
7619  d->bufstart_ofs = 0;
7620  d->call_len = 1;
7621  d->callstack[0] = &halt;
7622  d->pc = pc;
7623  d->skip = 0;
7624  return d;
7625 }
7626 
7627 void *upb_pbdecoder_startjit(void *closure, const void *hd, size_t size_hint) {
7628  upb_pbdecoder *d = closure;
7629  UPB_UNUSED(hd);
7630  UPB_UNUSED(size_hint);
7631  d->top->end_ofs = UINT64_MAX;
7632  d->bufstart_ofs = 0;
7633  d->call_len = 0;
7634  d->skip = 0;
7635  return d;
7636 }
7637 
7638 bool upb_pbdecoder_end(void *closure, const void *handler_data) {
7639  upb_pbdecoder *d = closure;
7640  const upb_pbdecodermethod *method = handler_data;
7641  uint64_t end;
7642  char dummy;
7643 
7644  if (d->residual_end > d->residual) {
7645  seterr(d, "Unexpected EOF: decoder still has buffered unparsed data");
7646  return false;
7647  }
7648 
7649  if (d->skip) {
7650  seterr(d, "Unexpected EOF inside skipped data");
7651  return false;
7652  }
7653 
7654  if (d->top->end_ofs != UINT64_MAX) {
7655  seterr(d, "Unexpected EOF inside delimited string");
7656  return false;
7657  }
7658 
7659  /* The user's end() call indicates that the message ends here. */
7660  end = offset(d);
7661  d->top->end_ofs = end;
7662 
7663 #ifdef UPB_USE_JIT_X64
7664  if (method->is_native_) {
7665  const mgroup *group = (const mgroup*)method->group;
7666  if (d->top != d->stack)
7667  d->stack->end_ofs = 0;
7668  group->jit_code(closure, method->code_base.ptr, &dummy, 0, NULL);
7669  } else
7670 #endif
7671  {
7672  const uint32_t *p = d->pc;
7673  d->stack->end_ofs = end;
7674  /* Check the previous bytecode, but guard against beginning. */
7675  if (p != method->code_base.ptr) p--;
7676  if (getop(*p) == OP_CHECKDELIM) {
7677  /* Rewind from OP_TAG* to OP_CHECKDELIM. */
7678  UPB_ASSERT(getop(*d->pc) == OP_TAG1 ||
7679  getop(*d->pc) == OP_TAG2 ||
7680  getop(*d->pc) == OP_TAGN ||
7681  getop(*d->pc) == OP_DISPATCH);
7682  d->pc = p;
7683  }
7684  upb_pbdecoder_decode(closure, handler_data, &dummy, 0, NULL);
7685  }
7686 
7687  if (d->call_len != 0) {
7688  seterr(d, "Unexpected EOF inside submessage or group");
7689  return false;
7690  }
7691 
7692  return true;
7693 }
7694 
7695 size_t upb_pbdecoder_decode(void *decoder, const void *group, const char *buf,
7696  size_t size, const upb_bufhandle *handle) {
7697  int32_t result = upb_pbdecoder_resume(decoder, NULL, buf, size, handle);
7698 
7699  if (result == DECODE_ENDGROUP) goto_endmsg(decoder);
7700  CHECK_RETURN(result);
7701 
7702  return run_decoder_vm(decoder, group, handle);
7703 }
7704 
7705 
7706 /* Public API *****************************************************************/
7707 
7709  d->top = d->stack;
7710  d->top->groupnum = 0;
7711  d->ptr = d->residual;
7712  d->buf = d->residual;
7713  d->end = d->residual;
7714  d->residual_end = d->residual;
7715 }
7716 
7718  upb_sink sink, upb_status *status) {
7719  const size_t default_max_nesting = 64;
7720 #ifndef NDEBUG
7721  size_t size_before = upb_arena_bytesallocated(a);
7722 #endif
7723 
7725  if (!d) return NULL;
7726 
7727  d->method_ = m;
7728  d->callstack = upb_arena_malloc(a, callstacksize(d, default_max_nesting));
7729  d->stack = upb_arena_malloc(a, stacksize(d, default_max_nesting));
7730  if (!d->stack || !d->callstack) {
7731  return NULL;
7732  }
7733 
7734  d->arena = a;
7735  d->limit = d->stack + default_max_nesting - 1;
7736  d->stack_size = default_max_nesting;
7737  d->status = status;
7738 
7740  upb_bytessink_reset(&d->input_, &m->input_handler_, d);
7741 
7742  if (d->method_->dest_handlers_) {
7743  if (sink.handlers != d->method_->dest_handlers_)
7744  return NULL;
7745  }
7746  d->top->sink = sink;
7747 
7748  /* If this fails, increase the value in decoder.h. */
7751  return d;
7752 }
7753 
7755  return offset(d);
7756 }
7757 
7759  return d->method_;
7760 }
7761 
7763  return d->input_;
7764 }
7765 
7767  return d->stack_size;
7768 }
7769 
7771  UPB_ASSERT(d->top >= d->stack);
7772 
7773  if (max < (size_t)(d->top - d->stack)) {
7774  /* Can't set a limit smaller than what we are currently at. */
7775  return false;
7776  }
7777 
7778  if (max > d->stack_size) {
7779  /* Need to reallocate stack and callstack to accommodate. */
7780  size_t old_size = stacksize(d, d->stack_size);
7781  size_t new_size = stacksize(d, max);
7782  void *p = upb_arena_realloc(d->arena, d->stack, old_size, new_size);
7783  if (!p) {
7784  return false;
7785  }
7786  d->stack = p;
7787 
7788  old_size = callstacksize(d, d->stack_size);
7789  new_size = callstacksize(d, max);
7790  p = upb_arena_realloc(d->arena, d->callstack, old_size, new_size);
7791  if (!p) {
7792  return false;
7793  }
7794  d->callstack = p;
7795 
7796  d->stack_size = max;
7797  }
7798 
7799  d->limit = d->stack + max - 1;
7800  return true;
7801 }
7802 /*
7803 ** upb::Encoder
7804 **
7805 ** Since we are implementing pure handlers (ie. without any out-of-band access
7806 ** to pre-computed lengths), we have to buffer all submessages before we can
7807 ** emit even their first byte.
7808 **
7809 ** Not knowing the size of submessages also means we can't write a perfect
7810 ** zero-copy implementation, even with buffering. Lengths are stored as
7811 ** varints, which means that we don't know how many bytes to reserve for the
7812 ** length until we know what the length is.
7813 **
7814 ** This leaves us with three main choices:
7815 **
7816 ** 1. buffer all submessage data in a temporary buffer, then copy it exactly
7817 ** once into the output buffer.
7818 **
7819 ** 2. attempt to buffer data directly into the output buffer, estimating how
7820 ** many bytes each length will take. When our guesses are wrong, use
7821 ** memmove() to grow or shrink the allotted space.
7822 **
7823 ** 3. buffer directly into the output buffer, allocating a max length
7824 ** ahead-of-time for each submessage length. If we overallocated, we waste
7825 ** space, but no memcpy() or memmove() is required. This approach requires
7826 ** defining a maximum size for submessages and rejecting submessages that
7827 ** exceed that size.
7828 **
7829 ** (2) and (3) have the potential to have better performance, but they are more
7830 ** complicated and subtle to implement:
7831 **
7832 ** (3) requires making an arbitrary choice of the maximum message size; it
7833 ** wastes space when submessages are shorter than this and fails
7834 ** completely when they are longer. This makes it more finicky and
7835 ** requires configuration based on the input. It also makes it impossible
7836 ** to perfectly match the output of reference encoders that always use the
7837 ** optimal amount of space for each length.
7838 **
7839 ** (2) requires guessing the the size upfront, and if multiple lengths are
7840 ** guessed wrong the minimum required number of memmove() operations may
7841 ** be complicated to compute correctly. Implemented properly, it may have
7842 ** a useful amortized or average cost, but more investigation is required
7843 ** to determine this and what the optimal algorithm is to achieve it.
7844 **
7845 ** (1) makes you always pay for exactly one copy, but its implementation is
7846 ** the simplest and its performance is predictable.
7847 **
7848 ** So for now, we implement (1) only. If we wish to optimize later, we should
7849 ** be able to do it without affecting users.
7850 **
7851 ** The strategy is to buffer the segments of data that do *not* depend on
7852 ** unknown lengths in one buffer, and keep a separate buffer of segment pointers
7853 ** and lengths. When the top-level submessage ends, we can go beginning to end,
7854 ** alternating the writing of lengths with memcpy() of the rest of the data.
7855 ** At the top level though, no buffering is required.
7856 */
7857 
7858 
7859 
7860 /* The output buffer is divided into segments; a segment is a string of data
7861  * that is "ready to go" -- it does not need any varint lengths inserted into
7862  * the middle. The seams between segments are where varints will be inserted
7863  * once they are known.
7864  *
7865  * We also use the concept of a "run", which is a range of encoded bytes that
7866  * occur at a single submessage level. Every segment contains one or more runs.
7867  *
7868  * A segment can span messages. Consider:
7869  *
7870  * .--Submessage lengths---------.
7871  * | | |
7872  * | V V
7873  * V | |--------------- | |-----------------
7874  * Submessages: | |-----------------------------------------------
7875  * Top-level msg: ------------------------------------------------------------
7876  *
7877  * Segments: ----- ------------------- -----------------
7878  * Runs: *---- *--------------*--- *----------------
7879  * (* marks the start)
7880  *
7881  * Note that the top-level menssage is not in any segment because it does not
7882  * have any length preceding it.
7883  *
7884  * A segment is only interrupted when another length needs to be inserted. So
7885  * observe how the second segment spans both the inner submessage and part of
7886  * the next enclosing message. */
7887 typedef struct {
7888  uint32_t msglen; /* The length to varint-encode before this segment. */
7889  uint32_t seglen; /* Length of the segment. */
7891 
7894 
7895  /* Our input and output. */
7898 
7899  /* The "subclosure" -- used as the inner closure as part of the bytessink
7900  * protocol. */
7901  void *subc;
7902 
7903  /* The output buffer and limit, and our current write position. "buf"
7904  * initially points to "initbuf", but is dynamically allocated if we need to
7905  * grow beyond the initial size. */
7906  char *buf, *ptr, *limit;
7907 
7908  /* The beginning of the current run, or undefined if we are at the top
7909  * level. */
7910  char *runbegin;
7911 
7912  /* The list of segments we are accumulating. */
7914 
7915  /* The stack of enclosing submessages. Each entry in the stack points to the
7916  * segment where this submessage's length is being accumulated. */
7918 
7919  /* Depth of startmsg/endmsg calls. */
7920  int depth;
7921 };
7922 
7923 /* low-level buffering ********************************************************/
7924 
7925 /* Low-level functions for interacting with the output buffer. */
7926 
7927 /* TODO(haberman): handle pushback */
7928 static void putbuf(upb_pb_encoder *e, const char *buf, size_t len) {
7929  size_t n = upb_bytessink_putbuf(e->output_, e->subc, buf, len, NULL);
7930  UPB_ASSERT(n == len);
7931 }
7932 
7934  return &e->segbuf[*e->top];
7935 }
7936 
7937 /* Call to ensure that at least "bytes" bytes are available for writing at
7938  * e->ptr. Returns false if the bytes could not be allocated. */
7939 static bool reserve(upb_pb_encoder *e, size_t bytes) {
7940  if ((size_t)(e->limit - e->ptr) < bytes) {
7941  /* Grow buffer. */
7942  char *new_buf;
7943  size_t needed = bytes + (e->ptr - e->buf);
7944  size_t old_size = e->limit - e->buf;
7945 
7946  size_t new_size = old_size;
7947 
7948  while (new_size < needed) {
7949  new_size *= 2;
7950  }
7951 
7952  new_buf = upb_arena_realloc(e->arena, e->buf, old_size, new_size);
7953 
7954  if (new_buf == NULL) {
7955  return false;
7956  }
7957 
7958  e->ptr = new_buf + (e->ptr - e->buf);
7959  e->runbegin = new_buf + (e->runbegin - e->buf);
7960  e->limit = new_buf + new_size;
7961  e->buf = new_buf;
7962  }
7963 
7964  return true;
7965 }
7966 
7967 /* Call when "bytes" bytes have been writte at e->ptr. The caller *must* have
7968  * previously called reserve() with at least this many bytes. */
7969 static void encoder_advance(upb_pb_encoder *e, size_t bytes) {
7970  UPB_ASSERT((size_t)(e->limit - e->ptr) >= bytes);
7971  e->ptr += bytes;
7972 }
7973 
7974 /* Call when all of the bytes for a handler have been written. Flushes the
7975  * bytes if possible and necessary, returning false if this failed. */
7976 static bool commit(upb_pb_encoder *e) {
7977  if (!e->top) {
7978  /* We aren't inside a delimited region. Flush our accumulated bytes to
7979  * the output.
7980  *
7981  * TODO(haberman): in the future we may want to delay flushing for
7982  * efficiency reasons. */
7983  putbuf(e, e->buf, e->ptr - e->buf);
7984  e->ptr = e->buf;
7985  }
7986 
7987  return true;
7988 }
7989 
7990 /* Writes the given bytes to the buffer, handling reserve/advance. */
7991 static bool encode_bytes(upb_pb_encoder *e, const void *data, size_t len) {
7992  if (!reserve(e, len)) {
7993  return false;
7994  }
7995 
7996  memcpy(e->ptr, data, len);
7997  encoder_advance(e, len);
7998  return true;
7999 }
8000 
8001 /* Finish the current run by adding the run totals to the segment and message
8002  * length. */
8003 static void accumulate(upb_pb_encoder *e) {
8004  size_t run_len;
8005  UPB_ASSERT(e->ptr >= e->runbegin);
8006  run_len = e->ptr - e->runbegin;
8007  e->segptr->seglen += run_len;
8008  top(e)->msglen += run_len;
8009  e->runbegin = e->ptr;
8010 }
8011 
8012 /* Call to indicate the start of delimited region for which the full length is
8013  * not yet known. All data will be buffered until the length is known.
8014  * Delimited regions may be nested; their lengths will all be tracked properly. */
8015 static bool start_delim(upb_pb_encoder *e) {
8016  if (e->top) {
8017  /* We are already buffering, advance to the next segment and push it on the
8018  * stack. */
8019  accumulate(e);
8020 
8021  if (++e->top == e->stacklimit) {
8022  /* TODO(haberman): grow stack? */
8023  return false;
8024  }
8025 
8026  if (++e->segptr == e->seglimit) {
8027  /* Grow segment buffer. */
8028  size_t old_size =
8029  (e->seglimit - e->segbuf) * sizeof(upb_pb_encoder_segment);
8030  size_t new_size = old_size * 2;
8031  upb_pb_encoder_segment *new_buf =
8032  upb_arena_realloc(e->arena, e->segbuf, old_size, new_size);
8033 
8034  if (new_buf == NULL) {
8035  return false;
8036  }
8037 
8038  e->segptr = new_buf + (e->segptr - e->segbuf);
8039  e->seglimit = new_buf + (new_size / sizeof(upb_pb_encoder_segment));
8040  e->segbuf = new_buf;
8041  }
8042  } else {
8043  /* We were previously at the top level, start buffering. */
8044  e->segptr = e->segbuf;
8045  e->top = e->stack;
8046  e->runbegin = e->ptr;
8047  }
8048 
8049  *e->top = e->segptr - e->segbuf;
8050  e->segptr->seglen = 0;
8051  e->segptr->msglen = 0;
8052 
8053  return true;
8054 }
8055 
8056 /* Call to indicate the end of a delimited region. We now know the length of
8057  * the delimited region. If we are not nested inside any other delimited
8058  * regions, we can now emit all of the buffered data we accumulated. */
8059 static bool end_delim(upb_pb_encoder *e) {
8060  size_t msglen;
8061  accumulate(e);
8062  msglen = top(e)->msglen;
8063 
8064  if (e->top == e->stack) {
8065  /* All lengths are now available, emit all buffered data. */
8066  char buf[UPB_PB_VARINT_MAX_LEN];
8068  const char *ptr = e->buf;
8069  for (s = e->segbuf; s <= e->segptr; s++) {
8070  size_t lenbytes = upb_vencode64(s->msglen, buf);
8071  putbuf(e, buf, lenbytes);
8072  putbuf(e, ptr, s->seglen);
8073  ptr += s->seglen;
8074  }
8075 
8076  e->ptr = e->buf;
8077  e->top = NULL;
8078  } else {
8079  /* Need to keep buffering; propagate length info into enclosing
8080  * submessages. */
8081  --e->top;
8082  top(e)->msglen += msglen + upb_varint_size(msglen);
8083  }
8084 
8085  return true;
8086 }
8087 
8088 
8089 /* tag_t **********************************************************************/
8090 
8091 /* A precomputed (pre-encoded) tag and length. */
8092 
8093 typedef struct {
8094  uint8_t bytes;
8095  char tag[7];
8096 } tag_t;
8097 
8098 /* Allocates a new tag for this field, and sets it in these handlerattr. */
8100  upb_handlerattr *attr) {
8101  uint32_t n = upb_fielddef_number(f);
8102 
8103  tag_t *tag = upb_gmalloc(sizeof(tag_t));
8104  tag->bytes = upb_vencode64((n << 3) | wt, tag->tag);
8105 
8106  attr->handler_data = tag;
8108 }
8109 
8110 static bool encode_tag(upb_pb_encoder *e, const tag_t *tag) {
8111  return encode_bytes(e, tag->tag, tag->bytes);
8112 }
8113 
8114 
8115 /* encoding of wire types *****************************************************/
8116 
8117 static bool encode_fixed64(upb_pb_encoder *e, uint64_t val) {
8118  /* TODO(haberman): byte-swap for big endian. */
8119  return encode_bytes(e, &val, sizeof(uint64_t));
8120 }
8121 
8122 static bool encode_fixed32(upb_pb_encoder *e, uint32_t val) {
8123  /* TODO(haberman): byte-swap for big endian. */
8124  return encode_bytes(e, &val, sizeof(uint32_t));
8125 }
8126 
8127 static bool encode_varint(upb_pb_encoder *e, uint64_t val) {
8128  if (!reserve(e, UPB_PB_VARINT_MAX_LEN)) {
8129  return false;
8130  }
8131 
8133  return true;
8134 }
8135 
8136 static uint64_t dbl2uint64(double d) {
8137  uint64_t ret;
8138  memcpy(&ret, &d, sizeof(uint64_t));
8139  return ret;
8140 }
8141 
8142 static uint32_t flt2uint32(float d) {
8143  uint32_t ret;
8144  memcpy(&ret, &d, sizeof(uint32_t));
8145  return ret;
8146 }
8147 
8148 
8149 /* encoding of proto types ****************************************************/
8150 
8151 static bool startmsg(void *c, const void *hd) {
8152  upb_pb_encoder *e = c;
8153  UPB_UNUSED(hd);
8154  if (e->depth++ == 0) {
8155  upb_bytessink_start(e->output_, 0, &e->subc);
8156  }
8157  return true;
8158 }
8159 
8160 static bool endmsg(void *c, const void *hd, upb_status *status) {
8161  upb_pb_encoder *e = c;
8162  UPB_UNUSED(hd);
8163  UPB_UNUSED(status);
8164  if (--e->depth == 0) {
8166  }
8167  return true;
8168 }
8169 
8170 static void *encode_startdelimfield(void *c, const void *hd) {
8171  bool ok = encode_tag(c, hd) && commit(c) && start_delim(c);
8172  return ok ? c : UPB_BREAK;
8173 }
8174 
8175 static bool encode_unknown(void *c, const void *hd, const char *buf,
8176  size_t len) {
8177  UPB_UNUSED(hd);
8178  return encode_bytes(c, buf, len) && commit(c);
8179 }
8180 
8181 static bool encode_enddelimfield(void *c, const void *hd) {
8182  UPB_UNUSED(hd);
8183  return end_delim(c);
8184 }
8185 
8186 static void *encode_startgroup(void *c, const void *hd) {
8187  return (encode_tag(c, hd) && commit(c)) ? c : UPB_BREAK;
8188 }
8189 
8190 static bool encode_endgroup(void *c, const void *hd) {
8191  return encode_tag(c, hd) && commit(c);
8192 }
8193 
8194 static void *encode_startstr(void *c, const void *hd, size_t size_hint) {
8195  UPB_UNUSED(size_hint);
8196  return encode_startdelimfield(c, hd);
8197 }
8198 
8199 static size_t encode_strbuf(void *c, const void *hd, const char *buf,
8200  size_t len, const upb_bufhandle *h) {
8201  UPB_UNUSED(hd);
8202  UPB_UNUSED(h);
8203  return encode_bytes(c, buf, len) ? len : 0;
8204 }
8205 
8206 #define T(type, ctype, convert, encode) \
8207  static bool encode_scalar_##type(void *e, const void *hd, ctype val) { \
8208  return encode_tag(e, hd) && encode(e, (convert)(val)) && commit(e); \
8209  } \
8210  static bool encode_packed_##type(void *e, const void *hd, ctype val) { \
8211  UPB_UNUSED(hd); \
8212  return encode(e, (convert)(val)); \
8213  }
8214 
8215 T(double, double, dbl2uint64, encode_fixed64)
8216 T(float, float, flt2uint32, encode_fixed32)
8217 T(int64, int64_t, uint64_t, encode_varint)
8218 T(int32, int32_t, int64_t, encode_varint)
8219 T(fixed64, uint64_t, uint64_t, encode_fixed64)
8220 T(fixed32, uint32_t, uint32_t, encode_fixed32)
8221 T(bool, bool, bool, encode_varint)
8222 T(uint32, uint32_t, uint32_t, encode_varint)
8223 T(uint64, uint64_t, uint64_t, encode_varint)
8224 T(enum, int32_t, uint32_t, encode_varint)
8225 T(sfixed32, int32_t, uint32_t, encode_fixed32)
8226 T(sfixed64, int64_t, uint64_t, encode_fixed64)
8227 T(sint32, int32_t, upb_zzenc_32, encode_varint)
8228 T(sint64, int64_t, upb_zzenc_64, encode_varint)
8229 
8230 #undef T
8231 
8232 
8233 /* code to build the handlers *************************************************/
8234 
8235 #include <stdio.h>
8236 static void newhandlers_callback(const void *closure, upb_handlers *h) {
8237  const upb_msgdef *m;
8239 
8240  UPB_UNUSED(closure);
8241 
8245 
8246  m = upb_handlers_msgdef(h);
8247  for(upb_msg_field_begin(&i, m);
8248  !upb_msg_field_done(&i);
8249  upb_msg_field_next(&i)) {
8250  const upb_fielddef *f = upb_msg_iter_field(&i);
8251  bool packed = upb_fielddef_isseq(f) && upb_fielddef_isprimitive(f) &&
8254  upb_wiretype_t wt =
8255  packed ? UPB_WIRE_TYPE_DELIMITED
8257 
8258  /* Pre-encode the tag for this field. */
8259  new_tag(h, f, wt, &attr);
8260 
8261  if (packed) {
8264  }
8265 
8266 #define T(upper, lower, upbtype) \
8267  case UPB_DESCRIPTOR_TYPE_##upper: \
8268  if (packed) { \
8269  upb_handlers_set##upbtype(h, f, encode_packed_##lower, &attr); \
8270  } else { \
8271  upb_handlers_set##upbtype(h, f, encode_scalar_##lower, &attr); \
8272  } \
8273  break;
8274 
8275  switch (upb_fielddef_descriptortype(f)) {
8276  T(DOUBLE, double, double);
8277  T(FLOAT, float, float);
8278  T(INT64, int64, int64);
8279  T(INT32, int32, int32);
8280  T(FIXED64, fixed64, uint64);
8281  T(FIXED32, fixed32, uint32);
8282  T(BOOL, bool, bool);
8283  T(UINT32, uint32, uint32);
8284  T(UINT64, uint64, uint64);
8285  T(ENUM, enum, int32);
8286  T(SFIXED32, sfixed32, int32);
8287  T(SFIXED64, sfixed64, int64);
8288  T(SINT32, sint32, int32);
8289  T(SINT64, sint64, int64);
8295  break;
8299  break;
8301  /* Endgroup takes a different tag (wire_type = END_GROUP). */
8303  new_tag(h, f, UPB_WIRE_TYPE_END_GROUP, &attr2);
8304 
8307 
8308  break;
8309  }
8310  }
8311 
8312 #undef T
8313  }
8314 }
8315 
8317  e->segptr = NULL;
8318  e->top = NULL;
8319  e->depth = 0;
8320 }
8321 
8322 
8323 /* public API *****************************************************************/
8324 
8326  return upb_handlercache_new(newhandlers_callback, NULL);
8327 }
8328 
8331  const size_t initial_bufsize = 256;
8332  const size_t initial_segbufsize = 16;
8333  /* TODO(haberman): make this configurable. */
8334  const size_t stack_size = 64;
8335 #ifndef NDEBUG
8336  const size_t size_before = upb_arena_bytesallocated(arena);
8337 #endif
8338 
8339  upb_pb_encoder *e = upb_arena_malloc(arena, sizeof(upb_pb_encoder));
8340  if (!e) return NULL;
8341 
8342  e->buf = upb_arena_malloc(arena, initial_bufsize);
8343  e->segbuf = upb_arena_malloc(arena, initial_segbufsize * sizeof(*e->segbuf));
8344  e->stack = upb_arena_malloc(arena, stack_size * sizeof(*e->stack));
8345 
8346  if (!e->buf || !e->segbuf || !e->stack) {
8347  return NULL;
8348  }
8349 
8350  e->limit = e->buf + initial_bufsize;
8351  e->seglimit = e->segbuf + initial_segbufsize;
8352  e->stacklimit = e->stack + stack_size;
8353 
8355  upb_sink_reset(&e->input_, h, e);
8356 
8357  e->arena = arena;
8358  e->output_ = output;
8359  e->subc = output.closure;
8360  e->ptr = e->buf;
8361 
8362  /* If this fails, increase the value in encoder.h. */
8363  UPB_ASSERT_DEBUGVAR(upb_arena_bytesallocated(arena) - size_before <=
8365  return e;
8366 }
8367 
8369 /*
8370  * upb::pb::TextPrinter
8371  *
8372  * OPT: This is not optimized at all. It uses printf() which parses the format
8373  * string every time, and it allocates memory for every put.
8374  */
8375 
8376 
8377 #include <ctype.h>
8378 #include <float.h>
8379 #include <inttypes.h>
8380 #include <stdarg.h>
8381 #include <stdio.h>
8382 #include <string.h>
8383 
8384 
8390  void *subc;
8391 };
8392 
8393 #define CHECK(x) if ((x) < 0) goto err;
8394 
8395 static const char *shortname(const char *longname) {
8396  const char *last = strrchr(longname, '.');
8397  return last ? last + 1 : longname;
8398 }
8399 
8400 static int indent(upb_textprinter *p) {
8401  int i;
8402  if (!p->single_line_)
8403  for (i = 0; i < p->indent_depth_; i++)
8404  upb_bytessink_putbuf(p->output_, p->subc, " ", 2, NULL);
8405  return 0;
8406 }
8407 
8409  const char ch = (p->single_line_ ? ' ' : '\n');
8410  upb_bytessink_putbuf(p->output_, p->subc, &ch, 1, NULL);
8411  return 0;
8412 }
8413 
8414 static int putescaped(upb_textprinter *p, const char *buf, size_t len,
8415  bool preserve_utf8) {
8416  /* Based on CEscapeInternal() from Google's protobuf release. */
8417  char dstbuf[4096], *dst = dstbuf, *dstend = dstbuf + sizeof(dstbuf);
8418  const char *end = buf + len;
8419 
8420  /* I think hex is prettier and more useful, but proto2 uses octal; should
8421  * investigate whether it can parse hex also. */
8422  const bool use_hex = false;
8423  bool last_hex_escape = false; /* true if last output char was \xNN */
8424 
8425  for (; buf < end; buf++) {
8426  bool is_hex_escape;
8427 
8428  if (dstend - dst < 4) {
8429  upb_bytessink_putbuf(p->output_, p->subc, dstbuf, dst - dstbuf, NULL);
8430  dst = dstbuf;
8431  }
8432 
8433  is_hex_escape = false;
8434  switch (*buf) {
8435  case '\n': *(dst++) = '\\'; *(dst++) = 'n'; break;
8436  case '\r': *(dst++) = '\\'; *(dst++) = 'r'; break;
8437  case '\t': *(dst++) = '\\'; *(dst++) = 't'; break;
8438  case '\"': *(dst++) = '\\'; *(dst++) = '\"'; break;
8439  case '\'': *(dst++) = '\\'; *(dst++) = '\''; break;
8440  case '\\': *(dst++) = '\\'; *(dst++) = '\\'; break;
8441  default:
8442  /* Note that if we emit \xNN and the buf character after that is a hex
8443  * digit then that digit must be escaped too to prevent it being
8444  * interpreted as part of the character code by C. */
8445  if ((!preserve_utf8 || (uint8_t)*buf < 0x80) &&
8446  (!isprint(*buf) || (last_hex_escape && isxdigit(*buf)))) {
8447  sprintf(dst, (use_hex ? "\\x%02x" : "\\%03o"), (uint8_t)*buf);
8448  is_hex_escape = use_hex;
8449  dst += 4;
8450  } else {
8451  *(dst++) = *buf; break;
8452  }
8453  }
8454  last_hex_escape = is_hex_escape;
8455  }
8456  /* Flush remaining data. */
8457  upb_bytessink_putbuf(p->output_, p->subc, dstbuf, dst - dstbuf, NULL);
8458  return 0;
8459 }
8460 
8461 bool putf(upb_textprinter *p, const char *fmt, ...) {
8462  va_list args;
8463  va_list args_copy;
8464  char *str;
8465  int written;
8466  int len;
8467  bool ok;
8468 
8469  va_start(args, fmt);
8470 
8471  /* Run once to get the length of the string. */
8472  _upb_va_copy(args_copy, args);
8473  len = _upb_vsnprintf(NULL, 0, fmt, args_copy);
8474  va_end(args_copy);
8475 
8476  /* + 1 for NULL terminator (vsprintf() requires it even if we don't). */
8477  str = upb_gmalloc(len + 1);
8478  if (!str) return false;
8479  written = vsprintf(str, fmt, args);
8480  va_end(args);
8481  UPB_ASSERT(written == len);
8482 
8483  ok = upb_bytessink_putbuf(p->output_, p->subc, str, len, NULL);
8484  upb_gfree(str);
8485  return ok;
8486 }
8487 
8488 
8489 /* handlers *******************************************************************/
8490 
8491 static bool textprinter_startmsg(void *c, const void *hd) {
8492  upb_textprinter *p = c;
8493  UPB_UNUSED(hd);
8494  if (p->indent_depth_ == 0) {
8495  upb_bytessink_start(p->output_, 0, &p->subc);
8496  }
8497  return true;
8498 }
8499 
8500 static bool textprinter_endmsg(void *c, const void *hd, upb_status *s) {
8501  upb_textprinter *p = c;
8502  UPB_UNUSED(hd);
8503  UPB_UNUSED(s);
8504  if (p->indent_depth_ == 0) {
8505  upb_bytessink_end(p->output_);
8506  }
8507  return true;
8508 }
8509 
8510 #define TYPE(name, ctype, fmt) \
8511  static bool textprinter_put ## name(void *closure, const void *handler_data, \
8512  ctype val) { \
8513  upb_textprinter *p = closure; \
8514  const upb_fielddef *f = handler_data; \
8515  CHECK(indent(p)); \
8516  putf(p, "%s: " fmt, upb_fielddef_name(f), val); \
8517  CHECK(endfield(p)); \
8518  return true; \
8519  err: \
8520  return false; \
8521 }
8522 
8523 static bool textprinter_putbool(void *closure, const void *handler_data,
8524  bool val) {
8525  upb_textprinter *p = closure;
8526  const upb_fielddef *f = handler_data;
8527  CHECK(indent(p));
8528  putf(p, "%s: %s", upb_fielddef_name(f), val ? "true" : "false");
8529  CHECK(endfield(p));
8530  return true;
8531 err:
8532  return false;
8533 }
8534 
8535 #define STRINGIFY_HELPER(x) #x
8536 #define STRINGIFY_MACROVAL(x) STRINGIFY_HELPER(x)
8537 
8538 TYPE(int32, int32_t, "%" PRId32)
8539 TYPE(int64, int64_t, "%" PRId64)
8540 TYPE(uint32, uint32_t, "%" PRIu32)
8541 TYPE(uint64, uint64_t, "%" PRIu64)
8542 TYPE(float, float, "%." STRINGIFY_MACROVAL(FLT_DIG) "g")
8543 TYPE(double, double, "%." STRINGIFY_MACROVAL(DBL_DIG) "g")
8544 
8545 #undef TYPE
8546 
8547 /* Output a symbolic value from the enum if found, else just print as int32. */
8548 static bool textprinter_putenum(void *closure, const void *handler_data,
8549  int32_t val) {
8550  upb_textprinter *p = closure;
8551  const upb_fielddef *f = handler_data;
8552  const upb_enumdef *enum_def = upb_fielddef_enumsubdef(f);
8553  const char *label = upb_enumdef_iton(enum_def, val);
8554  if (label) {
8555  indent(p);
8556  putf(p, "%s: %s", upb_fielddef_name(f), label);
8557  endfield(p);
8558  } else {
8559  if (!textprinter_putint32(closure, handler_data, val))
8560  return false;
8561  }
8562  return true;
8563 }
8564 
8565 static void *textprinter_startstr(void *closure, const void *handler_data,
8566  size_t size_hint) {
8567  upb_textprinter *p = closure;
8568  const upb_fielddef *f = handler_data;
8569  UPB_UNUSED(size_hint);
8570  indent(p);
8571  putf(p, "%s: \"", upb_fielddef_name(f));
8572  return p;
8573 }
8574 
8575 static bool textprinter_endstr(void *closure, const void *handler_data) {
8576  upb_textprinter *p = closure;
8577  UPB_UNUSED(handler_data);
8578  putf(p, "\"");
8579  endfield(p);
8580  return true;
8581 }
8582 
8583 static size_t textprinter_putstr(void *closure, const void *hd, const char *buf,
8584  size_t len, const upb_bufhandle *handle) {
8585  upb_textprinter *p = closure;
8586  const upb_fielddef *f = hd;
8587  UPB_UNUSED(handle);
8589  return len;
8590 err:
8591  return 0;
8592 }
8593 
8594 static void *textprinter_startsubmsg(void *closure, const void *handler_data) {
8595  upb_textprinter *p = closure;
8596  const char *name = handler_data;
8597  CHECK(indent(p));
8598  putf(p, "%s {%c", name, p->single_line_ ? ' ' : '\n');
8599  p->indent_depth_++;
8600  return p;
8601 err:
8602  return UPB_BREAK;
8603 }
8604 
8605 static bool textprinter_endsubmsg(void *closure, const void *handler_data) {
8606  upb_textprinter *p = closure;
8607  UPB_UNUSED(handler_data);
8608  p->indent_depth_--;
8609  CHECK(indent(p));
8610  upb_bytessink_putbuf(p->output_, p->subc, "}", 1, NULL);
8611  CHECK(endfield(p));
8612  return true;
8613 err:
8614  return false;
8615 }
8616 
8617 static void onmreg(const void *c, upb_handlers *h) {
8618  const upb_msgdef *m = upb_handlers_msgdef(h);
8620  UPB_UNUSED(c);
8621 
8624 
8625  for(upb_msg_field_begin(&i, m);
8626  !upb_msg_field_done(&i);
8627  upb_msg_field_next(&i)) {
8630  attr.handler_data = f;
8631  switch (upb_fielddef_type(f)) {
8632  case UPB_TYPE_INT32:
8633  upb_handlers_setint32(h, f, textprinter_putint32, &attr);
8634  break;
8635  case UPB_TYPE_INT64:
8636  upb_handlers_setint64(h, f, textprinter_putint64, &attr);
8637  break;
8638  case UPB_TYPE_UINT32:
8639  upb_handlers_setuint32(h, f, textprinter_putuint32, &attr);
8640  break;
8641  case UPB_TYPE_UINT64:
8642  upb_handlers_setuint64(h, f, textprinter_putuint64, &attr);
8643  break;
8644  case UPB_TYPE_FLOAT:
8645  upb_handlers_setfloat(h, f, textprinter_putfloat, &attr);
8646  break;
8647  case UPB_TYPE_DOUBLE:
8648  upb_handlers_setdouble(h, f, textprinter_putdouble, &attr);
8649  break;
8650  case UPB_TYPE_BOOL:
8652  break;
8653  case UPB_TYPE_STRING:
8654  case UPB_TYPE_BYTES:
8658  break;
8659  case UPB_TYPE_MESSAGE: {
8660  const char *name =
8663  : upb_fielddef_name(f);
8664  attr.handler_data = name;
8667  break;
8668  }
8669  case UPB_TYPE_ENUM:
8671  break;
8672  }
8673  }
8674 }
8675 
8676 static void textprinter_reset(upb_textprinter *p, bool single_line) {
8677  p->single_line_ = single_line;
8678  p->indent_depth_ = 0;
8679 }
8680 
8681 
8682 /* Public API *****************************************************************/
8683 
8687  if (!p) return NULL;
8688 
8689  p->output_ = output;
8690  upb_sink_reset(&p->input_, h, p);
8691  textprinter_reset(p, false);
8692 
8693  return p;
8694 }
8695 
8697  return upb_handlercache_new(&onmreg, NULL);
8698 }
8699 
8701 
8703  p->single_line_ = single_line;
8704 }
8705 
8706 
8707 /* Index is descriptor type. */
8708 const uint8_t upb_pb_native_wire_types[] = {
8709  UPB_WIRE_TYPE_END_GROUP, /* ENDGROUP */
8710  UPB_WIRE_TYPE_64BIT, /* DOUBLE */
8711  UPB_WIRE_TYPE_32BIT, /* FLOAT */
8712  UPB_WIRE_TYPE_VARINT, /* INT64 */
8713  UPB_WIRE_TYPE_VARINT, /* UINT64 */
8714  UPB_WIRE_TYPE_VARINT, /* INT32 */
8715  UPB_WIRE_TYPE_64BIT, /* FIXED64 */
8716  UPB_WIRE_TYPE_32BIT, /* FIXED32 */
8717  UPB_WIRE_TYPE_VARINT, /* BOOL */
8718  UPB_WIRE_TYPE_DELIMITED, /* STRING */
8719  UPB_WIRE_TYPE_START_GROUP, /* GROUP */
8720  UPB_WIRE_TYPE_DELIMITED, /* MESSAGE */
8721  UPB_WIRE_TYPE_DELIMITED, /* BYTES */
8722  UPB_WIRE_TYPE_VARINT, /* UINT32 */
8723  UPB_WIRE_TYPE_VARINT, /* ENUM */
8724  UPB_WIRE_TYPE_32BIT, /* SFIXED32 */
8725  UPB_WIRE_TYPE_64BIT, /* SFIXED64 */
8726  UPB_WIRE_TYPE_VARINT, /* SINT32 */
8727  UPB_WIRE_TYPE_VARINT, /* SINT64 */
8728 };
8729 
8730 /* A basic branch-based decoder, uses 32-bit values to get good performance
8731  * on 32-bit architectures (but performs well on 64-bits also).
8732  * This scheme comes from the original Google Protobuf implementation
8733  * (proto2). */
8735  upb_decoderet err = {NULL, 0};
8736  const char *p = r.p;
8737  uint32_t low = (uint32_t)r.val;
8738  uint32_t high = 0;
8739  uint32_t b;
8740  b = *(p++); low |= (b & 0x7fU) << 14; if (!(b & 0x80)) goto done;
8741  b = *(p++); low |= (b & 0x7fU) << 21; if (!(b & 0x80)) goto done;
8742  b = *(p++); low |= (b & 0x7fU) << 28;
8743  high = (b & 0x7fU) >> 4; if (!(b & 0x80)) goto done;
8744  b = *(p++); high |= (b & 0x7fU) << 3; if (!(b & 0x80)) goto done;
8745  b = *(p++); high |= (b & 0x7fU) << 10; if (!(b & 0x80)) goto done;
8746  b = *(p++); high |= (b & 0x7fU) << 17; if (!(b & 0x80)) goto done;
8747  b = *(p++); high |= (b & 0x7fU) << 24; if (!(b & 0x80)) goto done;
8748  b = *(p++); high |= (b & 0x7fU) << 31; if (!(b & 0x80)) goto done;
8749  return err;
8750 
8751 done:
8752  r.val = ((uint64_t)high << 32) | low;
8753  r.p = p;
8754  return r;
8755 }
8756 
8757 /* Like the previous, but uses 64-bit values. */
8759  const char *p = r.p;
8760  uint64_t val = r.val;
8761  uint64_t b;
8762  upb_decoderet err = {NULL, 0};
8763  b = *(p++); val |= (b & 0x7fU) << 14; if (!(b & 0x80)) goto done;
8764  b = *(p++); val |= (b & 0x7fU) << 21; if (!(b & 0x80)) goto done;
8765  b = *(p++); val |= (b & 0x7fU) << 28; if (!(b & 0x80)) goto done;
8766  b = *(p++); val |= (b & 0x7fU) << 35; if (!(b & 0x80)) goto done;
8767  b = *(p++); val |= (b & 0x7fU) << 42; if (!(b & 0x80)) goto done;
8768  b = *(p++); val |= (b & 0x7fU) << 49; if (!(b & 0x80)) goto done;
8769  b = *(p++); val |= (b & 0x7fU) << 56; if (!(b & 0x80)) goto done;
8770  b = *(p++); val |= (b & 0x7fU) << 63; if (!(b & 0x80)) goto done;
8771  return err;
8772 
8773 done:
8774  r.val = val;
8775  r.p = p;
8776  return r;
8777 }
8778 
8779 #line 1 "upb/json/parser.rl"
8780 /*
8781 ** upb::json::Parser (upb_json_parser)
8782 **
8783 ** A parser that uses the Ragel State Machine Compiler to generate
8784 ** the finite automata.
8785 **
8786 ** Ragel only natively handles regular languages, but we can manually
8787 ** program it a bit to handle context-free languages like JSON, by using
8788 ** the "fcall" and "fret" constructs.
8789 **
8790 ** This parser can handle the basics, but needs several things to be fleshed
8791 ** out:
8792 **
8793 ** - handling of unicode escape sequences (including high surrogate pairs).
8794 ** - properly check and report errors for unknown fields, stack overflow,
8795 ** improper array nesting (or lack of nesting).
8796 ** - handling of base64 sequences with padding characters.
8797 ** - handling of push-back (non-success returns from sink functions).
8798 ** - handling of keys/escape-sequences/etc that span input buffers.
8799 */
8800 
8801 #include <ctype.h>
8802 #include <errno.h>
8803 #include <float.h>
8804 #include <math.h>
8805 #include <stdint.h>
8806 #include <stdio.h>
8807 #include <stdlib.h>
8808 #include <string.h>
8809 
8810 #include <time.h>
8811 
8812 
8813 #define UPB_JSON_MAX_DEPTH 64
8814 
8815 /* Type of value message */
8816 enum {
8823 };
8824 
8825 /* Forward declare */
8826 static bool is_top_level(upb_json_parser *p);
8829 
8833 
8837 
8838 static bool does_fieldmask_start(upb_json_parser *p);
8839 static bool does_fieldmask_end(upb_json_parser *p);
8841 static void end_fieldmask_object(upb_json_parser *p);
8842 
8843 static void start_wrapper_object(upb_json_parser *p);
8844 static void end_wrapper_object(upb_json_parser *p);
8845 
8846 static void start_value_object(upb_json_parser *p, int value_type);
8847 static void end_value_object(upb_json_parser *p);
8848 
8850 static void end_listvalue_object(upb_json_parser *p);
8851 
8854 
8855 static void start_object(upb_json_parser *p);
8856 static void end_object(upb_json_parser *p);
8857 
8858 static void start_any_object(upb_json_parser *p, const char *ptr);
8859 static bool end_any_object(upb_json_parser *p, const char *ptr);
8860 
8861 static bool start_subobject(upb_json_parser *p);
8862 static void end_subobject(upb_json_parser *p);
8863 
8864 static void start_member(upb_json_parser *p);
8865 static void end_member(upb_json_parser *p);
8866 static bool end_membername(upb_json_parser *p);
8867 
8868 static void start_any_member(upb_json_parser *p, const char *ptr);
8869 static void end_any_member(upb_json_parser *p, const char *ptr);
8870 static bool end_any_membername(upb_json_parser *p);
8871 
8872 size_t parse(void *closure, const void *hd, const char *buf, size_t size,
8873  const upb_bufhandle *handle);
8874 static bool end(void *closure, const void *hd);
8875 
8876 static const char eof_ch = 'e';
8877 
8878 /* stringsink */
8879 typedef struct {
8882  char *ptr;
8883  size_t len, size;
8884 } upb_stringsink;
8885 
8886 
8887 static void *stringsink_start(void *_sink, const void *hd, size_t size_hint) {
8888  upb_stringsink *sink = _sink;
8889  sink->len = 0;
8890  UPB_UNUSED(hd);
8891  UPB_UNUSED(size_hint);
8892  return sink;
8893 }
8894 
8895 static size_t stringsink_string(void *_sink, const void *hd, const char *ptr,
8896  size_t len, const upb_bufhandle *handle) {
8897  upb_stringsink *sink = _sink;
8898  size_t new_size = sink->size;
8899 
8900  UPB_UNUSED(hd);
8901  UPB_UNUSED(handle);
8902 
8903  while (sink->len + len > new_size) {
8904  new_size *= 2;
8905  }
8906 
8907  if (new_size != sink->size) {
8908  sink->ptr = realloc(sink->ptr, new_size);
8909  sink->size = new_size;
8910  }
8911 
8912  memcpy(sink->ptr + sink->len, ptr, len);
8913  sink->len += len;
8914 
8915  return len;
8916 }
8917 
8922 
8923  upb_bytessink_reset(&sink->sink, &sink->handler, sink);
8924 
8925  sink->size = 32;
8926  sink->ptr = malloc(sink->size);
8927  sink->len = 0;
8928 }
8929 
8930 void upb_stringsink_uninit(upb_stringsink *sink) { free(sink->ptr); }
8931 
8932 typedef struct {
8933  /* For encoding Any value field in binary format. */
8936 
8937  /* For decoding Any value field in json format. */
8941 
8942  /* Mark the range of uninterpreted values in json input before type url. */
8944  const char *before_type_url_end;
8945 
8946  /* Mark the range of uninterpreted values in json input after type url. */
8949 
8950 typedef struct {
8952 
8953  /* The current message in which we're parsing, and the field whose value we're
8954  * expecting next. */
8955  const upb_msgdef *m;
8956  const upb_fielddef *f;
8957 
8958  /* The table mapping json name to fielddef for this message. */
8960 
8961  /* We are in a repeated-field context. We need this flag to decide whether to
8962  * handle the array as a normal repeated field or a
8963  * google.protobuf.ListValue/google.protobuf.Value. */
8965 
8966  /* We are in a repeated-field context, ready to emit mapentries as
8967  * submessages. This flag alters the start-of-object (open-brace) behavior to
8968  * begin a sequence of mapentry messages rather than a single submessage. */
8969  bool is_map;
8970 
8971  /* We are in a map-entry message context. This flag is set when parsing the
8972  * value field of a single map entry and indicates to all value-field parsers
8973  * (subobjects, strings, numbers, and bools) that the map-entry submessage
8974  * should end as soon as the value is parsed. */
8976 
8977  /* If |is_map| or |is_mapentry| is true, |mapfield| refers to the parent
8978  * message's map field that we're currently parsing. This differs from |f|
8979  * because |f| is the field in the *current* message (i.e., the map-entry
8980  * message itself), not the parent's field that leads to this map. */
8982 
8983  /* We are in an Any message context. This flag is set when parsing the Any
8984  * message and indicates to all field parsers (subobjects, strings, numbers,
8985  * and bools) that the parsed field should be serialized as binary data or
8986  * cached (type url not found yet). */
8987  bool is_any;
8988 
8989  /* The type of packed message in Any. */
8991 
8992  /* True if the field to be parsed is unknown. */
8995 
8996 static void init_frame(upb_jsonparser_frame* frame) {
8997  frame->m = NULL;
8998  frame->f = NULL;
8999  frame->name_table = NULL;
9000  frame->is_repeated = false;
9001  frame->is_map = false;
9002  frame->is_mapentry = false;
9003  frame->mapfield = NULL;
9004  frame->is_any = false;
9005  frame->any_frame = NULL;
9006  frame->is_unknown_field = false;
9007 }
9008 
9013 
9014  /* Stack to track the JSON scopes we are in. */
9018 
9020 
9021  /* Ragel's internal parsing stack for the parsing state machine. */
9025 
9026  /* The handle for the current buffer. */
9028 
9029  /* Accumulate buffer. See details in parser.rl. */
9030  const char *accumulated;
9034 
9035  /* Multi-part text data. See details in parser.rl. */
9038 
9039  /* Input capture. See details in parser.rl. */
9040  const char *capture;
9041 
9042  /* Intermediate result of parsing a unicode escape sequence. */
9043  uint32_t digit;
9044 
9045  /* For resolve type url in Any. */
9047 
9048  /* Whether to proceed if unknown field is met. */
9050 
9051  /* Cache for parsing timestamp due to base and zone are handled in different
9052  * handlers. */
9053  struct tm tm;
9054 };
9055 
9057  upb_jsonparser_frame *inner;
9058  inner = p->top + 1;
9059  init_frame(inner);
9060  return inner;
9061 }
9062 
9065  upb_inttable methods; /* upb_msgdef* -> upb_json_parsermethod* */
9066 };
9067 
9071 
9072  /* Maps json_name -> fielddef */
9074 };
9075 
9076 #define PARSER_CHECK_RETURN(x) if (!(x)) return false
9077 
9079  upb_json_parser *p) {
9080  upb_jsonparser_any_frame *frame;
9081 
9082  frame = upb_arena_malloc(p->arena, sizeof(upb_jsonparser_any_frame));
9083 
9086  frame->parser = NULL;
9087  frame->before_type_url_start = NULL;
9088  frame->before_type_url_end = NULL;
9089  frame->after_type_url_start = NULL;
9090 
9092 
9093  return frame;
9094 }
9095 
9097  upb_json_parser *p,
9098  upb_jsonparser_any_frame *frame,
9099  const upb_msgdef *payload_type) {
9100  const upb_handlers *h;
9101  const upb_json_parsermethod *parser_method;
9103 
9104  /* Initialize encoder. */
9105  h = upb_handlercache_get(frame->encoder_handlercache, payload_type);
9106  encoder = upb_pb_encoder_create(p->arena, h, frame->stringsink.sink);
9107 
9108  /* Initialize parser. */
9109  parser_method = upb_json_codecache_get(frame->parser_codecache, payload_type);
9110  upb_sink_reset(&frame->sink, h, encoder);
9111  frame->parser =
9112  upb_json_parser_create(p->arena, parser_method, p->symtab, frame->sink,
9113  p->status, p->ignore_json_unknown);
9114 }
9115 
9120 }
9121 
9123  upb_jsonparser_any_frame *frame) {
9124  return frame->parser != NULL;
9125 }
9126 
9128  upb_jsonparser_any_frame *frame) {
9129  return frame->before_type_url_start != frame->before_type_url_end;
9130 }
9131 
9133  upb_jsonparser_any_frame *frame) {
9134  return frame->after_type_url_start != NULL;
9135 }
9136 
9138  upb_jsonparser_any_frame *frame) {
9141 }
9142 
9144  upb_jsonparser_any_frame *frame,
9145  const char *ptr) {
9146  if (frame->parser == NULL) {
9147  frame->before_type_url_end = ptr;
9148  }
9149 }
9150 
9152  upb_jsonparser_any_frame *frame,
9153  const char *ptr) {
9155  frame->after_type_url_start == NULL) {
9156  frame->after_type_url_start = ptr;
9157  }
9158 }
9159 
9160 /* Used to signal that a capture has been suspended. */
9161 static char suspend_capture;
9162 
9165  upb_selector_t sel;
9166  bool ok = upb_handlers_getselector(p->top->f, type, &sel);
9167  UPB_ASSERT(ok);
9168  return sel;
9169 }
9170 
9172  return getsel_for_handlertype(
9174 }
9175 
9177  if ((p->top + 1) == p->limit) {
9178  upb_status_seterrmsg(p->status, "Nesting too deep");
9179  return false;
9180  }
9181 
9182  return true;
9183 }
9184 
9186  upb_value v;
9187  const upb_json_codecache *cache = p->method->cache;
9188  bool ok;
9190 
9191  ok = upb_inttable_lookupptr(&cache->methods, frame->m, &v);
9192  UPB_ASSERT(ok);
9193  method = upb_value_getconstptr(v);
9194 
9195  frame->name_table = &method->name_table;
9196 }
9197 
9198 /* There are GCC/Clang built-ins for overflow checking which we could start
9199  * using if there was any performance benefit to it. */
9200 
9201 static bool checked_add(size_t a, size_t b, size_t *c) {
9202  if (SIZE_MAX - a < b) return false;
9203  *c = a + b;
9204  return true;
9205 }
9206 
9207 static size_t saturating_multiply(size_t a, size_t b) {
9208  /* size_t is unsigned, so this is defined behavior even on overflow. */
9209  size_t ret = a * b;
9210  if (b != 0 && ret / b != a) {
9211  ret = SIZE_MAX;
9212  }
9213  return ret;
9214 }
9215 
9216 
9217 /* Base64 decoding ************************************************************/
9218 
9219 /* TODO(haberman): make this streaming. */
9220 
9221 static const signed char b64table[] = {
9222  -1, -1, -1, -1, -1, -1, -1, -1,
9223  -1, -1, -1, -1, -1, -1, -1, -1,
9224  -1, -1, -1, -1, -1, -1, -1, -1,
9225  -1, -1, -1, -1, -1, -1, -1, -1,
9226  -1, -1, -1, -1, -1, -1, -1, -1,
9227  -1, -1, -1, 62/*+*/, -1, -1, -1, 63/*/ */,
9228  52/*0*/, 53/*1*/, 54/*2*/, 55/*3*/, 56/*4*/, 57/*5*/, 58/*6*/, 59/*7*/,
9229  60/*8*/, 61/*9*/, -1, -1, -1, -1, -1, -1,
9230  -1, 0/*A*/, 1/*B*/, 2/*C*/, 3/*D*/, 4/*E*/, 5/*F*/, 6/*G*/,
9231  07/*H*/, 8/*I*/, 9/*J*/, 10/*K*/, 11/*L*/, 12/*M*/, 13/*N*/, 14/*O*/,
9232  15/*P*/, 16/*Q*/, 17/*R*/, 18/*S*/, 19/*T*/, 20/*U*/, 21/*V*/, 22/*W*/,
9233  23/*X*/, 24/*Y*/, 25/*Z*/, -1, -1, -1, -1, -1,
9234  -1, 26/*a*/, 27/*b*/, 28/*c*/, 29/*d*/, 30/*e*/, 31/*f*/, 32/*g*/,
9235  33/*h*/, 34/*i*/, 35/*j*/, 36/*k*/, 37/*l*/, 38/*m*/, 39/*n*/, 40/*o*/,
9236  41/*p*/, 42/*q*/, 43/*r*/, 44/*s*/, 45/*t*/, 46/*u*/, 47/*v*/, 48/*w*/,
9237  49/*x*/, 50/*y*/, 51/*z*/, -1, -1, -1, -1, -1,
9238  -1, -1, -1, -1, -1, -1, -1, -1,
9239  -1, -1, -1, -1, -1, -1, -1, -1,
9240  -1, -1, -1, -1, -1, -1, -1, -1,
9241  -1, -1, -1, -1, -1, -1, -1, -1,
9242  -1, -1, -1, -1, -1, -1, -1, -1,
9243  -1, -1, -1, -1, -1, -1, -1, -1,
9244  -1, -1, -1, -1, -1, -1, -1, -1,
9245  -1, -1, -1, -1, -1, -1, -1, -1,
9246  -1, -1, -1, -1, -1, -1, -1, -1,
9247  -1, -1, -1, -1, -1, -1, -1, -1,
9248  -1, -1, -1, -1, -1, -1, -1, -1,
9249  -1, -1, -1, -1, -1, -1, -1, -1,
9250  -1, -1, -1, -1, -1, -1, -1, -1,
9251  -1, -1, -1, -1, -1, -1, -1, -1,
9252  -1, -1, -1, -1, -1, -1, -1, -1,
9253  -1, -1, -1, -1, -1, -1, -1, -1
9254 };
9255 
9256 /* Returns the table value sign-extended to 32 bits. Knowing that the upper
9257  * bits will be 1 for unrecognized characters makes it easier to check for
9258  * this error condition later (see below). */
9259 int32_t b64lookup(unsigned char ch) { return b64table[ch]; }
9260 
9261 /* Returns true if the given character is not a valid base64 character or
9262  * padding. */
9263 bool nonbase64(unsigned char ch) { return b64lookup(ch) == -1 && ch != '='; }
9264 
9265 static bool base64_push(upb_json_parser *p, upb_selector_t sel, const char *ptr,
9266  size_t len) {
9267  const char *limit = ptr + len;
9268  for (; ptr < limit; ptr += 4) {
9269  uint32_t val;
9270  char output[3];
9271 
9272  if (limit - ptr < 4) {
9273  upb_status_seterrf(p->status,
9274  "Base64 input for bytes field not a multiple of 4: %s",
9275  upb_fielddef_name(p->top->f));
9276  return false;
9277  }
9278 
9279  val = b64lookup(ptr[0]) << 18 |
9280  b64lookup(ptr[1]) << 12 |
9281  b64lookup(ptr[2]) << 6 |
9282  b64lookup(ptr[3]);
9283 
9284  /* Test the upper bit; returns true if any of the characters returned -1. */
9285  if (val & 0x80000000) {
9286  goto otherchar;
9287  }
9288 
9289  output[0] = val >> 16;
9290  output[1] = (val >> 8) & 0xff;
9291  output[2] = val & 0xff;
9292  upb_sink_putstring(p->top->sink, sel, output, 3, NULL);
9293  }
9294  return true;
9295 
9296 otherchar:
9297  if (nonbase64(ptr[0]) || nonbase64(ptr[1]) || nonbase64(ptr[2]) ||
9298  nonbase64(ptr[3]) ) {
9299  upb_status_seterrf(p->status,
9300  "Non-base64 characters in bytes field: %s",
9301  upb_fielddef_name(p->top->f));
9302  return false;
9303  } if (ptr[2] == '=') {
9304  uint32_t val;
9305  char output;
9306 
9307  /* Last group contains only two input bytes, one output byte. */
9308  if (ptr[0] == '=' || ptr[1] == '=' || ptr[3] != '=') {
9309  goto badpadding;
9310  }
9311 
9312  val = b64lookup(ptr[0]) << 18 |
9313  b64lookup(ptr[1]) << 12;
9314 
9315  UPB_ASSERT(!(val & 0x80000000));
9316  output = val >> 16;
9317  upb_sink_putstring(p->top->sink, sel, &output, 1, NULL);
9318  return true;
9319  } else {
9320  uint32_t val;
9321  char output[2];
9322 
9323  /* Last group contains only three input bytes, two output bytes. */
9324  if (ptr[0] == '=' || ptr[1] == '=' || ptr[2] == '=') {
9325  goto badpadding;
9326  }
9327 
9328  val = b64lookup(ptr[0]) << 18 |
9329  b64lookup(ptr[1]) << 12 |
9330  b64lookup(ptr[2]) << 6;
9331 
9332  output[0] = val >> 16;
9333  output[1] = (val >> 8) & 0xff;
9334  upb_sink_putstring(p->top->sink, sel, output, 2, NULL);
9335  return true;
9336  }
9337 
9338 badpadding:
9339  upb_status_seterrf(p->status,
9340  "Incorrect base64 padding for field: %s (%.*s)",
9341  upb_fielddef_name(p->top->f),
9342  4, ptr);
9343  return false;
9344 }
9345 
9346 
9347 /* Accumulate buffer **********************************************************/
9348 
9349 /* Functionality for accumulating a buffer.
9350  *
9351  * Some parts of the parser need an entire value as a contiguous string. For
9352  * example, to look up a member name in a hash table, or to turn a string into
9353  * a number, the relevant library routines need the input string to be in
9354  * contiguous memory, even if the value spanned two or more buffers in the
9355  * input. These routines handle that.
9356  *
9357  * In the common case we can just point to the input buffer to get this
9358  * contiguous string and avoid any actual copy. So we optimistically begin
9359  * this way. But there are a few cases where we must instead copy into a
9360  * separate buffer:
9361  *
9362  * 1. The string was not contiguous in the input (it spanned buffers).
9363  *
9364  * 2. The string included escape sequences that need to be interpreted to get
9365  * the true value in a contiguous buffer. */
9366 
9368  UPB_ASSERT(p->accumulated == NULL);
9369  UPB_ASSERT(p->accumulated_len == 0);
9370 }
9371 
9373  p->accumulated = NULL;
9374  p->accumulated_len = 0;
9375 }
9376 
9377 /* Used internally by accumulate_append(). */
9378 static bool accumulate_realloc(upb_json_parser *p, size_t need) {
9379  void *mem;
9380  size_t old_size = p->accumulate_buf_size;
9381  size_t new_size = UPB_MAX(old_size, 128);
9382  while (new_size < need) {
9383  new_size = saturating_multiply(new_size, 2);
9384  }
9385 
9386  mem = upb_arena_realloc(p->arena, p->accumulate_buf, old_size, new_size);
9387  if (!mem) {
9388  upb_status_seterrmsg(p->status, "Out of memory allocating buffer.");
9389  return false;
9390  }
9391 
9392  p->accumulate_buf = mem;
9393  p->accumulate_buf_size = new_size;
9394  return true;
9395 }
9396 
9397 /* Logically appends the given data to the append buffer.
9398  * If "can_alias" is true, we will try to avoid actually copying, but the buffer
9399  * must be valid until the next accumulate_append() call (if any). */
9400 static bool accumulate_append(upb_json_parser *p, const char *buf, size_t len,
9401  bool can_alias) {
9402  size_t need;
9403 
9404  if (!p->accumulated && can_alias) {
9405  p->accumulated = buf;
9406  p->accumulated_len = len;
9407  return true;
9408  }
9409 
9410  if (!checked_add(p->accumulated_len, len, &need)) {
9411  upb_status_seterrmsg(p->status, "Integer overflow.");
9412  return false;
9413  }
9414 
9415  if (need > p->accumulate_buf_size && !accumulate_realloc(p, need)) {
9416  return false;
9417  }
9418 
9419  if (p->accumulated != p->accumulate_buf) {
9420  memcpy(p->accumulate_buf, p->accumulated, p->accumulated_len);
9421  p->accumulated = p->accumulate_buf;
9422  }
9423 
9424  memcpy(p->accumulate_buf + p->accumulated_len, buf, len);
9425  p->accumulated_len += len;
9426  return true;
9427 }
9428 
9429 /* Returns a pointer to the data accumulated since the last accumulate_clear()
9430  * call, and writes the length to *len. This with point either to the input
9431  * buffer or a temporary accumulate buffer. */
9432 static const char *accumulate_getptr(upb_json_parser *p, size_t *len) {
9433  UPB_ASSERT(p->accumulated);
9434  *len = p->accumulated_len;
9435  return p->accumulated;
9436 }
9437 
9438 
9439 /* Mult-part text data ********************************************************/
9440 
9441 /* When we have text data in the input, it can often come in multiple segments.
9442  * For example, there may be some raw string data followed by an escape
9443  * sequence. The two segments are processed with different logic. Also buffer
9444  * seams in the input can cause multiple segments.
9445  *
9446  * As we see segments, there are two main cases for how we want to process them:
9447  *
9448  * 1. we want to push the captured input directly to string handlers.
9449  *
9450  * 2. we need to accumulate all the parts into a contiguous buffer for further
9451  * processing (field name lookup, string->number conversion, etc). */
9452 
9453 /* This is the set of states for p->multipart_state. */
9454 enum {
9455  /* We are not currently processing multipart data. */
9457 
9458  /* We are processing multipart data by accumulating it into a contiguous
9459  * buffer. */
9461 
9462  /* We are processing multipart data by pushing each part directly to the
9463  * current string handlers. */
9465 };
9466 
9467 /* Start a multi-part text value where we accumulate the data for processing at
9468  * the end. */
9471  UPB_ASSERT(p->multipart_state == MULTIPART_INACTIVE);
9472  p->multipart_state = MULTIPART_ACCUMULATE;
9473 }
9474 
9475 /* Start a multi-part text value where we immediately push text data to a string
9476  * value with the given selector. */
9479  UPB_ASSERT(p->multipart_state == MULTIPART_INACTIVE);
9480  p->multipart_state = MULTIPART_PUSHEAGERLY;
9481  p->string_selector = sel;
9482 }
9483 
9484 static bool multipart_text(upb_json_parser *p, const char *buf, size_t len,
9485  bool can_alias) {
9486  switch (p->multipart_state) {
9487  case MULTIPART_INACTIVE:
9489  p->status, "Internal error: unexpected state MULTIPART_INACTIVE");
9490  return false;
9491 
9492  case MULTIPART_ACCUMULATE:
9493  if (!accumulate_append(p, buf, len, can_alias)) {
9494  return false;
9495  }
9496  break;
9497 
9498  case MULTIPART_PUSHEAGERLY: {
9499  const upb_bufhandle *handle = can_alias ? p->handle : NULL;
9500  upb_sink_putstring(p->top->sink, p->string_selector, buf, len, handle);
9501  break;
9502  }
9503  }
9504 
9505  return true;
9506 }
9507 
9508 /* Note: this invalidates the accumulate buffer! Call only after reading its
9509  * contents. */
9511  UPB_ASSERT(p->multipart_state != MULTIPART_INACTIVE);
9512  p->multipart_state = MULTIPART_INACTIVE;
9514 }
9515 
9516 
9517 /* Input capture **************************************************************/
9518 
9519 /* Functionality for capturing a region of the input as text. Gracefully
9520  * handles the case where a buffer seam occurs in the middle of the captured
9521  * region. */
9522 
9523 static void capture_begin(upb_json_parser *p, const char *ptr) {
9524  UPB_ASSERT(p->multipart_state != MULTIPART_INACTIVE);
9525  UPB_ASSERT(p->capture == NULL);
9526  p->capture = ptr;
9527 }
9528 
9529 static bool capture_end(upb_json_parser *p, const char *ptr) {
9530  UPB_ASSERT(p->capture);
9531  if (multipart_text(p, p->capture, ptr - p->capture, true)) {
9532  p->capture = NULL;
9533  return true;
9534  } else {
9535  return false;
9536  }
9537 }
9538 
9539 /* This is called at the end of each input buffer (ie. when we have hit a
9540  * buffer seam). If we are in the middle of capturing the input, this
9541  * processes the unprocessed capture region. */
9542 static void capture_suspend(upb_json_parser *p, const char **ptr) {
9543  if (!p->capture) return;
9544 
9545  if (multipart_text(p, p->capture, *ptr - p->capture, false)) {
9546  /* We use this as a signal that we were in the middle of capturing, and
9547  * that capturing should resume at the beginning of the next buffer.
9548  *
9549  * We can't use *ptr here, because we have no guarantee that this pointer
9550  * will be valid when we resume (if the underlying memory is freed, then
9551  * using the pointer at all, even to compare to NULL, is likely undefined
9552  * behavior). */
9553  p->capture = &suspend_capture;
9554  } else {
9555  /* Need to back up the pointer to the beginning of the capture, since
9556  * we were not able to actually preserve it. */
9557  *ptr = p->capture;
9558  }
9559 }
9560 
9561 static void capture_resume(upb_json_parser *p, const char *ptr) {
9562  if (p->capture) {
9563  UPB_ASSERT(p->capture == &suspend_capture);
9564  p->capture = ptr;
9565  }
9566 }
9567 
9568 
9569 /* Callbacks from the parser **************************************************/
9570 
9571 /* These are the functions called directly from the parser itself.
9572  * We define these in the same order as their declarations in the parser. */
9573 
9574 static char escape_char(char in) {
9575  switch (in) {
9576  case 'r': return '\r';
9577  case 't': return '\t';
9578  case 'n': return '\n';
9579  case 'f': return '\f';
9580  case 'b': return '\b';
9581  case '/': return '/';
9582  case '"': return '"';
9583  case '\\': return '\\';
9584  default:
9585  UPB_ASSERT(0);
9586  return 'x';
9587  }
9588 }
9589 
9590 static bool escape(upb_json_parser *p, const char *ptr) {
9591  char ch = escape_char(*ptr);
9592  return multipart_text(p, &ch, 1, false);
9593 }
9594 
9595 static void start_hex(upb_json_parser *p) {
9596  p->digit = 0;
9597 }
9598 
9599 static void hexdigit(upb_json_parser *p, const char *ptr) {
9600  char ch = *ptr;
9601 
9602  p->digit <<= 4;
9603 
9604  if (ch >= '0' && ch <= '9') {
9605  p->digit += (ch - '0');
9606  } else if (ch >= 'a' && ch <= 'f') {
9607  p->digit += ((ch - 'a') + 10);
9608  } else {
9609  UPB_ASSERT(ch >= 'A' && ch <= 'F');
9610  p->digit += ((ch - 'A') + 10);
9611  }
9612 }
9613 
9614 static bool end_hex(upb_json_parser *p) {
9615  uint32_t codepoint = p->digit;
9616 
9617  /* emit the codepoint as UTF-8. */
9618  char utf8[3]; /* support \u0000 -- \uFFFF -- need only three bytes. */
9619  int length = 0;
9620  if (codepoint <= 0x7F) {
9621  utf8[0] = codepoint;
9622  length = 1;
9623  } else if (codepoint <= 0x07FF) {
9624  utf8[1] = (codepoint & 0x3F) | 0x80;
9625  codepoint >>= 6;
9626  utf8[0] = (codepoint & 0x1F) | 0xC0;
9627  length = 2;
9628  } else /* codepoint <= 0xFFFF */ {
9629  utf8[2] = (codepoint & 0x3F) | 0x80;
9630  codepoint >>= 6;
9631  utf8[1] = (codepoint & 0x3F) | 0x80;
9632  codepoint >>= 6;
9633  utf8[0] = (codepoint & 0x0F) | 0xE0;
9634  length = 3;
9635  }
9636  /* TODO(haberman): Handle high surrogates: if codepoint is a high surrogate
9637  * we have to wait for the next escape to get the full code point). */
9638 
9639  return multipart_text(p, utf8, length, false);
9640 }
9641 
9642 static void start_text(upb_json_parser *p, const char *ptr) {
9643  capture_begin(p, ptr);
9644 }
9645 
9646 static bool end_text(upb_json_parser *p, const char *ptr) {
9647  return capture_end(p, ptr);
9648 }
9649 
9650 static bool start_number(upb_json_parser *p, const char *ptr) {
9651  if (is_top_level(p)) {
9652  if (is_number_wrapper_object(p)) {
9654  } else if (is_wellknown_msg(p, UPB_WELLKNOWN_VALUE)) {
9656  } else {
9657  return false;
9658  }
9659  } else if (does_number_wrapper_start(p)) {
9660  if (!start_subobject(p)) {
9661  return false;
9662  }
9664  } else if (is_wellknown_field(p, UPB_WELLKNOWN_VALUE)) {
9665  if (!start_subobject(p)) {
9666  return false;
9667  }
9669  }
9670 
9672  capture_begin(p, ptr);
9673  return true;
9674 }
9675 
9676 static bool parse_number(upb_json_parser *p, bool is_quoted);
9677 
9678 static bool end_number_nontop(upb_json_parser *p, const char *ptr) {
9679  if (!capture_end(p, ptr)) {
9680  return false;
9681  }
9682 
9683  if (p->top->f == NULL) {
9684  multipart_end(p);
9685  return true;
9686  }
9687 
9688  return parse_number(p, false);
9689 }
9690 
9691 static bool end_number(upb_json_parser *p, const char *ptr) {
9692  if (!end_number_nontop(p, ptr)) {
9693  return false;
9694  }
9695 
9696  if (does_number_wrapper_end(p)) {
9698  if (!is_top_level(p)) {
9699  end_subobject(p);
9700  }
9701  return true;
9702  }
9703 
9706  if (!is_top_level(p)) {
9707  end_subobject(p);
9708  }
9709  return true;
9710  }
9711 
9712  return true;
9713 }
9714 
9715 /* |buf| is NULL-terminated. |buf| itself will never include quotes;
9716  * |is_quoted| tells us whether this text originally appeared inside quotes. */
9717 static bool parse_number_from_buffer(upb_json_parser *p, const char *buf,
9718  bool is_quoted) {
9719  size_t len = strlen(buf);
9720  const char *bufend = buf + len;
9721  char *end;
9723  double val;
9724  double dummy;
9725  double inf = 1.0 / 0.0; /* C89 does not have an INFINITY macro. */
9726 
9727  errno = 0;
9728 
9729  if (len == 0 || buf[0] == ' ') {
9730  return false;
9731  }
9732 
9733  /* For integer types, first try parsing with integer-specific routines.
9734  * If these succeed, they will be more accurate for int64/uint64 than
9735  * strtod().
9736  */
9737  switch (type) {
9738  case UPB_TYPE_ENUM:
9739  case UPB_TYPE_INT32: {
9740  long val = strtol(buf, &end, 0);
9741  if (errno == ERANGE || end != bufend) {
9742  break;
9743  } else if (val > INT32_MAX || val < INT32_MIN) {
9744  return false;
9745  } else {
9746  upb_sink_putint32(p->top->sink, parser_getsel(p), val);
9747  return true;
9748  }
9749  }
9750  case UPB_TYPE_UINT32: {
9751  unsigned long val = strtoul(buf, &end, 0);
9752  if (end != bufend) {
9753  break;
9754  } else if (val > UINT32_MAX || errno == ERANGE) {
9755  return false;
9756  } else {
9757  upb_sink_putuint32(p->top->sink, parser_getsel(p), val);
9758  return true;
9759  }
9760  }
9761  /* XXX: We can't handle [u]int64 properly on 32-bit machines because
9762  * strto[u]ll isn't in C89. */
9763  case UPB_TYPE_INT64: {
9764  long val = strtol(buf, &end, 0);
9765  if (errno == ERANGE || end != bufend) {
9766  break;
9767  } else {
9768  upb_sink_putint64(p->top->sink, parser_getsel(p), val);
9769  return true;
9770  }
9771  }
9772  case UPB_TYPE_UINT64: {
9773  unsigned long val = strtoul(p->accumulated, &end, 0);
9774  if (end != bufend) {
9775  break;
9776  } else if (errno == ERANGE) {
9777  return false;
9778  } else {
9779  upb_sink_putuint64(p->top->sink, parser_getsel(p), val);
9780  return true;
9781  }
9782  }
9783  default:
9784  break;
9785  }
9786 
9787  if (type != UPB_TYPE_DOUBLE && type != UPB_TYPE_FLOAT && is_quoted) {
9788  /* Quoted numbers for integer types are not allowed to be in double form. */
9789  return false;
9790  }
9791 
9792  if (len == strlen("Infinity") && strcmp(buf, "Infinity") == 0) {
9793  /* C89 does not have an INFINITY macro. */
9794  val = inf;
9795  } else if (len == strlen("-Infinity") && strcmp(buf, "-Infinity") == 0) {
9796  val = -inf;
9797  } else {
9798  val = strtod(buf, &end);
9799  if (errno == ERANGE || end != bufend) {
9800  return false;
9801  }
9802  }
9803 
9804  switch (type) {
9805 #define CASE(capitaltype, smalltype, ctype, min, max) \
9806  case UPB_TYPE_ ## capitaltype: { \
9807  if (modf(val, &dummy) != 0 || val > max || val < min) { \
9808  return false; \
9809  } else { \
9810  upb_sink_put ## smalltype(p->top->sink, parser_getsel(p), \
9811  (ctype)val); \
9812  return true; \
9813  } \
9814  break; \
9815  }
9816  case UPB_TYPE_ENUM:
9817  CASE(INT32, int32, int32_t, INT32_MIN, INT32_MAX);
9818  CASE(INT64, int64, int64_t, INT64_MIN, INT64_MAX);
9819  CASE(UINT32, uint32, uint32_t, 0, UINT32_MAX);
9820  CASE(UINT64, uint64, uint64_t, 0, UINT64_MAX);
9821 #undef CASE
9822 
9823  case UPB_TYPE_DOUBLE:
9824  upb_sink_putdouble(p->top->sink, parser_getsel(p), val);
9825  return true;
9826  case UPB_TYPE_FLOAT:
9827  if ((val > FLT_MAX || val < -FLT_MAX) && val != inf && val != -inf) {
9828  return false;
9829  } else {
9830  upb_sink_putfloat(p->top->sink, parser_getsel(p), val);
9831  return true;
9832  }
9833  default:
9834  return false;
9835  }
9836 }
9837 
9838 static bool parse_number(upb_json_parser *p, bool is_quoted) {
9839  size_t len;
9840  const char *buf;
9841 
9842  /* strtol() and friends unfortunately do not support specifying the length of
9843  * the input string, so we need to force a copy into a NULL-terminated buffer. */
9844  if (!multipart_text(p, "\0", 1, false)) {
9845  return false;
9846  }
9847 
9848  buf = accumulate_getptr(p, &len);
9849 
9850  if (parse_number_from_buffer(p, buf, is_quoted)) {
9851  multipart_end(p);
9852  return true;
9853  } else {
9854  upb_status_seterrf(p->status, "error parsing number: %s", buf);
9855  multipart_end(p);
9856  return false;
9857  }
9858 }
9859 
9860 static bool parser_putbool(upb_json_parser *p, bool val) {
9861  bool ok;
9862 
9863  if (p->top->f == NULL) {
9864  return true;
9865  }
9866 
9867  if (upb_fielddef_type(p->top->f) != UPB_TYPE_BOOL) {
9868  upb_status_seterrf(p->status,
9869  "Boolean value specified for non-bool field: %s",
9870  upb_fielddef_name(p->top->f));
9871  return false;
9872  }
9873 
9874  ok = upb_sink_putbool(p->top->sink, parser_getsel(p), val);
9875  UPB_ASSERT(ok);
9876 
9877  return true;
9878 }
9879 
9880 static bool end_bool(upb_json_parser *p, bool val) {
9881  if (is_top_level(p)) {
9884  } else if (is_wellknown_msg(p, UPB_WELLKNOWN_VALUE)) {
9886  } else {
9887  return false;
9888  }
9890  if (!start_subobject(p)) {
9891  return false;
9892  }
9894  } else if (is_wellknown_field(p, UPB_WELLKNOWN_VALUE)) {
9895  if (!start_subobject(p)) {
9896  return false;
9897  }
9899  }
9900 
9901  if (p->top->is_unknown_field) {
9902  return true;
9903  }
9904 
9905  if (!parser_putbool(p, val)) {
9906  return false;
9907  }
9908 
9911  if (!is_top_level(p)) {
9912  end_subobject(p);
9913  }
9914  return true;
9915  }
9916 
9919  if (!is_top_level(p)) {
9920  end_subobject(p);
9921  }
9922  return true;
9923  }
9924 
9925  return true;
9926 }
9927 
9928 static bool end_null(upb_json_parser *p) {
9929  const char *zero_ptr = "0";
9930 
9931  if (is_top_level(p)) {
9934  } else {
9935  return true;
9936  }
9937  } else if (is_wellknown_field(p, UPB_WELLKNOWN_VALUE)) {
9938  if (!start_subobject(p)) {
9939  return false;
9940  }
9942  } else {
9943  return true;
9944  }
9945 
9946  /* Fill null_value field. */
9948  capture_begin(p, zero_ptr);
9949  capture_end(p, zero_ptr + 1);
9950  parse_number(p, false);
9951 
9953  if (!is_top_level(p)) {
9954  end_subobject(p);
9955  }
9956 
9957  return true;
9958 }
9959 
9962  return true;
9963 }
9964 
9966  if (is_top_level(p)) {
9967  if (is_string_wrapper_object(p)) {
9971  return true;
9974  start_object(p);
9975  } else if (is_wellknown_msg(p, UPB_WELLKNOWN_VALUE)) {
9977  } else {
9978  return false;
9979  }
9980  } else if (does_string_wrapper_start(p)) {
9981  if (!start_subobject(p)) {
9982  return false;
9983  }
9985  } else if (does_fieldmask_start(p)) {
9986  if (!start_subobject(p)) {
9987  return false;
9988  }
9990  return true;
9993  if (!start_subobject(p)) {
9994  return false;
9995  }
9996  start_object(p);
9997  } else if (is_wellknown_field(p, UPB_WELLKNOWN_VALUE)) {
9998  if (!start_subobject(p)) {
9999  return false;
10000  }
10002  }
10003 
10004  if (p->top->f == NULL) {
10006  return true;
10007  }
10008 
10009  if (p->top->is_any) {
10010  return start_any_stringval(p);
10011  }
10012 
10013  if (upb_fielddef_isstring(p->top->f)) {
10014  upb_jsonparser_frame *inner;
10015  upb_selector_t sel;
10016 
10017  if (!check_stack(p)) return false;
10018 
10019  /* Start a new parser frame: parser frames correspond one-to-one with
10020  * handler frames, and string events occur in a sub-frame. */
10021  inner = start_jsonparser_frame(p);
10023  upb_sink_startstr(p->top->sink, sel, 0, &inner->sink);
10024  inner->m = p->top->m;
10025  inner->f = p->top->f;
10026  p->top = inner;
10027 
10028  if (upb_fielddef_type(p->top->f) == UPB_TYPE_STRING) {
10029  /* For STRING fields we push data directly to the handlers as it is
10030  * parsed. We don't do this yet for BYTES fields, because our base64
10031  * decoder is not streaming.
10032  *
10033  * TODO(haberman): make base64 decoding streaming also. */
10035  return true;
10036  } else {
10038  return true;
10039  }
10040  } else if (upb_fielddef_type(p->top->f) != UPB_TYPE_BOOL &&
10041  upb_fielddef_type(p->top->f) != UPB_TYPE_MESSAGE) {
10042  /* No need to push a frame -- numeric values in quotes remain in the
10043  * current parser frame. These values must accmulate so we can convert
10044  * them all at once at the end. */
10046  return true;
10047  } else {
10048  upb_status_seterrf(p->status,
10049  "String specified for bool or submessage field: %s",
10050  upb_fielddef_name(p->top->f));
10051  return false;
10052  }
10053 }
10054 
10056  size_t len;
10057  const char *buf = accumulate_getptr(p, &len);
10058 
10059  /* Set type_url */
10060  upb_selector_t sel;
10061  upb_jsonparser_frame *inner;
10062  if (!check_stack(p)) return false;
10063  inner = p->top + 1;
10064 
10066  upb_sink_startstr(p->top->sink, sel, 0, &inner->sink);
10068  upb_sink_putstring(inner->sink, sel, buf, len, NULL);
10070  upb_sink_endstr(inner->sink, sel);
10071 
10072  multipart_end(p);
10073 
10074  /* Resolve type url */
10075  if (strncmp(buf, "type.googleapis.com/", 20) == 0 && len > 20) {
10076  const upb_msgdef *payload_type = NULL;
10077  buf += 20;
10078  len -= 20;
10079 
10080  payload_type = upb_symtab_lookupmsg2(p->symtab, buf, len);
10081  if (payload_type == NULL) {
10083  p->status, "Cannot find packed type: %.*s\n", (int)len, buf);
10084  return false;
10085  }
10086 
10087  json_parser_any_frame_set_payload_type(p, p->top->any_frame, payload_type);
10088 
10089  return true;
10090  } else {
10092  p->status, "Invalid type url: %.*s\n", (int)len, buf);
10093  return false;
10094  }
10095 }
10096 
10098  bool ok = true;
10099 
10102  multipart_end(p);
10103  return true;
10104  }
10105 
10106  if (p->top->f == NULL) {
10107  multipart_end(p);
10108  return true;
10109  }
10110 
10111  if (p->top->is_any) {
10112  return end_any_stringval(p);
10113  }
10114 
10115  switch (upb_fielddef_type(p->top->f)) {
10116  case UPB_TYPE_BYTES:
10118  p->accumulated, p->accumulated_len)) {
10119  return false;
10120  }
10121  /* Fall through. */
10122 
10123  case UPB_TYPE_STRING: {
10125  upb_sink_endstr(p->top->sink, sel);
10126  p->top--;
10127  break;
10128  }
10129 
10130  case UPB_TYPE_ENUM: {
10131  /* Resolve enum symbolic name to integer value. */
10132  const upb_enumdef *enumdef = upb_fielddef_enumsubdef(p->top->f);
10133 
10134  size_t len;
10135  const char *buf = accumulate_getptr(p, &len);
10136 
10137  int32_t int_val = 0;
10138  ok = upb_enumdef_ntoi(enumdef, buf, len, &int_val);
10139 
10140  if (ok) {
10142  upb_sink_putint32(p->top->sink, sel, int_val);
10143  } else {
10144  upb_status_seterrf(p->status, "Enum value unknown: '%.*s'", len, buf);
10145  }
10146 
10147  break;
10148  }
10149 
10150  case UPB_TYPE_INT32:
10151  case UPB_TYPE_INT64:
10152  case UPB_TYPE_UINT32:
10153  case UPB_TYPE_UINT64:
10154  case UPB_TYPE_DOUBLE:
10155  case UPB_TYPE_FLOAT:
10156  ok = parse_number(p, true);
10157  break;
10158 
10159  default:
10160  UPB_ASSERT(false);
10161  upb_status_seterrmsg(p->status, "Internal error in JSON decoder");
10162  ok = false;
10163  break;
10164  }
10165 
10166  multipart_end(p);
10167 
10168  return ok;
10169 }
10170 
10172  /* FieldMask's stringvals have been ended when handling them. Only need to
10173  * close FieldMask here.*/
10174  if (does_fieldmask_end(p)) {
10176  if (!is_top_level(p)) {
10177  end_subobject(p);
10178  }
10179  return true;
10180  }
10181 
10182  if (!end_stringval_nontop(p)) {
10183  return false;
10184  }
10185 
10186  if (does_string_wrapper_end(p)) {
10188  if (!is_top_level(p)) {
10189  end_subobject(p);
10190  }
10191  return true;
10192  }
10193 
10196  if (!is_top_level(p)) {
10197  end_subobject(p);
10198  }
10199  return true;
10200  }
10201 
10205  end_object(p);
10206  if (!is_top_level(p)) {
10207  end_subobject(p);
10208  }
10209  return true;
10210  }
10211 
10212  return true;
10213 }
10214 
10215 static void start_duration_base(upb_json_parser *p, const char *ptr) {
10216  capture_begin(p, ptr);
10217 }
10218 
10219 static bool end_duration_base(upb_json_parser *p, const char *ptr) {
10220  size_t len;
10221  const char *buf;
10222  char seconds_buf[14];
10223  char nanos_buf[12];
10224  char *end;
10225  int64_t seconds = 0;
10226  int32_t nanos = 0;
10227  double val = 0.0;
10228  const char *seconds_membername = "seconds";
10229  const char *nanos_membername = "nanos";
10230  size_t fraction_start;
10231 
10232  if (!capture_end(p, ptr)) {
10233  return false;
10234  }
10235 
10236  buf = accumulate_getptr(p, &len);
10237 
10238  memset(seconds_buf, 0, 14);
10239  memset(nanos_buf, 0, 12);
10240 
10241  /* Find out base end. The maximus duration is 315576000000, which cannot be
10242  * represented by double without losing precision. Thus, we need to handle
10243  * fraction and base separately. */
10244  for (fraction_start = 0; fraction_start < len && buf[fraction_start] != '.';
10245  fraction_start++);
10246 
10247  /* Parse base */
10248  memcpy(seconds_buf, buf, fraction_start);
10249  seconds = strtol(seconds_buf, &end, 10);
10250  if (errno == ERANGE || end != seconds_buf + fraction_start) {
10251  upb_status_seterrf(p->status, "error parsing duration: %s",
10252  seconds_buf);
10253  return false;
10254  }
10255 
10256  if (seconds > 315576000000) {
10257  upb_status_seterrf(p->status, "error parsing duration: "
10258  "maximum acceptable value is "
10259  "315576000000");
10260  return false;
10261  }
10262 
10263  if (seconds < -315576000000) {
10264  upb_status_seterrf(p->status, "error parsing duration: "
10265  "minimum acceptable value is "
10266  "-315576000000");
10267  return false;
10268  }
10269 
10270  /* Parse fraction */
10271  nanos_buf[0] = '0';
10272  memcpy(nanos_buf + 1, buf + fraction_start, len - fraction_start);
10273  val = strtod(nanos_buf, &end);
10274  if (errno == ERANGE || end != nanos_buf + len - fraction_start + 1) {
10275  upb_status_seterrf(p->status, "error parsing duration: %s",
10276  nanos_buf);
10277  return false;
10278  }
10279 
10280  nanos = val * 1000000000;
10281  if (seconds < 0) nanos = -nanos;
10282 
10283  /* Clean up buffer */
10284  multipart_end(p);
10285 
10286  /* Set seconds */
10287  start_member(p);
10288  capture_begin(p, seconds_membername);
10289  capture_end(p, seconds_membername + 7);
10290  end_membername(p);
10291  upb_sink_putint64(p->top->sink, parser_getsel(p), seconds);
10292  end_member(p);
10293 
10294  /* Set nanos */
10295  start_member(p);
10296  capture_begin(p, nanos_membername);
10297  capture_end(p, nanos_membername + 5);
10298  end_membername(p);
10299  upb_sink_putint32(p->top->sink, parser_getsel(p), nanos);
10300  end_member(p);
10301 
10302  /* Continue previous arena */
10304 
10305  return true;
10306 }
10307 
10309  size_t len;
10310  const char *buf;
10311  char *end;
10312  int val;
10313 
10314  /* atoi() and friends unfortunately do not support specifying the length of
10315  * the input string, so we need to force a copy into a NULL-terminated buffer. */
10316  multipart_text(p, "\0", 1, false);
10317 
10318  buf = accumulate_getptr(p, &len);
10319  val = atoi(buf);
10320  multipart_end(p);
10322 
10323  return val;
10324 }
10325 
10326 static void start_year(upb_json_parser *p, const char *ptr) {
10327  capture_begin(p, ptr);
10328 }
10329 
10330 static bool end_year(upb_json_parser *p, const char *ptr) {
10331  if (!capture_end(p, ptr)) {
10332  return false;
10333  }
10334  p->tm.tm_year = parse_timestamp_number(p) - 1900;
10335  return true;
10336 }
10337 
10338 static void start_month(upb_json_parser *p, const char *ptr) {
10339  capture_begin(p, ptr);
10340 }
10341 
10342 static bool end_month(upb_json_parser *p, const char *ptr) {
10343  if (!capture_end(p, ptr)) {
10344  return false;
10345  }
10346  p->tm.tm_mon = parse_timestamp_number(p) - 1;
10347  return true;
10348 }
10349 
10350 static void start_day(upb_json_parser *p, const char *ptr) {
10351  capture_begin(p, ptr);
10352 }
10353 
10354 static bool end_day(upb_json_parser *p, const char *ptr) {
10355  if (!capture_end(p, ptr)) {
10356  return false;
10357  }
10358  p->tm.tm_mday = parse_timestamp_number(p);
10359  return true;
10360 }
10361 
10362 static void start_hour(upb_json_parser *p, const char *ptr) {
10363  capture_begin(p, ptr);
10364 }
10365 
10366 static bool end_hour(upb_json_parser *p, const char *ptr) {
10367  if (!capture_end(p, ptr)) {
10368  return false;
10369  }
10370  p->tm.tm_hour = parse_timestamp_number(p);
10371  return true;
10372 }
10373 
10374 static void start_minute(upb_json_parser *p, const char *ptr) {
10375  capture_begin(p, ptr);
10376 }
10377 
10378 static bool end_minute(upb_json_parser *p, const char *ptr) {
10379  if (!capture_end(p, ptr)) {
10380  return false;
10381  }
10382  p->tm.tm_min = parse_timestamp_number(p);
10383  return true;
10384 }
10385 
10386 static void start_second(upb_json_parser *p, const char *ptr) {
10387  capture_begin(p, ptr);
10388 }
10389 
10390 static bool end_second(upb_json_parser *p, const char *ptr) {
10391  if (!capture_end(p, ptr)) {
10392  return false;
10393  }
10394  p->tm.tm_sec = parse_timestamp_number(p);
10395  return true;
10396 }
10397 
10399  memset(&p->tm, 0, sizeof(struct tm));
10400 }
10401 
10402 static void start_timestamp_fraction(upb_json_parser *p, const char *ptr) {
10403  capture_begin(p, ptr);
10404 }
10405 
10406 static bool end_timestamp_fraction(upb_json_parser *p, const char *ptr) {
10407  size_t len;
10408  const char *buf;
10409  char nanos_buf[12];
10410  char *end;
10411  double val = 0.0;
10412  int32_t nanos;
10413  const char *nanos_membername = "nanos";
10414 
10415  memset(nanos_buf, 0, 12);
10416 
10417  if (!capture_end(p, ptr)) {
10418  return false;
10419  }
10420 
10421  buf = accumulate_getptr(p, &len);
10422 
10423  if (len > 10) {
10424  upb_status_seterrf(p->status,
10425  "error parsing timestamp: at most 9-digit fraction.");
10426  return false;
10427  }
10428 
10429  /* Parse nanos */
10430  nanos_buf[0] = '0';
10431  memcpy(nanos_buf + 1, buf, len);
10432  val = strtod(nanos_buf, &end);
10433 
10434  if (errno == ERANGE || end != nanos_buf + len + 1) {
10435  upb_status_seterrf(p->status, "error parsing timestamp nanos: %s",
10436  nanos_buf);
10437  return false;
10438  }
10439 
10440  nanos = val * 1000000000;
10441 
10442  /* Clean up previous environment */
10443  multipart_end(p);
10444 
10445  /* Set nanos */
10446  start_member(p);
10447  capture_begin(p, nanos_membername);
10448  capture_end(p, nanos_membername + 5);
10449  end_membername(p);
10450  upb_sink_putint32(p->top->sink, parser_getsel(p), nanos);
10451  end_member(p);
10452 
10453  /* Continue previous environment */
10455 
10456  return true;
10457 }
10458 
10459 static void start_timestamp_zone(upb_json_parser *p, const char *ptr) {
10460  capture_begin(p, ptr);
10461 }
10462 
10463 #define EPOCH_YEAR 1970
10464 #define TM_YEAR_BASE 1900
10465 
10466 static bool isleap(int year) {
10467  return (year % 4) == 0 && (year % 100 != 0 || (year % 400) == 0);
10468 }
10469 
10470 const unsigned short int __mon_yday[2][13] = {
10471  /* Normal years. */
10472  { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 },
10473  /* Leap years. */
10474  { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 }
10475 };
10476 
10477 int64_t epoch(int year, int yday, int hour, int min, int sec) {
10478  int64_t years = year - EPOCH_YEAR;
10479 
10480  int64_t leap_days = years / 4 - years / 100 + years / 400;
10481 
10482  int64_t days = years * 365 + yday + leap_days;
10483  int64_t hours = days * 24 + hour;
10484  int64_t mins = hours * 60 + min;
10485  int64_t secs = mins * 60 + sec;
10486  return secs;
10487 }
10488 
10489 
10490 static int64_t upb_mktime(const struct tm *tp) {
10491  int sec = tp->tm_sec;
10492  int min = tp->tm_min;
10493  int hour = tp->tm_hour;
10494  int mday = tp->tm_mday;
10495  int mon = tp->tm_mon;
10496  int year = tp->tm_year + TM_YEAR_BASE;
10497 
10498  /* Calculate day of year from year, month, and day of month. */
10499  int mon_yday = ((__mon_yday[isleap(year)][mon]) - 1);
10500  int yday = mon_yday + mday;
10501 
10502  return epoch(year, yday, hour, min, sec);
10503 }
10504 
10505 static bool end_timestamp_zone(upb_json_parser *p, const char *ptr) {
10506  size_t len;
10507  const char *buf;
10508  int hours;
10509  int64_t seconds;
10510  const char *seconds_membername = "seconds";
10511 
10512  if (!capture_end(p, ptr)) {
10513  return false;
10514  }
10515 
10516  buf = accumulate_getptr(p, &len);
10517 
10518  if (buf[0] != 'Z') {
10519  if (sscanf(buf + 1, "%2d:00", &hours) != 1) {
10520  upb_status_seterrf(p->status, "error parsing timestamp offset");
10521  return false;
10522  }
10523 
10524  if (buf[0] == '+') {
10525  hours = -hours;
10526  }
10527 
10528  p->tm.tm_hour += hours;
10529  }
10530 
10531  /* Normalize tm */
10532  seconds = upb_mktime(&p->tm);
10533 
10534  /* Check timestamp boundary */
10535  if (seconds < -62135596800) {
10536  upb_status_seterrf(p->status, "error parsing timestamp: "
10537  "minimum acceptable value is "
10538  "0001-01-01T00:00:00Z");
10539  return false;
10540  }
10541 
10542  /* Clean up previous environment */
10543  multipart_end(p);
10544 
10545  /* Set seconds */
10546  start_member(p);
10547  capture_begin(p, seconds_membername);
10548  capture_end(p, seconds_membername + 7);
10549  end_membername(p);
10550  upb_sink_putint64(p->top->sink, parser_getsel(p), seconds);
10551  end_member(p);
10552 
10553  /* Continue previous environment */
10555 
10556  return true;
10557 }
10558 
10559 static void start_fieldmask_path_text(upb_json_parser *p, const char *ptr) {
10560  capture_begin(p, ptr);
10561 }
10562 
10563 static bool end_fieldmask_path_text(upb_json_parser *p, const char *ptr) {
10564  return capture_end(p, ptr);
10565 }
10566 
10568  upb_jsonparser_frame *inner;
10569  upb_selector_t sel;
10570 
10571  if (!check_stack(p)) return false;
10572 
10573  /* Start a new parser frame: parser frames correspond one-to-one with
10574  * handler frames, and string events occur in a sub-frame. */
10575  inner = start_jsonparser_frame(p);
10577  upb_sink_startstr(p->top->sink, sel, 0, &inner->sink);
10578  inner->m = p->top->m;
10579  inner->f = p->top->f;
10580  p->top = inner;
10581 
10583  return true;
10584 }
10585 
10586 static bool lower_camel_push(
10587  upb_json_parser *p, upb_selector_t sel, const char *ptr, size_t len) {
10588  const char *limit = ptr + len;
10589  bool first = true;
10590  for (;ptr < limit; ptr++) {
10591  if (*ptr >= 'A' && *ptr <= 'Z' && !first) {
10592  char lower = tolower(*ptr);
10593  upb_sink_putstring(p->top->sink, sel, "_", 1, NULL);
10594  upb_sink_putstring(p->top->sink, sel, &lower, 1, NULL);
10595  } else {
10596  upb_sink_putstring(p->top->sink, sel, ptr, 1, NULL);
10597  }
10598  first = false;
10599  }
10600  return true;
10601 }
10602 
10604  upb_selector_t sel;
10605 
10606  if (!lower_camel_push(
10608  p->accumulated, p->accumulated_len)) {
10609  return false;
10610  }
10611 
10613  upb_sink_endstr(p->top->sink, sel);
10614  p->top--;
10615 
10616  multipart_end(p);
10617  return true;
10618 }
10619 
10621  UPB_ASSERT(!p->top->f);
10623 }
10624 
10625 /* Helper: invoked during parse_mapentry() to emit the mapentry message's key
10626  * field based on the current contents of the accumulate buffer. */
10628 
10629  size_t len;
10630  const char *buf = accumulate_getptr(p, &len);
10631 
10632  /* Emit the key field. We do a bit of ad-hoc parsing here because the
10633  * parser state machine has already decided that this is a string field
10634  * name, and we are reinterpreting it as some arbitrary key type. In
10635  * particular, integer and bool keys are quoted, so we need to parse the
10636  * quoted string contents here. */
10637 
10638  p->top->f = upb_msgdef_itof(p->top->m, UPB_MAPENTRY_KEY);
10639  if (p->top->f == NULL) {
10640  upb_status_seterrmsg(p->status, "mapentry message has no key");
10641  return false;
10642  }
10643  switch (upb_fielddef_type(p->top->f)) {
10644  case UPB_TYPE_INT32:
10645  case UPB_TYPE_INT64:
10646  case UPB_TYPE_UINT32:
10647  case UPB_TYPE_UINT64:
10648  /* Invoke end_number. The accum buffer has the number's text already. */
10649  if (!parse_number(p, true)) {
10650  return false;
10651  }
10652  break;
10653  case UPB_TYPE_BOOL:
10654  if (len == 4 && !strncmp(buf, "true", 4)) {
10655  if (!parser_putbool(p, true)) {
10656  return false;
10657  }
10658  } else if (len == 5 && !strncmp(buf, "false", 5)) {
10659  if (!parser_putbool(p, false)) {
10660  return false;
10661  }
10662  } else {
10663  upb_status_seterrmsg(p->status,
10664  "Map bool key not 'true' or 'false'");
10665  return false;
10666  }
10667  multipart_end(p);
10668  break;
10669  case UPB_TYPE_STRING:
10670  case UPB_TYPE_BYTES: {
10671  upb_sink subsink;
10673  upb_sink_startstr(p->top->sink, sel, len, &subsink);
10675  upb_sink_putstring(subsink, sel, buf, len, NULL);
10677  upb_sink_endstr(subsink, sel);
10678  multipart_end(p);
10679  break;
10680  }
10681  default:
10682  upb_status_seterrmsg(p->status, "Invalid field type for map key");
10683  return false;
10684  }
10685 
10686  return true;
10687 }
10688 
10689 /* Helper: emit one map entry (as a submessage in the map field sequence). This
10690  * is invoked from end_membername(), at the end of the map entry's key string,
10691  * with the map key in the accumulate buffer. It parses the key from that
10692  * buffer, emits the handler calls to start the mapentry submessage (setting up
10693  * its subframe in the process), and sets up state in the subframe so that the
10694  * value parser (invoked next) will emit the mapentry's value field and then
10695  * end the mapentry message. */
10696 
10698  const upb_fielddef *mapfield;
10699  const upb_msgdef *mapentrymsg;
10700  upb_jsonparser_frame *inner;
10701  upb_selector_t sel;
10702 
10703  /* Map entry: p->top->sink is the seq frame, so we need to start a frame
10704  * for the mapentry itself, and then set |f| in that frame so that the map
10705  * value field is parsed, and also set a flag to end the frame after the
10706  * map-entry value is parsed. */
10707  if (!check_stack(p)) return false;
10708 
10709  mapfield = p->top->mapfield;
10710  mapentrymsg = upb_fielddef_msgsubdef(mapfield);
10711 
10712  inner = start_jsonparser_frame(p);
10713  p->top->f = mapfield;
10715  upb_sink_startsubmsg(p->top->sink, sel, &inner->sink);
10716  inner->m = mapentrymsg;
10717  inner->mapfield = mapfield;
10718 
10719  /* Don't set this to true *yet* -- we reuse parsing handlers below to push
10720  * the key field value to the sink, and these handlers will pop the frame
10721  * if they see is_mapentry (when invoked by the parser state machine, they
10722  * would have just seen the map-entry value, not key). */
10723  inner->is_mapentry = false;
10724  p->top = inner;
10725 
10726  /* send STARTMSG in submsg frame. */
10727  upb_sink_startmsg(p->top->sink);
10728 
10730 
10731  /* Set up the value field to receive the map-entry value. */
10732  p->top->f = upb_msgdef_itof(p->top->m, UPB_MAPENTRY_VALUE);
10733  p->top->is_mapentry = true; /* set up to pop frame after value is parsed. */
10734  p->top->mapfield = mapfield;
10735  if (p->top->f == NULL) {
10736  upb_status_seterrmsg(p->status, "mapentry message has no value");
10737  return false;
10738  }
10739 
10740  return true;
10741 }
10742 
10744  UPB_ASSERT(!p->top->f);
10745 
10746  if (!p->top->m) {
10747  p->top->is_unknown_field = true;
10748  multipart_end(p);
10749  return true;
10750  }
10751 
10752  if (p->top->is_any) {
10753  return end_any_membername(p);
10754  } else if (p->top->is_map) {
10755  return handle_mapentry(p);
10756  } else {
10757  size_t len;
10758  const char *buf = accumulate_getptr(p, &len);
10759  upb_value v;
10760 
10761  if (upb_strtable_lookup2(p->top->name_table, buf, len, &v)) {
10762  p->top->f = upb_value_getconstptr(v);
10763  multipart_end(p);
10764 
10765  return true;
10766  } else if (p->ignore_json_unknown) {
10767  p->top->is_unknown_field = true;
10768  multipart_end(p);
10769  return true;
10770  } else {
10771  upb_status_seterrf(p->status, "No such field: %.*s\n", (int)len, buf);
10772  return false;
10773  }
10774  }
10775 }
10776 
10778  size_t len;
10779  const char *buf = accumulate_getptr(p, &len);
10780  upb_value v;
10781 
10782  if (len == 5 && strncmp(buf, "@type", len) == 0) {
10783  upb_strtable_lookup2(p->top->name_table, "type_url", 8, &v);
10784  p->top->f = upb_value_getconstptr(v);
10785  multipart_end(p);
10786  return true;
10787  } else {
10788  p->top->is_unknown_field = true;
10789  multipart_end(p);
10790  return true;
10791  }
10792 }
10793 
10795  /* If we just parsed a map-entry value, end that frame too. */
10796  if (p->top->is_mapentry) {
10797  upb_selector_t sel;
10798  bool ok;
10799  const upb_fielddef *mapfield;
10800 
10801  UPB_ASSERT(p->top > p->stack);
10802  /* send ENDMSG on submsg. */
10803  upb_sink_endmsg(p->top->sink, p->status);
10804  mapfield = p->top->mapfield;
10805 
10806  /* send ENDSUBMSG in repeated-field-of-mapentries frame. */
10807  p->top--;
10809  UPB_ASSERT(ok);
10810  upb_sink_endsubmsg(p->top->sink, sel);
10811  }
10812 
10813  p->top->f = NULL;
10814  p->top->is_unknown_field = false;
10815 }
10816 
10817 static void start_any_member(upb_json_parser *p, const char *ptr) {
10818  start_member(p);
10820 }
10821 
10822 static void end_any_member(upb_json_parser *p, const char *ptr) {
10823  json_parser_any_frame_set_before_type_url_end(p->top->any_frame, ptr);
10824  end_member(p);
10825 }
10826 
10828  if (p->top->is_unknown_field) {
10829  upb_jsonparser_frame *inner;
10830  if (!check_stack(p)) return false;
10831 
10832  p->top = start_jsonparser_frame(p);
10833  return true;
10834  }
10835 
10836  if (upb_fielddef_ismap(p->top->f)) {
10837  upb_jsonparser_frame *inner;
10838  upb_selector_t sel;
10839 
10840  /* Beginning of a map. Start a new parser frame in a repeated-field
10841  * context. */
10842  if (!check_stack(p)) return false;
10843 
10844  inner = start_jsonparser_frame(p);
10846  upb_sink_startseq(p->top->sink, sel, &inner->sink);
10847  inner->m = upb_fielddef_msgsubdef(p->top->f);
10848  inner->mapfield = p->top->f;
10849  inner->is_map = true;
10850  p->top = inner;
10851 
10852  return true;
10853  } else if (upb_fielddef_issubmsg(p->top->f)) {
10854  upb_jsonparser_frame *inner;
10855  upb_selector_t sel;
10856 
10857  /* Beginning of a subobject. Start a new parser frame in the submsg
10858  * context. */
10859  if (!check_stack(p)) return false;
10860 
10861  inner = start_jsonparser_frame(p);
10863  upb_sink_startsubmsg(p->top->sink, sel, &inner->sink);
10864  inner->m = upb_fielddef_msgsubdef(p->top->f);
10865  set_name_table(p, inner);
10866  p->top = inner;
10867 
10869  p->top->is_any = true;
10870  p->top->any_frame = json_parser_any_frame_new(p);
10871  } else {
10872  p->top->is_any = false;
10873  p->top->any_frame = NULL;
10874  }
10875 
10876  return true;
10877  } else {
10878  upb_status_seterrf(p->status,
10879  "Object specified for non-message/group field: %s",
10880  upb_fielddef_name(p->top->f));
10881  return false;
10882  }
10883 }
10884 
10886  if (is_top_level(p)) {
10889  if (!start_subobject(p)) return false;
10891  } else if (is_wellknown_msg(p, UPB_WELLKNOWN_STRUCT)) {
10893  } else {
10894  return true;
10895  }
10896  } else if (is_wellknown_field(p, UPB_WELLKNOWN_STRUCT)) {
10897  if (!start_subobject(p)) return false;
10899  } else if (is_wellknown_field(p, UPB_WELLKNOWN_VALUE)) {
10900  if (!start_subobject(p)) return false;
10902  if (!start_subobject(p)) return false;
10904  }
10905 
10906  return start_subobject(p);
10907 }
10908 
10910  if (is_top_level(p)) {
10911  return;
10912  }
10913 
10914  if (p->top->is_map) {
10915  upb_selector_t sel;
10916  p->top--;
10918  upb_sink_endseq(p->top->sink, sel);
10919  } else {
10920  upb_selector_t sel;
10921  bool is_unknown = p->top->m == NULL;
10922  p->top--;
10923  if (!is_unknown) {
10925  upb_sink_endsubmsg(p->top->sink, sel);
10926  }
10927  }
10928 }
10929 
10931  end_subobject(p);
10932 
10935  if (!is_top_level(p)) {
10936  end_subobject(p);
10937  }
10938  }
10939 
10942  if (!is_top_level(p)) {
10943  end_subobject(p);
10944  }
10945  }
10946 }
10947 
10949  upb_jsonparser_frame *inner;
10950  upb_selector_t sel;
10951 
10952  if (is_top_level(p)) {
10955  if (!start_subobject(p)) return false;
10959  } else {
10960  return false;
10961  }
10963  (!upb_fielddef_isseq(p->top->f) ||
10964  p->top->is_repeated)) {
10965  if (!start_subobject(p)) return false;
10967  } else if (is_wellknown_field(p, UPB_WELLKNOWN_VALUE) &&
10968  (!upb_fielddef_isseq(p->top->f) ||
10969  p->top->is_repeated)) {
10970  if (!start_subobject(p)) return false;
10972  if (!start_subobject(p)) return false;
10974  }
10975 
10976  if (p->top->is_unknown_field) {
10977  inner = start_jsonparser_frame(p);
10978  inner->is_unknown_field = true;
10979  p->top = inner;
10980 
10981  return true;
10982  }
10983 
10984  if (!upb_fielddef_isseq(p->top->f)) {
10985  upb_status_seterrf(p->status,
10986  "Array specified for non-repeated field: %s",
10987  upb_fielddef_name(p->top->f));
10988  return false;
10989  }
10990 
10991  if (!check_stack(p)) return false;
10992 
10993  inner = start_jsonparser_frame(p);
10995  upb_sink_startseq(p->top->sink, sel, &inner->sink);
10996  inner->m = p->top->m;
10997  inner->f = p->top->f;
10998  inner->is_repeated = true;
10999  p->top = inner;
11000 
11001  return true;
11002 }
11003 
11004 static void end_array(upb_json_parser *p) {
11005  upb_selector_t sel;
11006 
11007  UPB_ASSERT(p->top > p->stack);
11008 
11009  p->top--;
11010 
11011  if (p->top->is_unknown_field) {
11012  return;
11013  }
11014 
11016  upb_sink_endseq(p->top->sink, sel);
11017 
11020  if (!is_top_level(p)) {
11021  end_subobject(p);
11022  }
11023  }
11024 
11027  if (!is_top_level(p)) {
11028  end_subobject(p);
11029  }
11030  }
11031 }
11032 
11034  if (!p->top->is_map && p->top->m != NULL) {
11035  upb_sink_startmsg(p->top->sink);
11036  }
11037 }
11038 
11040  if (!p->top->is_map && p->top->m != NULL) {
11041  upb_sink_endmsg(p->top->sink, p->status);
11042  }
11043 }
11044 
11045 static void start_any_object(upb_json_parser *p, const char *ptr) {
11046  start_object(p);
11047  p->top->any_frame->before_type_url_start = ptr;
11048  p->top->any_frame->before_type_url_end = ptr;
11049 }
11050 
11051 static bool end_any_object(upb_json_parser *p, const char *ptr) {
11052  const char *value_membername = "value";
11053  bool is_well_known_packed = false;
11054  const char *packed_end = ptr + 1;
11055  upb_selector_t sel;
11056  upb_jsonparser_frame *inner;
11057 
11058  if (json_parser_any_frame_has_value(p->top->any_frame) &&
11059  !json_parser_any_frame_has_type_url(p->top->any_frame)) {
11060  upb_status_seterrmsg(p->status, "No valid type url");
11061  return false;
11062  }
11063 
11064  /* Well known types data is represented as value field. */
11065  if (upb_msgdef_wellknowntype(p->top->any_frame->parser->top->m) !=
11067  is_well_known_packed = true;
11068 
11069  if (json_parser_any_frame_has_value_before_type_url(p->top->any_frame)) {
11070  p->top->any_frame->before_type_url_start =
11071  memchr(p->top->any_frame->before_type_url_start, ':',
11072  p->top->any_frame->before_type_url_end -
11073  p->top->any_frame->before_type_url_start);
11074  if (p->top->any_frame->before_type_url_start == NULL) {
11075  upb_status_seterrmsg(p->status, "invalid data for well known type.");
11076  return false;
11077  }
11078  p->top->any_frame->before_type_url_start++;
11079  }
11080 
11081  if (json_parser_any_frame_has_value_after_type_url(p->top->any_frame)) {
11082  p->top->any_frame->after_type_url_start =
11083  memchr(p->top->any_frame->after_type_url_start, ':',
11084  (ptr + 1) -
11085  p->top->any_frame->after_type_url_start);
11086  if (p->top->any_frame->after_type_url_start == NULL) {
11087  upb_status_seterrmsg(p->status, "Invalid data for well known type.");
11088  return false;
11089  }
11090  p->top->any_frame->after_type_url_start++;
11091  packed_end = ptr;
11092  }
11093  }
11094 
11095  if (json_parser_any_frame_has_value_before_type_url(p->top->any_frame)) {
11096  if (!parse(p->top->any_frame->parser, NULL,
11097  p->top->any_frame->before_type_url_start,
11098  p->top->any_frame->before_type_url_end -
11099  p->top->any_frame->before_type_url_start, NULL)) {
11100  return false;
11101  }
11102  } else {
11103  if (!is_well_known_packed) {
11104  if (!parse(p->top->any_frame->parser, NULL, "{", 1, NULL)) {
11105  return false;
11106  }
11107  }
11108  }
11109 
11110  if (json_parser_any_frame_has_value_before_type_url(p->top->any_frame) &&
11112  if (!parse(p->top->any_frame->parser, NULL, ",", 1, NULL)) {
11113  return false;
11114  }
11115  }
11116 
11117  if (json_parser_any_frame_has_value_after_type_url(p->top->any_frame)) {
11118  if (!parse(p->top->any_frame->parser, NULL,
11119  p->top->any_frame->after_type_url_start,
11120  packed_end - p->top->any_frame->after_type_url_start, NULL)) {
11121  return false;
11122  }
11123  } else {
11124  if (!is_well_known_packed) {
11125  if (!parse(p->top->any_frame->parser, NULL, "}", 1, NULL)) {
11126  return false;
11127  }
11128  }
11129  }
11130 
11131  if (!end(p->top->any_frame->parser, NULL)) {
11132  return false;
11133  }
11134 
11135  p->top->is_any = false;
11136 
11137  /* Set value */
11138  start_member(p);
11139  capture_begin(p, value_membername);
11140  capture_end(p, value_membername + 5);
11141  end_membername(p);
11142 
11143  if (!check_stack(p)) return false;
11144  inner = p->top + 1;
11145 
11147  upb_sink_startstr(p->top->sink, sel, 0, &inner->sink);
11149  upb_sink_putstring(inner->sink, sel, p->top->any_frame->stringsink.ptr,
11150  p->top->any_frame->stringsink.len, NULL);
11152  upb_sink_endstr(inner->sink, sel);
11153 
11154  end_member(p);
11155 
11156  end_object(p);
11157 
11158  /* Deallocate any parse frame. */
11159  json_parser_any_frame_free(p->top->any_frame);
11160 
11161  return true;
11162 }
11163 
11164 static bool is_string_wrapper(const upb_msgdef *m) {
11166  return type == UPB_WELLKNOWN_STRINGVALUE ||
11168 }
11169 
11170 static bool is_fieldmask(const upb_msgdef *m) {
11172  return type == UPB_WELLKNOWN_FIELDMASK;
11173 }
11174 
11176  const char *membername = "paths";
11177 
11178  start_object(p);
11179 
11180  /* Set up context for parsing value */
11181  start_member(p);
11182  capture_begin(p, membername);
11183  capture_end(p, membername + 5);
11184  end_membername(p);
11185 
11186  start_array(p);
11187 }
11188 
11190  end_array(p);
11191  end_member(p);
11192  end_object(p);
11193 }
11194 
11196  const char *membername = "value";
11197 
11198  start_object(p);
11199 
11200  /* Set up context for parsing value */
11201  start_member(p);
11202  capture_begin(p, membername);
11203  capture_end(p, membername + 5);
11204  end_membername(p);
11205 }
11206 
11208  end_member(p);
11209  end_object(p);
11210 }
11211 
11213  const char *nullmember = "null_value";
11214  const char *numbermember = "number_value";
11215  const char *stringmember = "string_value";
11216  const char *boolmember = "bool_value";
11217  const char *structmember = "struct_value";
11218  const char *listmember = "list_value";
11219  const char *membername = "";
11220 
11221  switch (value_type) {
11222  case VALUE_NULLVALUE:
11223  membername = nullmember;
11224  break;
11225  case VALUE_NUMBERVALUE:
11226  membername = numbermember;
11227  break;
11228  case VALUE_STRINGVALUE:
11229  membername = stringmember;
11230  break;
11231  case VALUE_BOOLVALUE:
11232  membername = boolmember;
11233  break;
11234  case VALUE_STRUCTVALUE:
11235  membername = structmember;
11236  break;
11237  case VALUE_LISTVALUE:
11238  membername = listmember;
11239  break;
11240  }
11241 
11242  start_object(p);
11243 
11244  /* Set up context for parsing value */
11245  start_member(p);
11246  capture_begin(p, membername);
11247  capture_end(p, membername + strlen(membername));
11248  end_membername(p);
11249 }
11250 
11252  end_member(p);
11253  end_object(p);
11254 }
11255 
11257  const char *membername = "values";
11258 
11259  start_object(p);
11260 
11261  /* Set up context for parsing value */
11262  start_member(p);
11263  capture_begin(p, membername);
11264  capture_end(p, membername + strlen(membername));
11265  end_membername(p);
11266 }
11267 
11269  end_member(p);
11270  end_object(p);
11271 }
11272 
11274  const char *membername = "fields";
11275 
11276  start_object(p);
11277 
11278  /* Set up context for parsing value */
11279  start_member(p);
11280  capture_begin(p, membername);
11281  capture_end(p, membername + strlen(membername));
11282  end_membername(p);
11283 }
11284 
11286  end_member(p);
11287  end_object(p);
11288 }
11289 
11291  return p->top == p->stack && p->top->f == NULL && !p->top->is_unknown_field;
11292 }
11293 
11295  return p->top->m != NULL && upb_msgdef_wellknowntype(p->top->m) == type;
11296 }
11297 
11299  return p->top->f != NULL &&
11300  upb_fielddef_issubmsg(p->top->f) &&
11302  == type);
11303 }
11304 
11306  return p->top->f != NULL &&
11307  upb_fielddef_issubmsg(p->top->f) &&
11309 }
11310 
11312  return p->top->m != NULL && upb_msgdef_isnumberwrapper(p->top->m);
11313 }
11314 
11316  return p->top->m != NULL && upb_msgdef_isnumberwrapper(p->top->m);
11317 }
11318 
11320  return p->top->f != NULL &&
11321  upb_fielddef_issubmsg(p->top->f) &&
11323 }
11324 
11326  return p->top->m != NULL && is_string_wrapper(p->top->m);
11327 }
11328 
11330  return p->top->m != NULL && is_string_wrapper(p->top->m);
11331 }
11332 
11334  return p->top->f != NULL &&
11335  upb_fielddef_issubmsg(p->top->f) &&
11337 }
11338 
11340  return p->top->m != NULL && is_fieldmask(p->top->m);
11341 }
11342 
11343 #define CHECK_RETURN_TOP(x) if (!(x)) goto error
11344 
11345 
11346 /* The actual parser **********************************************************/
11347 
11348 /* What follows is the Ragel parser itself. The language is specified in Ragel
11349  * and the actions call our C functions above.
11350  *
11351  * Ragel has an extensive set of functionality, and we use only a small part of
11352  * it. There are many action types but we only use a few:
11353  *
11354  * ">" -- transition into a machine
11355  * "%" -- transition out of a machine
11356  * "@" -- transition into a final state of a machine.
11357  *
11358  * "@" transitions are tricky because a machine can transition into a final
11359  * state repeatedly. But in some cases we know this can't happen, for example
11360  * a string which is delimited by a final '"' can only transition into its
11361  * final state once, when the closing '"' is seen. */
11362 
11363 
11364 #line 2749 "upb/json/parser.rl"
11365 
11366 
11367 
11368 #line 2552 "upb/json/parser.c"
11369 static const char _json_actions[] = {
11370  0, 1, 0, 1, 1, 1, 3, 1,
11371  4, 1, 6, 1, 7, 1, 8, 1,
11372  9, 1, 11, 1, 12, 1, 13, 1,
11373  14, 1, 15, 1, 16, 1, 17, 1,
11374  18, 1, 19, 1, 20, 1, 22, 1,
11375  23, 1, 24, 1, 35, 1, 37, 1,
11376  39, 1, 40, 1, 42, 1, 43, 1,
11377  44, 1, 46, 1, 48, 1, 49, 1,
11378  50, 1, 51, 1, 53, 1, 54, 2,
11379  4, 9, 2, 5, 6, 2, 7, 3,
11380  2, 7, 9, 2, 21, 26, 2, 25,
11381  10, 2, 27, 28, 2, 29, 30, 2,
11382  32, 34, 2, 33, 31, 2, 38, 36,
11383  2, 40, 42, 2, 45, 2, 2, 46,
11384  54, 2, 47, 36, 2, 49, 54, 2,
11385  50, 54, 2, 51, 54, 2, 52, 41,
11386  2, 53, 54, 3, 32, 34, 35, 4,
11387  21, 26, 27, 28
11388 };
11389 
11390 static const short _json_key_offsets[] = {
11391  0, 0, 12, 13, 18, 23, 28, 29,
11392  30, 31, 32, 33, 34, 35, 36, 37,
11393  38, 43, 44, 48, 53, 58, 63, 67,
11394  71, 74, 77, 79, 83, 87, 89, 91,
11395  96, 98, 100, 109, 115, 121, 127, 133,
11396  135, 139, 142, 144, 146, 149, 150, 154,
11397  156, 158, 160, 162, 163, 165, 167, 168,
11398  170, 172, 173, 175, 177, 178, 180, 182,
11399  183, 185, 187, 191, 193, 195, 196, 197,
11400  198, 199, 201, 206, 208, 210, 212, 221,
11401  222, 222, 222, 227, 232, 237, 238, 239,
11402  240, 241, 241, 242, 243, 244, 244, 245,
11403  246, 247, 247, 252, 253, 257, 262, 267,
11404  272, 276, 276, 279, 282, 285, 288, 291,
11405  294, 294, 294, 294, 294, 294
11406 };
11407 
11408 static const char _json_trans_keys[] = {
11409  32, 34, 45, 91, 102, 110, 116, 123,
11410  9, 13, 48, 57, 34, 32, 93, 125,
11411  9, 13, 32, 44, 93, 9, 13, 32,
11412  93, 125, 9, 13, 97, 108, 115, 101,
11413  117, 108, 108, 114, 117, 101, 32, 34,
11414  125, 9, 13, 34, 32, 58, 9, 13,
11415  32, 93, 125, 9, 13, 32, 44, 125,
11416  9, 13, 32, 44, 125, 9, 13, 32,
11417  34, 9, 13, 45, 48, 49, 57, 48,
11418  49, 57, 46, 69, 101, 48, 57, 69,
11419  101, 48, 57, 43, 45, 48, 57, 48,
11420  57, 48, 57, 46, 69, 101, 48, 57,
11421  34, 92, 34, 92, 34, 47, 92, 98,
11422  102, 110, 114, 116, 117, 48, 57, 65,
11423  70, 97, 102, 48, 57, 65, 70, 97,
11424  102, 48, 57, 65, 70, 97, 102, 48,
11425  57, 65, 70, 97, 102, 34, 92, 45,
11426  48, 49, 57, 48, 49, 57, 46, 115,
11427  48, 57, 115, 48, 57, 34, 46, 115,
11428  48, 57, 48, 57, 48, 57, 48, 57,
11429  48, 57, 45, 48, 57, 48, 57, 45,
11430  48, 57, 48, 57, 84, 48, 57, 48,
11431  57, 58, 48, 57, 48, 57, 58, 48,
11432  57, 48, 57, 43, 45, 46, 90, 48,
11433  57, 48, 57, 58, 48, 48, 34, 48,
11434  57, 43, 45, 90, 48, 57, 34, 44,
11435  34, 44, 34, 44, 34, 45, 91, 102,
11436  110, 116, 123, 48, 57, 34, 32, 93,
11437  125, 9, 13, 32, 44, 93, 9, 13,
11438  32, 93, 125, 9, 13, 97, 108, 115,
11439  101, 117, 108, 108, 114, 117, 101, 32,
11440  34, 125, 9, 13, 34, 32, 58, 9,
11441  13, 32, 93, 125, 9, 13, 32, 44,
11442  125, 9, 13, 32, 44, 125, 9, 13,
11443  32, 34, 9, 13, 32, 9, 13, 32,
11444  9, 13, 32, 9, 13, 32, 9, 13,
11445  32, 9, 13, 32, 9, 13, 0
11446 };
11447 
11448 static const char _json_single_lengths[] = {
11449  0, 8, 1, 3, 3, 3, 1, 1,
11450  1, 1, 1, 1, 1, 1, 1, 1,
11451  3, 1, 2, 3, 3, 3, 2, 2,
11452  1, 3, 0, 2, 2, 0, 0, 3,
11453  2, 2, 9, 0, 0, 0, 0, 2,
11454  2, 1, 2, 0, 1, 1, 2, 0,
11455  0, 0, 0, 1, 0, 0, 1, 0,
11456  0, 1, 0, 0, 1, 0, 0, 1,
11457  0, 0, 4, 0, 0, 1, 1, 1,
11458  1, 0, 3, 2, 2, 2, 7, 1,
11459  0, 0, 3, 3, 3, 1, 1, 1,
11460  1, 0, 1, 1, 1, 0, 1, 1,
11461  1, 0, 3, 1, 2, 3, 3, 3,
11462  2, 0, 1, 1, 1, 1, 1, 1,
11463  0, 0, 0, 0, 0, 0
11464 };
11465 
11466 static const char _json_range_lengths[] = {
11467  0, 2, 0, 1, 1, 1, 0, 0,
11468  0, 0, 0, 0, 0, 0, 0, 0,
11469  1, 0, 1, 1, 1, 1, 1, 1,
11470  1, 0, 1, 1, 1, 1, 1, 1,
11471  0, 0, 0, 3, 3, 3, 3, 0,
11472  1, 1, 0, 1, 1, 0, 1, 1,
11473  1, 1, 1, 0, 1, 1, 0, 1,
11474  1, 0, 1, 1, 0, 1, 1, 0,
11475  1, 1, 0, 1, 1, 0, 0, 0,
11476  0, 1, 1, 0, 0, 0, 1, 0,
11477  0, 0, 1, 1, 1, 0, 0, 0,
11478  0, 0, 0, 0, 0, 0, 0, 0,
11479  0, 0, 1, 0, 1, 1, 1, 1,
11480  1, 0, 1, 1, 1, 1, 1, 1,
11481  0, 0, 0, 0, 0, 0
11482 };
11483 
11484 static const short _json_index_offsets[] = {
11485  0, 0, 11, 13, 18, 23, 28, 30,
11486  32, 34, 36, 38, 40, 42, 44, 46,
11487  48, 53, 55, 59, 64, 69, 74, 78,
11488  82, 85, 89, 91, 95, 99, 101, 103,
11489  108, 111, 114, 124, 128, 132, 136, 140,
11490  143, 147, 150, 153, 155, 158, 160, 164,
11491  166, 168, 170, 172, 174, 176, 178, 180,
11492  182, 184, 186, 188, 190, 192, 194, 196,
11493  198, 200, 202, 207, 209, 211, 213, 215,
11494  217, 219, 221, 226, 229, 232, 235, 244,
11495  246, 247, 248, 253, 258, 263, 265, 267,
11496  269, 271, 272, 274, 276, 278, 279, 281,
11497  283, 285, 286, 291, 293, 297, 302, 307,
11498  312, 316, 317, 320, 323, 326, 329, 332,
11499  335, 336, 337, 338, 339, 340
11500 };
11501 
11502 static const unsigned char _json_indicies[] = {
11503  0, 2, 3, 4, 5, 6, 7, 8,
11504  0, 3, 1, 9, 1, 11, 12, 1,
11505  11, 10, 13, 14, 12, 13, 1, 14,
11506  1, 1, 14, 10, 15, 1, 16, 1,
11507  17, 1, 18, 1, 19, 1, 20, 1,
11508  21, 1, 22, 1, 23, 1, 24, 1,
11509  25, 26, 27, 25, 1, 28, 1, 29,
11510  30, 29, 1, 30, 1, 1, 30, 31,
11511  32, 33, 34, 32, 1, 35, 36, 27,
11512  35, 1, 36, 26, 36, 1, 37, 38,
11513  39, 1, 38, 39, 1, 41, 42, 42,
11514  40, 43, 1, 42, 42, 43, 40, 44,
11515  44, 45, 1, 45, 1, 45, 40, 41,
11516  42, 42, 39, 40, 47, 48, 46, 50,
11517  51, 49, 52, 52, 52, 52, 52, 52,
11518  52, 52, 53, 1, 54, 54, 54, 1,
11519  55, 55, 55, 1, 56, 56, 56, 1,
11520  57, 57, 57, 1, 59, 60, 58, 61,
11521  62, 63, 1, 64, 65, 1, 66, 67,
11522  1, 68, 1, 67, 68, 1, 69, 1,
11523  66, 67, 65, 1, 70, 1, 71, 1,
11524  72, 1, 73, 1, 74, 1, 75, 1,
11525  76, 1, 77, 1, 78, 1, 79, 1,
11526  80, 1, 81, 1, 82, 1, 83, 1,
11527  84, 1, 85, 1, 86, 1, 87, 1,
11528  88, 1, 89, 89, 90, 91, 1, 92,
11529  1, 93, 1, 94, 1, 95, 1, 96,
11530  1, 97, 1, 98, 1, 99, 99, 100,
11531  98, 1, 102, 1, 101, 104, 105, 103,
11532  1, 1, 101, 106, 107, 108, 109, 110,
11533  111, 112, 107, 1, 113, 1, 114, 115,
11534  117, 118, 1, 117, 116, 119, 120, 118,
11535  119, 1, 120, 1, 1, 120, 116, 121,
11536  1, 122, 1, 123, 1, 124, 1, 125,
11537  126, 1, 127, 1, 128, 1, 129, 130,
11538  1, 131, 1, 132, 1, 133, 134, 135,
11539  136, 134, 1, 137, 1, 138, 139, 138,
11540  1, 139, 1, 1, 139, 140, 141, 142,
11541  143, 141, 1, 144, 145, 136, 144, 1,
11542  145, 135, 145, 1, 146, 147, 147, 1,
11543  148, 148, 1, 149, 149, 1, 150, 150,
11544  1, 151, 151, 1, 152, 152, 1, 1,
11545  1, 1, 1, 1, 1, 0
11546 };
11547 
11548 static const char _json_trans_targs[] = {
11549  1, 0, 2, 107, 3, 6, 10, 13,
11550  16, 106, 4, 3, 106, 4, 5, 7,
11551  8, 9, 108, 11, 12, 109, 14, 15,
11552  110, 16, 17, 111, 18, 18, 19, 20,
11553  21, 22, 111, 21, 22, 24, 25, 31,
11554  112, 26, 28, 27, 29, 30, 33, 113,
11555  34, 33, 113, 34, 32, 35, 36, 37,
11556  38, 39, 33, 113, 34, 41, 42, 46,
11557  42, 46, 43, 45, 44, 114, 48, 49,
11558  50, 51, 52, 53, 54, 55, 56, 57,
11559  58, 59, 60, 61, 62, 63, 64, 65,
11560  66, 67, 73, 72, 68, 69, 70, 71,
11561  72, 115, 74, 67, 72, 76, 116, 76,
11562  116, 77, 79, 81, 82, 85, 90, 94,
11563  98, 80, 117, 117, 83, 82, 80, 83,
11564  84, 86, 87, 88, 89, 117, 91, 92,
11565  93, 117, 95, 96, 97, 117, 98, 99,
11566  105, 100, 100, 101, 102, 103, 104, 105,
11567  103, 104, 117, 106, 106, 106, 106, 106,
11568  106
11569 };
11570 
11571 static const unsigned char _json_trans_actions[] = {
11572  0, 0, 113, 107, 53, 0, 0, 0,
11573  125, 59, 45, 0, 55, 0, 0, 0,
11574  0, 0, 0, 0, 0, 0, 0, 0,
11575  0, 0, 101, 51, 47, 0, 0, 45,
11576  49, 49, 104, 0, 0, 0, 0, 0,
11577  3, 0, 0, 0, 0, 0, 5, 15,
11578  0, 0, 71, 7, 13, 0, 74, 9,
11579  9, 9, 77, 80, 11, 37, 37, 37,
11580  0, 0, 0, 39, 0, 41, 86, 0,
11581  0, 0, 17, 19, 0, 21, 23, 0,
11582  25, 27, 0, 29, 31, 0, 33, 35,
11583  0, 135, 83, 135, 0, 0, 0, 0,
11584  0, 92, 0, 89, 89, 98, 43, 0,
11585  131, 95, 113, 107, 53, 0, 0, 0,
11586  125, 59, 69, 110, 45, 0, 55, 0,
11587  0, 0, 0, 0, 0, 119, 0, 0,
11588  0, 122, 0, 0, 0, 116, 0, 101,
11589  51, 47, 0, 0, 45, 49, 49, 104,
11590  0, 0, 128, 0, 57, 63, 65, 61,
11591  67
11592 };
11593 
11594 static const unsigned char _json_eof_actions[] = {
11595  0, 0, 0, 0, 0, 0, 0, 0,
11596  0, 0, 0, 0, 0, 0, 0, 0,
11597  0, 0, 0, 0, 0, 0, 0, 0,
11598  0, 1, 0, 1, 0, 0, 1, 1,
11599  0, 0, 0, 0, 0, 0, 0, 0,
11600  0, 0, 0, 0, 0, 0, 0, 0,
11601  0, 0, 0, 0, 0, 0, 0, 0,
11602  0, 0, 0, 0, 0, 0, 0, 0,
11603  0, 0, 0, 0, 0, 0, 0, 0,
11604  0, 0, 0, 0, 0, 0, 0, 0,
11605  0, 0, 0, 0, 0, 0, 0, 0,
11606  0, 0, 0, 0, 0, 0, 0, 0,
11607  0, 0, 0, 0, 0, 0, 0, 0,
11608  0, 0, 0, 57, 63, 65, 61, 67,
11609  0, 0, 0, 0, 0, 0
11610 };
11611 
11612 static const int json_start = 1;
11613 
11614 static const int json_en_number_machine = 23;
11615 static const int json_en_string_machine = 32;
11616 static const int json_en_duration_machine = 40;
11617 static const int json_en_timestamp_machine = 47;
11618 static const int json_en_fieldmask_machine = 75;
11619 static const int json_en_value_machine = 78;
11620 static const int json_en_main = 1;
11621 
11622 
11623 #line 2752 "upb/json/parser.rl"
11624 
11625 size_t parse(void *closure, const void *hd, const char *buf, size_t size,
11626  const upb_bufhandle *handle) {
11627  upb_json_parser *parser = closure;
11628 
11629  /* Variables used by Ragel's generated code. */
11630  int cs = parser->current_state;
11631  int *stack = parser->parser_stack;
11632  int top = parser->parser_top;
11633 
11634  const char *p = buf;
11635  const char *pe = buf + size;
11636  const char *eof = &eof_ch;
11637 
11638  parser->handle = handle;
11639 
11640  UPB_UNUSED(hd);
11641  UPB_UNUSED(handle);
11642 
11644 
11645 
11646 #line 2830 "upb/json/parser.c"
11647  {
11648  int _klen;
11649  unsigned int _trans;
11650  const char *_acts;
11651  unsigned int _nacts;
11652  const char *_keys;
11653 
11654  if ( p == pe )
11655  goto _test_eof;
11656  if ( cs == 0 )
11657  goto _out;
11658 _resume:
11659  _keys = _json_trans_keys + _json_key_offsets[cs];
11660  _trans = _json_index_offsets[cs];
11661 
11662  _klen = _json_single_lengths[cs];
11663  if ( _klen > 0 ) {
11664  const char *_lower = _keys;
11665  const char *_mid;
11666  const char *_upper = _keys + _klen - 1;
11667  while (1) {
11668  if ( _upper < _lower )
11669  break;
11670 
11671  _mid = _lower + ((_upper-_lower) >> 1);
11672  if ( (*p) < *_mid )
11673  _upper = _mid - 1;
11674  else if ( (*p) > *_mid )
11675  _lower = _mid + 1;
11676  else {
11677  _trans += (unsigned int)(_mid - _keys);
11678  goto _match;
11679  }
11680  }
11681  _keys += _klen;
11682  _trans += _klen;
11683  }
11684 
11685  _klen = _json_range_lengths[cs];
11686  if ( _klen > 0 ) {
11687  const char *_lower = _keys;
11688  const char *_mid;
11689  const char *_upper = _keys + (_klen<<1) - 2;
11690  while (1) {
11691  if ( _upper < _lower )
11692  break;
11693 
11694  _mid = _lower + (((_upper-_lower) >> 1) & ~1);
11695  if ( (*p) < _mid[0] )
11696  _upper = _mid - 2;
11697  else if ( (*p) > _mid[1] )
11698  _lower = _mid + 2;
11699  else {
11700  _trans += (unsigned int)((_mid - _keys)>>1);
11701  goto _match;
11702  }
11703  }
11704  _trans += _klen;
11705  }
11706 
11707 _match:
11708  _trans = _json_indicies[_trans];
11709  cs = _json_trans_targs[_trans];
11710 
11711  if ( _json_trans_actions[_trans] == 0 )
11712  goto _again;
11713 
11714  _acts = _json_actions + _json_trans_actions[_trans];
11715  _nacts = (unsigned int) *_acts++;
11716  while ( _nacts-- > 0 )
11717  {
11718  switch ( *_acts++ )
11719  {
11720  case 1:
11721 #line 2557 "upb/json/parser.rl"
11722  { p--; {cs = stack[--top]; goto _again;} }
11723  break;
11724  case 2:
11725 #line 2559 "upb/json/parser.rl"
11726  { p--; {stack[top++] = cs; cs = 23;goto _again;} }
11727  break;
11728  case 3:
11729 #line 2563 "upb/json/parser.rl"
11730  { start_text(parser, p); }
11731  break;
11732  case 4:
11733 #line 2564 "upb/json/parser.rl"
11735  break;
11736  case 5:
11737 #line 2570 "upb/json/parser.rl"
11738  { start_hex(parser); }
11739  break;
11740  case 6:
11741 #line 2571 "upb/json/parser.rl"
11742  { hexdigit(parser, p); }
11743  break;
11744  case 7:
11745 #line 2572 "upb/json/parser.rl"
11747  break;
11748  case 8:
11749 #line 2578 "upb/json/parser.rl"
11751  break;
11752  case 9:
11753 #line 2584 "upb/json/parser.rl"
11754  { p--; {cs = stack[--top]; goto _again;} }
11755  break;
11756  case 10:
11757 #line 2589 "upb/json/parser.rl"
11758  { start_year(parser, p); }
11759  break;
11760  case 11:
11761 #line 2590 "upb/json/parser.rl"
11763  break;
11764  case 12:
11765 #line 2594 "upb/json/parser.rl"
11766  { start_month(parser, p); }
11767  break;
11768  case 13:
11769 #line 2595 "upb/json/parser.rl"
11771  break;
11772  case 14:
11773 #line 2599 "upb/json/parser.rl"
11774  { start_day(parser, p); }
11775  break;
11776  case 15:
11777 #line 2600 "upb/json/parser.rl"
11779  break;
11780  case 16:
11781 #line 2604 "upb/json/parser.rl"
11782  { start_hour(parser, p); }
11783  break;
11784  case 17:
11785 #line 2605 "upb/json/parser.rl"
11787  break;
11788  case 18:
11789 #line 2609 "upb/json/parser.rl"
11790  { start_minute(parser, p); }
11791  break;
11792  case 19:
11793 #line 2610 "upb/json/parser.rl"
11795  break;
11796  case 20:
11797 #line 2614 "upb/json/parser.rl"
11798  { start_second(parser, p); }
11799  break;
11800  case 21:
11801 #line 2615 "upb/json/parser.rl"
11803  break;
11804  case 22:
11805 #line 2620 "upb/json/parser.rl"
11807  break;
11808  case 23:
11809 #line 2621 "upb/json/parser.rl"
11811  break;
11812  case 24:
11813 #line 2623 "upb/json/parser.rl"
11814  { p--; {cs = stack[--top]; goto _again;} }
11815  break;
11816  case 25:
11817 #line 2628 "upb/json/parser.rl"
11819  break;
11820  case 26:
11821 #line 2630 "upb/json/parser.rl"
11823  break;
11824  case 27:
11825 #line 2631 "upb/json/parser.rl"
11827  break;
11828  case 28:
11829 #line 2633 "upb/json/parser.rl"
11831  break;
11832  case 29:
11833 #line 2634 "upb/json/parser.rl"
11835  break;
11836  case 30:
11837 #line 2636 "upb/json/parser.rl"
11838  { p--; {cs = stack[--top]; goto _again;} }
11839  break;
11840  case 31:
11841 #line 2641 "upb/json/parser.rl"
11843  break;
11844  case 32:
11845 #line 2642 "upb/json/parser.rl"
11847  break;
11848  case 33:
11849 #line 2647 "upb/json/parser.rl"
11851  break;
11852  case 34:
11853 #line 2648 "upb/json/parser.rl"
11855  break;
11856  case 35:
11857 #line 2654 "upb/json/parser.rl"
11858  { p--; {cs = stack[--top]; goto _again;} }
11859  break;
11860  case 36:
11861 #line 2659 "upb/json/parser.rl"
11862  {
11864  {stack[top++] = cs; cs = 47;goto _again;}
11866  {stack[top++] = cs; cs = 40;goto _again;}
11868  {stack[top++] = cs; cs = 75;goto _again;}
11869  } else {
11870  {stack[top++] = cs; cs = 32;goto _again;}
11871  }
11872  }
11873  break;
11874  case 37:
11875 #line 2672 "upb/json/parser.rl"
11876  { p--; {stack[top++] = cs; cs = 78;goto _again;} }
11877  break;
11878  case 38:
11879 #line 2677 "upb/json/parser.rl"
11880  {
11883  } else {
11885  }
11886  }
11887  break;
11888  case 39:
11889 #line 2684 "upb/json/parser.rl"
11891  break;
11892  case 40:
11893 #line 2687 "upb/json/parser.rl"
11894  {
11897  } else {
11898  end_member(parser);
11899  }
11900  }
11901  break;
11902  case 41:
11903 #line 2698 "upb/json/parser.rl"
11904  {
11907  } else {
11909  }
11910  }
11911  break;
11912  case 42:
11913 #line 2707 "upb/json/parser.rl"
11914  {
11917  } else {
11918  end_object(parser);
11919  }
11920  }
11921  break;
11922  case 43:
11923 #line 2719 "upb/json/parser.rl"
11925  break;
11926  case 44:
11927 #line 2723 "upb/json/parser.rl"
11928  { end_array(parser); }
11929  break;
11930  case 45:
11931 #line 2728 "upb/json/parser.rl"
11933  break;
11934  case 46:
11935 #line 2729 "upb/json/parser.rl"
11937  break;
11938  case 47:
11939 #line 2731 "upb/json/parser.rl"
11941  break;
11942  case 48:
11943 #line 2732 "upb/json/parser.rl"
11945  break;
11946  case 49:
11947 #line 2734 "upb/json/parser.rl"
11948  { CHECK_RETURN_TOP(end_bool(parser, true)); }
11949  break;
11950  case 50:
11951 #line 2736 "upb/json/parser.rl"
11952  { CHECK_RETURN_TOP(end_bool(parser, false)); }
11953  break;
11954  case 51:
11955 #line 2738 "upb/json/parser.rl"
11957  break;
11958  case 52:
11959 #line 2740 "upb/json/parser.rl"
11961  break;
11962  case 53:
11963 #line 2741 "upb/json/parser.rl"
11965  break;
11966  case 54:
11967 #line 2746 "upb/json/parser.rl"
11968  { p--; {cs = stack[--top]; goto _again;} }
11969  break;
11970 #line 3154 "upb/json/parser.c"
11971  }
11972  }
11973 
11974 _again:
11975  if ( cs == 0 )
11976  goto _out;
11977  if ( ++p != pe )
11978  goto _resume;
11979  _test_eof: {}
11980  if ( p == eof )
11981  {
11982  const char *__acts = _json_actions + _json_eof_actions[cs];
11983  unsigned int __nacts = (unsigned int) *__acts++;
11984  while ( __nacts-- > 0 ) {
11985  switch ( *__acts++ ) {
11986  case 0:
11987 #line 2555 "upb/json/parser.rl"
11988  { p--; {cs = stack[--top]; if ( p == pe )
11989  goto _test_eof;
11990 goto _again;} }
11991  break;
11992  case 46:
11993 #line 2729 "upb/json/parser.rl"
11995  break;
11996  case 49:
11997 #line 2734 "upb/json/parser.rl"
11998  { CHECK_RETURN_TOP(end_bool(parser, true)); }
11999  break;
12000  case 50:
12001 #line 2736 "upb/json/parser.rl"
12002  { CHECK_RETURN_TOP(end_bool(parser, false)); }
12003  break;
12004  case 51:
12005 #line 2738 "upb/json/parser.rl"
12007  break;
12008  case 53:
12009 #line 2741 "upb/json/parser.rl"
12011  break;
12012 #line 3196 "upb/json/parser.c"
12013  }
12014  }
12015  }
12016 
12017  _out: {}
12018  }
12019 
12020 #line 2774 "upb/json/parser.rl"
12021 
12022  if (p != pe) {
12023  upb_status_seterrf(parser->status, "Parse error at '%.*s'\n", pe - p, p);
12024  } else {
12026  }
12027 
12028 error:
12029  /* Save parsing state back to parser. */
12030  parser->current_state = cs;
12031  parser->parser_top = top;
12032 
12033  return p - buf;
12034 }
12035 
12036 static bool end(void *closure, const void *hd) {
12037  upb_json_parser *parser = closure;
12038 
12039  /* Prevent compile warning on unused static constants. */
12048 
12049  parse(parser, hd, &eof_ch, 0, NULL);
12050 
12051  return parser->current_state >= 106;
12052 }
12053 
12055  int cs;
12056  int top;
12057 
12058  p->top = p->stack;
12059  init_frame(p->top);
12060 
12061  /* Emit Ragel initialization of the parser. */
12062 
12063 #line 3247 "upb/json/parser.c"
12064  {
12065  cs = json_start;
12066  top = 0;
12067  }
12068 
12069 #line 2816 "upb/json/parser.rl"
12070  p->current_state = cs;
12071  p->parser_top = top;
12073  p->multipart_state = MULTIPART_INACTIVE;
12074  p->capture = NULL;
12075  p->accumulated = NULL;
12076 }
12077 
12079  const upb_msgdef *md) {
12081  upb_alloc *alloc = upb_arena_alloc(c->arena);
12082 
12083  upb_json_parsermethod *m = upb_malloc(alloc, sizeof(*m));
12084 
12085  m->cache = c;
12086 
12090 
12092 
12093  /* Build name_table */
12094 
12095  for(upb_msg_field_begin(&i, md);
12096  !upb_msg_field_done(&i);
12097  upb_msg_field_next(&i)) {
12098  const upb_fielddef *f = upb_msg_iter_field(&i);
12099  upb_value v = upb_value_constptr(f);
12100  char *buf;
12101 
12102  /* Add an entry for the JSON name. */
12103  size_t len = upb_fielddef_getjsonname(f, NULL, 0);
12104  buf = upb_malloc(alloc, len);
12106  upb_strtable_insert3(&m->name_table, buf, strlen(buf), v, alloc);
12107 
12108  if (strcmp(buf, upb_fielddef_name(f)) != 0) {
12109  /* Since the JSON name is different from the regular field name, add an
12110  * entry for the raw name (compliant proto3 JSON parsers must accept
12111  * both). */
12112  const char *name = upb_fielddef_name(f);
12113  upb_strtable_insert3(&m->name_table, name, strlen(name), v, alloc);
12114  }
12115  }
12116 
12117  return m;
12118 }
12119 
12120 /* Public API *****************************************************************/
12121 
12124  const upb_symtab* symtab,
12125  upb_sink output,
12126  upb_status *status,
12127  bool ignore_json_unknown) {
12128 #ifndef NDEBUG
12129  const size_t size_before = upb_arena_bytesallocated(arena);
12130 #endif
12132  if (!p) return false;
12133 
12134  p->arena = arena;
12135  p->method = method;
12136  p->status = status;
12137  p->limit = p->stack + UPB_JSON_MAX_DEPTH;
12138  p->accumulate_buf = NULL;
12139  p->accumulate_buf_size = 0;
12140  upb_bytessink_reset(&p->input_, &method->input_handler_, p);
12141 
12143  p->top->sink = output;
12144  p->top->m = upb_handlers_msgdef(output.handlers);
12146  p->top->is_any = true;
12147  p->top->any_frame = json_parser_any_frame_new(p);
12148  } else {
12149  p->top->is_any = false;
12150  p->top->any_frame = NULL;
12151  }
12152  set_name_table(p, p->top);
12153  p->symtab = symtab;
12154 
12155  p->ignore_json_unknown = ignore_json_unknown;
12156 
12157  /* If this fails, uncomment and increase the value in parser.h. */
12158  /* fprintf(stderr, "%zd\n", upb_arena_bytesallocated(arena) - size_before); */
12159  UPB_ASSERT_DEBUGVAR(upb_arena_bytesallocated(arena) - size_before <=
12161  return p;
12162 }
12163 
12165  return p->input_;
12166 }
12167 
12169  const upb_json_parsermethod *m) {
12170  return &m->input_handler_;
12171 }
12172 
12174  upb_alloc *alloc;
12175  upb_json_codecache *c;
12176 
12177  c = upb_gmalloc(sizeof(*c));
12178 
12179  c->arena = upb_arena_new();
12180  alloc = upb_arena_alloc(c->arena);
12181 
12183 
12184  return c;
12185 }
12186 
12188  upb_arena_free(c->arena);
12189  upb_gfree(c);
12190 }
12191 
12193  const upb_msgdef *md) {
12195  upb_value v;
12197  upb_alloc *alloc = upb_arena_alloc(c->arena);
12198 
12199  if (upb_inttable_lookupptr(&c->methods, md, &v)) {
12200  return upb_value_getconstptr(v);
12201  }
12202 
12203  m = parsermethod_new(c, md);
12204  v = upb_value_constptr(m);
12205 
12206  if (!m) return NULL;
12207  if (!upb_inttable_insertptr2(&c->methods, md, v, alloc)) return NULL;
12208 
12209  /* Populate parser methods for all submessages, so the name tables will
12210  * be available during parsing. */
12211  for(upb_msg_field_begin(&i, md);
12212  !upb_msg_field_done(&i);
12213  upb_msg_field_next(&i)) {
12215 
12216  if (upb_fielddef_issubmsg(f)) {
12217  const upb_msgdef *subdef = upb_fielddef_msgsubdef(f);
12218  const upb_json_parsermethod *sub_method =
12219  upb_json_codecache_get(c, subdef);
12220 
12221  if (!sub_method) return NULL;
12222  }
12223  }
12224 
12225  return m;
12226 }
12227 /*
12228 ** This currently uses snprintf() to format primitives, and could be optimized
12229 ** further.
12230 */
12231 
12232 
12233 #include <ctype.h>
12234 #include <stdint.h>
12235 #include <string.h>
12236 #include <time.h>
12237 
12240  /* BytesSink closure. */
12241  void *subc_;
12243 
12244  /* We track the depth so that we know when to emit startstr/endstr on the
12245  * output. */
12246  int depth_;
12247 
12248  /* Have we emitted the first element? This state is necessary to emit commas
12249  * without leaving a trailing comma in arrays/maps. We keep this state per
12250  * frame depth.
12251  *
12252  * Why max_depth * 2? UPB_MAX_HANDLER_DEPTH counts depth as nested messages.
12253  * We count frames (contexts in which we separate elements by commas) as both
12254  * repeated fields and messages (maps), and the worst case is a
12255  * message->repeated field->submessage->repeated field->... nesting. */
12257 
12258  /* To print timestamp, printer needs to cache its seconds and nanos values
12259  * and convert them when ending timestamp message. See comments of
12260  * printer_sethandlers_timestamp for more detail. */
12261  int64_t seconds;
12262  int32_t nanos;
12263 };
12264 
12265 /* StringPiece; a pointer plus a length. */
12266 typedef struct {
12267  char *ptr;
12268  size_t len;
12269 } strpc;
12270 
12271 void freestrpc(void *ptr) {
12272  strpc *pc = ptr;
12273  upb_gfree(pc->ptr);
12274  upb_gfree(pc);
12275 }
12276 
12277 typedef struct {
12280 
12281 /* Convert fielddef name to JSON name and return as a string piece. */
12283  bool preserve_fieldnames) {
12284  /* TODO(haberman): handle malloc failure. */
12285  strpc *ret = upb_gmalloc(sizeof(*ret));
12286  if (preserve_fieldnames) {
12288  ret->len = strlen(ret->ptr);
12289  } else {
12290  size_t len;
12291  ret->len = upb_fielddef_getjsonname(f, NULL, 0);
12292  ret->ptr = upb_gmalloc(ret->len);
12293  len = upb_fielddef_getjsonname(f, ret->ptr, ret->len);
12294  UPB_ASSERT(len == ret->len);
12295  ret->len--; /* NULL */
12296  }
12297 
12299  return ret;
12300 }
12301 
12302 /* Convert a null-terminated const char* to a string piece. */
12304  strpc * ret = upb_gmalloc(sizeof(*ret));
12305  ret->ptr = upb_gstrdup(str);
12306  ret->len = strlen(str);
12308  return ret;
12309 }
12310 
12311 /* ------------ JSON string printing: values, maps, arrays ------------------ */
12312 
12313 static void print_data(
12314  upb_json_printer *p, const char *buf, unsigned int len) {
12315  /* TODO: Will need to change if we support pushback from the sink. */
12316  size_t n = upb_bytessink_putbuf(p->output_, p->subc_, buf, len, NULL);
12317  UPB_ASSERT(n == len);
12318 }
12319 
12321  if (!p->first_elem_[p->depth_]) {
12322  print_data(p, ",", 1);
12323  }
12324  p->first_elem_[p->depth_] = false;
12325 }
12326 
12327 /* Helpers that print properly formatted elements to the JSON output stream. */
12328 
12329 /* Used for escaping control chars in strings. */
12330 static const char kControlCharLimit = 0x20;
12331 
12333  /* See RFC 4627. */
12334  unsigned char uc = (unsigned char)c;
12335  return uc < kControlCharLimit || uc == '"' || uc == '\\';
12336 }
12337 
12338 UPB_INLINE const char* json_nice_escape(char c) {
12339  switch (c) {
12340  case '"': return "\\\"";
12341  case '\\': return "\\\\";
12342  case '\b': return "\\b";
12343  case '\f': return "\\f";
12344  case '\n': return "\\n";
12345  case '\r': return "\\r";
12346  case '\t': return "\\t";
12347  default: return NULL;
12348  }
12349 }
12350 
12351 /* Write a properly escaped string chunk. The surrounding quotes are *not*
12352  * printed; this is so that the caller has the option of emitting the string
12353  * content in chunks. */
12354 static void putstring(upb_json_printer *p, const char *buf, unsigned int len) {
12355  const char* unescaped_run = NULL;
12356  unsigned int i;
12357  for (i = 0; i < len; i++) {
12358  char c = buf[i];
12359  /* Handle escaping. */
12360  if (is_json_escaped(c)) {
12361  /* Use a "nice" escape, like \n, if one exists for this character. */
12362  const char* escape = json_nice_escape(c);
12363  /* If we don't have a specific 'nice' escape code, use a \uXXXX-style
12364  * escape. */
12365  char escape_buf[8];
12366  if (!escape) {
12367  unsigned char byte = (unsigned char)c;
12368  _upb_snprintf(escape_buf, sizeof(escape_buf), "\\u%04x", (int)byte);
12369  escape = escape_buf;
12370  }
12371 
12372  /* N.B. that we assume that the input encoding is equal to the output
12373  * encoding (both UTF-8 for now), so for chars >= 0x20 and != \, ", we
12374  * can simply pass the bytes through. */
12375 
12376  /* If there's a current run of unescaped chars, print that run first. */
12377  if (unescaped_run) {
12378  print_data(p, unescaped_run, &buf[i] - unescaped_run);
12379  unescaped_run = NULL;
12380  }
12381  /* Then print the escape code. */
12382  print_data(p, escape, strlen(escape));
12383  } else {
12384  /* Add to the current unescaped run of characters. */
12385  if (unescaped_run == NULL) {
12386  unescaped_run = &buf[i];
12387  }
12388  }
12389  }
12390 
12391  /* If the string ended in a run of unescaped characters, print that last run. */
12392  if (unescaped_run) {
12393  print_data(p, unescaped_run, &buf[len] - unescaped_run);
12394  }
12395 }
12396 
12397 #define CHKLENGTH(x) if (!(x)) return -1;
12398 
12399 /* Helpers that format floating point values according to our custom formats.
12400  * Right now we use %.8g and %.17g for float/double, respectively, to match
12401  * proto2::util::JsonFormat's defaults. May want to change this later. */
12402 
12403 const char neginf[] = "\"-Infinity\"";
12404 const char inf[] = "\"Infinity\"";
12405 
12406 static size_t fmt_double(double val, char* buf, size_t length) {
12407  if (val == (1.0 / 0.0)) {
12408  CHKLENGTH(length >= strlen(inf));
12409  strcpy(buf, inf);
12410  return strlen(inf);
12411  } else if (val == (-1.0 / 0.0)) {
12412  CHKLENGTH(length >= strlen(neginf));
12413  strcpy(buf, neginf);
12414  return strlen(neginf);
12415  } else {
12416  size_t n = _upb_snprintf(buf, length, "%.17g", val);
12417  CHKLENGTH(n > 0 && n < length);
12418  return n;
12419  }
12420 }
12421 
12422 static size_t fmt_float(float val, char* buf, size_t length) {
12423  size_t n = _upb_snprintf(buf, length, "%.8g", val);
12424  CHKLENGTH(n > 0 && n < length);
12425  return n;
12426 }
12427 
12428 static size_t fmt_bool(bool val, char* buf, size_t length) {
12429  size_t n = _upb_snprintf(buf, length, "%s", (val ? "true" : "false"));
12430  CHKLENGTH(n > 0 && n < length);
12431  return n;
12432 }
12433 
12434 static size_t fmt_int64_as_number(long long val, char* buf, size_t length) {
12435  size_t n = _upb_snprintf(buf, length, "%lld", val);
12436  CHKLENGTH(n > 0 && n < length);
12437  return n;
12438 }
12439 
12440 static size_t fmt_uint64_as_number(
12441  unsigned long long val, char* buf, size_t length) {
12442  size_t n = _upb_snprintf(buf, length, "%llu", val);
12443  CHKLENGTH(n > 0 && n < length);
12444  return n;
12445 }
12446 
12447 static size_t fmt_int64_as_string(long long val, char* buf, size_t length) {
12448  size_t n = _upb_snprintf(buf, length, "\"%lld\"", val);
12449  CHKLENGTH(n > 0 && n < length);
12450  return n;
12451 }
12452 
12453 static size_t fmt_uint64_as_string(
12454  unsigned long long val, char* buf, size_t length) {
12455  size_t n = _upb_snprintf(buf, length, "\"%llu\"", val);
12456  CHKLENGTH(n > 0 && n < length);
12457  return n;
12458 }
12459 
12460 /* Print a map key given a field name. Called by scalar field handlers and by
12461  * startseq for repeated fields. */
12462 static bool putkey(void *closure, const void *handler_data) {
12463  upb_json_printer *p = closure;
12464  const strpc *key = handler_data;
12465  print_comma(p);
12466  print_data(p, "\"", 1);
12467  putstring(p, key->ptr, key->len);
12468  print_data(p, "\":", 2);
12469  return true;
12470 }
12471 
12472 #define CHKFMT(val) if ((val) == (size_t)-1) return false;
12473 #define CHK(val) if (!(val)) return false;
12474 
12475 #define TYPE_HANDLERS(type, fmt_func) \
12476  static bool put##type(void *closure, const void *handler_data, type val) { \
12477  upb_json_printer *p = closure; \
12478  char data[64]; \
12479  size_t length = fmt_func(val, data, sizeof(data)); \
12480  UPB_UNUSED(handler_data); \
12481  CHKFMT(length); \
12482  print_data(p, data, length); \
12483  return true; \
12484  } \
12485  static bool scalar_##type(void *closure, const void *handler_data, \
12486  type val) { \
12487  CHK(putkey(closure, handler_data)); \
12488  CHK(put##type(closure, handler_data, val)); \
12489  return true; \
12490  } \
12491  static bool repeated_##type(void *closure, const void *handler_data, \
12492  type val) { \
12493  upb_json_printer *p = closure; \
12494  print_comma(p); \
12495  CHK(put##type(closure, handler_data, val)); \
12496  return true; \
12497  }
12498 
12499 #define TYPE_HANDLERS_MAPKEY(type, fmt_func) \
12500  static bool putmapkey_##type(void *closure, const void *handler_data, \
12501  type val) { \
12502  upb_json_printer *p = closure; \
12503  char data[64]; \
12504  size_t length = fmt_func(val, data, sizeof(data)); \
12505  UPB_UNUSED(handler_data); \
12506  print_data(p, "\"", 1); \
12507  print_data(p, data, length); \
12508  print_data(p, "\":", 2); \
12509  return true; \
12510  }
12511 
12512 TYPE_HANDLERS(double, fmt_double)
12513 TYPE_HANDLERS(float, fmt_float)
12514 TYPE_HANDLERS(bool, fmt_bool)
12519 
12520 /* double and float are not allowed to be map keys. */
12526 
12527 #undef TYPE_HANDLERS
12528 #undef TYPE_HANDLERS_MAPKEY
12529 
12530 typedef struct {
12531  void *keyname;
12533 } EnumHandlerData;
12534 
12535 static bool scalar_enum(void *closure, const void *handler_data,
12536  int32_t val) {
12537  const EnumHandlerData *hd = handler_data;
12538  upb_json_printer *p = closure;
12539  const char *symbolic_name;
12540 
12541  CHK(putkey(closure, hd->keyname));
12542 
12543  symbolic_name = upb_enumdef_iton(hd->enumdef, val);
12544  if (symbolic_name) {
12545  print_data(p, "\"", 1);
12546  putstring(p, symbolic_name, strlen(symbolic_name));
12547  print_data(p, "\"", 1);
12548  } else {
12549  putint32_t(closure, NULL, val);
12550  }
12551 
12552  return true;
12553 }
12554 
12556  const upb_enumdef *def,
12557  int32_t val) {
12558  const char *symbolic_name = upb_enumdef_iton(def, val);
12559  if (symbolic_name) {
12560  print_data(p, "\"", 1);
12561  putstring(p, symbolic_name, strlen(symbolic_name));
12562  print_data(p, "\"", 1);
12563  } else {
12564  putint32_t(p, NULL, val);
12565  }
12566 }
12567 
12568 static bool repeated_enum(void *closure, const void *handler_data,
12569  int32_t val) {
12570  const EnumHandlerData *hd = handler_data;
12571  upb_json_printer *p = closure;
12572  print_comma(p);
12573 
12575 
12576  return true;
12577 }
12578 
12579 static bool mapvalue_enum(void *closure, const void *handler_data,
12580  int32_t val) {
12581  const EnumHandlerData *hd = handler_data;
12582  upb_json_printer *p = closure;
12583 
12585 
12586  return true;
12587 }
12588 
12589 static void *scalar_startsubmsg(void *closure, const void *handler_data) {
12590  return putkey(closure, handler_data) ? closure : UPB_BREAK;
12591 }
12592 
12593 static void *repeated_startsubmsg(void *closure, const void *handler_data) {
12594  upb_json_printer *p = closure;
12595  UPB_UNUSED(handler_data);
12596  print_comma(p);
12597  return closure;
12598 }
12599 
12601  p->depth_++;
12602  p->first_elem_[p->depth_] = true;
12603  print_data(p, "{", 1);
12604 }
12605 
12607  print_data(p, "}", 1);
12608  p->depth_--;
12609 }
12610 
12611 static bool printer_startmsg(void *closure, const void *handler_data) {
12612  upb_json_printer *p = closure;
12613  UPB_UNUSED(handler_data);
12614  if (p->depth_ == 0) {
12615  upb_bytessink_start(p->output_, 0, &p->subc_);
12616  }
12617  start_frame(p);
12618  return true;
12619 }
12620 
12621 static bool printer_endmsg(void *closure, const void *handler_data, upb_status *s) {
12622  upb_json_printer *p = closure;
12623  UPB_UNUSED(handler_data);
12624  UPB_UNUSED(s);
12625  end_frame(p);
12626  if (p->depth_ == 0) {
12627  upb_bytessink_end(p->output_);
12628  }
12629  return true;
12630 }
12631 
12632 static void *startseq(void *closure, const void *handler_data) {
12633  upb_json_printer *p = closure;
12634  CHK(putkey(closure, handler_data));
12635  p->depth_++;
12636  p->first_elem_[p->depth_] = true;
12637  print_data(p, "[", 1);
12638  return closure;
12639 }
12640 
12641 static bool endseq(void *closure, const void *handler_data) {
12642  upb_json_printer *p = closure;
12643  UPB_UNUSED(handler_data);
12644  print_data(p, "]", 1);
12645  p->depth_--;
12646  return true;
12647 }
12648 
12649 static void *startmap(void *closure, const void *handler_data) {
12650  upb_json_printer *p = closure;
12651  CHK(putkey(closure, handler_data));
12652  p->depth_++;
12653  p->first_elem_[p->depth_] = true;
12654  print_data(p, "{", 1);
12655  return closure;
12656 }
12657 
12658 static bool endmap(void *closure, const void *handler_data) {
12659  upb_json_printer *p = closure;
12660  UPB_UNUSED(handler_data);
12661  print_data(p, "}", 1);
12662  p->depth_--;
12663  return true;
12664 }
12665 
12666 static size_t putstr(void *closure, const void *handler_data, const char *str,
12667  size_t len, const upb_bufhandle *handle) {
12668  upb_json_printer *p = closure;
12669  UPB_UNUSED(handler_data);
12670  UPB_UNUSED(handle);
12671  putstring(p, str, len);
12672  return len;
12673 }
12674 
12675 /* This has to Base64 encode the bytes, because JSON has no "bytes" type. */
12676 static size_t putbytes(void *closure, const void *handler_data, const char *str,
12677  size_t len, const upb_bufhandle *handle) {
12678  upb_json_printer *p = closure;
12679 
12680  /* This is the regular base64, not the "web-safe" version. */
12681  static const char base64[] =
12682  "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
12683 
12684  /* Base64-encode. */
12685  char data[16000];
12686  const char *limit = data + sizeof(data);
12687  const unsigned char *from = (const unsigned char*)str;
12688  char *to = data;
12689  size_t remaining = len;
12690  size_t bytes;
12691 
12692  UPB_UNUSED(handler_data);
12693  UPB_UNUSED(handle);
12694 
12695  print_data(p, "\"", 1);
12696 
12697  while (remaining > 2) {
12698  if (limit - to < 4) {
12699  bytes = to - data;
12700  putstring(p, data, bytes);
12701  to = data;
12702  }
12703 
12704  to[0] = base64[from[0] >> 2];
12705  to[1] = base64[((from[0] & 0x3) << 4) | (from[1] >> 4)];
12706  to[2] = base64[((from[1] & 0xf) << 2) | (from[2] >> 6)];
12707  to[3] = base64[from[2] & 0x3f];
12708 
12709  remaining -= 3;
12710  to += 4;
12711  from += 3;
12712  }
12713 
12714  switch (remaining) {
12715  case 2:
12716  to[0] = base64[from[0] >> 2];
12717  to[1] = base64[((from[0] & 0x3) << 4) | (from[1] >> 4)];
12718  to[2] = base64[(from[1] & 0xf) << 2];
12719  to[3] = '=';
12720  to += 4;
12721  from += 2;
12722  break;
12723  case 1:
12724  to[0] = base64[from[0] >> 2];
12725  to[1] = base64[((from[0] & 0x3) << 4)];
12726  to[2] = '=';
12727  to[3] = '=';
12728  to += 4;
12729  from += 1;
12730  break;
12731  }
12732 
12733  bytes = to - data;
12734  putstring(p, data, bytes);
12735  print_data(p, "\"", 1);
12736  return len;
12737 }
12738 
12739 static void *scalar_startstr(void *closure, const void *handler_data,
12740  size_t size_hint) {
12741  upb_json_printer *p = closure;
12742  UPB_UNUSED(handler_data);
12743  UPB_UNUSED(size_hint);
12744  CHK(putkey(closure, handler_data));
12745  print_data(p, "\"", 1);
12746  return p;
12747 }
12748 
12749 static size_t scalar_str(void *closure, const void *handler_data,
12750  const char *str, size_t len,
12751  const upb_bufhandle *handle) {
12752  CHK(putstr(closure, handler_data, str, len, handle));
12753  return len;
12754 }
12755 
12756 static bool scalar_endstr(void *closure, const void *handler_data) {
12757  upb_json_printer *p = closure;
12758  UPB_UNUSED(handler_data);
12759  print_data(p, "\"", 1);
12760  return true;
12761 }
12762 
12763 static void *repeated_startstr(void *closure, const void *handler_data,
12764  size_t size_hint) {
12765  upb_json_printer *p = closure;
12766  UPB_UNUSED(handler_data);
12767  UPB_UNUSED(size_hint);
12768  print_comma(p);
12769  print_data(p, "\"", 1);
12770  return p;
12771 }
12772 
12773 static size_t repeated_str(void *closure, const void *handler_data,
12774  const char *str, size_t len,
12775  const upb_bufhandle *handle) {
12776  CHK(putstr(closure, handler_data, str, len, handle));
12777  return len;
12778 }
12779 
12780 static bool repeated_endstr(void *closure, const void *handler_data) {
12781  upb_json_printer *p = closure;
12782  UPB_UNUSED(handler_data);
12783  print_data(p, "\"", 1);
12784  return true;
12785 }
12786 
12787 static void *mapkeyval_startstr(void *closure, const void *handler_data,
12788  size_t size_hint) {
12789  upb_json_printer *p = closure;
12790  UPB_UNUSED(handler_data);
12791  UPB_UNUSED(size_hint);
12792  print_data(p, "\"", 1);
12793  return p;
12794 }
12795 
12796 static size_t mapkey_str(void *closure, const void *handler_data,
12797  const char *str, size_t len,
12798  const upb_bufhandle *handle) {
12799  CHK(putstr(closure, handler_data, str, len, handle));
12800  return len;
12801 }
12802 
12803 static bool mapkey_endstr(void *closure, const void *handler_data) {
12804  upb_json_printer *p = closure;
12805  UPB_UNUSED(handler_data);
12806  print_data(p, "\":", 2);
12807  return true;
12808 }
12809 
12810 static bool mapvalue_endstr(void *closure, const void *handler_data) {
12811  upb_json_printer *p = closure;
12812  UPB_UNUSED(handler_data);
12813  print_data(p, "\"", 1);
12814  return true;
12815 }
12816 
12817 static size_t scalar_bytes(void *closure, const void *handler_data,
12818  const char *str, size_t len,
12819  const upb_bufhandle *handle) {
12820  CHK(putkey(closure, handler_data));
12821  CHK(putbytes(closure, handler_data, str, len, handle));
12822  return len;
12823 }
12824 
12825 static size_t repeated_bytes(void *closure, const void *handler_data,
12826  const char *str, size_t len,
12827  const upb_bufhandle *handle) {
12828  upb_json_printer *p = closure;
12829  print_comma(p);
12830  CHK(putbytes(closure, handler_data, str, len, handle));
12831  return len;
12832 }
12833 
12834 static size_t mapkey_bytes(void *closure, const void *handler_data,
12835  const char *str, size_t len,
12836  const upb_bufhandle *handle) {
12837  upb_json_printer *p = closure;
12838  CHK(putbytes(closure, handler_data, str, len, handle));
12839  print_data(p, ":", 1);
12840  return len;
12841 }
12842 
12844  const upb_fielddef *f,
12845  bool preserve_fieldnames,
12846  upb_handlerattr *attr) {
12849  hd->keyname = newstrpc(h, f, preserve_fieldnames);
12851  attr->handler_data = hd;
12852 }
12853 
12854 /* Set up handlers for a mapentry submessage (i.e., an individual key/value pair
12855  * in a map).
12856  *
12857  * TODO: Handle missing key, missing value, out-of-order key/value, or repeated
12858  * key or value cases properly. The right way to do this is to allocate a
12859  * temporary structure at the start of a mapentry submessage, store key and
12860  * value data in it as key and value handlers are called, and then print the
12861  * key/value pair once at the end of the submessage. If we don't do this, we
12862  * should at least detect the case and throw an error. However, so far all of
12863  * our sources that emit mapentry messages do so canonically (with one key
12864  * field, and then one value field), so this is not a pressing concern at the
12865  * moment. */
12866 void printer_sethandlers_mapentry(const void *closure, bool preserve_fieldnames,
12867  upb_handlers *h) {
12868  const upb_msgdef *md = upb_handlers_msgdef(h);
12869 
12870  /* A mapentry message is printed simply as '"key": value'. Rather than
12871  * special-case key and value for every type below, we just handle both
12872  * fields explicitly here. */
12873  const upb_fielddef* key_field = upb_msgdef_itof(md, UPB_MAPENTRY_KEY);
12874  const upb_fielddef* value_field = upb_msgdef_itof(md, UPB_MAPENTRY_VALUE);
12875 
12877 
12878  UPB_UNUSED(closure);
12879 
12880  switch (upb_fielddef_type(key_field)) {
12881  case UPB_TYPE_INT32:
12882  upb_handlers_setint32(h, key_field, putmapkey_int32_t, &empty_attr);
12883  break;
12884  case UPB_TYPE_INT64:
12885  upb_handlers_setint64(h, key_field, putmapkey_int64_t, &empty_attr);
12886  break;
12887  case UPB_TYPE_UINT32:
12888  upb_handlers_setuint32(h, key_field, putmapkey_uint32_t, &empty_attr);
12889  break;
12890  case UPB_TYPE_UINT64:
12891  upb_handlers_setuint64(h, key_field, putmapkey_uint64_t, &empty_attr);
12892  break;
12893  case UPB_TYPE_BOOL:
12894  upb_handlers_setbool(h, key_field, putmapkey_bool, &empty_attr);
12895  break;
12896  case UPB_TYPE_STRING:
12897  upb_handlers_setstartstr(h, key_field, mapkeyval_startstr, &empty_attr);
12898  upb_handlers_setstring(h, key_field, mapkey_str, &empty_attr);
12899  upb_handlers_setendstr(h, key_field, mapkey_endstr, &empty_attr);
12900  break;
12901  case UPB_TYPE_BYTES:
12902  upb_handlers_setstring(h, key_field, mapkey_bytes, &empty_attr);
12903  break;
12904  default:
12905  UPB_ASSERT(false);
12906  break;
12907  }
12908 
12909  switch (upb_fielddef_type(value_field)) {
12910  case UPB_TYPE_INT32:
12911  upb_handlers_setint32(h, value_field, putint32_t, &empty_attr);
12912  break;
12913  case UPB_TYPE_INT64:
12914  upb_handlers_setint64(h, value_field, putint64_t, &empty_attr);
12915  break;
12916  case UPB_TYPE_UINT32:
12917  upb_handlers_setuint32(h, value_field, putuint32_t, &empty_attr);
12918  break;
12919  case UPB_TYPE_UINT64:
12920  upb_handlers_setuint64(h, value_field, putuint64_t, &empty_attr);
12921  break;
12922  case UPB_TYPE_BOOL:
12923  upb_handlers_setbool(h, value_field, putbool, &empty_attr);
12924  break;
12925  case UPB_TYPE_FLOAT:
12926  upb_handlers_setfloat(h, value_field, putfloat, &empty_attr);
12927  break;
12928  case UPB_TYPE_DOUBLE:
12929  upb_handlers_setdouble(h, value_field, putdouble, &empty_attr);
12930  break;
12931  case UPB_TYPE_STRING:
12932  upb_handlers_setstartstr(h, value_field, mapkeyval_startstr, &empty_attr);
12933  upb_handlers_setstring(h, value_field, putstr, &empty_attr);
12934  upb_handlers_setendstr(h, value_field, mapvalue_endstr, &empty_attr);
12935  break;
12936  case UPB_TYPE_BYTES:
12937  upb_handlers_setstring(h, value_field, putbytes, &empty_attr);
12938  break;
12939  case UPB_TYPE_ENUM: {
12941  set_enum_hd(h, value_field, preserve_fieldnames, &enum_attr);
12942  upb_handlers_setint32(h, value_field, mapvalue_enum, &enum_attr);
12943  break;
12944  }
12945  case UPB_TYPE_MESSAGE:
12946  /* No handler necessary -- the submsg handlers will print the message
12947  * as appropriate. */
12948  break;
12949  }
12950 }
12951 
12952 static bool putseconds(void *closure, const void *handler_data,
12953  int64_t seconds) {
12954  upb_json_printer *p = closure;
12955  p->seconds = seconds;
12956  UPB_UNUSED(handler_data);
12957  return true;
12958 }
12959 
12960 static bool putnanos(void *closure, const void *handler_data,
12961  int32_t nanos) {
12962  upb_json_printer *p = closure;
12963  p->nanos = nanos;
12964  UPB_UNUSED(handler_data);
12965  return true;
12966 }
12967 
12968 static void *scalar_startstr_nokey(void *closure, const void *handler_data,
12969  size_t size_hint) {
12970  upb_json_printer *p = closure;
12971  UPB_UNUSED(handler_data);
12972  UPB_UNUSED(size_hint);
12973  print_data(p, "\"", 1);
12974  return p;
12975 }
12976 
12977 static size_t putstr_nokey(void *closure, const void *handler_data,
12978  const char *str, size_t len,
12979  const upb_bufhandle *handle) {
12980  upb_json_printer *p = closure;
12981  UPB_UNUSED(handler_data);
12982  UPB_UNUSED(handle);
12983  print_data(p, "\"", 1);
12984  putstring(p, str, len);
12985  print_data(p, "\"", 1);
12986  return len + 2;
12987 }
12988 
12989 static void *startseq_nokey(void *closure, const void *handler_data) {
12990  upb_json_printer *p = closure;
12991  UPB_UNUSED(handler_data);
12992  p->depth_++;
12993  p->first_elem_[p->depth_] = true;
12994  print_data(p, "[", 1);
12995  return closure;
12996 }
12997 
12998 static void *startseq_fieldmask(void *closure, const void *handler_data) {
12999  upb_json_printer *p = closure;
13000  UPB_UNUSED(handler_data);
13001  p->depth_++;
13002  p->first_elem_[p->depth_] = true;
13003  return closure;
13004 }
13005 
13006 static bool endseq_fieldmask(void *closure, const void *handler_data) {
13007  upb_json_printer *p = closure;
13008  UPB_UNUSED(handler_data);
13009  p->depth_--;
13010  return true;
13011 }
13012 
13014  void *closure, const void *handler_data,
13015  size_t size_hint) {
13016  upb_json_printer *p = closure;
13017  UPB_UNUSED(handler_data);
13018  UPB_UNUSED(size_hint);
13019  print_comma(p);
13020  return p;
13021 }
13022 
13024  void *closure, const void *handler_data,
13025  const char *str, size_t len,
13026  const upb_bufhandle *handle) {
13027  const char* limit = str + len;
13028  bool upper = false;
13029  size_t result_len = 0;
13030  for (; str < limit; str++) {
13031  if (*str == '_') {
13032  upper = true;
13033  continue;
13034  }
13035  if (upper && *str >= 'a' && *str <= 'z') {
13036  char upper_char = toupper(*str);
13037  CHK(putstr(closure, handler_data, &upper_char, 1, handle));
13038  } else {
13039  CHK(putstr(closure, handler_data, str, 1, handle));
13040  }
13041  upper = false;
13042  result_len++;
13043  }
13044  return result_len;
13045 }
13046 
13047 static void *startmap_nokey(void *closure, const void *handler_data) {
13048  upb_json_printer *p = closure;
13049  UPB_UNUSED(handler_data);
13050  p->depth_++;
13051  p->first_elem_[p->depth_] = true;
13052  print_data(p, "{", 1);
13053  return closure;
13054 }
13055 
13056 static bool putnull(void *closure, const void *handler_data,
13057  int32_t null) {
13058  upb_json_printer *p = closure;
13059  print_data(p, "null", 4);
13060  UPB_UNUSED(handler_data);
13061  UPB_UNUSED(null);
13062  return true;
13063 }
13064 
13065 static bool printer_startdurationmsg(void *closure, const void *handler_data) {
13066  upb_json_printer *p = closure;
13067  UPB_UNUSED(handler_data);
13068  if (p->depth_ == 0) {
13069  upb_bytessink_start(p->output_, 0, &p->subc_);
13070  }
13071  return true;
13072 }
13073 
13074 #define UPB_DURATION_MAX_JSON_LEN 23
13075 #define UPB_DURATION_MAX_NANO_LEN 9
13076 
13077 static bool printer_enddurationmsg(void *closure, const void *handler_data,
13078  upb_status *s) {
13079  upb_json_printer *p = closure;
13081  size_t base_len;
13082  size_t curr;
13083  size_t i;
13084 
13085  memset(buffer, 0, UPB_DURATION_MAX_JSON_LEN);
13086 
13087  if (p->seconds < -315576000000) {
13088  upb_status_seterrf(s, "error parsing duration: "
13089  "minimum acceptable value is "
13090  "-315576000000");
13091  return false;
13092  }
13093 
13094  if (p->seconds > 315576000000) {
13095  upb_status_seterrf(s, "error serializing duration: "
13096  "maximum acceptable value is "
13097  "315576000000");
13098  return false;
13099  }
13100 
13101  _upb_snprintf(buffer, sizeof(buffer), "%ld", (long)p->seconds);
13102  base_len = strlen(buffer);
13103 
13104  if (p->nanos != 0) {
13105  char nanos_buffer[UPB_DURATION_MAX_NANO_LEN + 3];
13106  _upb_snprintf(nanos_buffer, sizeof(nanos_buffer), "%.9f",
13107  p->nanos / 1000000000.0);
13108  /* Remove trailing 0. */
13109  for (i = UPB_DURATION_MAX_NANO_LEN + 2;
13110  nanos_buffer[i] == '0'; i--) {
13111  nanos_buffer[i] = 0;
13112  }
13113  strcpy(buffer + base_len, nanos_buffer + 1);
13114  }
13115 
13116  curr = strlen(buffer);
13117  strcpy(buffer + curr, "s");
13118 
13119  p->seconds = 0;
13120  p->nanos = 0;
13121 
13122  print_data(p, "\"", 1);
13123  print_data(p, buffer, strlen(buffer));
13124  print_data(p, "\"", 1);
13125 
13126  if (p->depth_ == 0) {
13127  upb_bytessink_end(p->output_);
13128  }
13129 
13130  UPB_UNUSED(handler_data);
13131  return true;
13132 }
13133 
13134 static bool printer_starttimestampmsg(void *closure, const void *handler_data) {
13135  upb_json_printer *p = closure;
13136  UPB_UNUSED(handler_data);
13137  if (p->depth_ == 0) {
13138  upb_bytessink_start(p->output_, 0, &p->subc_);
13139  }
13140  return true;
13141 }
13142 
13143 #define UPB_TIMESTAMP_MAX_JSON_LEN 31
13144 #define UPB_TIMESTAMP_BEFORE_NANO_LEN 19
13145 #define UPB_TIMESTAMP_MAX_NANO_LEN 9
13146 
13147 static bool printer_endtimestampmsg(void *closure, const void *handler_data,
13148  upb_status *s) {
13149  upb_json_printer *p = closure;
13151  time_t time = p->seconds;
13152  size_t curr;
13153  size_t i;
13154  size_t year_length =
13155  strftime(buffer, UPB_TIMESTAMP_MAX_JSON_LEN, "%Y", gmtime(&time));
13156 
13157  if (p->seconds < -62135596800) {
13158  upb_status_seterrf(s, "error parsing timestamp: "
13159  "minimum acceptable value is "
13160  "0001-01-01T00:00:00Z");
13161  return false;
13162  }
13163 
13164  if (p->seconds > 253402300799) {
13165  upb_status_seterrf(s, "error parsing timestamp: "
13166  "maximum acceptable value is "
13167  "9999-12-31T23:59:59Z");
13168  return false;
13169  }
13170 
13171  /* strftime doesn't guarantee 4 digits for year. Prepend 0 by ourselves. */
13172  for (i = 0; i < 4 - year_length; i++) {
13173  buffer[i] = '0';
13174  }
13175 
13176  strftime(buffer + (4 - year_length), UPB_TIMESTAMP_MAX_JSON_LEN,
13177  "%Y-%m-%dT%H:%M:%S", gmtime(&time));
13178  if (p->nanos != 0) {
13179  char nanos_buffer[UPB_TIMESTAMP_MAX_NANO_LEN + 3];
13180  _upb_snprintf(nanos_buffer, sizeof(nanos_buffer), "%.9f",
13181  p->nanos / 1000000000.0);
13182  /* Remove trailing 0. */
13183  for (i = UPB_TIMESTAMP_MAX_NANO_LEN + 2;
13184  nanos_buffer[i] == '0'; i--) {
13185  nanos_buffer[i] = 0;
13186  }
13187  strcpy(buffer + UPB_TIMESTAMP_BEFORE_NANO_LEN, nanos_buffer + 1);
13188  }
13189 
13190  curr = strlen(buffer);
13191  strcpy(buffer + curr, "Z");
13192 
13193  p->seconds = 0;
13194  p->nanos = 0;
13195 
13196  print_data(p, "\"", 1);
13197  print_data(p, buffer, strlen(buffer));
13198  print_data(p, "\"", 1);
13199 
13200  if (p->depth_ == 0) {
13201  upb_bytessink_end(p->output_);
13202  }
13203 
13204  UPB_UNUSED(handler_data);
13205  UPB_UNUSED(s);
13206  return true;
13207 }
13208 
13209 static bool printer_startmsg_noframe(void *closure, const void *handler_data) {
13210  upb_json_printer *p = closure;
13211  UPB_UNUSED(handler_data);
13212  if (p->depth_ == 0) {
13213  upb_bytessink_start(p->output_, 0, &p->subc_);
13214  }
13215  return true;
13216 }
13217 
13219  void *closure, const void *handler_data, upb_status *s) {
13220  upb_json_printer *p = closure;
13221  UPB_UNUSED(handler_data);
13222  UPB_UNUSED(s);
13223  if (p->depth_ == 0) {
13224  upb_bytessink_end(p->output_);
13225  }
13226  return true;
13227 }
13228 
13230  void *closure, const void *handler_data) {
13231  upb_json_printer *p = closure;
13232  UPB_UNUSED(handler_data);
13233  if (p->depth_ == 0) {
13234  upb_bytessink_start(p->output_, 0, &p->subc_);
13235  }
13236  print_data(p, "\"", 1);
13237  return true;
13238 }
13239 
13241  void *closure, const void *handler_data, upb_status *s) {
13242  upb_json_printer *p = closure;
13243  UPB_UNUSED(handler_data);
13244  UPB_UNUSED(s);
13245  print_data(p, "\"", 1);
13246  if (p->depth_ == 0) {
13247  upb_bytessink_end(p->output_);
13248  }
13249  return true;
13250 }
13251 
13253  void *closure, const void *handler_data, size_t size_hint) {
13254  upb_json_printer *p = closure;
13255  UPB_UNUSED(size_hint);
13256  CHK(putkey(closure, handler_data));
13257  return p;
13258 }
13259 
13260 /* Set up handlers for an Any submessage. */
13261 void printer_sethandlers_any(const void *closure, upb_handlers *h) {
13262  const upb_msgdef *md = upb_handlers_msgdef(h);
13263 
13264  const upb_fielddef* type_field = upb_msgdef_itof(md, UPB_ANY_TYPE);
13265  const upb_fielddef* value_field = upb_msgdef_itof(md, UPB_ANY_VALUE);
13266 
13268 
13269  /* type_url's json name is "@type" */
13270  upb_handlerattr type_name_attr = UPB_HANDLERATTR_INIT;
13271  upb_handlerattr value_name_attr = UPB_HANDLERATTR_INIT;
13272  strpc *type_url_json_name = newstrpc_str(h, "@type");
13273  strpc *value_json_name = newstrpc_str(h, "value");
13274 
13275  type_name_attr.handler_data = type_url_json_name;
13276  value_name_attr.handler_data = value_json_name;
13277 
13278  /* Set up handlers. */
13280  upb_handlers_setendmsg(h, printer_endmsg, &empty_attr);
13281 
13282  upb_handlers_setstartstr(h, type_field, scalar_startstr, &type_name_attr);
13283  upb_handlers_setstring(h, type_field, scalar_str, &empty_attr);
13284  upb_handlers_setendstr(h, type_field, scalar_endstr, &empty_attr);
13285 
13286  /* This is not the full and correct JSON encoding for the Any value field. It
13287  * requires further processing by the wrapper code based on the type URL.
13288  */
13290  &value_name_attr);
13291 
13292  UPB_UNUSED(closure);
13293 }
13294 
13295 /* Set up handlers for a fieldmask submessage. */
13296 void printer_sethandlers_fieldmask(const void *closure, upb_handlers *h) {
13297  const upb_msgdef *md = upb_handlers_msgdef(h);
13298  const upb_fielddef* f = upb_msgdef_itof(md, 1);
13299 
13301 
13303  upb_handlers_setendseq(h, f, endseq_fieldmask, &empty_attr);
13304 
13307 
13310 
13311  UPB_UNUSED(closure);
13312 }
13313 
13314 /* Set up handlers for a duration submessage. */
13315 void printer_sethandlers_duration(const void *closure, upb_handlers *h) {
13316  const upb_msgdef *md = upb_handlers_msgdef(h);
13317 
13318  const upb_fielddef* seconds_field =
13320  const upb_fielddef* nanos_field =
13322 
13324 
13326  upb_handlers_setint64(h, seconds_field, putseconds, &empty_attr);
13327  upb_handlers_setint32(h, nanos_field, putnanos, &empty_attr);
13329 
13330  UPB_UNUSED(closure);
13331 }
13332 
13333 /* Set up handlers for a timestamp submessage. Instead of printing fields
13334  * separately, the json representation of timestamp follows RFC 3339 */
13335 void printer_sethandlers_timestamp(const void *closure, upb_handlers *h) {
13336  const upb_msgdef *md = upb_handlers_msgdef(h);
13337 
13338  const upb_fielddef* seconds_field =
13340  const upb_fielddef* nanos_field =
13342 
13344 
13346  upb_handlers_setint64(h, seconds_field, putseconds, &empty_attr);
13347  upb_handlers_setint32(h, nanos_field, putnanos, &empty_attr);
13349 
13350  UPB_UNUSED(closure);
13351 }
13352 
13353 void printer_sethandlers_value(const void *closure, upb_handlers *h) {
13354  const upb_msgdef *md = upb_handlers_msgdef(h);
13356 
13358 
13361 
13362  upb_msg_field_begin(&i, md);
13363  for(; !upb_msg_field_done(&i); upb_msg_field_next(&i)) {
13364  const upb_fielddef *f = upb_msg_iter_field(&i);
13365 
13366  switch (upb_fielddef_type(f)) {
13367  case UPB_TYPE_ENUM:
13368  upb_handlers_setint32(h, f, putnull, &empty_attr);
13369  break;
13370  case UPB_TYPE_DOUBLE:
13371  upb_handlers_setdouble(h, f, putdouble, &empty_attr);
13372  break;
13373  case UPB_TYPE_STRING:
13375  upb_handlers_setstring(h, f, scalar_str, &empty_attr);
13376  upb_handlers_setendstr(h, f, scalar_endstr, &empty_attr);
13377  break;
13378  case UPB_TYPE_BOOL:
13379  upb_handlers_setbool(h, f, putbool, &empty_attr);
13380  break;
13381  case UPB_TYPE_MESSAGE:
13382  break;
13383  default:
13384  UPB_ASSERT(false);
13385  break;
13386  }
13387  }
13388 
13389  UPB_UNUSED(closure);
13390 }
13391 
13392 #define WRAPPER_SETHANDLERS(wrapper, type, putmethod) \
13393 void printer_sethandlers_##wrapper(const void *closure, upb_handlers *h) { \
13394  const upb_msgdef *md = upb_handlers_msgdef(h); \
13395  const upb_fielddef* f = upb_msgdef_itof(md, 1); \
13396  upb_handlerattr empty_attr = UPB_HANDLERATTR_INIT; \
13397  upb_handlers_setstartmsg(h, printer_startmsg_noframe, &empty_attr); \
13398  upb_handlers_setendmsg(h, printer_endmsg_noframe, &empty_attr); \
13399  upb_handlers_set##type(h, f, putmethod, &empty_attr); \
13400  UPB_UNUSED(closure); \
13401 }
13402 
13403 WRAPPER_SETHANDLERS(doublevalue, double, putdouble)
13404 WRAPPER_SETHANDLERS(floatvalue, float, putfloat)
13405 WRAPPER_SETHANDLERS(int64value, int64, putint64_t)
13406 WRAPPER_SETHANDLERS(uint64value, uint64, putuint64_t)
13407 WRAPPER_SETHANDLERS(int32value, int32, putint32_t)
13408 WRAPPER_SETHANDLERS(uint32value, uint32, putuint32_t)
13409 WRAPPER_SETHANDLERS(boolvalue, bool, putbool)
13410 WRAPPER_SETHANDLERS(stringvalue, string, putstr_nokey)
13411 WRAPPER_SETHANDLERS(bytesvalue, string, putbytes)
13412 
13413 #undef WRAPPER_SETHANDLERS
13414 
13415 void printer_sethandlers_listvalue(const void *closure, upb_handlers *h) {
13416  const upb_msgdef *md = upb_handlers_msgdef(h);
13417  const upb_fielddef* f = upb_msgdef_itof(md, 1);
13418 
13420 
13421  upb_handlers_setstartseq(h, f, startseq_nokey, &empty_attr);
13422  upb_handlers_setendseq(h, f, endseq, &empty_attr);
13423 
13426 
13428 
13429  UPB_UNUSED(closure);
13430 }
13431 
13432 void printer_sethandlers_structvalue(const void *closure, upb_handlers *h) {
13433  const upb_msgdef *md = upb_handlers_msgdef(h);
13434  const upb_fielddef* f = upb_msgdef_itof(md, 1);
13435 
13437 
13438  upb_handlers_setstartseq(h, f, startmap_nokey, &empty_attr);
13439  upb_handlers_setendseq(h, f, endmap, &empty_attr);
13440 
13443 
13445 
13446  UPB_UNUSED(closure);
13447 }
13448 
13449 void printer_sethandlers(const void *closure, upb_handlers *h) {
13450  const upb_msgdef *md = upb_handlers_msgdef(h);
13451  bool is_mapentry = upb_msgdef_mapentry(md);
13454  const upb_json_printercache *cache = closure;
13455  const bool preserve_fieldnames = cache->preserve_fieldnames;
13456 
13457  if (is_mapentry) {
13458  /* mapentry messages are sufficiently different that we handle them
13459  * separately. */
13460  printer_sethandlers_mapentry(closure, preserve_fieldnames, h);
13461  return;
13462  }
13463 
13464  switch (upb_msgdef_wellknowntype(md)) {
13466  break;
13467  case UPB_WELLKNOWN_ANY:
13468  printer_sethandlers_any(closure, h);
13469  return;
13471  printer_sethandlers_fieldmask(closure, h);
13472  return;
13474  printer_sethandlers_duration(closure, h);
13475  return;
13477  printer_sethandlers_timestamp(closure, h);
13478  return;
13479  case UPB_WELLKNOWN_VALUE:
13480  printer_sethandlers_value(closure, h);
13481  return;
13483  printer_sethandlers_listvalue(closure, h);
13484  return;
13485  case UPB_WELLKNOWN_STRUCT:
13487  return;
13488 #define WRAPPER(wellknowntype, name) \
13489  case wellknowntype: \
13490  printer_sethandlers_##name(closure, h); \
13491  return; \
13492 
13493  WRAPPER(UPB_WELLKNOWN_DOUBLEVALUE, doublevalue);
13494  WRAPPER(UPB_WELLKNOWN_FLOATVALUE, floatvalue);
13495  WRAPPER(UPB_WELLKNOWN_INT64VALUE, int64value);
13496  WRAPPER(UPB_WELLKNOWN_UINT64VALUE, uint64value);
13497  WRAPPER(UPB_WELLKNOWN_INT32VALUE, int32value);
13498  WRAPPER(UPB_WELLKNOWN_UINT32VALUE, uint32value);
13499  WRAPPER(UPB_WELLKNOWN_BOOLVALUE, boolvalue);
13500  WRAPPER(UPB_WELLKNOWN_STRINGVALUE, stringvalue);
13501  WRAPPER(UPB_WELLKNOWN_BYTESVALUE, bytesvalue);
13502 
13503 #undef WRAPPER
13504  }
13505 
13507  upb_handlers_setendmsg(h, printer_endmsg, &empty_attr);
13508 
13509 #define TYPE(type, name, ctype) \
13510  case type: \
13511  if (upb_fielddef_isseq(f)) { \
13512  upb_handlers_set##name(h, f, repeated_##ctype, &empty_attr); \
13513  } else { \
13514  upb_handlers_set##name(h, f, scalar_##ctype, &name_attr); \
13515  } \
13516  break;
13517 
13518  upb_msg_field_begin(&i, md);
13519  for(; !upb_msg_field_done(&i); upb_msg_field_next(&i)) {
13520  const upb_fielddef *f = upb_msg_iter_field(&i);
13521 
13523  name_attr.handler_data = newstrpc(h, f, preserve_fieldnames);
13524 
13525  if (upb_fielddef_ismap(f)) {
13526  upb_handlers_setstartseq(h, f, startmap, &name_attr);
13527  upb_handlers_setendseq(h, f, endmap, &name_attr);
13528  } else if (upb_fielddef_isseq(f)) {
13529  upb_handlers_setstartseq(h, f, startseq, &name_attr);
13530  upb_handlers_setendseq(h, f, endseq, &empty_attr);
13531  }
13532 
13533  switch (upb_fielddef_type(f)) {
13534  TYPE(UPB_TYPE_FLOAT, float, float);
13535  TYPE(UPB_TYPE_DOUBLE, double, double);
13536  TYPE(UPB_TYPE_BOOL, bool, bool);
13537  TYPE(UPB_TYPE_INT32, int32, int32_t);
13538  TYPE(UPB_TYPE_UINT32, uint32, uint32_t);
13539  TYPE(UPB_TYPE_INT64, int64, int64_t);
13540  TYPE(UPB_TYPE_UINT64, uint64, uint64_t);
13541  case UPB_TYPE_ENUM: {
13542  /* For now, we always emit symbolic names for enums. We may want an
13543  * option later to control this behavior, but we will wait for a real
13544  * need first. */
13546  set_enum_hd(h, f, preserve_fieldnames, &enum_attr);
13547 
13548  if (upb_fielddef_isseq(f)) {
13549  upb_handlers_setint32(h, f, repeated_enum, &enum_attr);
13550  } else {
13551  upb_handlers_setint32(h, f, scalar_enum, &enum_attr);
13552  }
13553 
13554  break;
13555  }
13556  case UPB_TYPE_STRING:
13557  if (upb_fielddef_isseq(f)) {
13559  upb_handlers_setstring(h, f, repeated_str, &empty_attr);
13560  upb_handlers_setendstr(h, f, repeated_endstr, &empty_attr);
13561  } else {
13563  upb_handlers_setstring(h, f, scalar_str, &empty_attr);
13564  upb_handlers_setendstr(h, f, scalar_endstr, &empty_attr);
13565  }
13566  break;
13567  case UPB_TYPE_BYTES:
13568  /* XXX: this doesn't support strings that span buffers yet. The base64
13569  * encoder will need to be made resumable for this to work properly. */
13570  if (upb_fielddef_isseq(f)) {
13571  upb_handlers_setstring(h, f, repeated_bytes, &empty_attr);
13572  } else {
13573  upb_handlers_setstring(h, f, scalar_bytes, &name_attr);
13574  }
13575  break;
13576  case UPB_TYPE_MESSAGE:
13577  if (upb_fielddef_isseq(f)) {
13579  } else {
13581  }
13582  break;
13583  }
13584  }
13585 
13586 #undef TYPE
13587 }
13588 
13590  p->depth_ = 0;
13591 }
13592 
13593 
13594 /* Public API *****************************************************************/
13595 
13598 #ifndef NDEBUG
13599  size_t size_before = upb_arena_bytesallocated(a);
13600 #endif
13601 
13603  if (!p) return NULL;
13604 
13605  p->output_ = output;
13607  upb_sink_reset(&p->input_, h, p);
13608  p->seconds = 0;
13609  p->nanos = 0;
13610 
13611  /* If this fails, increase the value in printer.h. */
13614  return p;
13615 }
13616 
13618  return p->input_;
13619 }
13620 
13621 upb_handlercache *upb_json_printer_newcache(bool preserve_proto_fieldnames) {
13622  upb_json_printercache *cache = upb_gmalloc(sizeof(*cache));
13624 
13625  cache->preserve_fieldnames = preserve_proto_fieldnames;
13627 
13628  return ret;
13629 }
13630 
13631 #undef UPB_SIZE
13632 #undef UPB_FIELD_AT
13633 #undef UPB_READ_ONEOF
13634 #undef UPB_WRITE_ONEOF
upb_pbdecoder_end
bool upb_pbdecoder_end(void *closure, const void *handler_data)
Definition: php/ext/google/protobuf/upb.c:7638
upb_double_handlerfunc
bool upb_double_handlerfunc(void *c, const void *hd, double val)
Definition: php/ext/google/protobuf/upb.h:4139
putkey
static bool putkey(void *closure, const void *handler_data)
Definition: php/ext/google/protobuf/upb.c:12462
upb_strtable_resize
bool upb_strtable_resize(upb_strtable *t, size_t size_lg2, upb_alloc *a)
Definition: php/ext/google/protobuf/upb.c:4939
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: php/ext/google/protobuf/upb.h:1248
upb_pbdecoder_decode
size_t upb_pbdecoder_decode(void *decoder, const void *group, const char *buf, size_t size, const upb_bufhandle *handle)
Definition: php/ext/google/protobuf/upb.c:7695
is_string_wrapper_object
static bool is_string_wrapper_object(upb_json_parser *p)
Definition: php/ext/google/protobuf/upb.c:11329
upb_vdecode_fast
UPB_INLINE upb_decoderet upb_vdecode_fast(const char *p)
Definition: php/ext/google/protobuf/upb.h:6829
upb_enum_iter_number
int32_t upb_enum_iter_number(upb_enum_iter *iter)
Definition: php/ext/google/protobuf/upb.c:1494
upb_pbdecoder_input
upb_bytessink upb_pbdecoder_input(upb_pbdecoder *d)
Definition: php/ext/google/protobuf/upb.c:7762
upb_oneofdef::full_name
const char * full_name
Definition: php/ext/google/protobuf/upb.c:1178
json_parser_any_frame_has_type_url
static bool json_parser_any_frame_has_type_url(upb_jsonparser_any_frame *frame)
Definition: php/ext/google/protobuf/upb.c:9122
create_fielddef
static bool create_fielddef(const symtab_addctx *ctx, const char *prefix, upb_msgdef *m, const google_protobuf_FieldDescriptorProto *field_proto)
Definition: php/ext/google/protobuf/upb.c:2183
google_protobuf_OneofDescriptorProto
struct google_protobuf_OneofDescriptorProto google_protobuf_OneofDescriptorProto
Definition: php/ext/google/protobuf/upb.h:938
PTR_AT
#define PTR_AT(msg, ofs, type)
Definition: php/ext/google/protobuf/upb.c:3851
upb_pb_encoder_input
upb_sink upb_pb_encoder_input(upb_pb_encoder *e)
Definition: php/ext/google/protobuf/upb.c:8368
enums
static const upb_enumdef enums[5]
Definition: ruby/ext/google/protobuf_c/upb.c:7672
google_protobuf_FileDescriptorSet_msginit
const upb_msglayout google_protobuf_FileDescriptorSet_msginit
Definition: php/ext/google/protobuf/upb.c:44
google_protobuf_DescriptorProto
struct google_protobuf_DescriptorProto google_protobuf_DescriptorProto
Definition: php/ext/google/protobuf/upb.h:933
upb_oneofdef_index
uint32_t upb_oneofdef_index(const upb_oneofdef *o)
Definition: php/ext/google/protobuf/upb.c:1894
UPB_DEFTYPE_ONEOF
@ UPB_DEFTYPE_ONEOF
Definition: php/ext/google/protobuf/upb.c:1213
UPB_SYNTAX_PROTO2
@ UPB_SYNTAX_PROTO2
Definition: php/ext/google/protobuf/upb.h:3140
upb_pb_encoder::subc
void * subc
Definition: php/ext/google/protobuf/upb.c:7901
upb_mapiter_begin
void upb_mapiter_begin(upb_mapiter *i, const upb_map *map)
Definition: php/ext/google/protobuf/upb.c:4305
parser_getsel
static upb_selector_t parser_getsel(upb_json_parser *p)
Definition: php/ext/google/protobuf/upb.c:9171
lookup
static bool lookup(const upb_table *t, lookupkey_t key, upb_value *v, uint32_t hash, eqlfunc_t *eql)
Definition: php/ext/google/protobuf/upb.c:4790
upb_arena_bytesallocated
size_t upb_arena_bytesallocated(const upb_arena *a)
Definition: php/ext/google/protobuf/upb.c:5799
upb_pb_encoder::stacklimit
int * stacklimit
Definition: php/ext/google/protobuf/upb.c:7917
upb_filedef::enums
const upb_enumdef * enums
Definition: php/ext/google/protobuf/upb.c:1193
start_month
static void start_month(upb_json_parser *p, const char *ptr)
Definition: php/ext/google/protobuf/upb.c:10338
UPB_MAX_HANDLER_DEPTH
#define UPB_MAX_HANDLER_DEPTH
Definition: php/ext/google/protobuf/upb.h:4031
upb_jsonparser_any_frame::encoder_handlercache
upb_handlercache * encoder_handlercache
Definition: php/ext/google/protobuf/upb.c:8934
upb_json_codecache
Definition: php/ext/google/protobuf/upb.c:9063
upb_fielddef_defaultint64
int64_t upb_fielddef_defaultint64(const upb_fielddef *f)
Definition: php/ext/google/protobuf/upb.c:1628
upb_fielddef_defaultuint64
uint64_t upb_fielddef_defaultuint64(const upb_fielddef *f)
Definition: php/ext/google/protobuf/upb.c:1638
start_any_stringval
static bool start_any_stringval(upb_json_parser *p)
Definition: php/ext/google/protobuf/upb.c:9960
OP_POP
@ OP_POP
Definition: php/ext/google/protobuf/upb.h:6473
upb_inttable_init2
bool upb_inttable_init2(upb_inttable *t, upb_ctype_t ctype, upb_alloc *a)
Definition: php/ext/google/protobuf/upb.c:5124
upb_int32_handlerfunc
bool upb_int32_handlerfunc(void *c, const void *hd, int32_t val)
Definition: php/ext/google/protobuf/upb.h:4134
upb_filedef_dep
const upb_filedef * upb_filedef_dep(const upb_filedef *f, int i)
Definition: php/ext/google/protobuf/upb.c:2728
upb_desctype_to_fieldtype
const uint8_t upb_desctype_to_fieldtype[]
Definition: php/ext/google/protobuf/upb.c:508
MULTIPART_ACCUMULATE
@ MULTIPART_ACCUMULATE
Definition: php/ext/google/protobuf/upb.c:9460
end_member
static void end_member(upb_json_parser *p)
Definition: php/ext/google/protobuf/upb.c:10794
upb_json_parsermethod::cache
const upb_json_codecache * cache
Definition: php/ext/google/protobuf/upb.c:9069
UPB_DESCRIPTOR_TYPE_UINT64
@ UPB_DESCRIPTOR_TYPE_UINT64
Definition: php/ext/google/protobuf/upb.h:440
isleap
static bool isleap(int year)
Definition: php/ext/google/protobuf/upb.c:10466
upb_selector_t
int32_t upb_selector_t
Definition: php/ext/google/protobuf/upb.h:4062
upb_arena_init
upb_arena * upb_arena_init(void *mem, size_t n, upb_alloc *alloc)
Definition: php/ext/google/protobuf/upb.c:5725
upb_msg_set
void upb_msg_set(upb_msg *msg, int field_index, upb_msgval val, const upb_msglayout *l)
Definition: php/ext/google/protobuf/upb.c:4083
oom
static UPB_NORETURN void oom(tarjan *t)
Definition: ruby/ext/google/protobuf_c/upb.c:5857
is_string_wrapper
static bool is_string_wrapper(const upb_msgdef *m)
Definition: php/ext/google/protobuf/upb.c:11164
upb_handlers::sub
const upb_handlers ** sub
Definition: php/ext/google/protobuf/upb.c:3272
TRY
#define TRY(type)
upb_msg_iter_oneof
const upb_oneofdef * upb_msg_iter_oneof(const upb_msg_oneof_iter *iter)
Definition: php/ext/google/protobuf/upb.c:1867
upb_jsonparser_frame::m
const upb_msgdef * m
Definition: php/ext/google/protobuf/upb.c:8955
NO_WIRE_TYPE
#define NO_WIRE_TYPE
Definition: php/ext/google/protobuf/upb.h:6695
upb_pbdecoder_bytesparsed
uint64_t upb_pbdecoder_bytesparsed(const upb_pbdecoder *d)
Definition: php/ext/google/protobuf/upb.c:7754
upb_enum_next
void upb_enum_next(upb_enum_iter *iter)
Definition: php/ext/google/protobuf/upb.c:1471
UPB_HANDLER_INT64
@ UPB_HANDLER_INT64
Definition: php/ext/google/protobuf/upb.h:4037
upb_status_seterrf
void upb_status_seterrf(upb_status *status, const char *fmt,...)
Definition: php/ext/google/protobuf/upb.c:5584
UPB_UNUSED
#define UPB_UNUSED(var)
Definition: php/ext/google/protobuf/upb.h:141
name
GLuint const GLchar * name
Definition: glcorearb.h:3055
upb_handlers_getselector
bool upb_handlers_getselector(const upb_fielddef *f, upb_handlertype_t type, upb_selector_t *s)
Definition: php/ext/google/protobuf/upb.c:3563
UPB_HANDLER_ENDSEQ
@ UPB_HANDLER_ENDSEQ
Definition: php/ext/google/protobuf/upb.h:4049
streql
static bool streql(upb_tabkey k1, lookupkey_t k2)
Definition: php/ext/google/protobuf/upb.c:4922
upb_filedef::msgs
const upb_msgdef * msgs
Definition: php/ext/google/protobuf/upb.c:1192
printer_sethandlers_mapentry
void printer_sethandlers_mapentry(const void *closure, bool preserve_fieldnames, upb_handlers *h)
Definition: php/ext/google/protobuf/upb.c:12866
upb_pbdecoder_method
const upb_pbdecodermethod * upb_pbdecoder_method(const upb_pbdecoder *d)
Definition: php/ext/google/protobuf/upb.c:7758
cleanup_ent::next
struct cleanup_ent * next
Definition: php/ext/google/protobuf/upb.c:5652
UPB_CTYPE_UINT32
@ UPB_CTYPE_UINT32
Definition: php/ext/google/protobuf/upb.h:2645
upb_handlers_tabent
Definition: php/ext/google/protobuf/upb.h:4632
upb_msgdef::map_entry
bool map_entry
Definition: php/ext/google/protobuf/upb.c:1162
google_protobuf_MethodOptions_msginit
const upb_msglayout google_protobuf_MethodOptions_msginit
Definition: php/ext/google/protobuf/upb.c:411
upb_arena
Definition: php/ext/google/protobuf/upb.c:5623
upb_arena
struct upb_arena upb_arena
Definition: php/ext/google/protobuf/upb.h:303
field_rank
uint32_t field_rank(const upb_fielddef *f)
Definition: php/ext/google/protobuf/upb.c:1287
upb_symtab_lookupenum
const upb_enumdef * upb_symtab_lookupenum(const upb_symtab *s, const char *sym)
Definition: php/ext/google/protobuf/upb.c:2778
start_stringval
static bool start_stringval(upb_json_parser *p)
Definition: php/ext/google/protobuf/upb.c:9965
upb_pbdecoder_setmaxnesting
bool upb_pbdecoder_setmaxnesting(upb_pbdecoder *d, size_t max)
Definition: php/ext/google/protobuf/upb.c:7770
decode_varint
static UPB_FORCEINLINE int32_t decode_varint(upb_pbdecoder *d, uint64_t *u64)
Definition: php/ext/google/protobuf/upb.c:7148
upb_inttable_insertptr
UPB_INLINE bool upb_inttable_insertptr(upb_inttable *t, const void *key, upb_value val)
Definition: php/ext/google/protobuf/upb.h:2983
freestrpc
void freestrpc(void *ptr)
Definition: php/ext/google/protobuf/upb.c:12271
repeated_str_fieldmask
static size_t repeated_str_fieldmask(void *closure, const void *handler_data, const char *str, size_t len, const upb_bufhandle *handle)
Definition: php/ext/google/protobuf/upb.c:13023
upb_arena_allocblock
static mem_block * upb_arena_allocblock(upb_arena *a, size_t size)
Definition: php/ext/google/protobuf/upb.c:5671
upb_strtable_iter_isequal
bool upb_strtable_iter_isequal(const upb_strtable_iter *i1, const upb_strtable_iter *i2)
Definition: php/ext/google/protobuf/upb.c:5046
kUnterminatedVarint
static const char * kUnterminatedVarint
Definition: php/ext/google/protobuf/upb.c:6757
OP_SETDELIM
@ OP_SETDELIM
Definition: php/ext/google/protobuf/upb.h:6474
upb_startfield_handlerfunc
void * upb_startfield_handlerfunc(void *c, const void *hd)
Definition: php/ext/google/protobuf/upb.h:4132
inttable_val_const
static const upb_tabval * inttable_val_const(const upb_inttable *t, uintptr_t key)
Definition: php/ext/google/protobuf/upb.c:5079
getbytes
static UPB_FORCEINLINE int32_t getbytes(upb_pbdecoder *d, void *buf, size_t bytes)
Definition: php/ext/google/protobuf/upb.c:7092
MSG_WRITER
#define MSG_WRITER(type, ctype)
Definition: php/ext/google/protobuf/upb.c:3756
upb_stringsink_uninit
void upb_stringsink_uninit(upb_stringsink *sink)
Definition: php/ext/google/protobuf/upb.c:8930
upb_status_clear
void upb_status_clear(upb_status *status)
Definition: php/ext/google/protobuf/upb.c:5567
upb_zzdec_32
UPB_INLINE int32_t upb_zzdec_32(uint32_t n)
Definition: php/ext/google/protobuf/upb.h:6775
upb_handlers_selectorcount
uint32_t upb_handlers_selectorcount(const upb_fielddef *f)
Definition: php/ext/google/protobuf/upb.c:3631
upb_msg_get
upb_msgval upb_msg_get(const upb_msg *msg, int field_index, const upb_msglayout *l)
Definition: php/ext/google/protobuf/upb.c:4076
EnumHandlerData::enumdef
const upb_enumdef * enumdef
Definition: php/ext/google/protobuf/upb.c:12532
upb_pbdecoder_skipunknown
int32_t upb_pbdecoder_skipunknown(upb_pbdecoder *d, int32_t fieldnum, uint8_t wire_type)
Definition: php/ext/google/protobuf/upb.c:7266
advancetobuf
static void advancetobuf(upb_pbdecoder *d, const char *buf, size_t len)
Definition: php/ext/google/protobuf/upb.c:6895
google_protobuf_UninterpretedOption_submsgs
static const upb_msglayout *const google_protobuf_UninterpretedOption_submsgs[1]
Definition: php/ext/google/protobuf/upb.c:417
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: php/ext/google/protobuf/upb.c:4804
upb_func
void upb_func()
Definition: php/ext/google/protobuf/upb.h:395
UPB_DESCRIPTOR_TYPE_FIXED32
@ UPB_DESCRIPTOR_TYPE_FIXED32
Definition: php/ext/google/protobuf/upb.h:443
upb_handlers_setunknown
bool upb_handlers_setunknown(upb_handlers *h, upb_unknown_handlerfunc *func, const upb_handlerattr *attr)
Definition: php/ext/google/protobuf/upb.c:3484
upb_msgfactory::layouts
upb_inttable layouts
Definition: php/ext/google/protobuf/upb.c:4545
printer_starttimestampmsg
static bool printer_starttimestampmsg(void *closure, const void *handler_data)
Definition: php/ext/google/protobuf/upb.c:13134
does_fieldmask_start
static bool does_fieldmask_start(upb_json_parser *p)
Definition: php/ext/google/protobuf/upb.c:11333
getsel
static upb_selector_t getsel(const upb_fielddef *f, upb_handlertype_t type)
Definition: php/ext/google/protobuf/upb.c:6243
UPB_BUFHANDLE_INIT
#define UPB_BUFHANDLE_INIT
Definition: php/ext/google/protobuf/upb.h:4124
upb_inttable_remove
bool upb_inttable_remove(upb_inttable *t, uintptr_t key, upb_value *val)
Definition: php/ext/google/protobuf/upb.c:5190
upb_filedef_msgcount
int upb_filedef_msgcount(const upb_filedef *f)
Definition: php/ext/google/protobuf/upb.c:2716
UPB_HANDLER_STARTSUBMSG
@ UPB_HANDLER_STARTSUBMSG
Definition: php/ext/google/protobuf/upb.h:4046
upb_msglayout::fields
const upb_msglayout_field * fields
Definition: php/ext/google/protobuf/upb.h:525
google_protobuf_FileDescriptorSet__fields
static const upb_msglayout_field google_protobuf_FileDescriptorSet__fields[1]
Definition: php/ext/google/protobuf/upb.c:40
upb_inttable_done
bool upb_inttable_done(const upb_inttable_iter *i)
Definition: php/ext/google/protobuf/upb.c:5331
mem_block
struct mem_block mem_block
nonbase64
bool nonbase64(unsigned char ch)
Definition: php/ext/google/protobuf/upb.c:9263
dummy_char
static const char dummy_char
Definition: php/ext/google/protobuf/upb.c:6766
upb_msg_internal::unknown_size
size_t unknown_size
Definition: php/ext/google/protobuf/upb.c:3959
neginf
const char neginf[]
Definition: php/ext/google/protobuf/upb.c:12403
google_protobuf_ExtensionRangeOptions__fields
static const upb_msglayout_field google_protobuf_ExtensionRangeOptions__fields[1]
Definition: php/ext/google/protobuf/upb.c:140
benchmarks.python.py_benchmark.const
const
Definition: py_benchmark.py:14
UPB_DESCRIPTOR_TYPE_FIXED64
@ UPB_DESCRIPTOR_TYPE_FIXED64
Definition: php/ext/google/protobuf/upb.h:442
upb_json_parser::ignore_json_unknown
bool ignore_json_unknown
Definition: php/ext/google/protobuf/upb.c:9049
upb_msg_getinternal
static upb_msg_internal * upb_msg_getinternal(upb_msg *msg)
Definition: php/ext/google/protobuf/upb.c:3972
upb_pbcodecache::arena
upb_arena * arena
Definition: php/ext/google/protobuf/upb.h:6505
DISPATCH_ENDMSG
#define DISPATCH_ENDMSG
Definition: php/ext/google/protobuf/upb.h:6691
upb_strdup
char * upb_strdup(const char *s, upb_alloc *a)
Definition: php/ext/google/protobuf/upb.c:4675
upb_symtab::arena
upb_arena * arena
Definition: php/ext/google/protobuf/upb.c:1203
OP_TAGN
@ OP_TAGN
Definition: php/ext/google/protobuf/upb.h:6486
upb_json_parser::digit
uint32_t digit
Definition: php/ext/google/protobuf/upb.c:9043
google_protobuf_FileDescriptorProto_dependency
UPB_INLINE upb_strview const * google_protobuf_FileDescriptorProto_dependency(const google_protobuf_FileDescriptorProto *msg, size_t *len)
Definition: php/ext/google/protobuf/upb.h:1089
putbytes
static size_t putbytes(void *closure, const void *handler_data, const char *str, size_t len, const upb_bufhandle *handle)
Definition: php/ext/google/protobuf/upb.c:12676
encode_startdelimfield
static void * encode_startdelimfield(void *c, const void *hd)
Definition: php/ext/google/protobuf/upb.c:8170
upb_zzdec_64
UPB_INLINE int64_t upb_zzdec_64(uint64_t n)
Definition: php/ext/google/protobuf/upb.h:6778
cmp_fields
int cmp_fields(const void *p1, const void *p2)
Definition: php/ext/google/protobuf/upb.c:1296
UPB_DESCRIPTOR_TYPE_INT64
@ UPB_DESCRIPTOR_TYPE_INT64
Definition: php/ext/google/protobuf/upb.h:439
putsel
static void putsel(compiler *c, opcode op, upb_selector_t sel, const upb_handlers *h)
Definition: php/ext/google/protobuf/upb.c:6307
UPB_WELLKNOWN_STRINGVALUE
@ UPB_WELLKNOWN_STRINGVALUE
Definition: php/ext/google/protobuf/upb.h:3162
google::protobuf.internal::k2
static int k2
Definition: src/google/protobuf/map_test.cc:327
UPB_WELLKNOWN_UINT64VALUE
@ UPB_WELLKNOWN_UINT64VALUE
Definition: php/ext/google/protobuf/upb.h:3158
MAX_LOAD
static const double MAX_LOAD
Definition: php/ext/google/protobuf/upb.c:4658
upb_json_parsermethod
Definition: php/ext/google/protobuf/upb.c:9068
decl_counts::msg_count
int msg_count
Definition: php/ext/google/protobuf/upb.c:2432
google_protobuf_EnumDescriptorProto_msginit
const upb_msglayout google_protobuf_EnumDescriptorProto_msginit
Definition: php/ext/google/protobuf/upb.c:202
google_protobuf_DescriptorProto_submsgs
static const upb_msglayout *const google_protobuf_DescriptorProto_submsgs[8]
Definition: php/ext/google/protobuf/upb.c:80
EMPTYLABEL
#define EMPTYLABEL
Definition: php/ext/google/protobuf/upb.c:5818
upb_arena_new
UPB_INLINE upb_arena * upb_arena_new()
Definition: php/ext/google/protobuf/upb.h:330
upb_status
Definition: php/ext/google/protobuf/upb.h:170
end
GLuint GLuint end
Definition: glcorearb.h:2858
upb_msgdef_mapentry
bool upb_msgdef_mapentry(const upb_msgdef *m)
Definition: php/ext/google/protobuf/upb.c:1809
upb_pbdecoder_frame
Definition: php/ext/google/protobuf/upb.h:6548
printer_sethandlers_structvalue
void printer_sethandlers_structvalue(const void *closure, upb_handlers *h)
Definition: php/ext/google/protobuf/upb.c:13432
UPB_CTYPE_FLOAT
@ UPB_CTYPE_FLOAT
Definition: php/ext/google/protobuf/upb.h:2652
google_protobuf_OneofDescriptorProto_name
UPB_INLINE upb_strview google_protobuf_OneofDescriptorProto_name(const google_protobuf_OneofDescriptorProto *msg)
Definition: php/ext/google/protobuf/upb.h:1577
UPB_HANDLER_INT32
@ UPB_HANDLER_INT32
Definition: php/ext/google/protobuf/upb.h:4036
upb_handlers_setstartmsg
bool upb_handlers_setstartmsg(upb_handlers *h, upb_startmsg_handlerfunc *func, const upb_handlerattr *attr)
Definition: php/ext/google/protobuf/upb.c:3490
upb_filedef::ext_count
int ext_count
Definition: php/ext/google/protobuf/upb.c:1199
lower_camel_push
static bool lower_camel_push(upb_json_parser *p, upb_selector_t sel, const char *ptr, size_t len)
Definition: php/ext/google/protobuf/upb.c:10586
upb_pb_encoder_create
upb_pb_encoder * upb_pb_encoder_create(upb_arena *arena, const upb_handlers *h, upb_bytessink output)
Definition: php/ext/google/protobuf/upb.c:8329
upb_filedef_syntax
upb_syntax_t upb_filedef_syntax(const upb_filedef *f)
Definition: php/ext/google/protobuf/upb.c:2712
upb_msglayout::size
uint16_t size
Definition: php/ext/google/protobuf/upb.h:528
symtab_add
static bool symtab_add(const symtab_addctx *ctx, const char *name, upb_value v)
Definition: php/ext/google/protobuf/upb.c:1979
upb_handlers_getsubhandlers_sel
const upb_handlers * upb_handlers_getsubhandlers_sel(const upb_handlers *h, upb_selector_t sel)
Definition: php/ext/google/protobuf/upb.c:3537
encode_varint
static bool encode_varint(upb_pb_encoder *e, uint64_t val)
Definition: php/ext/google/protobuf/upb.c:8127
upb_json_printer
Definition: php/ext/google/protobuf/upb.c:12238
NULL
NULL
Definition: test_security_zap.cpp:405
g
GLboolean GLboolean g
Definition: glcorearb.h:3228
printer_endtimestampmsg
static bool printer_endtimestampmsg(void *closure, const void *handler_data, upb_status *s)
Definition: php/ext/google/protobuf/upb.c:13147
OP_BRANCH
@ OP_BRANCH
Definition: php/ext/google/protobuf/upb.h:6481
parse
size_t parse(void *closure, const void *hd, const char *buf, size_t size, const upb_bufhandle *handle)
Definition: php/ext/google/protobuf/upb.c:11625
src
GLenum src
Definition: glcorearb.h:3364
_json_actions
static const char _json_actions[]
Definition: php/ext/google/protobuf/upb.c:11369
upb_enumdef::file
const upb_filedef * file
Definition: php/ext/google/protobuf/upb.c:1169
upb_msgdef::well_known_type
upb_wellknowntype_t well_known_type
Definition: php/ext/google/protobuf/upb.c:1163
google::protobuf.internal.wire_format.INT64_MIN
INT64_MIN
Definition: wire_format.py:62
upb_inttable_iter_isequal
bool upb_inttable_iter_isequal(const upb_inttable_iter *i1, const upb_inttable_iter *i2)
Definition: php/ext/google/protobuf/upb.c:5360
google::protobuf::int64
int64_t int64
Definition: protobuf/src/google/protobuf/stubs/port.h:151
upb_decode_64bitfield
static bool upb_decode_64bitfield(upb_decstate *d, upb_decframe *frame, const char *field_start, const upb_msglayout_field *field)
Definition: php/ext/google/protobuf/upb.c:830
MIN_DENSITY
static const double MIN_DENSITY
Definition: php/ext/google/protobuf/upb.c:4663
google_protobuf_FileDescriptorProto_name
UPB_INLINE upb_strview google_protobuf_FileDescriptorProto_name(const google_protobuf_FileDescriptorProto *msg)
Definition: php/ext/google/protobuf/upb.h:1086
upb_pbdecodermethod::dispatch
upb_inttable dispatch
Definition: php/ext/google/protobuf/upb.h:6597
accumulate
static void accumulate(upb_pb_encoder *e)
Definition: php/ext/google/protobuf/upb.c:8003
upb_msgdef_ntoo
const upb_oneofdef * upb_msgdef_ntoo(const upb_msgdef *m, const char *name, size_t len)
Definition: php/ext/google/protobuf/upb.c:1774
upb_json_parser::accumulate_buf_size
size_t accumulate_buf_size
Definition: php/ext/google/protobuf/upb.c:9033
upb_msgdef::submsg_field_count
uint32_t submsg_field_count
Definition: php/ext/google/protobuf/upb.c:1150
upb_fielddef::file
const upb_filedef * file
Definition: php/ext/google/protobuf/upb.c:1119
textprinter_reset
static void textprinter_reset(upb_textprinter *p, bool single_line)
Definition: php/ext/google/protobuf/upb.c:8676
upb_strtable_iter_keylength
size_t upb_strtable_iter_keylength(const upb_strtable_iter *i)
Definition: php/ext/google/protobuf/upb.c:5029
is_wellknown_field
static bool is_wellknown_field(upb_json_parser *p, upb_wellknowntype_t type)
Definition: php/ext/google/protobuf/upb.c:11298
google_protobuf_OneofOptions_submsgs
static const upb_msglayout *const google_protobuf_OneofOptions_submsgs[1]
Definition: php/ext/google/protobuf/upb.c:341
upb_put_fixed32
static bool upb_put_fixed32(upb_encstate *e, uint32_t val)
Definition: php/ext/google/protobuf/upb.c:2961
upb_inttable_iter::t
const upb_inttable * t
Definition: php/ext/google/protobuf/upb.h:3089
symtab_addctx::alloc
upb_alloc * alloc
Definition: php/ext/google/protobuf/upb.c:1944
upb_json_printercache
Definition: php/ext/google/protobuf/upb.c:12277
UPB_TABVALUE_EMPTY_INIT
#define UPB_TABVALUE_EMPTY_INIT
Definition: php/ext/google/protobuf/upb.h:2777
VALUE_BOOLVALUE
@ VALUE_BOOLVALUE
Definition: php/ext/google/protobuf/upb.c:8820
google_protobuf_OneofDescriptorProto_msginit
const upb_msglayout google_protobuf_OneofDescriptorProto_msginit
Definition: php/ext/google/protobuf/upb.c:182
upb_json_parser_input
upb_bytessink upb_json_parser_input(upb_json_parser *p)
Definition: php/ext/google/protobuf/upb.c:12164
upb_decode_toarray
static bool upb_decode_toarray(upb_decstate *d, upb_decframe *frame, const char *field_start, const upb_msglayout_field *field, upb_strview val)
Definition: php/ext/google/protobuf/upb.c:890
indent
static int indent(upb_textprinter *p)
Definition: php/ext/google/protobuf/upb.c:8400
upb_msg_internal_withext::extdict
upb_inttable * extdict
Definition: php/ext/google/protobuf/upb.c:3964
upb_isletter
static bool upb_isletter(char c)
Definition: php/ext/google/protobuf/upb.c:1231
json_printer_reset
static void json_printer_reset(upb_json_printer *p)
Definition: php/ext/google/protobuf/upb.c:13589
upb_inttable_begin
void upb_inttable_begin(upb_inttable_iter *i, const upb_inttable *t)
Definition: php/ext/google/protobuf/upb.c:5309
end_any_stringval
static bool end_any_stringval(upb_json_parser *p)
Definition: php/ext/google/protobuf/upb.c:10055
length
GLenum GLuint GLenum GLsizei length
Definition: glcorearb.h:2695
google_protobuf_EnumDescriptorProto_submsgs
static const upb_msglayout *const google_protobuf_EnumDescriptorProto_submsgs[3]
Definition: php/ext/google/protobuf/upb.c:188
upb_pb_encoder::segbuf
upb_pb_encoder_segment * segbuf
Definition: php/ext/google/protobuf/upb.c:7913
UPB_HANDLER_DOUBLE
@ UPB_HANDLER_DOUBLE
Definition: php/ext/google/protobuf/upb.h:4041
UPB_DURATION_MAX_NANO_LEN
#define UPB_DURATION_MAX_NANO_LEN
Definition: php/ext/google/protobuf/upb.c:13075
end_minute
static bool end_minute(upb_json_parser *p, const char *ptr)
Definition: php/ext/google/protobuf/upb.c:10378
UPB_WELLKNOWN_TIMESTAMP
@ UPB_WELLKNOWN_TIMESTAMP
Definition: php/ext/google/protobuf/upb.h:3153
upb_fielddef::full_name
const char * full_name
Definition: php/ext/google/protobuf/upb.c:1121
upb_msgdef::field_count
int field_count
Definition: php/ext/google/protobuf/upb.c:1158
OP_STARTSUBMSG
@ OP_STARTSUBMSG
Definition: php/ext/google/protobuf/upb.h:6465
google_protobuf_EnumValueOptions_submsgs
static const upb_msglayout *const google_protobuf_EnumValueOptions_submsgs[1]
Definition: php/ext/google/protobuf/upb.c:371
start_object
static void start_object(upb_json_parser *p)
Definition: php/ext/google/protobuf/upb.c:11033
upb_alignof
#define upb_alignof(type)
Definition: php/ext/google/protobuf/upb.c:5723
upb_pbdecoder_suspend
size_t upb_pbdecoder_suspend(upb_pbdecoder *d)
Definition: php/ext/google/protobuf/upb.c:7004
options
Message * options
Definition: src/google/protobuf/descriptor.cc:3119
upb_fielddef_packed
bool upb_fielddef_packed(const upb_fielddef *f)
Definition: php/ext/google/protobuf/upb.c:1564
LABEL_DISPATCH
#define LABEL_DISPATCH
Definition: php/ext/google/protobuf/upb.h:6687
upb_fielddef_descriptortype
upb_descriptortype_t upb_fielddef_descriptortype(const upb_fielddef *f)
Definition: php/ext/google/protobuf/upb.c:1540
rm
static bool rm(upb_table *t, lookupkey_t key, upb_value *val, upb_tabkey *removed, uint32_t hash, eqlfunc_t *eql)
Definition: php/ext/google/protobuf/upb.c:4850
upb_deftype_t
upb_deftype_t
Definition: php/ext/google/protobuf/upb.c:1209
upb_value_size
UPB_INLINE int upb_value_size(uint64_t val)
Definition: php/ext/google/protobuf/upb.h:6839
DECODE_MISMATCH
#define DECODE_MISMATCH
Definition: php/ext/google/protobuf/upb.h:6730
upb_enumdef_iton
const char * upb_enumdef_iton(const upb_enumdef *def, int32_t num)
Definition: php/ext/google/protobuf/upb.c:1484
base
Definition: logging.cc:2162
consumes_input
static bool consumes_input(opcode op)
Definition: php/ext/google/protobuf/upb.c:6769
upb_inttable_count
size_t upb_inttable_count(const upb_inttable *t)
Definition: php/ext/google/protobuf/upb.c:5084
upb_pbdecoder_frame::end_ofs
uint64_t end_ofs
Definition: php/ext/google/protobuf/upb.h:6564
OP_TAG2
@ OP_TAG2
Definition: php/ext/google/protobuf/upb.h:6485
upb_oneofdef_itof
const upb_fielddef * upb_oneofdef_itof(const upb_oneofdef *o, uint32_t num)
Definition: php/ext/google/protobuf/upb.c:1905
VALUE_NUMBERVALUE
@ VALUE_NUMBERVALUE
Definition: php/ext/google/protobuf/upb.c:8818
escape
static bool escape(upb_json_parser *p, const char *ptr)
Definition: php/ext/google/protobuf/upb.c:9590
upb_pbdecoder
Definition: php/ext/google/protobuf/upb.h:6600
upb_array_set
bool upb_array_set(upb_array *arr, size_t i, upb_msgval val)
Definition: php/ext/google/protobuf/upb.c:4126
upb_msg_field_begin
void upb_msg_field_begin(upb_msg_field_iter *iter, const upb_msgdef *m)
Definition: php/ext/google/protobuf/upb.c:1823
upb_value
Definition: php/ext/google/protobuf/upb.h:2656
effective_closure_type
const void * effective_closure_type(upb_handlers *h, const upb_fielddef *f, upb_handlertype_t type)
Definition: php/ext/google/protobuf/upb.c:3381
upb_def_init
Definition: php/ext/google/protobuf/upb.h:3937
upb_arena::max_block_size
size_t max_block_size
Definition: php/ext/google/protobuf/upb.c:5634
upb_mapiter_sizeof
size_t upb_mapiter_sizeof()
Definition: php/ext/google/protobuf/upb.c:4301
upb_pb_encoder_newcache
upb_handlercache * upb_pb_encoder_newcache()
Definition: php/ext/google/protobuf/upb.c:8325
set_default_default
static void set_default_default(const symtab_addctx *ctx, upb_fielddef *f)
Definition: php/ext/google/protobuf/upb.c:2156
upb_strtable_insert3
bool upb_strtable_insert3(upb_strtable *t, const char *k, size_t len, upb_value v, upb_alloc *a)
Definition: php/ext/google/protobuf/upb.c:4961
upb_oneofdef::itof
upb_inttable itof
Definition: php/ext/google/protobuf/upb.c:1181
upb_arena_addcleanup
bool upb_arena_addcleanup(upb_arena *a, void *ud, upb_cleanup_func *func)
Definition: php/ext/google/protobuf/upb.c:5785
assign_msg_indices
static bool assign_msg_indices(upb_msgdef *m, upb_status *s)
Definition: php/ext/google/protobuf/upb.c:1302
upb_pb_encoder::seglimit
upb_pb_encoder_segment * seglimit
Definition: php/ext/google/protobuf/upb.c:7913
peekbytes_slow
static UPB_NOINLINE size_t peekbytes_slow(upb_pbdecoder *d, void *buf, size_t bytes)
Definition: php/ext/google/protobuf/upb.c:7103
upb_msg_oneofcase
static uint32_t * upb_msg_oneofcase(const upb_msg *msg, int field_index, const upb_msglayout *l)
Definition: php/ext/google/protobuf/upb.c:4015
startseq_nokey
static void * startseq_nokey(void *closure, const void *handler_data)
Definition: php/ext/google/protobuf/upb.c:12989
symtab_addctx::tmp
upb_alloc * tmp
Definition: php/ext/google/protobuf/upb.c:1945
upb_json_parser_create
upb_json_parser * upb_json_parser_create(upb_arena *arena, const upb_json_parsermethod *method, const upb_symtab *symtab, upb_sink output, upb_status *status, bool ignore_json_unknown)
Definition: php/ext/google/protobuf/upb.c:12122
checkpoint
static void checkpoint(upb_pbdecoder *d)
Definition: php/ext/google/protobuf/upb.c:6901
s
XmlRpcServer s
upb_msgdef_file
const upb_filedef * upb_msgdef_file(const upb_msgdef *m)
Definition: php/ext/google/protobuf/upb.c:1737
end_stringval
static bool end_stringval(upb_json_parser *p)
Definition: php/ext/google/protobuf/upb.c:10171
upb_handlers_setstartseq
bool upb_handlers_setstartseq(upb_handlers *h, const upb_fielddef *f, upb_startfield_handlerfunc *func, const upb_handlerattr *attr)
upb_enumdef_name
const char * upb_enumdef_name(const upb_enumdef *e)
Definition: php/ext/google/protobuf/upb.c:1449
end_fieldmask_object
static void end_fieldmask_object(upb_json_parser *p)
Definition: php/ext/google/protobuf/upb.c:11189
encode_fixed64
static bool encode_fixed64(upb_pb_encoder *e, uint64_t val)
Definition: php/ext/google/protobuf/upb.c:8117
UPB_TYPE_INT32
@ UPB_TYPE_INT32
Definition: php/ext/google/protobuf/upb.h:415
upb_pbdecodermethod::input_handler_
upb_byteshandler input_handler_
Definition: php/ext/google/protobuf/upb.h:6589
upb_textprinter_create
upb_textprinter * upb_textprinter_create(upb_arena *arena, const upb_handlers *h, upb_bytessink output)
Definition: php/ext/google/protobuf/upb.c:8684
encoder_advance
static void encoder_advance(upb_pb_encoder *e, size_t bytes)
Definition: php/ext/google/protobuf/upb.c:7969
upb_json_codecache::arena
upb_arena * arena
Definition: php/ext/google/protobuf/upb.c:9064
printer_enddurationmsg
static bool printer_enddurationmsg(void *closure, const void *handler_data, upb_status *s)
Definition: php/ext/google/protobuf/upb.c:13077
end_second
static bool end_second(upb_json_parser *p, const char *ptr)
Definition: php/ext/google/protobuf/upb.c:10390
upb_fielddef_issubmsg
bool upb_fielddef_issubmsg(const upb_fielddef *f)
Definition: php/ext/google/protobuf/upb.c:1687
UPB_DESCRIPTOR_TYPE_SFIXED32
@ UPB_DESCRIPTOR_TYPE_SFIXED32
Definition: php/ext/google/protobuf/upb.h:451
upb_handlers_setendstr
bool upb_handlers_setendstr(upb_handlers *h, const upb_fielddef *f, upb_endfield_handlerfunc *func, const upb_handlerattr *attr)
upb_json_parser::method
const upb_json_parsermethod * method
Definition: php/ext/google/protobuf/upb.c:9011
upb_msglayout_init
static bool upb_msglayout_init(const upb_msgdef *m, upb_msglayout *l, upb_msgfactory *factory)
Definition: php/ext/google/protobuf/upb.c:4411
google_protobuf_MethodDescriptorProto_submsgs
static const upb_msglayout *const google_protobuf_MethodDescriptorProto_submsgs[1]
Definition: php/ext/google/protobuf/upb.c:252
start_listvalue_object
static void start_listvalue_object(upb_json_parser *p)
Definition: php/ext/google/protobuf/upb.c:11256
upb_pb_encoder::output_
upb_bytessink output_
Definition: php/ext/google/protobuf/upb.c:7897
STRINGIFY_MACROVAL
#define STRINGIFY_MACROVAL(x)
Definition: php/ext/google/protobuf/upb.c:8536
parse_number_from_buffer
static bool parse_number_from_buffer(upb_json_parser *p, const char *buf, bool is_quoted)
Definition: php/ext/google/protobuf/upb.c:9717
google_protobuf_ServiceOptions_submsgs
static const upb_msglayout *const google_protobuf_ServiceOptions_submsgs[1]
Definition: php/ext/google/protobuf/upb.c:386
upb_jsonparser_any_frame::parser
upb_json_parser * parser
Definition: php/ext/google/protobuf/upb.c:8940
upb_fielddef::packed_
bool packed_
Definition: php/ext/google/protobuf/upb.c:1141
label
GLuint GLsizei const GLchar * label
Definition: glcorearb.h:4316
upb_encode
char * upb_encode(const void *msg, const upb_msglayout *m, upb_arena *arena, size_t *size)
Definition: php/ext/google/protobuf/upb.c:3234
google_protobuf_FieldDescriptorProto_has_default_value
UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_default_value(const google_protobuf_FieldDescriptorProto *msg)
Definition: php/ext/google/protobuf/upb.h:1502
upb_fielddef_checkdescriptortype
bool upb_fielddef_checkdescriptortype(int32_t type)
Definition: php/ext/google/protobuf/upb.c:1727
upb_array_size
size_t upb_array_size(const upb_array *arr)
Definition: php/ext/google/protobuf/upb.c:4113
google_protobuf_FileDescriptorProto__fields
static const upb_msglayout_field google_protobuf_FileDescriptorProto__fields[12]
Definition: php/ext/google/protobuf/upb.c:59
upb_handlers::msg
const upb_msgdef * msg
Definition: php/ext/google/protobuf/upb.c:3271
newgroup
mgroup * newgroup()
Definition: php/ext/google/protobuf/upb.c:5869
start_duration_base
static void start_duration_base(upb_json_parser *p, const char *ptr)
Definition: php/ext/google/protobuf/upb.c:10215
upb_symtab_lookupmsg2
const upb_msgdef * upb_symtab_lookupmsg2(const upb_symtab *s, const char *sym, size_t len)
Definition: php/ext/google/protobuf/upb.c:2771
upb_json_printer_create
upb_json_printer * upb_json_printer_create(upb_arena *a, const upb_handlers *h, upb_bytessink output)
Definition: php/ext/google/protobuf/upb.c:13596
symtab_addctx::status
upb_status * status
Definition: php/ext/google/protobuf/upb.c:1947
upb_fielddef_selectorbase
uint32_t upb_fielddef_selectorbase(const upb_fielddef *f)
Definition: php/ext/google/protobuf/upb.c:1572
upb_msgval_sizeof2
static size_t upb_msgval_sizeof2(upb_fieldtype_t type)
Definition: php/ext/google/protobuf/upb.c:4365
upb_pb_encoder::runbegin
char * runbegin
Definition: php/ext/google/protobuf/upb.c:7910
google::protobuf.internal.wire_format.UINT32_MAX
tuple UINT32_MAX
Definition: wire_format.py:59
upb_endfield_handlerfunc
bool upb_endfield_handlerfunc(void *c, const void *hd)
Definition: php/ext/google/protobuf/upb.h:4133
google::protobuf::uint32
uint32_t uint32
Definition: protobuf/src/google/protobuf/stubs/port.h:155
UPB_DESCRIPTOR_TYPE_FLOAT
@ UPB_DESCRIPTOR_TYPE_FLOAT
Definition: php/ext/google/protobuf/upb.h:438
upb_jsonparser_frame::is_mapentry
bool is_mapentry
Definition: php/ext/google/protobuf/upb.c:8975
upb_fielddef::sub
union upb_fielddef::@87 sub
upb_json_codecache_get
const upb_json_parsermethod * upb_json_codecache_get(upb_json_codecache *c, const upb_msgdef *md)
Definition: php/ext/google/protobuf/upb.c:12192
json_parser_any_frame_has_value_after_type_url
static bool json_parser_any_frame_has_value_after_type_url(upb_jsonparser_any_frame *frame)
Definition: php/ext/google/protobuf/upb.c:9132
upb_map::val_type
upb_fieldtype_t val_type
Definition: php/ext/google/protobuf/upb.c:4161
UPB_CTYPE_CSTR
@ UPB_CTYPE_CSTR
Definition: php/ext/google/protobuf/upb.h:2648
find_methods
static void find_methods(compiler *c, const upb_handlers *h)
Definition: php/ext/google/protobuf/upb.c:6561
findentry_mutable
static upb_tabent * findentry_mutable(upb_table *t, lookupkey_t key, uint32_t hash, eqlfunc_t *eql)
Definition: php/ext/google/protobuf/upb.c:4785
count_types_in_msg
static void count_types_in_msg(const google_protobuf_DescriptorProto *msg_proto, decl_counts *counts)
Definition: php/ext/google/protobuf/upb.c:2437
textprinter_startsubmsg
static void * textprinter_startsubmsg(void *closure, const void *handler_data)
Definition: php/ext/google/protobuf/upb.c:8594
upb_inttable_init
UPB_INLINE bool upb_inttable_init(upb_inttable *table, upb_ctype_t ctype)
Definition: php/ext/google/protobuf/upb.h:2876
encode_unknown
static bool encode_unknown(void *c, const void *hd, const char *buf, size_t len)
Definition: php/ext/google/protobuf/upb.c:8175
upb_msg_getscalarhandlerdata
bool upb_msg_getscalarhandlerdata(const upb_handlers *h, upb_selector_t s, upb_fieldtype_t *type, size_t *offset, int32_t *hasbit)
Definition: php/ext/google/protobuf/upb.c:3810
upb_msg_checkfield
static const upb_msglayout_field * upb_msg_checkfield(int field_index, const upb_msglayout *l)
Definition: php/ext/google/protobuf/upb.c:4005
upb_pbcodecache::lazy
bool lazy
Definition: php/ext/google/protobuf/upb.h:6508
is_power_of_two
static bool is_power_of_two(size_t val)
Definition: php/ext/google/protobuf/upb.c:4351
upb_byteshandler_setendstr
bool upb_byteshandler_setendstr(upb_byteshandler *h, upb_endfield_handlerfunc *func, void *d)
Definition: php/ext/google/protobuf/upb.c:3741
google_protobuf_FieldDescriptorProto_extendee
UPB_INLINE upb_strview google_protobuf_FieldDescriptorProto_extendee(const google_protobuf_FieldDescriptorProto *msg)
Definition: php/ext/google/protobuf/upb.h:1493
upb_tabent
struct _upb_tabent upb_tabent
freemethod
static void freemethod(upb_pbdecodermethod *method)
Definition: php/ext/google/protobuf/upb.c:5822
OP_ENDSEQ
@ OP_ENDSEQ
Definition: php/ext/google/protobuf/upb.h:6464
upb_arena::block_alloc
upb_alloc * block_alloc
Definition: php/ext/google/protobuf/upb.c:5630
maybeput
static void maybeput(compiler *c, opcode op, const upb_handlers *h, const upb_fielddef *f, upb_handlertype_t type)
Definition: php/ext/google/protobuf/upb.c:6316
UPB_FORCEINLINE
#define UPB_FORCEINLINE
Definition: php/ext/google/protobuf/upb.h:105
upb_msgfactory
Definition: php/ext/google/protobuf/upb.c:4543
UPB_ASSERT
#define UPB_ASSERT(expr)
Definition: php/ext/google/protobuf/upb.h:146
end_fieldmask_path
static bool end_fieldmask_path(upb_json_parser *p)
Definition: php/ext/google/protobuf/upb.c:10603
json_en_fieldmask_machine
static const int json_en_fieldmask_machine
Definition: php/ext/google/protobuf/upb.c:11618
repeated_startstr
static void * repeated_startstr(void *closure, const void *handler_data, size_t size_hint)
Definition: php/ext/google/protobuf/upb.c:12763
upb_strtable_init2
bool upb_strtable_init2(upb_strtable *t, upb_ctype_t ctype, upb_alloc *a)
Definition: php/ext/google/protobuf/upb.c:4928
upb_stringsink::size
size_t size
Definition: php/ext/google/protobuf/upb.c:8883
str_t::str
char str[1]
Definition: php/ext/google/protobuf/upb.c:1106
google_protobuf_DescriptorProto_options
const UPB_INLINE google_protobuf_MessageOptions * google_protobuf_DescriptorProto_options(const google_protobuf_DescriptorProto *msg)
Definition: php/ext/google/protobuf/upb.h:1247
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: php/ext/google/protobuf/upb.h:1091
google_protobuf_FieldDescriptorProto_options
const UPB_INLINE google_protobuf_FieldOptions * google_protobuf_FieldDescriptorProto_options(const google_protobuf_FieldDescriptorProto *msg)
Definition: php/ext/google/protobuf/upb.h:1505
upb_int64_handlerfunc
bool upb_int64_handlerfunc(void *c, const void *hd, int64_t val)
Definition: php/ext/google/protobuf/upb.h:4135
UPB_UNKNOWN_SELECTOR
#define UPB_UNKNOWN_SELECTOR
Definition: php/ext/google/protobuf/upb.h:4067
UPB_STATIC_SELECTOR_COUNT
#define UPB_STATIC_SELECTOR_COUNT
Definition: php/ext/google/protobuf/upb.h:4068
end_timestamp_zone
static bool end_timestamp_zone(upb_json_parser *p, const char *ptr)
Definition: php/ext/google/protobuf/upb.c:10505
eqlfunc_t
bool eqlfunc_t(upb_tabkey k1, lookupkey_t k2)
Definition: php/ext/google/protobuf/upb.c:4719
upb_arena_doalloc
static void * upb_arena_doalloc(upb_alloc *alloc, void *ptr, size_t oldsize, size_t size)
Definition: php/ext/google/protobuf/upb.c:5685
upb_json_printer::first_elem_
bool first_elem_[UPB_MAX_HANDLER_DEPTH *2]
Definition: php/ext/google/protobuf/upb.c:12256
upb_mapiter_next
void upb_mapiter_next(upb_mapiter *i)
Definition: php/ext/google/protobuf/upb.c:4325
upb_mapiter
struct upb_mapiter upb_mapiter
Definition: php/ext/google/protobuf/upb.h:506
upb_msg_addunknown
void upb_msg_addunknown(upb_msg *msg, const char *data, size_t len)
Definition: php/ext/google/protobuf/upb.c:3986
upb_decode_varintfield
static bool upb_decode_varintfield(upb_decstate *d, upb_decframe *frame, const char *field_start, const upb_msglayout_field *field)
Definition: php/ext/google/protobuf/upb.c:785
upb_sethasbit
static void upb_sethasbit(upb_decframe *frame, const upb_msglayout_field *field)
Definition: php/ext/google/protobuf/upb.c:724
init
static bool init(upb_table *t, upb_ctype_t ctype, uint8_t size_lg2, upb_alloc *a)
Definition: php/ext/google/protobuf/upb.c:4736
in_residual_buf
static bool in_residual_buf(const upb_pbdecoder *d, const char *p)
Definition: php/ext/google/protobuf/upb.c:6871
google_protobuf_FileDescriptorProto_extension
const UPB_INLINE google_protobuf_FieldDescriptorProto *const * google_protobuf_FileDescriptorProto_extension(const google_protobuf_FileDescriptorProto *msg, size_t *len)
Definition: php/ext/google/protobuf/upb.h:1093
multipart_start
static void multipart_start(upb_json_parser *p, upb_selector_t sel)
Definition: php/ext/google/protobuf/upb.c:9477
json_en_number_machine
static const int json_en_number_machine
Definition: php/ext/google/protobuf/upb.c:11614
startmap
static void * startmap(void *closure, const void *handler_data)
Definition: php/ext/google/protobuf/upb.c:12649
parsermethod_new
static upb_json_parsermethod * parsermethod_new(upb_json_codecache *c, const upb_msgdef *md)
Definition: php/ext/google/protobuf/upb.c:12078
google_protobuf_DescriptorProto_extension
const UPB_INLINE google_protobuf_FieldDescriptorProto *const * google_protobuf_DescriptorProto_extension(const google_protobuf_DescriptorProto *msg, size_t *len)
Definition: php/ext/google/protobuf/upb.h:1245
upb_vencode64
UPB_INLINE size_t upb_vencode64(uint64_t val, char *buf)
Definition: php/ext/google/protobuf/upb.h:6854
repack
static uint64_t repack(uint64_t dispatch, int new_wt2)
Definition: php/ext/google/protobuf/upb.c:6253
upb_pb_encoder::ptr
char * ptr
Definition: php/ext/google/protobuf/upb.c:7906
printer_sethandlers_duration
void printer_sethandlers_duration(const void *closure, upb_handlers *h)
Definition: php/ext/google/protobuf/upb.c:13315
upb_msgdef_selectorcount
size_t upb_msgdef_selectorcount(const upb_msgdef *m)
Definition: php/ext/google/protobuf/upb.c:1749
upb_sink_putstring
UPB_INLINE size_t upb_sink_putstring(upb_sink s, upb_selector_t sel, const char *buf, size_t n, const upb_bufhandle *handle)
Definition: php/ext/google/protobuf/upb.h:5704
UPB_MAX
#define UPB_MAX(x, y)
Definition: php/ext/google/protobuf/upb.h:138
upb_set32
static void upb_set32(void *msg, size_t ofs, uint32_t val)
Definition: php/ext/google/protobuf/upb.c:628
symtab_resolve
const void * symtab_resolve(const symtab_addctx *ctx, const upb_fielddef *f, const char *base, upb_strview sym, upb_deftype_t type)
Definition: php/ext/google/protobuf/upb.c:2026
upb_decframe::m
const upb_msglayout * m
Definition: php/ext/google/protobuf/upb.c:544
if
PHP_PROTO_OBJECT_FREE_END PHP_PROTO_OBJECT_DTOR_END if(!upb_strtable_init(&intern->table, UPB_CTYPE_UINT64))
Definition: php/ext/google/protobuf/map.c:232
encode_startstr
static void * encode_startstr(void *c, const void *hd, size_t size_hint)
Definition: php/ext/google/protobuf/upb.c:8194
upb_status_seterrmsg
void upb_status_seterrmsg(upb_status *status, const char *msg)
Definition: php/ext/google/protobuf/upb.c:5577
errno
int errno
_json_trans_keys
static const char _json_trans_keys[]
Definition: php/ext/google/protobuf/upb.c:11408
SUBH_F
#define SUBH_F(h, f)
Definition: php/ext/google/protobuf/upb.c:3294
upb_json_parser::string_selector
upb_selector_t string_selector
Definition: php/ext/google/protobuf/upb.c:9037
upb_inttable::t
upb_table t
Definition: php/ext/google/protobuf/upb.h:2824
putnull
static bool putnull(void *closure, const void *handler_data, int32_t null)
Definition: php/ext/google/protobuf/upb.c:13056
google_protobuf_FileOptions_has_php_namespace
UPB_INLINE bool google_protobuf_FileOptions_has_php_namespace(const google_protobuf_FileOptions *msg)
Definition: php/ext/google/protobuf/upb.h:1910
upb_msgdef::fields
const upb_fielddef * fields
Definition: php/ext/google/protobuf/upb.c:1156
encoder
static char encoder[85+1]
Definition: zmq_utils.cpp:72
upb_handlercache_addcleanup
bool upb_handlercache_addcleanup(upb_handlercache *c, void *p, upb_handlerfree *func)
Definition: php/ext/google/protobuf/upb.c:3720
upb_fielddef_enumsubdef
const upb_enumdef * upb_fielddef_enumsubdef(const upb_fielddef *f)
Definition: php/ext/google/protobuf/upb.c:1682
upb_map::arena
upb_arena * arena
Definition: php/ext/google/protobuf/upb.c:4165
eof_ch
static const char eof_ch
Definition: php/ext/google/protobuf/upb.c:8876
printer_sethandlers_timestamp
void printer_sethandlers_timestamp(const void *closure, upb_handlers *h)
Definition: php/ext/google/protobuf/upb.c:13335
getop
UPB_INLINE opcode getop(uint32_t instr)
Definition: php/ext/google/protobuf/upb.h:6502
OP_DISPATCH
@ OP_DISPATCH
Definition: php/ext/google/protobuf/upb.h:6495
int_tabent
static const upb_tabent * int_tabent(const upb_inttable_iter *i)
Definition: php/ext/google/protobuf/upb.c:5299
upb_oneofdef_numfields
int upb_oneofdef_numfields(const upb_oneofdef *o)
Definition: php/ext/google/protobuf/upb.c:1890
upb_inttable::array
const upb_tabval * array
Definition: php/ext/google/protobuf/upb.h:2825
decl_counts::ext_count
int ext_count
Definition: php/ext/google/protobuf/upb.c:2434
google_protobuf_FieldOptions_msginit
const upb_msglayout google_protobuf_FieldOptions_msginit
Definition: php/ext/google/protobuf/upb.c:335
google_protobuf_MessageOptions_msginit
const upb_msglayout google_protobuf_MessageOptions_msginit
Definition: php/ext/google/protobuf/upb.c:315
upb_inttable_iter_value
upb_value upb_inttable_iter_value(const upb_inttable_iter *i)
Definition: php/ext/google/protobuf/upb.c:5347
upb_inttable_pop
upb_value upb_inttable_pop(upb_inttable *t)
Definition: php/ext/google/protobuf/upb.c:5216
upb_fielddef_isprimitive
bool upb_fielddef_isprimitive(const upb_fielddef *f)
Definition: php/ext/google/protobuf/upb.c:1700
upb_pb_encoder::stack
int * stack
Definition: php/ext/google/protobuf/upb.c:7917
upb_mapiter_setdone
void upb_mapiter_setdone(upb_mapiter *i)
Definition: php/ext/google/protobuf/upb.c:4342
upb_jsonparser_frame::any_frame
upb_jsonparser_any_frame * any_frame
Definition: php/ext/google/protobuf/upb.c:8990
pack_def
static upb_value pack_def(const void *ptr, upb_deftype_t type)
Definition: php/ext/google/protobuf/upb.c:1221
google_protobuf_GeneratedCodeInfo_Annotation_msginit
const upb_msglayout google_protobuf_GeneratedCodeInfo_Annotation_msginit
Definition: php/ext/google/protobuf/upb.c:497
upb_handlers_setbool
bool upb_handlers_setbool(upb_handlers *h, const upb_fielddef *f, upb_bool_handlerfunc *func, const upb_handlerattr *attr)
strpc::ptr
char * ptr
Definition: php/ext/google/protobuf/upb.c:12267
upb_desctype_to_fieldtype2
static const uint8_t upb_desctype_to_fieldtype2[]
Definition: php/ext/google/protobuf/upb.c:2873
UPB_CTYPE_INT32
@ UPB_CTYPE_INT32
Definition: php/ext/google/protobuf/upb.h:2643
upb_inttable_lookup32
UPB_INLINE bool upb_inttable_lookup32(const upb_inttable *t, uint32_t key, upb_value *v)
Definition: php/ext/google/protobuf/upb.h:2999
upb_enumdef::full_name
const char * full_name
Definition: php/ext/google/protobuf/upb.c:1170
google_protobuf_SourceCodeInfo_msginit
const upb_msglayout google_protobuf_SourceCodeInfo_msginit
Definition: php/ext/google/protobuf/upb.c:456
upb_strview::data
const char * data
Definition: php/ext/google/protobuf/upb.h:536
upb_json_parser::top
upb_jsonparser_frame * top
Definition: php/ext/google/protobuf/upb.c:9016
fmt_bool
static size_t fmt_bool(bool val, char *buf, size_t length)
Definition: php/ext/google/protobuf/upb.c:12428
google_protobuf_GeneratedCodeInfo_Annotation__fields
static const upb_msglayout_field google_protobuf_GeneratedCodeInfo_Annotation__fields[4]
Definition: php/ext/google/protobuf/upb.c:490
json_nice_escape
const UPB_INLINE char * json_nice_escape(char c)
Definition: php/ext/google/protobuf/upb.c:12338
UPB_LABEL_OPTIONAL
@ UPB_LABEL_OPTIONAL
Definition: php/ext/google/protobuf/upb.h:430
UPB_TYPE_FLOAT
@ UPB_TYPE_FLOAT
Definition: php/ext/google/protobuf/upb.h:414
upb_map_size
size_t upb_map_size(const upb_map *map)
Definition: php/ext/google/protobuf/upb.c:4238
print_comma
static void print_comma(upb_json_printer *p)
Definition: php/ext/google/protobuf/upb.c:12320
upb_symtab_new
upb_symtab * upb_symtab_new()
Definition: php/ext/google/protobuf/upb.c:2745
upb_decode_32bitfield
static bool upb_decode_32bitfield(upb_decstate *d, upb_decframe *frame, const char *field_start, const upb_msglayout_field *field)
Definition: php/ext/google/protobuf/upb.c:854
mapkeyval_startstr
static void * mapkeyval_startstr(void *closure, const void *handler_data, size_t size_hint)
Definition: php/ext/google/protobuf/upb.c:12787
fmt_int64_as_string
static size_t fmt_int64_as_string(long long val, char *buf, size_t length)
Definition: php/ext/google/protobuf/upb.c:12447
mapkey_bytes
static size_t mapkey_bytes(void *closure, const void *handler_data, const char *str, size_t len, const upb_bufhandle *handle)
Definition: php/ext/google/protobuf/upb.c:12834
printer_sethandlers
void printer_sethandlers(const void *closure, upb_handlers *h)
Definition: php/ext/google/protobuf/upb.c:13449
map
zval * map
Definition: php/ext/google/protobuf/encode_decode.c:473
found
return found
Definition: socket_poller.cpp:456
printer_endmsg
static bool printer_endmsg(void *closure, const void *handler_data, upb_status *s)
Definition: php/ext/google/protobuf/upb.c:12621
UPB_ASSERT_DEBUGVAR
#define UPB_ASSERT_DEBUGVAR(expr)
Definition: php/ext/google/protobuf/upb.h:153
start_minute
static void start_minute(upb_json_parser *p, const char *ptr)
Definition: php/ext/google/protobuf/upb.c:10374
upb_handlers_getprimitivehandlertype
upb_handlertype_t upb_handlers_getprimitivehandlertype(const upb_fielddef *f)
Definition: php/ext/google/protobuf/upb.c:3549
upb_fielddef::defaultval
union upb_fielddef::@86 defaultval
dispatch
static int32_t dispatch(upb_pbdecoder *d)
Definition: php/ext/google/protobuf/upb.c:7343
x
GLint GLenum GLint x
Definition: glcorearb.h:2834
upb_jsonparser_frame::is_any
bool is_any
Definition: php/ext/google/protobuf/upb.c:8987
dummy
ReturnVal dummy
Definition: register_benchmark_test.cc:68
accumulate_getptr
static const char * accumulate_getptr(upb_json_parser *p, size_t *len)
Definition: php/ext/google/protobuf/upb.c:9432
UPB_CTYPE_UINT64
@ UPB_CTYPE_UINT64
Definition: php/ext/google/protobuf/upb.h:2646
upb_json_codecache::methods
upb_inttable methods
Definition: php/ext/google/protobuf/upb.c:9065
encode_startgroup
static void * encode_startgroup(void *c, const void *hd)
Definition: php/ext/google/protobuf/upb.c:8186
google_protobuf_ServiceDescriptorProto_msginit
const upb_msglayout google_protobuf_ServiceDescriptorProto_msginit
Definition: php/ext/google/protobuf/upb.c:246
dispatchtarget
static void dispatchtarget(compiler *c, upb_pbdecodermethod *method, const upb_fielddef *f, int wire_type)
Definition: php/ext/google/protobuf/upb.c:6264
upb_inttable_iter_key
uintptr_t upb_inttable_iter_key(const upb_inttable_iter *i)
Definition: php/ext/google/protobuf/upb.c:5342
printer_sethandlers_fieldmask
void printer_sethandlers_fieldmask(const void *closure, upb_handlers *h)
Definition: php/ext/google/protobuf/upb.c:13296
upb_msglayout::extendable
bool extendable
Definition: php/ext/google/protobuf/upb.h:530
upb_json_printer_newcache
upb_handlercache * upb_json_printer_newcache(bool preserve_proto_fieldnames)
Definition: php/ext/google/protobuf/upb.c:13621
suspend_capture
static char suspend_capture
Definition: php/ext/google/protobuf/upb.c:9161
OP_ENDMSG
@ OP_ENDMSG
Definition: php/ext/google/protobuf/upb.h:6462
UPB_ANY_VALUE
#define UPB_ANY_VALUE
Definition: php/ext/google/protobuf/upb.h:3482
compiler::pc
uint32_t * pc
Definition: php/ext/google/protobuf/upb.c:5884
UPB_WIRE_TYPE_VARINT
@ UPB_WIRE_TYPE_VARINT
Definition: php/ext/google/protobuf/upb.h:399
upb_arena_malloc
UPB_INLINE void * upb_arena_malloc(upb_arena *a, size_t size)
Definition: php/ext/google/protobuf/upb.h:321
upb_sink::handlers
const upb_handlers * handlers
Definition: php/ext/google/protobuf/upb.h:5674
DECODE_ENDGROUP
#define DECODE_ENDGROUP
Definition: php/ext/google/protobuf/upb.h:6731
base64_push
static bool base64_push(upb_json_parser *p, upb_selector_t sel, const char *ptr, size_t len)
Definition: php/ext/google/protobuf/upb.c:9265
getentry_mutable
static upb_tabent * getentry_mutable(upb_table *t, uint32_t hash)
Definition: php/ext/google/protobuf/upb.c:4768
upb_filedef_depcount
int upb_filedef_depcount(const upb_filedef *f)
Definition: php/ext/google/protobuf/upb.c:2720
upb_msg_arena
upb_arena * upb_msg_arena(const upb_msg *msg)
Definition: php/ext/google/protobuf/upb.c:4055
inteql
static bool inteql(upb_tabkey k1, lookupkey_t k2)
Definition: php/ext/google/protobuf/upb.c:5061
upb_encode_reserve
static bool upb_encode_reserve(upb_encstate *e, size_t bytes)
Definition: php/ext/google/protobuf/upb.c:2941
error
Definition: cJSON.c:88
labelref
static int32_t labelref(compiler *c, int label)
Definition: php/ext/google/protobuf/upb.c:5985
_upb_value_val
UPB_INLINE upb_value _upb_value_val(uint64_t val, upb_ctype_t ctype)
Definition: php/ext/google/protobuf/upb.h:2687
upb_arena::next_block_size
size_t next_block_size
Definition: php/ext/google/protobuf/upb.c:5633
google_protobuf_FileDescriptorProto_has_package
UPB_INLINE bool google_protobuf_FileDescriptorProto_has_package(const google_protobuf_FileDescriptorProto *msg)
Definition: php/ext/google/protobuf/upb.h:1087
google_protobuf_SourceCodeInfo__fields
static const upb_msglayout_field google_protobuf_SourceCodeInfo__fields[1]
Definition: php/ext/google/protobuf/upb.c:452
multipart_text
static bool multipart_text(upb_json_parser *p, const char *buf, size_t len, bool can_alias)
Definition: php/ext/google/protobuf/upb.c:9484
strviewdup
static char * strviewdup(const symtab_addctx *ctx, upb_strview view)
Definition: php/ext/google/protobuf/upb.c:1950
OP_SETBIGGROUPNUM
@ OP_SETBIGGROUPNUM
Definition: php/ext/google/protobuf/upb.h:6475
upb_isbetween
static bool upb_isbetween(char c, char low, char high)
Definition: php/ext/google/protobuf/upb.c:1227
bytes
uint8 bytes[10]
Definition: coded_stream_unittest.cc:153
upb_varint_size
UPB_INLINE size_t upb_varint_size(uint64_t val)
Definition: php/ext/google/protobuf/upb.h:6867
upb_fieldtype_mapkeyok
bool upb_fieldtype_mapkeyok(upb_fieldtype_t type)
Definition: php/ext/google/protobuf/upb.c:3845
google::protobuf.internal.wire_format.INT64_MAX
tuple INT64_MAX
Definition: wire_format.py:61
upb_pbdecoder_seterr
void upb_pbdecoder_seterr(upb_pbdecoder *d, const char *msg)
Definition: php/ext/google/protobuf/upb.c:6829
upb_bool_handlerfunc
bool upb_bool_handlerfunc(void *c, const void *hd, bool val)
Definition: php/ext/google/protobuf/upb.h:4140
start_subobject_full
static bool start_subobject_full(upb_json_parser *p)
Definition: php/ext/google/protobuf/upb.c:10885
google_protobuf_FieldDescriptorProto__fields
static const upb_msglayout_field google_protobuf_FieldDescriptorProto__fields[10]
Definition: php/ext/google/protobuf/upb.c:154
fmt_float
static size_t fmt_float(float val, char *buf, size_t length)
Definition: php/ext/google/protobuf/upb.c:12422
upb_msg_oneof_iter_isequal
bool upb_msg_oneof_iter_isequal(const upb_msg_oneof_iter *iter1, const upb_msg_oneof_iter *iter2)
Definition: php/ext/google/protobuf/upb.c:1875
offset
uint64_t offset(const upb_pbdecoder *d)
Definition: php/ext/google/protobuf/upb.c:6852
OP_CALL
@ OP_CALL
Definition: php/ext/google/protobuf/upb.h:6479
mgroup_new
const mgroup * mgroup_new(const upb_handlers *dest, bool allowjit, bool lazy)
Definition: php/ext/google/protobuf/upb.c:6622
upb_stringsink
Definition: php/ext/google/protobuf/upb.c:8879
upb_msg_new
upb_msg * upb_msg_new(const upb_msglayout *l, upb_arena *a)
Definition: php/ext/google/protobuf/upb.c:4026
endseq
static bool endseq(void *closure, const void *handler_data)
Definition: php/ext/google/protobuf/upb.c:12641
put32
static void put32(compiler *c, uint32_t v)
Definition: php/ext/google/protobuf/upb.c:6003
MULTIPART_INACTIVE
@ MULTIPART_INACTIVE
Definition: php/ext/google/protobuf/upb.c:9456
callstacksize
static size_t callstacksize(upb_pbdecoder *d, size_t entries)
Definition: php/ext/google/protobuf/upb.c:6799
strkey2
static lookupkey_t strkey2(const char *str, size_t len)
Definition: php/ext/google/protobuf/upb.c:4705
google_protobuf_MethodDescriptorProto_msginit
const upb_msglayout google_protobuf_MethodDescriptorProto_msginit
Definition: php/ext/google/protobuf/upb.c:265
upb_fielddef_defaultdouble
double upb_fielddef_defaultdouble(const upb_fielddef *f)
Definition: php/ext/google/protobuf/upb.c:1658
MULTIPART_PUSHEAGERLY
@ MULTIPART_PUSHEAGERLY
Definition: php/ext/google/protobuf/upb.c:9464
upb_handlers_msgdef
const upb_msgdef * upb_handlers_msgdef(const upb_handlers *h)
Definition: php/ext/google/protobuf/upb.c:3543
inttable_val
static upb_tabval * inttable_val(upb_inttable *t, uintptr_t key)
Definition: php/ext/google/protobuf/upb.c:5069
start_second
static void start_second(upb_json_parser *p, const char *ptr)
Definition: php/ext/google/protobuf/upb.c:10386
upb_zzdecode_32
static int32_t upb_zzdecode_32(uint32_t n)
Definition: php/ext/google/protobuf/upb.c:607
end_delim
static bool end_delim(upb_pb_encoder *e)
Definition: php/ext/google/protobuf/upb.c:8059
google_protobuf_FieldOptions__fields
static const upb_msglayout_field google_protobuf_FieldOptions__fields[7]
Definition: php/ext/google/protobuf/upb.c:325
cleanup_ent
struct cleanup_ent cleanup_ent
google_protobuf_UninterpretedOption_NamePart__fields
static const upb_msglayout_field google_protobuf_UninterpretedOption_NamePart__fields[2]
Definition: php/ext/google/protobuf/upb.c:437
upb_encstate::buf
char * buf
Definition: php/ext/google/protobuf/upb.c:2913
google_protobuf_FieldDescriptorProto_submsgs
static const upb_msglayout *const google_protobuf_FieldDescriptorProto_submsgs[1]
Definition: php/ext/google/protobuf/upb.c:150
align_up
static size_t align_up(size_t val, size_t align)
Definition: php/ext/google/protobuf/upb.c:4356
printer_endmsg_fieldmask
static bool printer_endmsg_fieldmask(void *closure, const void *handler_data, upb_status *s)
Definition: php/ext/google/protobuf/upb.c:13240
parse_timestamp_number
static int parse_timestamp_number(upb_json_parser *p)
Definition: php/ext/google/protobuf/upb.c:10308
doset
static bool doset(upb_handlers *h, int32_t sel, const upb_fielddef *f, upb_handlertype_t type, upb_func *func, const upb_handlerattr *attr)
Definition: php/ext/google/protobuf/upb.c:3321
encode_tag
static bool encode_tag(upb_pb_encoder *e, const tag_t *tag)
Definition: php/ext/google/protobuf/upb.c:8110
upb_encstate
Definition: php/ext/google/protobuf/upb.c:2911
upb_map_del
bool upb_map_del(upb_map *map, upb_msgval key)
Definition: php/ext/google/protobuf/upb.c:4284
epoch
int64_t epoch(int year, int yday, int hour, int min, int sec)
Definition: php/ext/google/protobuf/upb.c:10477
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: php/ext/google/protobuf/upb.h:1090
upb_mapiter_key
upb_msgval upb_mapiter_key(const upb_mapiter *i)
Definition: php/ext/google/protobuf/upb.c:4333
upb_fielddef_isstring
bool upb_fielddef_isstring(const upb_fielddef *f)
Definition: php/ext/google/protobuf/upb.c:1691
upb_append_unknown
static bool upb_append_unknown(upb_decstate *d, upb_decframe *frame, const char *start)
Definition: php/ext/google/protobuf/upb.c:632
UPB_WELLKNOWN_ANY
@ UPB_WELLKNOWN_ANY
Definition: php/ext/google/protobuf/upb.h:3150
upb_textprinter_newcache
upb_handlercache * upb_textprinter_newcache()
Definition: php/ext/google/protobuf/upb.c:8696
repeated_startsubmsg
static void * repeated_startsubmsg(void *closure, const void *handler_data)
Definition: php/ext/google/protobuf/upb.c:12593
upb_handlers_setendsubmsg
bool upb_handlers_setendsubmsg(upb_handlers *h, const upb_fielddef *f, upb_endfield_handlerfunc *func, const upb_handlerattr *attr)
upb_handlercache_new
upb_handlercache * upb_handlercache_new(upb_handlers_callback *callback, const void *closure)
Definition: php/ext/google/protobuf/upb.c:3694
ok
ROSCPP_DECL bool ok()
b
GLboolean GLboolean GLboolean b
Definition: glcorearb.h:3228
upb_json_parser::multipart_state
int multipart_state
Definition: php/ext/google/protobuf/upb.c:9036
start_member
static void start_member(upb_json_parser *p)
Definition: php/ext/google/protobuf/upb.c:10620
UPB_ENDSTR_SELECTOR
#define UPB_ENDSTR_SELECTOR
Definition: php/ext/google/protobuf/upb.h:4073
upb_calloc
static void * upb_calloc(upb_arena *arena, size_t size)
Definition: php/ext/google/protobuf/upb.c:3277
scalar_startsubmsg
static void * scalar_startsubmsg(void *closure, const void *handler_data)
Definition: php/ext/google/protobuf/upb.c:12589
upb_msg_handlerdata::offset
size_t offset
Definition: php/ext/google/protobuf/upb.c:3751
upb_table::count
size_t count
Definition: php/ext/google/protobuf/upb.h:2794
handlers_getsel
static upb_selector_t handlers_getsel(upb_handlers *h, const upb_fielddef *f, upb_handlertype_t type)
Definition: php/ext/google/protobuf/upb.c:3309
chkdefaulttype
static void chkdefaulttype(const upb_fielddef *f, int ctype)
Definition: php/ext/google/protobuf/upb.c:1623
google_protobuf_GeneratedCodeInfo_msginit
const upb_msglayout google_protobuf_GeneratedCodeInfo_msginit
Definition: php/ext/google/protobuf/upb.c:484
upb_handlers_setstartstr
bool upb_handlers_setstartstr(upb_handlers *h, const upb_fielddef *f, upb_startstr_handlerfunc *func, const upb_handlerattr *attr)
start_year
static void start_year(upb_json_parser *p, const char *ptr)
Definition: php/ext/google/protobuf/upb.c:10326
upb_sink_startstr
UPB_INLINE bool upb_sink_startstr(upb_sink s, upb_selector_t sel, size_t size_hint, upb_sink *sub)
Definition: php/ext/google/protobuf/upb.h:5779
upb_mapiter_free
void upb_mapiter_free(upb_mapiter *i, upb_alloc *a)
Definition: php/ext/google/protobuf/upb.c:4321
upb_pbcodecache
Definition: php/ext/google/protobuf/upb.h:6504
cleanup_ent::ud
void * ud
Definition: php/ext/google/protobuf/upb.c:5654
upb_oneofdef
Definition: php/ext/google/protobuf/upb.c:1176
upb_pb_encoder::segptr
upb_pb_encoder_segment * segptr
Definition: php/ext/google/protobuf/upb.c:7913
start_frame
static void start_frame(upb_json_printer *p)
Definition: php/ext/google/protobuf/upb.c:12600
upb_fielddef_isseq
bool upb_fielddef_isseq(const upb_fielddef *f)
Definition: php/ext/google/protobuf/upb.c:1696
upb_msgdef::full_name
const char * full_name
Definition: php/ext/google/protobuf/upb.c:1148
google::protobuf.internal.wire_format.INT32_MIN
INT32_MIN
Definition: wire_format.py:58
upb_array::type
upb_fieldtype_t type
Definition: php/ext/google/protobuf/upb.h:469
values
GLenum GLsizei GLsizei GLint * values
Definition: glcorearb.h:3591
UPB_WELLKNOWN_BYTESVALUE
@ UPB_WELLKNOWN_BYTESVALUE
Definition: php/ext/google/protobuf/upb.h:3163
upb_oneofdef_ntof
const upb_fielddef * upb_oneofdef_ntof(const upb_oneofdef *o, const char *name, size_t length)
Definition: php/ext/google/protobuf/upb.c:1898
upb_tabkey
uintptr_t upb_tabkey
Definition: php/ext/google/protobuf/upb.h:2762
end_wrapper_object
static void end_wrapper_object(upb_json_parser *p)
Definition: php/ext/google/protobuf/upb.c:11207
upb_filedef::dep_count
int dep_count
Definition: php/ext/google/protobuf/upb.c:1196
escape_char
static char escape_char(char in)
Definition: php/ext/google/protobuf/upb.c:9574
end_stringval_nontop
static bool end_stringval_nontop(upb_json_parser *p)
Definition: php/ext/google/protobuf/upb.c:10097
encode_enddelimfield
static bool encode_enddelimfield(void *c, const void *hd)
Definition: php/ext/google/protobuf/upb.c:8181
symtab
upb_symtab * symtab
Definition: php/ext/google/protobuf/protobuf.h:765
is_json_escaped
UPB_INLINE bool is_json_escaped(char c)
Definition: php/ext/google/protobuf/upb.c:12332
upb_mapiter
Definition: php/ext/google/protobuf/upb.c:4296
upb_put_fixedarray
static bool upb_put_fixedarray(upb_encstate *e, const upb_array *arr, size_t size)
Definition: php/ext/google/protobuf/upb.c:3008
UPB_TYPE_UINT32
@ UPB_TYPE_UINT32
Definition: php/ext/google/protobuf/upb.h:416
google_protobuf_EnumValueDescriptorProto_submsgs
static const upb_msglayout *const google_protobuf_EnumValueDescriptorProto_submsgs[1]
Definition: php/ext/google/protobuf/upb.c:219
capture_resume
static void capture_resume(upb_json_parser *p, const char *ptr)
Definition: php/ext/google/protobuf/upb.c:9561
strhash
static uint32_t strhash(upb_tabkey key)
Definition: php/ext/google/protobuf/upb.c:4916
upb_bufhandle::buf
const char * buf
Definition: php/ext/google/protobuf/upb.h:4099
upb_json_printer::input_
upb_sink input_
Definition: php/ext/google/protobuf/upb.c:12239
upb_isident
static bool upb_isident(upb_strview name, bool full, upb_status *s)
Definition: php/ext/google/protobuf/upb.c:1239
upb_pbcodecache_allowjit
bool upb_pbcodecache_allowjit(const upb_pbcodecache *c)
Definition: php/ext/google/protobuf/upb.c:6696
upb_arrhas
UPB_INLINE bool upb_arrhas(upb_tabval key)
Definition: php/ext/google/protobuf/upb.h:2865
upb_decode_message
static bool upb_decode_message(upb_decstate *d, const char *limit, int group_number, char *msg, const upb_msglayout *l)
Definition: php/ext/google/protobuf/upb.c:1072
upb_vencode32
UPB_INLINE uint64_t upb_vencode32(uint32_t val)
Definition: php/ext/google/protobuf/upb.h:6873
begin
static size_t begin(const upb_table *t)
Definition: php/ext/google/protobuf/upb.c:4898
upb_skip_unknownfielddata
static bool upb_skip_unknownfielddata(upb_decstate *d, upb_decframe *frame, int field_number, int wire_type)
Definition: php/ext/google/protobuf/upb.c:638
google_protobuf_FileDescriptorProto
struct google_protobuf_FileDescriptorProto google_protobuf_FileDescriptorProto
Definition: php/ext/google/protobuf/upb.h:932
end_array
static void end_array(upb_json_parser *p)
Definition: php/ext/google/protobuf/upb.c:11004
upb_pbdecoder_unpackdispatch
UPB_INLINE void upb_pbdecoder_unpackdispatch(uint64_t dispatch, uint64_t *ofs, uint8_t *wt1, uint8_t *wt2)
Definition: php/ext/google/protobuf/upb.h:6715
google::protobuf::int32
int32_t int32
Definition: protobuf/src/google/protobuf/stubs/port.h:150
upb_msg_internal
Definition: php/ext/google/protobuf/upb.c:3953
json_en_value_machine
static const int json_en_value_machine
Definition: php/ext/google/protobuf/upb.c:11619
upb_msg_internal::unknown_len
size_t unknown_len
Definition: php/ext/google/protobuf/upb.c:3958
upb_fielddef_defaultfloat
float upb_fielddef_defaultfloat(const upb_fielddef *f)
Definition: php/ext/google/protobuf/upb.c:1653
start_subobject
static bool start_subobject(upb_json_parser *p)
Definition: php/ext/google/protobuf/upb.c:10827
newmethod
static upb_pbdecodermethod * newmethod(const upb_handlers *dest_handlers, mgroup *group)
Definition: php/ext/google/protobuf/upb.c:5827
generate_primitivefield
static void generate_primitivefield(compiler *c, const upb_fielddef *f, upb_pbdecodermethod *method)
Definition: php/ext/google/protobuf/upb.c:6440
OP_STARTSTR
@ OP_STARTSTR
Definition: php/ext/google/protobuf/upb.h:6467
SETTER
#define SETTER(name, handlerctype, handlertype)
Definition: php/ext/google/protobuf/upb.c:3459
end_any_membername
static bool end_any_membername(upb_json_parser *p)
Definition: php/ext/google/protobuf/upb.c:10777
intkey
static lookupkey_t intkey(uintptr_t key)
Definition: php/ext/google/protobuf/upb.c:4712
UPB_SYNTAX_PROTO3
@ UPB_SYNTAX_PROTO3
Definition: php/ext/google/protobuf/upb.h:3141
printer_sethandlers_listvalue
void printer_sethandlers_listvalue(const void *closure, upb_handlers *h)
Definition: php/ext/google/protobuf/upb.c:13415
UPB_ENDMSG_SELECTOR
#define UPB_ENDMSG_SELECTOR
Definition: php/ext/google/protobuf/upb.h:4066
UPB_WIRE_TYPE_START_GROUP
@ UPB_WIRE_TYPE_START_GROUP
Definition: php/ext/google/protobuf/upb.h:402
upb_strtable_next
void upb_strtable_next(upb_strtable_iter *i)
Definition: php/ext/google/protobuf/upb.c:5014
base64
upb_msg_internal_withext
Definition: php/ext/google/protobuf/upb.c:3963
upb_textprinter::subc
void * subc
Definition: php/ext/google/protobuf/upb.c:8390
stacksize
static size_t stacksize(upb_pbdecoder *d, size_t entries)
Definition: php/ext/google/protobuf/upb.c:6794
saturating_multiply
static size_t saturating_multiply(size_t a, size_t b)
Definition: php/ext/google/protobuf/upb.c:9207
decode_fixed32
static UPB_FORCEINLINE int32_t decode_fixed32(upb_pbdecoder *d, uint32_t *u32)
Definition: php/ext/google/protobuf/upb.c:7191
assert_accumulate_empty
static void assert_accumulate_empty(upb_json_parser *p)
Definition: php/ext/google/protobuf/upb.c:9367
upb_pbdecoder_getopname
const char * upb_pbdecoder_getopname(unsigned int op)
start_timestamp_fraction
static void start_timestamp_fraction(upb_json_parser *p, const char *ptr)
Definition: php/ext/google/protobuf/upb.c:10402
upb_symtab::files
upb_strtable files
Definition: php/ext/google/protobuf/upb.c:1205
str_t::len
size_t len
Definition: php/ext/google/protobuf/upb.c:1105
google_protobuf_FileDescriptorProto_has_name
UPB_INLINE bool google_protobuf_FileDescriptorProto_has_name(const google_protobuf_FileDescriptorProto *msg)
Definition: php/ext/google/protobuf/upb.h:1085
UPB_WELLKNOWN_BOOLVALUE
@ UPB_WELLKNOWN_BOOLVALUE
Definition: php/ext/google/protobuf/upb.h:3164
mutable_array
static upb_tabval * mutable_array(upb_inttable *t)
Definition: php/ext/google/protobuf/upb.c:5065
package
string package
google_protobuf_FileOptions_php_class_prefix
UPB_INLINE upb_strview google_protobuf_FileOptions_php_class_prefix(const google_protobuf_FileOptions *msg)
Definition: php/ext/google/protobuf/upb.h:1909
upb_msg_internal_withext::base
upb_msg_internal base
Definition: php/ext/google/protobuf/upb.c:3965
upb_pb_encoder_segment::seglen
uint32_t seglen
Definition: php/ext/google/protobuf/upb.c:7889
upb_handlers_setsubhandlers
bool upb_handlers_setsubhandlers(upb_handlers *h, const upb_fielddef *f, const upb_handlers *sub)
Definition: php/ext/google/protobuf/upb.c:3502
CHKLENGTH
#define CHKLENGTH(x)
Definition: php/ext/google/protobuf/upb.c:12397
between
static bool between(int32_t x, int32_t low, int32_t high)
Definition: php/ext/google/protobuf/upb.c:1719
upb_uint64_handlerfunc
bool upb_uint64_handlerfunc(void *c, const void *hd, uint64_t val)
Definition: php/ext/google/protobuf/upb.h:4137
CASE
#define CASE(ctype, type, wire_type, encodeval)
EnumHandlerData::keyname
void * keyname
Definition: php/ext/google/protobuf/upb.c:12531
upb_msg_internal::unknown
char * unknown
Definition: php/ext/google/protobuf/upb.c:3957
UPB_MAPENTRY_KEY
#define UPB_MAPENTRY_KEY
Definition: php/ext/google/protobuf/upb.h:3477
google_protobuf_MethodDescriptorProto__fields
static const upb_msglayout_field google_protobuf_MethodDescriptorProto__fields[6]
Definition: php/ext/google/protobuf/upb.c:256
upb_bufhandle
Definition: php/ext/google/protobuf/upb.h:4095
upb_sink_putunknown
UPB_INLINE bool upb_sink_putunknown(upb_sink s, const char *buf, size_t n)
Definition: php/ext/google/protobuf/upb.h:5717
upb_pbdecodermethod_inputhandler
const upb_byteshandler * upb_pbdecodermethod_inputhandler(const upb_pbdecodermethod *m)
Definition: php/ext/google/protobuf/upb.c:5844
_json_indicies
static const unsigned char _json_indicies[]
Definition: php/ext/google/protobuf/upb.c:11502
upb_fielddef_isextension
bool upb_fielddef_isextension(const upb_fielddef *f)
Definition: php/ext/google/protobuf/upb.c:1556
upb_handlers::table
upb_handlers_tabent table[1]
Definition: php/ext/google/protobuf/upb.c:3274
google_protobuf_FileDescriptorProto_has_syntax
UPB_INLINE bool google_protobuf_FileDescriptorProto_has_syntax(const google_protobuf_FileDescriptorProto *msg)
Definition: php/ext/google/protobuf/upb.h:1100
start_timestamp_base
static void start_timestamp_base(upb_json_parser *p)
Definition: php/ext/google/protobuf/upb.c:10398
accumulate_realloc
static bool accumulate_realloc(upb_json_parser *p, size_t need)
Definition: php/ext/google/protobuf/upb.c:9378
upb_filedef_package
const char * upb_filedef_package(const upb_filedef *f)
Definition: php/ext/google/protobuf/upb.c:2700
UPB_MAPENTRY_VALUE
#define UPB_MAPENTRY_VALUE
Definition: php/ext/google/protobuf/upb.h:3478
upb_sink_endseq
UPB_INLINE bool upb_sink_endseq(upb_sink s, upb_selector_t sel)
Definition: php/ext/google/protobuf/upb.h:5768
upb_enumdef_numvals
int upb_enumdef_numvals(const upb_enumdef *e)
Definition: php/ext/google/protobuf/upb.c:1462
upb_free
UPB_INLINE void upb_free(upb_alloc *alloc, void *ptr)
Definition: php/ext/google/protobuf/upb.h:260
mem_block::used
size_t used
Definition: php/ext/google/protobuf/upb.c:5646
UPB_TIMESTAMP_NANOS
#define UPB_TIMESTAMP_NANOS
Definition: php/ext/google/protobuf/upb.h:3490
upb_fielddef_fullname
const char * upb_fielddef_fullname(const upb_fielddef *f)
Definition: php/ext/google/protobuf/upb.c:1501
upb_array_grow
static bool upb_array_grow(upb_array *arr, size_t elements)
Definition: php/ext/google/protobuf/upb.c:667
upb_strtable_done
bool upb_strtable_done(const upb_strtable_iter *i)
Definition: php/ext/google/protobuf/upb.c:5018
upb_pbcodecache::dest
upb_handlercache * dest
Definition: php/ext/google/protobuf/upb.h:6506
upb_mapiter_value
upb_msgval upb_mapiter_value(const upb_mapiter *i)
Definition: php/ext/google/protobuf/upb.c:4338
putbuf
static void putbuf(upb_pb_encoder *e, const char *buf, size_t len)
Definition: php/ext/google/protobuf/upb.c:7928
upb_fielddef::uint
uint64_t uint
Definition: php/ext/google/protobuf/upb.c:1124
is_fieldmask
static bool is_fieldmask(const upb_msgdef *m)
Definition: php/ext/google/protobuf/upb.c:11170
OP_PUSHTAGDELIM
@ OP_PUSHTAGDELIM
Definition: php/ext/google/protobuf/upb.h:6471
google_protobuf_EnumDescriptorProto
struct google_protobuf_EnumDescriptorProto google_protobuf_EnumDescriptorProto
Definition: php/ext/google/protobuf/upb.h:939
upb_json_printer::output_
upb_bytessink output_
Definition: php/ext/google/protobuf/upb.c:12242
google_protobuf_ServiceOptions_msginit
const upb_msglayout google_protobuf_ServiceOptions_msginit
Definition: php/ext/google/protobuf/upb.c:395
upb_map_fromkey
static upb_msgval upb_map_fromkey(upb_fieldtype_t type, const char *key, size_t len)
Definition: php/ext/google/protobuf/upb.c:4195
upb_pbdecoder_reset
void upb_pbdecoder_reset(upb_pbdecoder *d)
Definition: php/ext/google/protobuf/upb.c:7708
upb_gfree
UPB_INLINE void upb_gfree(void *ptr)
Definition: php/ext/google/protobuf/upb.h:282
google_protobuf_FieldDescriptorProto_has_options
UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_options(const google_protobuf_FieldDescriptorProto *msg)
Definition: php/ext/google/protobuf/upb.h:1504
upb_byteshandler
Definition: php/ext/google/protobuf/upb.h:4650
_upb_tabent::val
upb_tabval val
Definition: php/ext/google/protobuf/upb.h:2784
putescaped
static int putescaped(upb_textprinter *p, const char *buf, size_t len, bool preserve_utf8)
Definition: php/ext/google/protobuf/upb.c:8414
upb_msg_fieldsize
static uint8_t upb_msg_fieldsize(const upb_msglayout_field *field)
Definition: php/ext/google/protobuf/upb.c:3897
upb_pbdecoder_decode_f32
int32_t upb_pbdecoder_decode_f32(upb_pbdecoder *d, uint32_t *u32)
Definition: php/ext/google/protobuf/upb.c:7204
end_fieldmask_path_text
static bool end_fieldmask_path_text(upb_json_parser *p, const char *ptr)
Definition: php/ext/google/protobuf/upb.c:10563
upb_decode
bool upb_decode(const char *buf, size_t size, void *msg, const upb_msglayout *l)
Definition: php/ext/google/protobuf/upb.c:1088
mutable_entries
static upb_tabent * mutable_entries(upb_table *t)
Definition: php/ext/google/protobuf/upb.c:4724
upb_symtab::syms
upb_strtable syms
Definition: php/ext/google/protobuf/upb.c:1204
upb_handlerattr::closure_type
const void * closure_type
Definition: php/ext/google/protobuf/upb.h:4087
UPB_DESCRIPTOR_TYPE_BOOL
@ UPB_DESCRIPTOR_TYPE_BOOL
Definition: php/ext/google/protobuf/upb.h:444
upb_table::size_lg2
uint8_t size_lg2
Definition: php/ext/google/protobuf/upb.h:2797
OP_ENDSTR
@ OP_ENDSTR
Definition: php/ext/google/protobuf/upb.h:6469
upb_decode_string
static bool upb_decode_string(const char **ptr, const char *limit, upb_strview *val)
Definition: php/ext/google/protobuf/upb.c:615
upb_fielddef::lazy_
bool lazy_
Definition: php/ext/google/protobuf/upb.c:1140
google_protobuf_EnumValueDescriptorProto
struct google_protobuf_EnumValueDescriptorProto google_protobuf_EnumValueDescriptorProto
Definition: php/ext/google/protobuf/upb.h:941
upb_handlers_setendseq
bool upb_handlers_setendseq(upb_handlers *h, const upb_fielddef *f, upb_endfield_handlerfunc *func, const upb_handlerattr *attr)
mgroup
Definition: php/ext/google/protobuf/upb.h:6516
UPB_DESCRIPTOR_TYPE_BYTES
@ UPB_DESCRIPTOR_TYPE_BYTES
Definition: php/ext/google/protobuf/upb.h:448
upb_bytessink_start
UPB_INLINE bool upb_bytessink_start(upb_bytessink s, size_t size_hint, void **subc)
Definition: php/ext/google/protobuf/upb.h:6042
upb_pbcodecache_free
void upb_pbcodecache_free(upb_pbcodecache *c)
Definition: php/ext/google/protobuf/upb.c:6681
prefix
static const char prefix[]
Definition: test_pair_ipc.cpp:26
upb_table_size
UPB_INLINE size_t upb_table_size(const upb_table *t)
Definition: php/ext/google/protobuf/upb.h:2838
upb_array::len
size_t len
Definition: php/ext/google/protobuf/upb.h:472
decl_counts::enum_count
int enum_count
Definition: php/ext/google/protobuf/upb.c:2433
upb_pb_encoder_segment
Definition: php/ext/google/protobuf/upb.c:7887
fmt_uint64_as_number
static size_t fmt_uint64_as_number(unsigned long long val, char *buf, size_t length)
Definition: php/ext/google/protobuf/upb.c:12440
upb_sink_startmsg
UPB_INLINE bool upb_sink_startmsg(upb_sink s)
Definition: php/ext/google/protobuf/upb.h:5729
scalar_str
static size_t scalar_str(void *closure, const void *handler_data, const char *str, size_t len, const upb_bufhandle *handle)
Definition: php/ext/google/protobuf/upb.c:12749
upb_strtable_iter_key
const char * upb_strtable_iter_key(const upb_strtable_iter *i)
Definition: php/ext/google/protobuf/upb.c:5024
upb_handlercache_free
void upb_handlercache_free(upb_handlercache *cache)
Definition: php/ext/google/protobuf/upb.c:3714
upb_encode_growbuffer
static bool upb_encode_growbuffer(upb_encstate *e, size_t bytes)
Definition: php/ext/google/protobuf/upb.c:2924
upb_inttable_iter
Definition: php/ext/google/protobuf/upb.h:3088
upb_mktime
static int64_t upb_mktime(const struct tm *tp)
Definition: php/ext/google/protobuf/upb.c:10490
haslazyhandlers
static bool haslazyhandlers(const upb_handlers *h, const upb_fielddef *f)
Definition: php/ext/google/protobuf/upb.c:6321
offset
GLintptr offset
Definition: glcorearb.h:2944
handle_mapentry
static bool handle_mapentry(upb_json_parser *p)
Definition: php/ext/google/protobuf/upb.c:10697
UPB_HANDLER_ENDSTR
@ UPB_HANDLER_ENDSTR
Definition: php/ext/google/protobuf/upb.h:4045
upb_msg_handlerdata
Definition: php/ext/google/protobuf/upb.c:3750
upb_handlercache::closure
const void * closure
Definition: php/ext/google/protobuf/upb.c:3652
upb_json_parser::tm
struct tm tm
Definition: php/ext/google/protobuf/upb.c:9053
mapvalue_endstr
static bool mapvalue_endstr(void *closure, const void *handler_data)
Definition: php/ext/google/protobuf/upb.c:12810
upb_msgdef_submsgfieldcount
uint32_t upb_msgdef_submsgfieldcount(const upb_msgdef *m)
Definition: php/ext/google/protobuf/upb.c:1753
google::protobuf::isprint
bool isprint(char c)
Definition: strutil.cc:79
upb_json_parser::current_state
int current_state
Definition: php/ext/google/protobuf/upb.c:9022
LABEL_FIELD
#define LABEL_FIELD
Definition: php/ext/google/protobuf/upb.c:6336
tag_t
Definition: php/ext/google/protobuf/upb.c:8093
returntype
static const void ** returntype(upb_handlers *h, const upb_fielddef *f, upb_handlertype_t type)
Definition: php/ext/google/protobuf/upb.c:3316
as_double
static double as_double(uint64_t n)
Definition: php/ext/google/protobuf/upb.c:7212
upb_pb_encoder::depth
int depth
Definition: php/ext/google/protobuf/upb.c:7920
upb_byteshandler_setstartstr
bool upb_byteshandler_setstartstr(upb_byteshandler *h, upb_startstr_handlerfunc *func, void *d)
Definition: php/ext/google/protobuf/upb.c:3727
shortdefname
static const char * shortdefname(const char *fullname)
Definition: php/ext/google/protobuf/upb.c:1271
google_protobuf_FieldDescriptorProto
struct google_protobuf_FieldDescriptorProto google_protobuf_FieldDescriptorProto
Definition: php/ext/google/protobuf/upb.h:937
end_number
static bool end_number(upb_json_parser *p, const char *ptr)
Definition: php/ext/google/protobuf/upb.c:9691
goto_endmsg
static void goto_endmsg(upb_pbdecoder *d)
Definition: php/ext/google/protobuf/upb.c:7330
kPbDecoderSubmessageTooLong
const char * kPbDecoderSubmessageTooLong
Definition: php/ext/google/protobuf/upb.c:6753
LABEL_LOOPSTART
#define LABEL_LOOPSTART
Definition: php/ext/google/protobuf/upb.c:6334
json_en_string_machine
static const int json_en_string_machine
Definition: php/ext/google/protobuf/upb.c:11615
OP_RET
@ OP_RET
Definition: php/ext/google/protobuf/upb.h:6480
upb_inttable_iter_setdone
void upb_inttable_iter_setdone(upb_inttable_iter *i)
Definition: php/ext/google/protobuf/upb.c:5354
start
GLuint start
Definition: glcorearb.h:2858
inthash
static uint32_t inthash(upb_tabkey key)
Definition: php/ext/google/protobuf/upb.c:5059
UPB_WELLKNOWN_INT32VALUE
@ UPB_WELLKNOWN_INT32VALUE
Definition: php/ext/google/protobuf/upb.h:3159
opcode
opcode
Definition: php/ext/google/protobuf/upb.h:6454
hexdigit
static void hexdigit(upb_json_parser *p, const char *ptr)
Definition: php/ext/google/protobuf/upb.c:9599
end_null
static bool end_null(upb_json_parser *p)
Definition: php/ext/google/protobuf/upb.c:9928
is_wellknown_msg
static bool is_wellknown_msg(upb_json_parser *p, upb_wellknowntype_t type)
Definition: php/ext/google/protobuf/upb.c:11294
textprinter_startstr
static void * textprinter_startstr(void *closure, const void *handler_data, size_t size_hint)
Definition: php/ext/google/protobuf/upb.c:8565
upb_filedef::msg_count
int msg_count
Definition: php/ext/google/protobuf/upb.c:1197
in_buf
static bool in_buf(const char *p, const char *buf, const char *end)
Definition: php/ext/google/protobuf/upb.c:6867
upb_unknown_handlerfunc
bool upb_unknown_handlerfunc(void *c, const void *hd, const char *buf, size_t n)
Definition: php/ext/google/protobuf/upb.h:4128
upb_textprinter::output_
upb_bytessink output_
Definition: php/ext/google/protobuf/upb.c:8387
new_tag
static void new_tag(upb_handlers *h, const upb_fielddef *f, upb_wiretype_t wt, upb_handlerattr *attr)
Definition: php/ext/google/protobuf/upb.c:8099
google_protobuf_EnumValueDescriptorProto_name
UPB_INLINE upb_strview google_protobuf_EnumValueDescriptorProto_name(const google_protobuf_EnumValueDescriptorProto *msg)
Definition: php/ext/google/protobuf/upb.h:1721
streql_view
static bool streql_view(upb_strview view, const char *b)
Definition: php/ext/google/protobuf/upb.c:1958
update_failure_list.str
str
Definition: update_failure_list.py:41
upb_fielddef_containingoneof
const upb_oneofdef * upb_fielddef_containingoneof(const upb_fielddef *f)
Definition: php/ext/google/protobuf/upb.c:1619
upb_readcase
static uint32_t upb_readcase(const char *msg, const upb_msglayout_field *f)
Definition: php/ext/google/protobuf/upb.c:2991
outer_frame
upb_pbdecoder_frame * outer_frame(upb_pbdecoder *d)
Definition: php/ext/google/protobuf/upb.c:7396
cleanup_ent
Definition: php/ext/google/protobuf/upb.c:5651
LABEL_LOOPBREAK
#define LABEL_LOOPBREAK
Definition: php/ext/google/protobuf/upb.c:6335
upb_fielddef_ismap
bool upb_fielddef_ismap(const upb_fielddef *f)
Definition: php/ext/google/protobuf/upb.c:1704
upb_msg_oneof_begin
void upb_msg_oneof_begin(upb_msg_oneof_iter *iter, const upb_msgdef *m)
Definition: php/ext/google/protobuf/upb.c:1846
OP_STARTMSG
@ OP_STARTMSG
Definition: php/ext/google/protobuf/upb.h:6461
upb_inttable
Definition: php/ext/google/protobuf/upb.h:2823
google_protobuf_FieldDescriptorProto_label
UPB_INLINE int32_t google_protobuf_FieldDescriptorProto_label(const google_protobuf_FieldDescriptorProto *msg)
Definition: php/ext/google/protobuf/upb.h:1497
upb_oneof_iter_setdone
void upb_oneof_iter_setdone(upb_oneof_iter *iter)
Definition: php/ext/google/protobuf/upb.c:1927
google_protobuf_GeneratedCodeInfo__fields
static const upb_msglayout_field google_protobuf_GeneratedCodeInfo__fields[1]
Definition: php/ext/google/protobuf/upb.c:480
reserve
static bool reserve(upb_pb_encoder *e, size_t bytes)
Definition: php/ext/google/protobuf/upb.c:7939
upb_enumdef::ntoi
upb_strtable ntoi
Definition: php/ext/google/protobuf/upb.c:1171
start_wrapper_object
static void start_wrapper_object(upb_json_parser *p)
Definition: php/ext/google/protobuf/upb.c:11195
UPB_BREAK
#define UPB_BREAK
Definition: php/ext/google/protobuf/upb.h:4054
UPB_DURATION_SECONDS
#define UPB_DURATION_SECONDS
Definition: php/ext/google/protobuf/upb.h:3485
fmt_int64_as_number
static size_t fmt_int64_as_number(long long val, char *buf, size_t length)
Definition: php/ext/google/protobuf/upb.c:12434
UPB_CTYPE_BOOL
@ UPB_CTYPE_BOOL
Definition: php/ext/google/protobuf/upb.h:2647
capture_end
static bool capture_end(upb_json_parser *p, const char *ptr)
Definition: php/ext/google/protobuf/upb.c:9529
json_start
static const int json_start
Definition: php/ext/google/protobuf/upb.c:11612
upb_msgdef_numoneofs
int upb_msgdef_numoneofs(const upb_msgdef *m)
Definition: php/ext/google/protobuf/upb.c:1804
upb_fielddef::unresolved
const google_protobuf_FieldDescriptorProto * unresolved
Definition: php/ext/google/protobuf/upb.c:1134
upb_fielddef_lazy
bool upb_fielddef_lazy(const upb_fielddef *f)
Definition: php/ext/google/protobuf/upb.c:1560
upb_msgval_write
static void upb_msgval_write(void *p, size_t ofs, upb_msgval val, uint8_t size)
Definition: php/ext/google/protobuf/upb.c:3869
start_value_object
static void start_value_object(upb_json_parser *p, int value_type)
Definition: php/ext/google/protobuf/upb.c:11212
end_listvalue_object
static void end_listvalue_object(upb_json_parser *p)
Definition: php/ext/google/protobuf/upb.c:11268
repeated_enum
static bool repeated_enum(void *closure, const void *handler_data, int32_t val)
Definition: php/ext/google/protobuf/upb.c:12568
upb_msgval_fromval
static upb_msgval upb_msgval_fromval(upb_value val)
Definition: php/ext/google/protobuf/upb.c:3916
upb_getorcreatearr
static upb_array * upb_getorcreatearr(upb_decframe *frame, const upb_msglayout_field *field)
Definition: php/ext/google/protobuf/upb.c:708
lookupkey_t::num
uintptr_t num
Definition: php/ext/google/protobuf/upb.c:4698
textprinter_putenum
static bool textprinter_putenum(void *closure, const void *handler_data, int32_t val)
Definition: php/ext/google/protobuf/upb.c:8548
upb_handlercache::tab
upb_inttable tab
Definition: php/ext/google/protobuf/upb.c:3650
google_protobuf_DescriptorProto_ReservedRange_msginit
const upb_msglayout google_protobuf_DescriptorProto_ReservedRange_msginit
Definition: php/ext/google/protobuf/upb.c:130
end_membername
static bool end_membername(upb_json_parser *p)
Definition: php/ext/google/protobuf/upb.c:10743
isfull
static bool isfull(upb_table *t)
Definition: php/ext/google/protobuf/upb.c:4728
UPB_WIRE_TYPE_END_GROUP
@ UPB_WIRE_TYPE_END_GROUP
Definition: php/ext/google/protobuf/upb.h:403
UPB_DURATION_MAX_JSON_LEN
#define UPB_DURATION_MAX_JSON_LEN
Definition: php/ext/google/protobuf/upb.c:13074
upb_fieldtotabtype
static upb_ctype_t upb_fieldtotabtype(upb_fieldtype_t type)
Definition: php/ext/google/protobuf/upb.c:3923
upb_enumdef_fullname
const char * upb_enumdef_fullname(const upb_enumdef *e)
Definition: php/ext/google/protobuf/upb.c:1445
upb_strtable_remove3
bool upb_strtable_remove3(upb_strtable *t, const char *key, size_t len, upb_value *val, upb_alloc *alloc)
Definition: php/ext/google/protobuf/upb.c:4991
upb_strtable_iter_value
upb_value upb_strtable_iter_value(const upb_strtable_iter *i)
Definition: php/ext/google/protobuf/upb.c:5036
upb_fielddef::type_
upb_descriptortype_t type_
Definition: php/ext/google/protobuf/upb.c:1142
upb_status_vseterrf
void upb_status_vseterrf(upb_status *status, const char *fmt, va_list args)
Definition: php/ext/google/protobuf/upb.c:5591
upb_textprinter::single_line_
bool single_line_
Definition: php/ext/google/protobuf/upb.c:8389
compiler::fwd_labels
int fwd_labels[MAXLABEL]
Definition: php/ext/google/protobuf/upb.c:5885
hashfunc_t
uint32_t hashfunc_t(upb_tabkey key)
Definition: php/ext/google/protobuf/upb.c:4718
WRITE
#define WRITE(byte)
VALUE_STRUCTVALUE
@ VALUE_STRUCTVALUE
Definition: php/ext/google/protobuf/upb.c:8821
textprinter_endsubmsg
static bool textprinter_endsubmsg(void *closure, const void *handler_data)
Definition: php/ext/google/protobuf/upb.c:8605
printer_startdurationmsg
static bool printer_startdurationmsg(void *closure, const void *handler_data)
Definition: php/ext/google/protobuf/upb.c:13065
testing::internal::fmt
GTEST_API_ const char * fmt
Definition: gtest.h:1835
upb_arena_free
void upb_arena_free(upb_arena *a)
Definition: php/ext/google/protobuf/upb.c:5762
upb_symtab
Definition: php/ext/google/protobuf/upb.c:1202
upb_enumdef::defaultval
int32_t defaultval
Definition: php/ext/google/protobuf/upb.c:1173
UPB_JSON_PRINTER_SIZE
#define UPB_JSON_PRINTER_SIZE
Definition: php/ext/google/protobuf/upb.h:7200
upb_map_new
upb_map * upb_map_new(upb_fieldtype_t ktype, upb_fieldtype_t vtype, upb_arena *a)
Definition: php/ext/google/protobuf/upb.c:4216
count_types_in_file
static void count_types_in_file(const google_protobuf_FileDescriptorProto *file_proto, decl_counts *counts)
Definition: php/ext/google/protobuf/upb.c:2456
upb_getarr
static upb_array * upb_getarr(upb_decframe *frame, const upb_msglayout_field *field)
Definition: php/ext/google/protobuf/upb.c:702
upb_wiretype_t
upb_wiretype_t
Definition: php/ext/google/protobuf/upb.h:398
upb_encode_message
bool upb_encode_message(upb_encstate *e, const char *msg, const upb_msglayout *m, size_t *size)
Definition: php/ext/google/protobuf/upb.c:3192
p
const char * p
Definition: gmock-matchers_test.cc:3863
upb_tabval
Definition: php/ext/google/protobuf/upb.h:2773
mapvalue_enum
static bool mapvalue_enum(void *closure, const void *handler_data, int32_t val)
Definition: php/ext/google/protobuf/upb.c:12579
UPB_WELLKNOWN_UNSPECIFIED
@ UPB_WELLKNOWN_UNSPECIFIED
Definition: php/ext/google/protobuf/upb.h:3149
upb_byteshandler_init
UPB_INLINE void upb_byteshandler_init(upb_byteshandler *handler)
Definition: php/ext/google/protobuf/upb.h:4659
multipart_startaccum
static void multipart_startaccum(upb_json_parser *p)
Definition: php/ext/google/protobuf/upb.c:9469
UPB_DEFTYPE_MSG
@ UPB_DEFTYPE_MSG
Definition: php/ext/google/protobuf/upb.c:1210
UPB_TYPE_DOUBLE
@ UPB_TYPE_DOUBLE
Definition: php/ext/google/protobuf/upb.h:423
UPB_TYPE_STRING
@ UPB_TYPE_STRING
Definition: php/ext/google/protobuf/upb.h:419
upb_jsonparser_frame::sink
upb_sink sink
Definition: php/ext/google/protobuf/upb.c:8951
upb_msglayout::submsgs
const struct upb_msglayout *const * submsgs
Definition: php/ext/google/protobuf/upb.h:524
upb_msg
void upb_msg
Definition: php/ext/google/protobuf/upb.h:497
upb_oneofdef_name
const char * upb_oneofdef_name(const upb_oneofdef *o)
Definition: php/ext/google/protobuf/upb.c:1882
upb_msgfactory_new
upb_msgfactory * upb_msgfactory_new(const upb_symtab *symtab)
Definition: php/ext/google/protobuf/upb.c:4548
upb_handlers_getattr
bool upb_handlers_getattr(const upb_handlers *h, upb_selector_t sel, upb_handlerattr *attr)
Definition: php/ext/google/protobuf/upb.c:3529
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: php/ext/google/protobuf/upb.h:1242
upb_table::ctype
upb_ctype_t ctype
Definition: php/ext/google/protobuf/upb.h:2796
upb_handlerfree
void upb_handlerfree(void *d)
Definition: php/ext/google/protobuf/upb.h:4127
UPB_WIRE_TYPE_64BIT
@ UPB_WIRE_TYPE_64BIT
Definition: php/ext/google/protobuf/upb.h:400
end_object
static void end_object(upb_json_parser *p)
Definition: php/ext/google/protobuf/upb.c:11039
upb_isalphanum
static bool upb_isalphanum(char c)
Definition: php/ext/google/protobuf/upb.c:1235
upb_msgdef::oneofs
const upb_oneofdef * oneofs
Definition: php/ext/google/protobuf/upb.c:1157
kPbDecoderStackOverflow
const char * kPbDecoderStackOverflow
Definition: php/ext/google/protobuf/upb.c:6752
UPB_WELLKNOWN_INT64VALUE
@ UPB_WELLKNOWN_INT64VALUE
Definition: php/ext/google/protobuf/upb.h:3157
upb_fielddef::msgdef
const upb_msgdef * msgdef
Definition: php/ext/google/protobuf/upb.c:1120
google_protobuf_EnumDescriptorProto__fields
static const upb_msglayout_field google_protobuf_EnumDescriptorProto__fields[5]
Definition: php/ext/google/protobuf/upb.c:194
google_protobuf_EnumOptions_submsgs
static const upb_msglayout *const google_protobuf_EnumOptions_submsgs[1]
Definition: php/ext/google/protobuf/upb.c:355
getbytes_slow
static UPB_NOINLINE int32_t getbytes_slow(upb_pbdecoder *d, void *buf, size_t bytes)
Definition: php/ext/google/protobuf/upb.c:7069
start_delim
static bool start_delim(upb_pb_encoder *e)
Definition: php/ext/google/protobuf/upb.c:8015
UPB_HANDLER_STARTSEQ
@ UPB_HANDLER_STARTSEQ
Definition: php/ext/google/protobuf/upb.h:4048
upb_oneofdef_containingtype
const upb_msgdef * upb_oneofdef_containingtype(const upb_oneofdef *o)
Definition: php/ext/google/protobuf/upb.c:1886
upb_handlercache::callback
upb_handlers_callback * callback
Definition: php/ext/google/protobuf/upb.c:3651
upb_label_t
upb_label_t
Definition: php/ext/google/protobuf/upb.h:429
upb_sink_startseq
UPB_INLINE bool upb_sink_startseq(upb_sink s, upb_selector_t sel, upb_sink *sub)
Definition: php/ext/google/protobuf/upb.h:5753
err
static UPB_NORETURN void err(tarjan *t)
Definition: ruby/ext/google/protobuf_c/upb.c:5856
google::protobuf::uint64
uint64_t uint64
Definition: protobuf/src/google/protobuf/stubs/port.h:156
json_parser_reset
static void json_parser_reset(upb_json_parser *p)
Definition: php/ext/google/protobuf/upb.c:12054
upb_filedef_name
const char * upb_filedef_name(const upb_filedef *f)
Definition: php/ext/google/protobuf/upb.c:2696
does_string_wrapper_start
static bool does_string_wrapper_start(upb_json_parser *p)
Definition: php/ext/google/protobuf/upb.c:11319
upb_handlers_getsubhandlers
const upb_handlers * upb_handlers_getsubhandlers(const upb_handlers *h, const upb_fielddef *f)
Definition: php/ext/google/protobuf/upb.c:3514
upb_fielddef_checkintfmt
bool upb_fielddef_checkintfmt(int32_t fmt)
Definition: php/ext/google/protobuf/upb.c:1725
size
#define size
Definition: glcorearb.h:2944
upb_json_codecache_free
void upb_json_codecache_free(upb_json_codecache *c)
Definition: php/ext/google/protobuf/upb.c:12187
json_parser_any_frame_new
static upb_jsonparser_any_frame * json_parser_any_frame_new(upb_json_parser *p)
Definition: php/ext/google/protobuf/upb.c:9078
compiler::back_labels
int back_labels[MAXLABEL]
Definition: php/ext/google/protobuf/upb.c:5886
trygetsel
static int32_t trygetsel(upb_handlers *h, const upb_fielddef *f, upb_handlertype_t type)
Definition: php/ext/google/protobuf/upb.c:3296
upb_fielddef_name
const char * upb_fielddef_name(const upb_fielddef *f)
Definition: php/ext/google/protobuf/upb.c:1568
_json_single_lengths
static const char _json_single_lengths[]
Definition: php/ext/google/protobuf/upb.c:11448
UPB_DEFTYPE_FIELD
@ UPB_DEFTYPE_FIELD
Definition: php/ext/google/protobuf/upb.c:1212
upb_strtable_iter_setdone
void upb_strtable_iter_setdone(upb_strtable_iter *i)
Definition: php/ext/google/protobuf/upb.c:5041
_json_eof_actions
static const unsigned char _json_eof_actions[]
Definition: php/ext/google/protobuf/upb.c:11594
google_protobuf_FileDescriptorProto_syntax
UPB_INLINE upb_strview google_protobuf_FileDescriptorProto_syntax(const google_protobuf_FileDescriptorProto *msg)
Definition: php/ext/google/protobuf/upb.h:1101
fmt_uint64_as_string
static size_t fmt_uint64_as_string(unsigned long long val, char *buf, size_t length)
Definition: php/ext/google/protobuf/upb.c:12453
strpc::len
size_t len
Definition: php/ext/google/protobuf/upb.c:12268
end_structvalue_object
static void end_structvalue_object(upb_json_parser *p)
Definition: php/ext/google/protobuf/upb.c:11285
UPB_MAX_FIELDNUMBER
#define UPB_MAX_FIELDNUMBER
Definition: php/ext/google/protobuf/upb.h:3174
CHECK
#define CHECK(x)
Definition: php/ext/google/protobuf/upb.c:8393
VALUE_LISTVALUE
@ VALUE_LISTVALUE
Definition: php/ext/google/protobuf/upb.c:8822
UPB_WIRE_TYPE_DELIMITED
@ UPB_WIRE_TYPE_DELIMITED
Definition: php/ext/google/protobuf/upb.h:401
fmt_double
static size_t fmt_double(double val, char *buf, size_t length)
Definition: php/ext/google/protobuf/upb.c:12406
streql2
static bool streql2(const char *a, size_t n, const char *b)
Definition: php/ext/google/protobuf/upb.c:1954
mem_block
Definition: php/ext/google/protobuf/upb.c:5643
upb_handlers_setuint32
bool upb_handlers_setuint32(upb_handlers *h, const upb_fielddef *f, upb_uint32_handlerfunc *func, const upb_handlerattr *attr)
log2ceil
int log2ceil(uint64_t v)
Definition: php/ext/google/protobuf/upb.c:4667
upb_decode_fixedpacked
static bool upb_decode_fixedpacked(upb_array *arr, upb_strview data, int elem_size)
Definition: php/ext/google/protobuf/upb.c:878
google_protobuf_FieldDescriptorProto_has_type_name
UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_type_name(const google_protobuf_FieldDescriptorProto *msg)
Definition: php/ext/google/protobuf/upb.h:1500
getsel_for_handlertype
static upb_selector_t getsel_for_handlertype(upb_json_parser *p, upb_handlertype_t type)
Definition: php/ext/google/protobuf/upb.c:9163
upb_json_printer::nanos
int32_t nanos
Definition: php/ext/google/protobuf/upb.c:12262
upb_encode_array
static bool upb_encode_array(upb_encstate *e, const char *field_mem, const upb_msglayout *m, const upb_msglayout_field *f)
Definition: php/ext/google/protobuf/upb.c:3017
decode_v32
static UPB_FORCEINLINE int32_t decode_v32(upb_pbdecoder *d, uint32_t *u32)
Definition: php/ext/google/protobuf/upb.c:7171
upb_string_handlerfunc
size_t upb_string_handlerfunc(void *c, const void *hd, const char *buf, size_t n, const upb_bufhandle *handle)
Definition: php/ext/google/protobuf/upb.h:4143
upb_array
Definition: php/ext/google/protobuf/upb.h:468
symtab_addctx::addtab
upb_strtable * addtab
Definition: php/ext/google/protobuf/upb.c:1946
upb_symtab::symtab
upb_strtable symtab
Definition: ruby/ext/google/protobuf_c/upb.h:3395
textprinter_putbool
static bool textprinter_putbool(void *closure, const void *handler_data, bool val)
Definition: php/ext/google/protobuf/upb.c:8523
upb_fielddef
Definition: php/ext/google/protobuf/upb.c:1118
UPB_HANDLERATTR_INIT
#define UPB_HANDLERATTR_INIT
Definition: php/ext/google/protobuf/upb.h:4092
upb_fielddef_defaultint32
int32_t upb_fielddef_defaultint32(const upb_fielddef *f)
Definition: php/ext/google/protobuf/upb.c:1633
upb_jsonparser_frame
Definition: php/ext/google/protobuf/upb.c:8950
upb_put_bytes
static bool upb_put_bytes(upb_encstate *e, const void *data, size_t len)
Definition: php/ext/google/protobuf/upb.c:2950
upb_json_parser::accumulate_buf
char * accumulate_buf
Definition: php/ext/google/protobuf/upb.c:9032
UPB_MAXARRSIZE
#define UPB_MAXARRSIZE
Definition: php/ext/google/protobuf/upb.c:4646
UPB_NOINLINE
#define UPB_NOINLINE
Definition: php/ext/google/protobuf/upb.h:106
upb_filedef::syntax
upb_syntax_t syntax
Definition: php/ext/google/protobuf/upb.c:1189
upb_decstate
Definition: php/ext/google/protobuf/upb.c:531
upb_pbdecoder_checktag_slow
UPB_NOINLINE int32_t upb_pbdecoder_checktag_slow(upb_pbdecoder *d, uint64_t expected)
Definition: php/ext/google/protobuf/upb.c:7249
upb_decode_field
static bool upb_decode_field(upb_decstate *d, upb_decframe *frame)
Definition: php/ext/google/protobuf/upb.c:1016
upb_stringsink_init
void upb_stringsink_init(upb_stringsink *sink)
Definition: php/ext/google/protobuf/upb.c:8918
upb_mapiter_isequal
bool upb_mapiter_isequal(const upb_mapiter *i1, const upb_mapiter *i2)
Definition: php/ext/google/protobuf/upb.c:4346
OP_STRING
@ OP_STRING
Definition: php/ext/google/protobuf/upb.h:6468
upb_filedef
Definition: php/ext/google/protobuf/upb.c:1184
UPB_PB_DECODER_SIZE
#define UPB_PB_DECODER_SIZE
Definition: php/ext/google/protobuf/upb.h:6295
UPB_HANDLER_UINT32
@ UPB_HANDLER_UINT32
Definition: php/ext/google/protobuf/upb.h:4038
upb_status_setoom
UPB_INLINE void upb_status_setoom(upb_status *status)
Definition: php/ext/google/protobuf/upb.h:190
google_protobuf_DescriptorProto_field
const UPB_INLINE google_protobuf_FieldDescriptorProto *const * google_protobuf_DescriptorProto_field(const google_protobuf_DescriptorProto *msg, size_t *len)
Definition: php/ext/google/protobuf/upb.h:1241
upb_cleanup_func
void upb_cleanup_func(void *ud)
Definition: php/ext/google/protobuf/upb.h:300
upb_json_codecache_new
upb_json_codecache * upb_json_codecache_new()
Definition: php/ext/google/protobuf/upb.c:12173
json_en_duration_machine
static const int json_en_duration_machine
Definition: php/ext/google/protobuf/upb.c:11616
mem_block::next
struct mem_block * next
Definition: php/ext/google/protobuf/upb.c:5644
google_protobuf_DescriptorProto_ExtensionRange_submsgs
static const upb_msglayout *const google_protobuf_DescriptorProto_ExtensionRange_submsgs[1]
Definition: php/ext/google/protobuf/upb.c:109
upb_zzenc_32
UPB_INLINE uint32_t upb_zzenc_32(int32_t n)
Definition: php/ext/google/protobuf/upb.h:6781
OP_MAX
#define OP_MAX
Definition: php/ext/google/protobuf/upb.h:6500
buffer
Definition: buffer_processor.h:43
OP_HALT
@ OP_HALT
Definition: php/ext/google/protobuf/upb.h:6497
byte
SETUP_TEARDOWN_TESTCONTEXT typedef uint8_t byte
Definition: test_stream.cpp:12
upb_array::data
void * data
Definition: php/ext/google/protobuf/upb.h:471
upb_alloc_global
upb_alloc upb_alloc_global
Definition: php/ext/google/protobuf/upb.c:5612
accumulate_clear
static void accumulate_clear(upb_json_parser *p)
Definition: php/ext/google/protobuf/upb.c:9372
upb_jsonparser_frame::is_unknown_field
bool is_unknown_field
Definition: php/ext/google/protobuf/upb.c:8993
d
d
upb_map_keytype
upb_fieldtype_t upb_map_keytype(const upb_map *map)
Definition: php/ext/google/protobuf/upb.c:4242
upb_table::mask
size_t mask
Definition: php/ext/google/protobuf/upb.h:2795
endfield
static int endfield(upb_textprinter *p)
Definition: php/ext/google/protobuf/upb.c:8408
UPB_MIN
#define UPB_MIN(x, y)
Definition: php/ext/google/protobuf/upb.h:139
google::protobuf::isxdigit
bool isxdigit(char c)
Definition: strutil.cc:73
bufleft
static size_t bufleft(const upb_pbdecoder *d)
Definition: php/ext/google/protobuf/upb.c:6847
upb_syntax_t
upb_syntax_t
Definition: php/ext/google/protobuf/upb.h:3139
upb_pbdecoder_frame::groupnum
int32_t groupnum
Definition: php/ext/google/protobuf/upb.h:6570
upb_array_reserve
static void * upb_array_reserve(upb_array *arr, size_t elements)
Definition: php/ext/google/protobuf/upb.c:689
upb_pb_encoder
Definition: php/ext/google/protobuf/upb.c:7892
json_parser_any_frame_has_value_before_type_url
static bool json_parser_any_frame_has_value_before_type_url(upb_jsonparser_any_frame *frame)
Definition: php/ext/google/protobuf/upb.c:9127
start_structvalue_object
static void start_structvalue_object(upb_json_parser *p)
Definition: php/ext/google/protobuf/upb.c:11273
printer_startmsg
static bool printer_startmsg(void *closure, const void *handler_data)
Definition: php/ext/google/protobuf/upb.c:12611
set_bytecode_handlers
static void set_bytecode_handlers(mgroup *g)
Definition: php/ext/google/protobuf/upb.c:6604
google_protobuf_FieldDescriptorProto_has_oneof_index
UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_oneof_index(const google_protobuf_FieldDescriptorProto *msg)
Definition: php/ext/google/protobuf/upb.h:1506
textprinter_putstr
static size_t textprinter_putstr(void *closure, const void *hd, const char *buf, size_t len, const upb_bufhandle *handle)
Definition: php/ext/google/protobuf/upb.c:8583
VARINT_CASE
#define VARINT_CASE(ctype, decode)
upb_fielddef::boolean
bool boolean
Definition: php/ext/google/protobuf/upb.c:1127
upb_oneofdef::index
uint32_t index
Definition: php/ext/google/protobuf/upb.c:1179
resolve_fielddef
static bool resolve_fielddef(const symtab_addctx *ctx, const char *prefix, upb_fielddef *f)
Definition: php/ext/google/protobuf/upb.c:2474
TYPE_HANDLERS_MAPKEY
#define TYPE_HANDLERS_MAPKEY(type, fmt_func)
Definition: php/ext/google/protobuf/upb.c:12499
scalar_endstr
static bool scalar_endstr(void *closure, const void *handler_data)
Definition: php/ext/google/protobuf/upb.c:12756
google_protobuf_OneofDescriptorProto__fields
static const upb_msglayout_field google_protobuf_OneofDescriptorProto__fields[2]
Definition: php/ext/google/protobuf/upb.c:177
upb_oneofdef::parent
const upb_msgdef * parent
Definition: php/ext/google/protobuf/upb.c:1177
upb_msglayout::field_count
uint16_t field_count
Definition: php/ext/google/protobuf/upb.h:529
DECODE_OK
#define DECODE_OK
Definition: php/ext/google/protobuf/upb.h:6729
msgs
static const upb_msgdef msgs[22]
Definition: ruby/ext/google/protobuf_c/upb.c:7670
upb_decoderet
Definition: php/ext/google/protobuf/upb.h:6787
google_protobuf_OneofDescriptorProto_submsgs
static const upb_msglayout *const google_protobuf_OneofDescriptorProto_submsgs[1]
Definition: php/ext/google/protobuf/upb.c:173
upb_msg_oneof_done
bool upb_msg_oneof_done(const upb_msg_oneof_iter *iter)
Definition: php/ext/google/protobuf/upb.c:1863
MAXLABEL
#define MAXLABEL
Definition: php/ext/google/protobuf/upb.c:5817
UPB_TYPE_MESSAGE
@ UPB_TYPE_MESSAGE
Definition: php/ext/google/protobuf/upb.h:421
upb_map_tokey
static void upb_map_tokey(upb_fieldtype_t type, upb_msgval *key, const char **out_key, size_t *out_len)
Definition: php/ext/google/protobuf/upb.c:4168
UPB_ANY_TYPE
#define UPB_ANY_TYPE
Definition: php/ext/google/protobuf/upb.h:3481
google_protobuf_FieldOptions
struct google_protobuf_FieldOptions google_protobuf_FieldOptions
Definition: php/ext/google/protobuf/upb.h:946
field
const FieldDescriptor * field
Definition: parser_unittest.cc:2694
upb_strview_make
UPB_INLINE upb_strview upb_strview_make(const char *data, size_t size)
Definition: php/ext/google/protobuf/upb.h:540
compiler::lazy
bool lazy
Definition: php/ext/google/protobuf/upb.c:5889
upb_vdecode_max8_branch64
upb_decoderet upb_vdecode_max8_branch64(upb_decoderet r)
Definition: php/ext/google/protobuf/upb.c:8758
buf
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glcorearb.h:4175
_json_index_offsets
static const short _json_index_offsets[]
Definition: php/ext/google/protobuf/upb.c:11484
putf
bool putf(upb_textprinter *p, const char *fmt,...)
Definition: php/ext/google/protobuf/upb.c:8461
VALUE_NULLVALUE
@ VALUE_NULLVALUE
Definition: php/ext/google/protobuf/upb.c:8817
upb_array::element_size
uint8_t element_size
Definition: php/ext/google/protobuf/upb.h:470
upb_tabent_isempty
UPB_INLINE bool upb_tabent_isempty(const upb_tabent *e)
Definition: php/ext/google/protobuf/upb.h:2846
UPB_TYPE_ENUM
@ UPB_TYPE_ENUM
Definition: php/ext/google/protobuf/upb.h:417
upb_put_double
static bool upb_put_double(upb_encstate *e, double d)
Definition: php/ext/google/protobuf/upb.c:2977
key
const SETUP_TEARDOWN_TESTCONTEXT char * key
Definition: test_wss_transport.cpp:10
putstring
static void putstring(upb_json_printer *p, const char *buf, unsigned int len)
Definition: php/ext/google/protobuf/upb.c:12354
google_protobuf_FileDescriptorProto_options
const UPB_INLINE google_protobuf_FileOptions * google_protobuf_FileDescriptorProto_options(const google_protobuf_FileDescriptorProto *msg)
Definition: php/ext/google/protobuf/upb.h:1095
upb_textprinter_setsingleline
void upb_textprinter_setsingleline(upb_textprinter *p, bool single_line)
Definition: php/ext/google/protobuf/upb.c:8702
OP_ENDSUBMSG
@ OP_ENDSUBMSG
Definition: php/ext/google/protobuf/upb.h:6466
assign_msg_wellknowntype
static void assign_msg_wellknowntype(upb_msgdef *m)
Definition: php/ext/google/protobuf/upb.c:1399
end_any_member
static void end_any_member(upb_json_parser *p, const char *ptr)
Definition: php/ext/google/protobuf/upb.c:10822
upb_pb_encoder_reset
void upb_pb_encoder_reset(upb_pb_encoder *e)
Definition: php/ext/google/protobuf/upb.c:8316
google_protobuf_EnumDescriptorProto_EnumReservedRange__fields
static const upb_msglayout_field google_protobuf_EnumDescriptorProto_EnumReservedRange__fields[2]
Definition: php/ext/google/protobuf/upb.c:208
upb_inttable_iter::array_part
bool array_part
Definition: php/ext/google/protobuf/upb.h:3091
mem_block::owned
bool owned
Definition: php/ext/google/protobuf/upb.c:5647
start_fieldmask_object
static void start_fieldmask_object(upb_json_parser *p)
Definition: php/ext/google/protobuf/upb.c:11175
google_protobuf_MessageOptions_submsgs
static const upb_msglayout *const google_protobuf_MessageOptions_submsgs[1]
Definition: php/ext/google/protobuf/upb.c:303
set_name_table
static void set_name_table(upb_json_parser *p, upb_jsonparser_frame *frame)
Definition: php/ext/google/protobuf/upb.c:9185
UPB_CTYPE_INT64
@ UPB_CTYPE_INT64
Definition: php/ext/google/protobuf/upb.h:2644
upb_handlers_setfloat
bool upb_handlers_setfloat(upb_handlers *h, const upb_fielddef *f, upb_float_handlerfunc *func, const upb_handlerattr *attr)
label
static void label(compiler *c, unsigned int label)
Definition: php/ext/google/protobuf/upb.c:5961
UPB_HANDLER_FLOAT
@ UPB_HANDLER_FLOAT
Definition: php/ext/google/protobuf/upb.h:4040
upb_jsonparser_any_frame::before_type_url_end
const char * before_type_url_end
Definition: php/ext/google/protobuf/upb.c:8944
pcofs
static uint32_t pcofs(compiler *c)
Definition: php/ext/google/protobuf/upb.c:5956
ptr_words
const size_t ptr_words
Definition: php/ext/google/protobuf/upb.c:5909
google_protobuf_FileOptions_submsgs
static const upb_msglayout *const google_protobuf_FileOptions_submsgs[1]
Definition: php/ext/google/protobuf/upb.c:271
google_protobuf_FileDescriptorProto_parse
UPB_INLINE google_protobuf_FileDescriptorProto * google_protobuf_FileDescriptorProto_parse(const char *buf, size_t size, upb_arena *arena)
Definition: php/ext/google/protobuf/upb.h:1076
upb_filedef_phpprefix
const char * upb_filedef_phpprefix(const upb_filedef *f)
Definition: php/ext/google/protobuf/upb.c:2704
TYPE_HANDLERS
#define TYPE_HANDLERS(type, fmt_func)
Definition: php/ext/google/protobuf/upb.c:12475
upb_msgdef::ntof
upb_strtable ntof
Definition: php/ext/google/protobuf/upb.c:1154
PRIMITIVE_OP
#define PRIMITIVE_OP(type, wt, name, convfunc, ctype)
suspend_save
static size_t suspend_save(upb_pbdecoder *d)
Definition: php/ext/google/protobuf/upb.c:7026
does_string_wrapper_end
static bool does_string_wrapper_end(upb_json_parser *p)
Definition: php/ext/google/protobuf/upb.c:11325
printer_endmsg_noframe
static bool printer_endmsg_noframe(void *closure, const void *handler_data, upb_status *s)
Definition: php/ext/google/protobuf/upb.c:13218
google_protobuf_DescriptorProto_ExtensionRange__fields
static const upb_msglayout_field google_protobuf_DescriptorProto_ExtensionRange__fields[3]
Definition: php/ext/google/protobuf/upb.c:113
_json_range_lengths
static const char _json_range_lengths[]
Definition: php/ext/google/protobuf/upb.c:11466
scalar_bytes
static size_t scalar_bytes(void *closure, const void *handler_data, const char *str, size_t len, const upb_bufhandle *handle)
Definition: php/ext/google/protobuf/upb.c:12817
UPB_LABEL_REQUIRED
@ UPB_LABEL_REQUIRED
Definition: php/ext/google/protobuf/upb.h:431
compile_methods
static void compile_methods(compiler *c)
Definition: php/ext/google/protobuf/upb.c:6591
start_jsonparser_frame
static upb_jsonparser_frame * start_jsonparser_frame(upb_json_parser *p)
Definition: php/ext/google/protobuf/upb.c:9056
google_protobuf_EnumOptions__fields
static const upb_msglayout_field google_protobuf_EnumOptions__fields[3]
Definition: php/ext/google/protobuf/upb.c:359
upb_msgval_sizeof
static size_t upb_msgval_sizeof(upb_fieldtype_t type)
Definition: php/ext/google/protobuf/upb.c:3875
upb_sink_endstr
UPB_INLINE bool upb_sink_endstr(upb_sink s, upb_selector_t sel)
Definition: php/ext/google/protobuf/upb.h:5794
encode_bytes
static bool encode_bytes(upb_pb_encoder *e, const void *data, size_t len)
Definition: php/ext/google/protobuf/upb.c:7991
UPB_DESCRIPTOR_TYPE_UINT32
@ UPB_DESCRIPTOR_TYPE_UINT32
Definition: php/ext/google/protobuf/upb.h:449
upb_jsonparser_any_frame::stringsink
upb_stringsink stringsink
Definition: php/ext/google/protobuf/upb.c:8935
decoder
static uint8_t decoder[96]
Definition: zmq_utils.cpp:85
freecompiler
static void freecompiler(compiler *c)
Definition: php/ext/google/protobuf/upb.c:5905
capture_begin
static void capture_begin(upb_json_parser *p, const char *ptr)
Definition: php/ext/google/protobuf/upb.c:9523
end_frame
static void end_frame(upb_json_printer *p)
Definition: php/ext/google/protobuf/upb.c:12606
void
typedef void(APIENTRY *GLDEBUGPROCARB)(GLenum source
n
GLdouble n
Definition: glcorearb.h:4153
google_protobuf_UninterpretedOption_NamePart_msginit
const upb_msglayout google_protobuf_UninterpretedOption_NamePart_msginit
Definition: php/ext/google/protobuf/upb.c:442
strcopy
static upb_tabkey strcopy(lookupkey_t k2, upb_alloc *a)
Definition: php/ext/google/protobuf/upb.c:4907
ignore_json_unknown
const upb_json_parsermethod const upb_symtab upb_sink bool ignore_json_unknown
Definition: ruby/ext/google/protobuf_c/upb.h:10504
upb_pbdecoder_maxnesting
size_t upb_pbdecoder_maxnesting(const upb_pbdecoder *d)
Definition: php/ext/google/protobuf/upb.c:7766
UPB_TYPE_UINT64
@ UPB_TYPE_UINT64
Definition: php/ext/google/protobuf/upb.h:425
upb_sink_endsubmsg
UPB_INLINE bool upb_sink_endsubmsg(upb_sink s, upb_selector_t sel)
Definition: php/ext/google/protobuf/upb.h:5823
upb_textprinter::indent_depth_
int indent_depth_
Definition: php/ext/google/protobuf/upb.c:8388
upb_handlers_addcleanup
bool upb_handlers_addcleanup(upb_handlers *h, void *p, upb_handlerfree *func)
Definition: php/ext/google/protobuf/upb.c:3545
upb_json_parser::parser_top
int parser_top
Definition: php/ext/google/protobuf/upb.c:9024
upb_handlers_setint32
bool upb_handlers_setint32(upb_handlers *h, const upb_fielddef *f, upb_int32_handlerfunc *func, const upb_handlerattr *attr)
upb_msgfactory::symtab
const upb_symtab * symtab
Definition: php/ext/google/protobuf/upb.c:4544
_upb_tabent::next
const struct _upb_tabent * next
Definition: php/ext/google/protobuf/upb.h:2790
upb_msgdef::file
const upb_filedef * file
Definition: php/ext/google/protobuf/upb.c:1147
upb_put_tag
static bool upb_put_tag(upb_encstate *e, int field_number, int wire_type)
Definition: php/ext/google/protobuf/upb.c:3004
UPB_WIRE_TYPE_32BIT
@ UPB_WIRE_TYPE_32BIT
Definition: php/ext/google/protobuf/upb.h:404
i
int i
Definition: gmock-matchers_test.cc:764
upb_json_parser::arena
upb_arena * arena
Definition: php/ext/google/protobuf/upb.c:9010
upb_json_printercache::preserve_fieldnames
bool preserve_fieldnames
Definition: php/ext/google/protobuf/upb.c:12278
google_protobuf_ServiceDescriptorProto__fields
static const upb_msglayout_field google_protobuf_ServiceDescriptorProto__fields[3]
Definition: php/ext/google/protobuf/upb.c:240
decl_counts
Definition: php/ext/google/protobuf/upb.c:2431
start_text
static void start_text(upb_json_parser *p, const char *ptr)
Definition: php/ext/google/protobuf/upb.c:9642
end_month
static bool end_month(upb_json_parser *p, const char *ptr)
Definition: php/ext/google/protobuf/upb.c:10342
upb_realloc
UPB_INLINE void * upb_realloc(upb_alloc *alloc, void *ptr, size_t oldsize, size_t size)
Definition: php/ext/google/protobuf/upb.h:254
google_protobuf_FileDescriptorSet_submsgs
static const upb_msglayout *const google_protobuf_FileDescriptorSet_submsgs[1]
Definition: php/ext/google/protobuf/upb.c:36
upb_sink_reset
UPB_INLINE void upb_sink_reset(upb_sink *s, const upb_handlers *h, void *c)
Definition: php/ext/google/protobuf/upb.h:5699
upb_oneof_next
void upb_oneof_next(upb_oneof_iter *iter)
Definition: php/ext/google/protobuf/upb.c:1915
upb_decframe::msg
char * msg
Definition: php/ext/google/protobuf/upb.c:543
end_hour
static bool end_hour(upb_json_parser *p, const char *ptr)
Definition: php/ext/google/protobuf/upb.c:10366
google_protobuf_MethodOptions__fields
static const upb_msglayout_field google_protobuf_MethodOptions__fields[3]
Definition: php/ext/google/protobuf/upb.c:405
upb_jsonparser_frame::mapfield
const upb_fielddef * mapfield
Definition: php/ext/google/protobuf/upb.c:8981
upb_json_parser
Definition: php/ext/google/protobuf/upb.c:9009
textprinter_endstr
static bool textprinter_endstr(void *closure, const void *handler_data)
Definition: php/ext/google/protobuf/upb.c:8575
upb_map::strtab
upb_strtable strtab
Definition: php/ext/google/protobuf/upb.c:4164
upb_fielddef_type
upb_fieldtype_t upb_fielddef_type(const upb_fielddef *f)
Definition: php/ext/google/protobuf/upb.c:1505
upb_msg_iter_field
upb_fielddef * upb_msg_iter_field(const upb_msg_field_iter *iter)
Definition: php/ext/google/protobuf/upb.c:1833
div_round_up
static size_t div_round_up(size_t n, size_t d)
Definition: php/ext/google/protobuf/upb.c:4361
upb_pb_encoder::arena
upb_arena * arena
Definition: php/ext/google/protobuf/upb.c:7893
upb_symtab_free
void upb_symtab_free(upb_symtab *s)
Definition: php/ext/google/protobuf/upb.c:2740
UPB_INLINE
#define UPB_INLINE
Definition: php/ext/google/protobuf/upb.h:87
upb_strtable_iter::index
size_t index
Definition: php/ext/google/protobuf/upb.h:3063
upb_sink
Definition: php/ext/google/protobuf/upb.h:5673
OP_SETDISPATCH
@ OP_SETDISPATCH
Definition: php/ext/google/protobuf/upb.h:6491
upb_inttable::array_count
size_t array_count
Definition: php/ext/google/protobuf/upb.h:2827
UPB_DESCRIPTOR_TYPE_MESSAGE
@ UPB_DESCRIPTOR_TYPE_MESSAGE
Definition: php/ext/google/protobuf/upb.h:447
upb_stringsink::handler
upb_byteshandler handler
Definition: php/ext/google/protobuf/upb.c:8880
google_protobuf_DescriptorProto_ReservedRange__fields
static const upb_msglayout_field google_protobuf_DescriptorProto_ReservedRange__fields[2]
Definition: php/ext/google/protobuf/upb.c:125
UPB_HANDLER_STRING
@ UPB_HANDLER_STRING
Definition: php/ext/google/protobuf/upb.h:4044
upb_msgdef_wellknowntype
upb_wellknowntype_t upb_msgdef_wellknowntype(const upb_msgdef *m)
Definition: php/ext/google/protobuf/upb.c:1813
upb_handlers_setstartsubmsg
bool upb_handlers_setstartsubmsg(upb_handlers *h, const upb_fielddef *f, upb_startfield_handlerfunc *func, const upb_handlerattr *attr)
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: php/ext/google/protobuf/upb.c:1785
upb_enum_done
bool upb_enum_done(upb_enum_iter *iter)
Definition: php/ext/google/protobuf/upb.c:1472
repeated_startstr_fieldmask
static void * repeated_startstr_fieldmask(void *closure, const void *handler_data, size_t size_hint)
Definition: php/ext/google/protobuf/upb.c:13013
str_tabent
static const upb_tabent * str_tabent(const upb_strtable_iter *i)
Definition: php/ext/google/protobuf/upb.c:5005
fields
static const upb_fielddef fields[107]
Definition: ruby/ext/google/protobuf_c/upb.c:7671
startseq
static void * startseq(void *closure, const void *handler_data)
Definition: php/ext/google/protobuf/upb.c:12632
upb_fielddef_defaultbool
bool upb_fielddef_defaultbool(const upb_fielddef *f)
Definition: php/ext/google/protobuf/upb.c:1648
upb_fielddef_getjsonname
size_t upb_fielddef_getjsonname(const upb_fielddef *f, char *buf, size_t len)
Definition: php/ext/google/protobuf/upb.c:1576
peekbytes
static UPB_FORCEINLINE size_t peekbytes(upb_pbdecoder *d, void *buf, size_t bytes)
Definition: php/ext/google/protobuf/upb.c:7115
google_protobuf_MessageOptions__fields
static const upb_msglayout_field google_protobuf_MessageOptions__fields[5]
Definition: php/ext/google/protobuf/upb.c:307
upb_arena::alloc
upb_alloc alloc
Definition: php/ext/google/protobuf/upb.c:5626
type
GLenum type
Definition: glcorearb.h:2695
upb_msgdef::oneof_count
int oneof_count
Definition: php/ext/google/protobuf/upb.c:1159
upb_json_parser::parser_stack
int parser_stack[UPB_JSON_MAX_DEPTH]
Definition: php/ext/google/protobuf/upb.c:9023
capture_suspend
static void capture_suspend(upb_json_parser *p, const char **ptr)
Definition: php/ext/google/protobuf/upb.c:9542
google_protobuf_FieldDescriptorProto_name
UPB_INLINE upb_strview google_protobuf_FieldDescriptorProto_name(const google_protobuf_FieldDescriptorProto *msg)
Definition: php/ext/google/protobuf/upb.h:1491
generate_delimfield
static void generate_delimfield(compiler *c, const upb_fielddef *f, upb_pbdecodermethod *method)
Definition: php/ext/google/protobuf/upb.c:6401
upb_oneof_iter_field
upb_fielddef * upb_oneof_iter_field(const upb_oneof_iter *iter)
Definition: php/ext/google/protobuf/upb.c:1923
google_protobuf_DescriptorProto__fields
static const upb_msglayout_field google_protobuf_DescriptorProto__fields[10]
Definition: php/ext/google/protobuf/upb.c:90
upb_filedef::phpprefix
const char * phpprefix
Definition: php/ext/google/protobuf/upb.c:1187
upb_arena_realloc
UPB_INLINE void * upb_arena_realloc(upb_arena *a, void *ptr, size_t oldsize, size_t size)
Definition: php/ext/google/protobuf/upb.h:325
OP_CHECKDELIM
@ OP_CHECKDELIM
Definition: php/ext/google/protobuf/upb.h:6478
upb_arena::cleanup_head
void * cleanup_head
Definition: php/ext/google/protobuf/upb.c:5640
upb_vdecode_max8_branch32
upb_decoderet upb_vdecode_max8_branch32(upb_decoderet r)
Definition: php/ext/google/protobuf/upb.c:8734
newcompiler
static compiler * newcompiler(mgroup *group, bool lazy)
Definition: php/ext/google/protobuf/upb.c:5892
upb_handlers_setdouble
bool upb_handlers_setdouble(upb_handlers *h, const upb_fielddef *f, upb_double_handlerfunc *func, const upb_handlerattr *attr)
upb_decode_submsg
static bool upb_decode_submsg(upb_decstate *d, upb_decframe *frame, const char *limit, const upb_msglayout_field *field, int group_number)
Definition: php/ext/google/protobuf/upb.c:763
upb_oneofdef::ntof
upb_strtable ntof
Definition: php/ext/google/protobuf/upb.c:1180
symtab_addctx::symtab
const upb_symtab * symtab
Definition: php/ext/google/protobuf/upb.c:1942
freegroup
static void freegroup(mgroup *g)
Definition: php/ext/google/protobuf/upb.c:5856
upb_inttable_push2
bool upb_inttable_push2(upb_inttable *t, upb_value val, upb_alloc *a)
Definition: php/ext/google/protobuf/upb.c:5211
upb_msglayout
Definition: php/ext/google/protobuf/upb.h:523
int_arrent
static upb_tabval int_arrent(const upb_inttable_iter *i)
Definition: php/ext/google/protobuf/upb.c:5304
upb_oneof_begin
void upb_oneof_begin(upb_oneof_iter *iter, const upb_oneofdef *o)
Definition: php/ext/google/protobuf/upb.c:1911
UPB_UNREACHABLE
#define UPB_UNREACHABLE()
Definition: php/ext/google/protobuf/upb.h:158
upb_msgval
Definition: php/ext/google/protobuf/upb.h:565
upb_pbdecoder_create
upb_pbdecoder * upb_pbdecoder_create(upb_arena *a, const upb_pbdecodermethod *m, upb_sink sink, upb_status *status)
Definition: php/ext/google/protobuf/upb.c:7717
find_submethod
static upb_pbdecodermethod * find_submethod(const compiler *c, const upb_pbdecodermethod *method, const upb_fielddef *f)
Definition: php/ext/google/protobuf/upb.c:6296
upb_jsonparser_any_frame::after_type_url_start
const char * after_type_url_start
Definition: php/ext/google/protobuf/upb.c:8947
UPB_DESCRIPTOR_TYPE_SINT32
@ UPB_DESCRIPTOR_TYPE_SINT32
Definition: php/ext/google/protobuf/upb.h:453
op_has_longofs
bool op_has_longofs(int32_t instruction)
Definition: php/ext/google/protobuf/upb.c:5921
upb_mapiter_done
bool upb_mapiter_done(const upb_mapiter *i)
Definition: php/ext/google/protobuf/upb.c:4329
json_parser_any_frame_set_after_type_url_start_once
static void json_parser_any_frame_set_after_type_url_start_once(upb_jsonparser_any_frame *frame, const char *ptr)
Definition: php/ext/google/protobuf/upb.c:9151
putop
static void putop(compiler *c, int op,...)
Definition: php/ext/google/protobuf/upb.c:6018
mapkey_str
static size_t mapkey_str(void *closure, const void *handler_data, const char *str, size_t len, const upb_bufhandle *handle)
Definition: php/ext/google/protobuf/upb.c:12796
is_pow2
bool is_pow2(uint64_t v)
Definition: php/ext/google/protobuf/upb.c:4665
makefullname
static const char * makefullname(const symtab_addctx *ctx, const char *prefix, upb_strview name)
Definition: php/ext/google/protobuf/upb.c:1962
upb_inttable::array_size
size_t array_size
Definition: php/ext/google/protobuf/upb.h:2826
upb_filedef::deps
const upb_filedef ** deps
Definition: php/ext/google/protobuf/upb.c:1191
upb_check_alloc
static void upb_check_alloc(upb_table *t, upb_alloc *a)
Definition: php/ext/google/protobuf/upb.c:4652
upb_encstate::alloc
upb_alloc * alloc
Definition: php/ext/google/protobuf/upb.c:2912
print_data
static void print_data(upb_json_printer *p, const char *buf, unsigned int len)
Definition: php/ext/google/protobuf/upb.c:12313
UPB_WELLKNOWN_FLOATVALUE
@ UPB_WELLKNOWN_FLOATVALUE
Definition: php/ext/google/protobuf/upb.h:3156
printer_startmsg_fieldmask
static bool printer_startmsg_fieldmask(void *closure, const void *handler_data)
Definition: php/ext/google/protobuf/upb.c:13229
decoder_pop
static void decoder_pop(upb_pbdecoder *d)
Definition: php/ext/google/protobuf/upb.c:7247
len
int len
Definition: php/ext/google/protobuf/map.c:206
upb_textprinter::input_
upb_sink input_
Definition: php/ext/google/protobuf/upb.c:8386
setofs
static void setofs(uint32_t *instruction, int32_t ofs)
Definition: php/ext/google/protobuf/upb.c:5947
upb_fielddef_msgsubdef
const upb_msgdef * upb_fielddef_msgsubdef(const upb_fielddef *f)
Definition: php/ext/google/protobuf/upb.c:1677
upb_enumdef::iton
upb_inttable iton
Definition: php/ext/google/protobuf/upb.c:1172
upb_ctype_t
upb_ctype_t
Definition: php/ext/google/protobuf/upb.h:2642
UPB_DURATION_NANOS
#define UPB_DURATION_NANOS
Definition: php/ext/google/protobuf/upb.h:3486
google::protobuf.internal::k1
static int k1
Definition: src/google/protobuf/map_test.cc:326
upb_arena_alloc
UPB_INLINE upb_alloc * upb_arena_alloc(upb_arena *a)
Definition: php/ext/google/protobuf/upb.h:317
CHECK_RETURN
#define CHECK_RETURN(x)
Definition: php/ext/google/protobuf/upb.h:6733
end_subobject
static void end_subobject(upb_json_parser *p)
Definition: php/ext/google/protobuf/upb.c:10909
upb_msg_field_iter_setdone
void upb_msg_field_iter_setdone(upb_msg_field_iter *iter)
Definition: php/ext/google/protobuf/upb.c:1837
upb_symtab_addfile
const upb_filedef * upb_symtab_addfile(upb_symtab *s, const google_protobuf_FileDescriptorProto *file_proto, upb_status *status)
Definition: php/ext/google/protobuf/upb.c:2790
upb_msg_field_next
void upb_msg_field_next(upb_msg_field_iter *iter)
Definition: php/ext/google/protobuf/upb.c:1827
google_protobuf_EnumValueDescriptorProto_msginit
const upb_msglayout google_protobuf_EnumValueDescriptorProto_msginit
Definition: php/ext/google/protobuf/upb.c:229
startseq_fieldmask
static void * startseq_fieldmask(void *closure, const void *handler_data)
Definition: php/ext/google/protobuf/upb.c:12998
json_parser_any_frame_free
static void json_parser_any_frame_free(upb_jsonparser_any_frame *frame)
Definition: php/ext/google/protobuf/upb.c:9116
google_protobuf_FileOptions__fields
static const upb_msglayout_field google_protobuf_FileOptions__fields[19]
Definition: php/ext/google/protobuf/upb.c:275
set_delim_end
static void set_delim_end(upb_pbdecoder *d)
Definition: php/ext/google/protobuf/upb.c:6877
v
const GLdouble * v
Definition: glcorearb.h:3106
upb_enumdef
Definition: php/ext/google/protobuf/upb.c:1168
upb_strtable_uninit2
void upb_strtable_uninit2(upb_strtable *t, upb_alloc *a)
Definition: php/ext/google/protobuf/upb.c:4932
google_protobuf_SourceCodeInfo_submsgs
static const upb_msglayout *const google_protobuf_SourceCodeInfo_submsgs[1]
Definition: php/ext/google/protobuf/upb.c:448
google_protobuf_EnumDescriptorProto_value
const UPB_INLINE google_protobuf_EnumValueDescriptorProto *const * google_protobuf_EnumDescriptorProto_value(const google_protobuf_EnumDescriptorProto *msg, size_t *len)
Definition: php/ext/google/protobuf/upb.h:1616
upb_msg_setscalarhandler
bool upb_msg_setscalarhandler(upb_handlers *h, const upb_fielddef *f, size_t offset, int32_t hasbit)
Definition: php/ext/google/protobuf/upb.c:3774
upb_bytessink_reset
UPB_INLINE void upb_bytessink_reset(upb_bytessink *s, const upb_byteshandler *h, void *closure)
Definition: php/ext/google/protobuf/upb.h:6036
upb_fielddef::number_
uint32_t number_
Definition: php/ext/google/protobuf/upb.c:1136
upb_handlers_new
static upb_handlers * upb_handlers_new(const upb_msgdef *md, upb_handlercache *cache, upb_arena *arena)
Definition: php/ext/google/protobuf/upb.c:3432
upb_sink_startsubmsg
UPB_INLINE bool upb_sink_startsubmsg(upb_sink s, upb_selector_t sel, upb_sink *sub)
Definition: php/ext/google/protobuf/upb.h:5805
upb_json_parsermethod::input_handler_
upb_byteshandler input_handler_
Definition: php/ext/google/protobuf/upb.c:9070
UPB_WELLKNOWN_LISTVALUE
@ UPB_WELLKNOWN_LISTVALUE
Definition: php/ext/google/protobuf/upb.h:3166
upb_msg_fielddefsize
static uint8_t upb_msg_fielddefsize(const upb_fielddef *f)
Definition: php/ext/google/protobuf/upb.c:4387
upb_strtable::t
upb_table t
Definition: php/ext/google/protobuf/upb.h:2820
upb_inttable_uninit2
void upb_inttable_uninit2(upb_inttable *t, upb_alloc *a)
Definition: php/ext/google/protobuf/upb.c:5128
upb_jsonparser_frame::is_map
bool is_map
Definition: php/ext/google/protobuf/upb.c:8969
UPB_DESCRIPTOR_TYPE_INT32
@ UPB_DESCRIPTOR_TYPE_INT32
Definition: php/ext/google/protobuf/upb.h:441
flt2uint32
static uint32_t flt2uint32(float d)
Definition: php/ext/google/protobuf/upb.c:8142
upb_mapiter::iter
upb_strtable_iter iter
Definition: php/ext/google/protobuf/upb.c:4297
upb_jsonparser_any_frame::sink
upb_sink sink
Definition: php/ext/google/protobuf/upb.c:8939
upb_global_allocfunc
static void * upb_global_allocfunc(upb_alloc *alloc, void *ptr, size_t oldsize, size_t size)
Definition: php/ext/google/protobuf/upb.c:5600
UPB_LABEL_REPEATED
@ UPB_LABEL_REPEATED
Definition: php/ext/google/protobuf/upb.h:432
start_any_object
static void start_any_object(upb_json_parser *p, const char *ptr)
Definition: php/ext/google/protobuf/upb.c:11045
lookupkey_t::str
const char * str
Definition: php/ext/google/protobuf/upb.c:4700
upb_setoneofcase
static void upb_setoneofcase(upb_decframe *frame, const upb_msglayout_field *field)
Definition: php/ext/google/protobuf/upb.c:731
upb_msgdef_numfields
int upb_msgdef_numfields(const upb_msgdef *m)
Definition: php/ext/google/protobuf/upb.c:1799
commit
static bool commit(upb_pb_encoder *e)
Definition: php/ext/google/protobuf/upb.c:7976
lookupkey_t::len
size_t len
Definition: php/ext/google/protobuf/upb.c:4701
upb_symtab_lookupmsg
const upb_msgdef * upb_symtab_lookupmsg(const upb_symtab *s, const char *sym)
Definition: php/ext/google/protobuf/upb.c:2765
upb_pb_encoder_segment::msglen
uint32_t msglen
Definition: php/ext/google/protobuf/upb.c:7888
upb_handlers_selectorbaseoffset
uint32_t upb_handlers_selectorbaseoffset(const upb_fielddef *f)
Definition: php/ext/google/protobuf/upb.c:3627
upb_zzenc_64
UPB_INLINE uint64_t upb_zzenc_64(int64_t n)
Definition: php/ext/google/protobuf/upb.h:6782
google_protobuf_UninterpretedOption__fields
static const upb_msglayout_field google_protobuf_UninterpretedOption__fields[7]
Definition: php/ext/google/protobuf/upb.c:421
upb_inttable_replace
bool upb_inttable_replace(upb_inttable *t, uintptr_t key, upb_value val)
Definition: php/ext/google/protobuf/upb.c:5183
endmsg
static bool endmsg(void *c, const void *hd, upb_status *status)
Definition: php/ext/google/protobuf/upb.c:8160
UPB_HANDLER_UINT64
@ UPB_HANDLER_UINT64
Definition: php/ext/google/protobuf/upb.h:4039
upb_json_parsermethod::name_table
upb_strtable name_table
Definition: php/ext/google/protobuf/upb.c:9073
upb_jsonparser_any_frame::parser_codecache
upb_json_codecache * parser_codecache
Definition: php/ext/google/protobuf/upb.c:8938
upb_fielddef_hassubdef
bool upb_fielddef_hassubdef(const upb_fielddef *f)
Definition: php/ext/google/protobuf/upb.c:1709
inf
const char inf[]
Definition: php/ext/google/protobuf/upb.c:12404
upb_status::msg
char msg[UPB_STATUS_MAX_MESSAGE]
Definition: php/ext/google/protobuf/upb.h:172
UPB_TIMESTAMP_SECONDS
#define UPB_TIMESTAMP_SECONDS
Definition: php/ext/google/protobuf/upb.h:3489
_upb_tabent
Definition: php/ext/google/protobuf/upb.h:2782
upb_fielddef_checktype
bool upb_fielddef_checktype(int32_t type)
Definition: php/ext/google/protobuf/upb.c:1724
upb_table
Definition: php/ext/google/protobuf/upb.h:2793
upb_inttable_next
void upb_inttable_next(upb_inttable_iter *iter)
Definition: php/ext/google/protobuf/upb.c:5316
google_protobuf_FieldDescriptorProto_has_name
UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_name(const google_protobuf_FieldDescriptorProto *msg)
Definition: php/ext/google/protobuf/upb.h:1490
upb_inttable_sizedinit
bool upb_inttable_sizedinit(upb_inttable *t, upb_ctype_t ctype, size_t asize, int hsize_lg2, upb_alloc *a)
Definition: php/ext/google/protobuf/upb.c:5104
google_protobuf_FileOptions_msginit
const upb_msglayout google_protobuf_FileOptions_msginit
Definition: php/ext/google/protobuf/upb.c:297
upb_handlers_callback
void upb_handlers_callback(const void *closure, upb_handlers *h)
Definition: php/ext/google/protobuf/upb.h:4597
value_type
zend_class_entry * value_type
Definition: php/ext/google/protobuf/message.c:2546
start_timestamp_zone
static void start_timestamp_zone(upb_json_parser *p, const char *ptr)
Definition: php/ext/google/protobuf/upb.c:10459
newstrpc
strpc * newstrpc(upb_handlers *h, const upb_fielddef *f, bool preserve_fieldnames)
Definition: php/ext/google/protobuf/upb.c:12282
ch
char ch
Definition: gmock-matchers_test.cc:3871
upb_textprinter_input
upb_sink upb_textprinter_input(upb_textprinter *p)
Definition: php/ext/google/protobuf/upb.c:8700
upb_msg_internalsize
static int upb_msg_internalsize(const upb_msglayout *l)
Definition: php/ext/google/protobuf/upb.c:3968
google_protobuf_OneofOptions_msginit
const upb_msglayout google_protobuf_OneofOptions_msginit
Definition: php/ext/google/protobuf/upb.c:349
benchmarks.python.py_benchmark.dest
dest
Definition: py_benchmark.py:13
MurmurHash2
uint32_t MurmurHash2(const void *key, size_t len, uint32_t seed)
Definition: php/ext/google/protobuf/upb.c:5430
UPB_HANDLER_BOOL
@ UPB_HANDLER_BOOL
Definition: php/ext/google/protobuf/upb.h:4042
upb_zzencode_32
static uint32_t upb_zzencode_32(int32_t n)
Definition: php/ext/google/protobuf/upb.c:2908
UPB_CTYPE_CONSTPTR
@ UPB_CTYPE_CONSTPTR
Definition: php/ext/google/protobuf/upb.h:2650
size
GLsizeiptr size
Definition: glcorearb.h:2943
UPB_STRING_SELECTOR
#define UPB_STRING_SELECTOR
Definition: php/ext/google/protobuf/upb.h:4072
upb_enumdef_default
int32_t upb_enumdef_default(const upb_enumdef *e)
Definition: php/ext/google/protobuf/upb.c:1457
upb_msgdef_isnumberwrapper
bool upb_msgdef_isnumberwrapper(const upb_msgdef *m)
Definition: php/ext/google/protobuf/upb.c:1817
google_protobuf_UninterpretedOption_msginit
const upb_msglayout google_protobuf_UninterpretedOption_msginit
Definition: php/ext/google/protobuf/upb.c:431
mapkey_endstr
static bool mapkey_endstr(void *closure, const void *handler_data)
Definition: php/ext/google/protobuf/upb.c:12803
upb_msg_getinternalwithext
static upb_msg_internal_withext * upb_msg_getinternalwithext(upb_msg *msg, const upb_msglayout *l)
Definition: php/ext/google/protobuf/upb.c:3980
upb_arena::bytes_allocated
size_t bytes_allocated
Definition: php/ext/google/protobuf/upb.c:5632
UPB_DEFTYPE_ENUM
@ UPB_DEFTYPE_ENUM
Definition: php/ext/google/protobuf/upb.c:1211
google_protobuf_ExtensionRangeOptions_msginit
const upb_msglayout google_protobuf_ExtensionRangeOptions_msginit
Definition: php/ext/google/protobuf/upb.c:144
putstr
static size_t putstr(void *closure, const void *handler_data, const char *str, size_t len, const upb_bufhandle *handle)
Definition: php/ext/google/protobuf/upb.c:12666
print_enum_symbolic_name
static void print_enum_symbolic_name(upb_json_printer *p, const upb_enumdef *def, int32_t val)
Definition: php/ext/google/protobuf/upb.c:12555
checked_add
static bool checked_add(size_t a, size_t b, size_t *c)
Definition: php/ext/google/protobuf/upb.c:9201
google_protobuf_ServiceDescriptorProto_submsgs
static const upb_msglayout *const google_protobuf_ServiceDescriptorProto_submsgs[2]
Definition: php/ext/google/protobuf/upb.c:235
startmsg
static bool startmsg(void *c, const void *hd)
Definition: php/ext/google/protobuf/upb.c:8151
WRAPPER_SETHANDLERS
#define WRAPPER_SETHANDLERS(wrapper, type, putmethod)
Definition: php/ext/google/protobuf/upb.c:13392
_json_trans_actions
static const unsigned char _json_trans_actions[]
Definition: php/ext/google/protobuf/upb.c:11571
halt
static opcode halt
Definition: php/ext/google/protobuf/upb.c:6761
upb_fielddef::is_extension_
bool is_extension_
Definition: php/ext/google/protobuf/upb.c:1139
upb_msgfactory_symtab
const upb_symtab * upb_msgfactory_symtab(const upb_msgfactory *f)
Definition: php/ext/google/protobuf/upb.c:4569
upb_bytessink_putbuf
UPB_INLINE size_t upb_bytessink_putbuf(upb_bytessink s, void *subc, const char *buf, size_t size, const upb_bufhandle *handle)
Definition: php/ext/google/protobuf/upb.h:6057
google_protobuf_EnumDescriptorProto_name
UPB_INLINE upb_strview google_protobuf_EnumDescriptorProto_name(const google_protobuf_EnumDescriptorProto *msg)
Definition: php/ext/google/protobuf/upb.h:1615
upb_byteshandler_setstring
bool upb_byteshandler_setstring(upb_byteshandler *h, upb_string_handlerfunc *func, void *d)
Definition: php/ext/google/protobuf/upb.c:3734
upb_enum_iter_name
const char * upb_enum_iter_name(upb_enum_iter *iter)
Definition: php/ext/google/protobuf/upb.c:1490
upb_decstate::ptr
const char * ptr
Definition: php/ext/google/protobuf/upb.c:534
upb_pbdecoder_frame::dispatch
upb_inttable * dispatch
Definition: php/ext/google/protobuf/upb.h:6571
upb_msg_field_done
bool upb_msg_field_done(const upb_msg_field_iter *iter)
Definition: php/ext/google/protobuf/upb.c:1829
upb_inttable_lookupptr
bool upb_inttable_lookupptr(const upb_inttable *t, const void *key, upb_value *v)
Definition: php/ext/google/protobuf/upb.c:5229
unpack_def
static const void * unpack_def(upb_value v, upb_deftype_t type)
Definition: php/ext/google/protobuf/upb.c:1216
upb_json_printer::depth_
int depth_
Definition: php/ext/google/protobuf/upb.c:12246
putpush
static void putpush(compiler *c, const upb_fielddef *f)
Definition: php/ext/google/protobuf/upb.c:6282
upb_pbcodecache_setallowjit
void upb_pbcodecache_setallowjit(upb_pbcodecache *c, bool allow)
Definition: php/ext/google/protobuf/upb.c:6700
google_protobuf_FileDescriptorProto_msginit
const upb_msglayout google_protobuf_FileDescriptorProto_msginit
Definition: php/ext/google/protobuf/upb.c:74
stringsink_start
static void * stringsink_start(void *_sink, const void *hd, size_t size_hint)
Definition: php/ext/google/protobuf/upb.c:8887
func
GLenum func
Definition: glcorearb.h:3052
end_duration_base
static bool end_duration_base(upb_json_parser *p, const char *ptr)
Definition: php/ext/google/protobuf/upb.c:10219
upb_msgdef_itof
const upb_fielddef * upb_msgdef_itof(const upb_msgdef *m, uint32_t i)
Definition: php/ext/google/protobuf/upb.c:1757
CHECK_RETURN_TOP
#define CHECK_RETURN_TOP(x)
Definition: php/ext/google/protobuf/upb.c:11343
upb_getentry
static const upb_tabent * upb_getentry(const upb_table *t, uint32_t hash)
Definition: php/ext/google/protobuf/upb.h:2861
upb_handlerattr::return_closure_type
const void * return_closure_type
Definition: php/ext/google/protobuf/upb.h:4088
printer_startmsg_noframe
static bool printer_startmsg_noframe(void *closure, const void *handler_data)
Definition: php/ext/google/protobuf/upb.c:13209
UPB_CTYPE_PTR
@ UPB_CTYPE_PTR
Definition: php/ext/google/protobuf/upb.h:2649
printer_sethandlers_value
void printer_sethandlers_value(const void *closure, upb_handlers *h)
Definition: php/ext/google/protobuf/upb.c:13353
upb_handlers_gethandler
upb_func * upb_handlers_gethandler(const upb_handlers *h, upb_selector_t s, const void **handler_data)
Definition: php/ext/google/protobuf/upb.c:3520
upb_array::arena
upb_arena * arena
Definition: php/ext/google/protobuf/upb.h:474
strpc
Definition: php/ext/google/protobuf/upb.c:12266
json_en_main
static const int json_en_main
Definition: php/ext/google/protobuf/upb.c:11620
upb_enumdef_ntoi
bool upb_enumdef_ntoi(const upb_enumdef *def, const char *name, size_t len, int32_t *num)
Definition: php/ext/google/protobuf/upb.c:1474
upb_decframe
Definition: php/ext/google/protobuf/upb.c:538
start_fieldmask_path
static bool start_fieldmask_path(upb_json_parser *p)
Definition: php/ext/google/protobuf/upb.c:10567
upb_arena::block_head
void * block_head
Definition: php/ext/google/protobuf/upb.c:5637
stringsink_string
static size_t stringsink_string(void *_sink, const void *hd, const char *ptr, size_t len, const upb_bufhandle *handle)
Definition: php/ext/google/protobuf/upb.c:8895
upb_wellknowntype_t
upb_wellknowntype_t
Definition: php/ext/google/protobuf/upb.h:3148
upb_json_parser::accumulated_len
size_t accumulated_len
Definition: php/ext/google/protobuf/upb.c:9031
m
const upb_json_parsermethod * m
Definition: ruby/ext/google/protobuf_c/upb.h:10501
T
#define T(type, ctype, convert, encode)
Definition: php/ext/google/protobuf/upb.c:8206
parse_number
static bool parse_number(upb_json_parser *p, bool is_quoted)
Definition: php/ext/google/protobuf/upb.c:9838
init_frame
static void init_frame(upb_jsonparser_frame *frame)
Definition: php/ext/google/protobuf/upb.c:8996
parse_mapentry_key
static bool parse_mapentry_key(upb_json_parser *p)
Definition: php/ext/google/protobuf/upb.c:10627
google::protobuf.internal.wire_format.UINT64_MAX
tuple UINT64_MAX
Definition: wire_format.py:63
upb_strtable_begin
void upb_strtable_begin(upb_strtable_iter *i, const upb_strtable *t)
Definition: php/ext/google/protobuf/upb.c:5009
end_timestamp_fraction
static bool end_timestamp_fraction(upb_json_parser *p, const char *ptr)
Definition: php/ext/google/protobuf/upb.c:10406
UPB_DESCRIPTOR_TYPE_ENUM
@ UPB_DESCRIPTOR_TYPE_ENUM
Definition: php/ext/google/protobuf/upb.h:450
upb_enum_begin
void upb_enum_begin(upb_enum_iter *i, const upb_enumdef *e)
Definition: php/ext/google/protobuf/upb.c:1466
putseconds
static bool putseconds(void *closure, const void *handler_data, int64_t seconds)
Definition: php/ext/google/protobuf/upb.c:12952
upb_decode_delimitedfield
static bool upb_decode_delimitedfield(upb_decstate *d, upb_decframe *frame, const char *field_start, const upb_msglayout_field *field)
Definition: php/ext/google/protobuf/upb.c:971
get_encoded_tag
static uint64_t get_encoded_tag(const upb_fielddef *f, int wire_type)
Definition: php/ext/google/protobuf/upb.c:6219
endseq_fieldmask
static bool endseq_fieldmask(void *closure, const void *handler_data)
Definition: php/ext/google/protobuf/upb.c:13006
CHK
#define CHK(x)
Definition: php/ext/google/protobuf/upb.c:12473
google_protobuf_EnumValueOptions__fields
static const upb_msglayout_field google_protobuf_EnumValueOptions__fields[2]
Definition: php/ext/google/protobuf/upb.c:375
google_protobuf_MethodOptions_submsgs
static const upb_msglayout *const google_protobuf_MethodOptions_submsgs[1]
Definition: php/ext/google/protobuf/upb.c:401
upb_decframe::group_number
int32_t group_number
Definition: php/ext/google/protobuf/upb.c:540
r
GLboolean r
Definition: glcorearb.h:3228
instruction_len
static int instruction_len(uint32_t instr)
Definition: php/ext/google/protobuf/upb.c:5912
upb_startstr_handlerfunc
void * upb_startstr_handlerfunc(void *c, const void *hd, size_t size_hint)
Definition: php/ext/google/protobuf/upb.h:4141
google_protobuf_DescriptorProto_name
UPB_INLINE upb_strview google_protobuf_DescriptorProto_name(const google_protobuf_DescriptorProto *msg)
Definition: php/ext/google/protobuf/upb.h:1240
UPB_TYPE_BYTES
@ UPB_TYPE_BYTES
Definition: php/ext/google/protobuf/upb.h:420
start_any_member
static void start_any_member(upb_json_parser *p, const char *ptr)
Definition: php/ext/google/protobuf/upb.c:10817
seterr
static void seterr(upb_pbdecoder *d, const char *msg)
Definition: php/ext/google/protobuf/upb.c:6825
DEREF
#define DEREF(msg, ofs, type)
Definition: php/ext/google/protobuf/upb.c:3946
UPB_HANDLER_ENDSUBMSG
@ UPB_HANDLER_ENDSUBMSG
Definition: php/ext/google/protobuf/upb.h:4047
upb_decframe::limit
const char * limit
Definition: php/ext/google/protobuf/upb.c:539
upb_inthash
UPB_INLINE uint32_t upb_inthash(uintptr_t key)
Definition: php/ext/google/protobuf/upb.h:2857
end_hex
static bool end_hex(upb_json_parser *p)
Definition: php/ext/google/protobuf/upb.c:9614
upb_msgval_makestr
UPB_INLINE upb_msgval upb_msgval_makestr(const char *data, size_t size)
Definition: php/ext/google/protobuf/upb.h:608
parser_putbool
static bool parser_putbool(upb_json_parser *p, bool val)
Definition: php/ext/google/protobuf/upb.c:9860
upb_fielddef_checklabel
bool upb_fielddef_checklabel(int32_t label)
Definition: php/ext/google/protobuf/upb.c:1723
UPB_DESCRIPTOR_TYPE_SINT64
@ UPB_DESCRIPTOR_TYPE_SINT64
Definition: php/ext/google/protobuf/upb.h:454
start_number
static bool start_number(upb_json_parser *p, const char *ptr)
Definition: php/ext/google/protobuf/upb.c:9650
upb_put_varint
static bool upb_put_varint(upb_encstate *e, uint64_t val)
Definition: php/ext/google/protobuf/upb.c:2966
upb_inttable_insert
UPB_INLINE bool upb_inttable_insert(upb_inttable *t, uintptr_t key, upb_value val)
Definition: php/ext/google/protobuf/upb.h:2917
textprinter_startmsg
static bool textprinter_startmsg(void *c, const void *hd)
Definition: php/ext/google/protobuf/upb.c:8491
dst
GLenum GLenum dst
Definition: glcorearb.h:3364
upb_json_parser::handle
const upb_bufhandle * handle
Definition: php/ext/google/protobuf/upb.c:9027
upb_handlers::top_closure_type
const void * top_closure_type
Definition: php/ext/google/protobuf/upb.c:3273
printer_sethandlers_any
void printer_sethandlers_any(const void *closure, upb_handlers *h)
Definition: php/ext/google/protobuf/upb.c:13261
upb_map_set
bool upb_map_set(upb_map *map, upb_msgval key, upb_msgval val, upb_msgval *removed)
Definition: php/ext/google/protobuf/upb.c:4265
upb_inttable_compact
UPB_INLINE void upb_inttable_compact(upb_inttable *t)
Definition: php/ext/google/protobuf/upb.h:2993
upb_stringsink::ptr
char * ptr
Definition: php/ext/google/protobuf/upb.c:8882
upb_bytessink_end
UPB_INLINE bool upb_bytessink_end(upb_bytessink s)
Definition: php/ext/google/protobuf/upb.h:6070
is_number_wrapper_object
static bool is_number_wrapper_object(upb_json_parser *p)
Definition: php/ext/google/protobuf/upb.c:11315
upb_map_valuetype
upb_fieldtype_t upb_map_valuetype(const upb_map *map)
Definition: php/ext/google/protobuf/upb.c:4246
upb_msg_inoneof
static bool upb_msg_inoneof(const upb_msglayout_field *field)
Definition: php/ext/google/protobuf/upb.c:4011
upb_fielddef_number
uint32_t upb_fielddef_number(const upb_fielddef *f)
Definition: php/ext/google/protobuf/upb.c:1552
align_up_max
static size_t align_up_max(size_t size)
Definition: php/ext/google/protobuf/upb.c:5619
first
GLint first
Definition: glcorearb.h:2830
upb_encstate::ptr
char * ptr
Definition: php/ext/google/protobuf/upb.c:2913
VALUE_STRINGVALUE
@ VALUE_STRINGVALUE
Definition: php/ext/google/protobuf/upb.c:8819
upb_json_parser::input_
upb_bytessink input_
Definition: php/ext/google/protobuf/upb.c:9012
multipart_end
static void multipart_end(upb_json_parser *p)
Definition: php/ext/google/protobuf/upb.c:9510
upb_pbdecodermethodopts_setlazy
void upb_pbdecodermethodopts_setlazy(upb_pbcodecache *c, bool lazy)
Definition: php/ext/google/protobuf/upb.c:6705
upb_decode_varint32
static bool upb_decode_varint32(const char **ptr, const char *limit, uint32_t *val)
Definition: php/ext/google/protobuf/upb.c:574
putstr_nokey
static size_t putstr_nokey(void *closure, const void *handler_data, const char *str, size_t len, const upb_bufhandle *handle)
Definition: php/ext/google/protobuf/upb.c:12977
putchecktag
static void putchecktag(compiler *c, const upb_fielddef *f, int wire_type, int dest)
Definition: php/ext/google/protobuf/upb.c:6227
upb_msg_handlerdata::hasbit
int32_t hasbit
Definition: php/ext/google/protobuf/upb.c:3752
google_protobuf_SourceCodeInfo_Location_msginit
const upb_msglayout google_protobuf_SourceCodeInfo_Location_msginit
Definition: php/ext/google/protobuf/upb.c:470
upb_strtable
Definition: php/ext/google/protobuf/upb.h:2819
upb_put_fixed64
static bool upb_put_fixed64(upb_encstate *e, uint64_t val)
Definition: php/ext/google/protobuf/upb.c:2956
upb_fielddef::enumdef
const upb_enumdef * enumdef
Definition: php/ext/google/protobuf/upb.c:1133
does_number_wrapper_end
static bool does_number_wrapper_end(upb_json_parser *p)
Definition: php/ext/google/protobuf/upb.c:11311
does_number_wrapper_start
static bool does_number_wrapper_start(upb_json_parser *p)
Definition: php/ext/google/protobuf/upb.c:11305
upb_decode_prepareslot
static char * upb_decode_prepareslot(upb_decframe *frame, const upb_msglayout_field *field)
Definition: php/ext/google/protobuf/upb.c:737
upb_fielddef_label
upb_label_t upb_fielddef_label(const upb_fielddef *f)
Definition: php/ext/google/protobuf/upb.c:1548
upb_gmalloc
UPB_INLINE void * upb_gmalloc(size_t size)
Definition: php/ext/google/protobuf/upb.h:274
google_protobuf_DescriptorProto_ExtensionRange_msginit
const upb_msglayout google_protobuf_DescriptorProto_ExtensionRange_msginit
Definition: php/ext/google/protobuf/upb.c:119
upb_tabval::val
uint64_t val
Definition: php/ext/google/protobuf/upb.h:2774
newstr
static str_t * newstr(upb_alloc *alloc, const char *data, size_t len)
Definition: php/ext/google/protobuf/upb.c:1109
generate_msgfield
static void generate_msgfield(compiler *c, const upb_fielddef *f, upb_pbdecodermethod *method)
Definition: php/ext/google/protobuf/upb.c:6340
TYPE
#define TYPE(u, l)
Definition: php/ext/google/protobuf/upb.c:8510
google_protobuf_ExtensionRangeOptions_submsgs
static const upb_msglayout *const google_protobuf_ExtensionRangeOptions_submsgs[1]
Definition: php/ext/google/protobuf/upb.c:136
OP_PUSHLENDELIM
@ OP_PUSHLENDELIM
Definition: php/ext/google/protobuf/upb.h:6472
LABEL_ENDMSG
#define LABEL_ENDMSG
Definition: php/ext/google/protobuf/upb.c:6337
UPB_STRVIEW_ARGS
#define UPB_STRVIEW_ARGS(view)
Definition: php/ext/google/protobuf/upb.h:558
json_parser_any_frame_set_before_type_url_end
static void json_parser_any_frame_set_before_type_url_end(upb_jsonparser_any_frame *frame, const char *ptr)
Definition: php/ext/google/protobuf/upb.c:9143
start_hex
static void start_hex(upb_json_parser *p)
Definition: php/ext/google/protobuf/upb.c:9595
repeated_endstr
static bool repeated_endstr(void *closure, const void *handler_data)
Definition: php/ext/google/protobuf/upb.c:12780
UPB_JSON_PARSER_SIZE
#define UPB_JSON_PARSER_SIZE
Definition: php/ext/google/protobuf/upb.h:7100
upb_filedef_enumcount
int upb_filedef_enumcount(const upb_filedef *f)
Definition: php/ext/google/protobuf/upb.c:2724
UPB_TYPE_INT64
@ UPB_TYPE_INT64
Definition: php/ext/google/protobuf/upb.h:424
upb_fielddef::label_
upb_label_t label_
Definition: php/ext/google/protobuf/upb.c:1143
upb_inttable_uninit
UPB_INLINE void upb_inttable_uninit(upb_inttable *table)
Definition: php/ext/google/protobuf/upb.h:2884
OP_STARTSEQ
@ OP_STARTSEQ
Definition: php/ext/google/protobuf/upb.h:6463
repeated_str
static size_t repeated_str(void *closure, const void *handler_data, const char *str, size_t len, const upb_bufhandle *handle)
Definition: php/ext/google/protobuf/upb.c:12773
upb_put_float
static bool upb_put_float(upb_encstate *e, float d)
Definition: php/ext/google/protobuf/upb.c:2984
EPOCH_YEAR
#define EPOCH_YEAR
Definition: php/ext/google/protobuf/upb.c:10463
decode_fixed64
static UPB_FORCEINLINE int32_t decode_fixed64(upb_pbdecoder *d, uint64_t *u64)
Definition: php/ext/google/protobuf/upb.c:7198
cleanup_ent::cleanup
upb_cleanup_func * cleanup
Definition: php/ext/google/protobuf/upb.c:5653
upb_map::key_type
upb_fieldtype_t key_type
Definition: php/ext/google/protobuf/upb.c:4160
end_value_object
static void end_value_object(upb_json_parser *p)
Definition: php/ext/google/protobuf/upb.c:11251
dbl2uint64
static uint64_t dbl2uint64(double d)
Definition: php/ext/google/protobuf/upb.c:8136
upb_handlerattr
Definition: php/ext/google/protobuf/upb.h:4085
create_oneofdef
static bool create_oneofdef(const symtab_addctx *ctx, upb_msgdef *m, const google_protobuf_OneofDescriptorProto *oneof_proto)
Definition: php/ext/google/protobuf/upb.c:2040
upb_oneof_done
bool upb_oneof_done(upb_oneof_iter *iter)
Definition: php/ext/google/protobuf/upb.c:1919
data
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: glcorearb.h:2879
upb_stringsink::len
size_t len
Definition: php/ext/google/protobuf/upb.c:8883
google_protobuf_FieldDescriptorProto_has_extendee
UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_extendee(const google_protobuf_FieldDescriptorProto *msg)
Definition: php/ext/google/protobuf/upb.h:1492
upb_array_type
upb_fieldtype_t upb_array_type(const upb_array *arr)
Definition: php/ext/google/protobuf/upb.c:4117
upb_grealloc
UPB_INLINE void * upb_grealloc(void *ptr, size_t oldsize, size_t size)
Definition: php/ext/google/protobuf/upb.h:278
upb_decode_32bit
static bool upb_decode_32bit(const char **ptr, const char *limit, uint32_t *val)
Definition: php/ext/google/protobuf/upb.c:590
upb_json_parser::capture
const char * capture
Definition: php/ext/google/protobuf/upb.c:9040
compile_method
static void compile_method(compiler *c, upb_pbdecodermethod *method)
Definition: php/ext/google/protobuf/upb.c:6495
build_filedef
static bool build_filedef(const symtab_addctx *ctx, upb_filedef *file, const google_protobuf_FileDescriptorProto *file_proto)
Definition: php/ext/google/protobuf/upb.c:2543
upb_encode_varint
static size_t upb_encode_varint(uint64_t val, char *buf)
Definition: php/ext/google/protobuf/upb.c:2895
upb_msg_oneof_iter_setdone
void upb_msg_oneof_iter_setdone(upb_msg_oneof_iter *iter)
Definition: php/ext/google/protobuf/upb.c:1871
google_protobuf_FileOptions
struct google_protobuf_FileOptions google_protobuf_FileOptions
Definition: php/ext/google/protobuf/upb.h:944
__mon_yday
const unsigned short int __mon_yday[2][13]
Definition: php/ext/google/protobuf/upb.c:10470
SUBH
#define SUBH(h, selector)
Definition: php/ext/google/protobuf/upb.c:3291
upb_filedef::exts
const upb_fielddef * exts
Definition: php/ext/google/protobuf/upb.c:1194
upb_pbdecodermethod_desthandlers
const upb_handlers * upb_pbdecodermethod_desthandlers(const upb_pbdecodermethod *m)
Definition: php/ext/google/protobuf/upb.c:5839
upb_filedef::phpnamespace
const char * phpnamespace
Definition: php/ext/google/protobuf/upb.c:1188
upb_inttable_iter::index
size_t index
Definition: php/ext/google/protobuf/upb.h:3090
upb_inttable_lookup
bool upb_inttable_lookup(const upb_inttable *t, uintptr_t key, upb_value *v)
Definition: php/ext/google/protobuf/upb.c:5176
upb_json_printer_input
upb_sink upb_json_printer_input(upb_json_printer *p)
Definition: php/ext/google/protobuf/upb.c:13617
upb_toval
static upb_value upb_toval(upb_msgval val)
Definition: php/ext/google/protobuf/upb.c:3909
upb_bytessink
Definition: php/ext/google/protobuf/upb.h:6031
emptyent
static upb_tabent * emptyent(upb_table *t)
Definition: php/ext/google/protobuf/upb.c:4763
upb_msgval_read
static upb_msgval upb_msgval_read(const void *p, size_t ofs, uint8_t size)
Definition: php/ext/google/protobuf/upb.c:3861
upb_fielddef::index_
uint32_t index_
Definition: php/ext/google/protobuf/upb.c:1137
putnanos
static bool putnanos(void *closure, const void *handler_data, int32_t nanos)
Definition: php/ext/google/protobuf/upb.c:12960
upb_msg_getinternal_const
static const upb_msg_internal * upb_msg_getinternal_const(const upb_msg *msg)
Definition: php/ext/google/protobuf/upb.c:3976
nullz
static void nullz(upb_status *status)
Definition: php/ext/google/protobuf/upb.c:5558
findentry
static const upb_tabent * findentry(const upb_table *t, lookupkey_t key, uint32_t hash, eqlfunc_t *eql)
Definition: php/ext/google/protobuf/upb.c:4772
WRAPPER
#define WRAPPER(wellknowntype, name)
upb_json_parser::limit
upb_jsonparser_frame * limit
Definition: php/ext/google/protobuf/upb.c:9017
symtab_addctx
Definition: php/ext/google/protobuf/upb.c:1941
upb_table::alloc
upb_alloc * alloc
Definition: ruby/ext/google/protobuf_c/upb.h:1103
_json_key_offsets
static const short _json_key_offsets[]
Definition: php/ext/google/protobuf/upb.c:11390
upb_jsonparser_any_frame::before_type_url_start
const char * before_type_url_start
Definition: php/ext/google/protobuf/upb.c:8943
google_protobuf_ServiceOptions__fields
static const upb_msglayout_field google_protobuf_ServiceOptions__fields[2]
Definition: php/ext/google/protobuf/upb.c:390
VOIDPTR_AT
#define VOIDPTR_AT(msg, ofs)
Definition: php/ext/google/protobuf/upb.c:3852
google_protobuf_SourceCodeInfo_Location__fields
static const upb_msglayout_field google_protobuf_SourceCodeInfo_Location__fields[5]
Definition: php/ext/google/protobuf/upb.c:462
upb_status_errmsg
const char * upb_status_errmsg(const upb_status *status)
Definition: php/ext/google/protobuf/upb.c:5575
end_bool
static bool end_bool(upb_json_parser *p, bool val)
Definition: php/ext/google/protobuf/upb.c:9880
upb_pbdecodermethod_isnative
bool upb_pbdecodermethod_isnative(const upb_pbdecodermethod *m)
Definition: php/ext/google/protobuf/upb.c:5849
end_number_nontop
static bool end_number_nontop(upb_json_parser *p, const char *ptr)
Definition: php/ext/google/protobuf/upb.c:9678
upb_pbdecodermethod::dest_handlers_
const upb_handlers * dest_handlers_
Definition: php/ext/google/protobuf/upb.h:6592
upb_strview
Definition: php/ext/google/protobuf/upb.h:535
upb_find_field
static const upb_msglayout_field * upb_find_field(const upb_msglayout *l, uint32_t field_number)
Definition: php/ext/google/protobuf/upb.c:1003
val
GLuint GLfloat * val
Definition: glcorearb.h:3604
upb_msgdef_name
const char * upb_msgdef_name(const upb_msgdef *m)
Definition: php/ext/google/protobuf/upb.c:1741
start_fieldmask_path_text
static void start_fieldmask_path_text(upb_json_parser *p, const char *ptr)
Definition: php/ext/google/protobuf/upb.c:10559
CHECK_SUSPEND
#define CHECK_SUSPEND(x)
Definition: php/ext/google/protobuf/upb.c:6749
repeated_bytes
static size_t repeated_bytes(void *closure, const void *handler_data, const char *str, size_t len, const upb_bufhandle *handle)
Definition: php/ext/google/protobuf/upb.c:12825
json_parser_any_frame_has_value
static bool json_parser_any_frame_has_value(upb_jsonparser_any_frame *frame)
Definition: php/ext/google/protobuf/upb.c:9137
upb_symtab_addtotabs
static bool upb_symtab_addtotabs(upb_symtab *s, symtab_addctx *ctx, upb_status *status)
Definition: php/ext/google/protobuf/upb.c:2674
end_any_object
static bool end_any_object(upb_json_parser *p, const char *ptr)
Definition: php/ext/google/protobuf/upb.c:11051
upb_float_handlerfunc
bool upb_float_handlerfunc(void *c, const void *hd, float val)
Definition: php/ext/google/protobuf/upb.h:4138
upb_gstrdup
UPB_INLINE char * upb_gstrdup(const char *s)
Definition: php/ext/google/protobuf/upb.h:2677
upb_json_parser::symtab
const upb_symtab * symtab
Definition: php/ext/google/protobuf/upb.c:9046
upb_tabstr
UPB_INLINE char * upb_tabstr(upb_tabkey key, uint32_t *len)
Definition: php/ext/google/protobuf/upb.h:2764
google_protobuf_MessageOptions
struct google_protobuf_MessageOptions google_protobuf_MessageOptions
Definition: php/ext/google/protobuf/upb.h:945
str_t
Definition: php/ext/google/protobuf/upb.c:1104
upb_handlercache::arena
upb_arena * arena
Definition: php/ext/google/protobuf/upb.c:3649
upb_handlers::cache
upb_handlercache * cache
Definition: php/ext/google/protobuf/upb.c:3270
ARRAY_SIZE
#define ARRAY_SIZE(x)
Definition: php/ext/google/protobuf/upb.c:4649
set_enum_hd
static void set_enum_hd(upb_handlers *h, const upb_fielddef *f, bool preserve_fieldnames, upb_handlerattr *attr)
Definition: php/ext/google/protobuf/upb.c:12843
upb_enumdef_file
const upb_filedef * upb_enumdef_file(const upb_enumdef *e)
Definition: php/ext/google/protobuf/upb.c:1453
upb_msg_has
bool upb_msg_has(const upb_msg *msg, int field_index, const upb_msglayout *l)
Definition: php/ext/google/protobuf/upb.c:4059
upb_jsonparser_frame::f
const upb_fielddef * f
Definition: php/ext/google/protobuf/upb.c:8956
b64table
static const signed char b64table[]
Definition: php/ext/google/protobuf/upb.c:9221
upb_pbcodecache::groups
upb_inttable groups
Definition: php/ext/google/protobuf/upb.h:6511
upb_array::size
size_t size
Definition: php/ext/google/protobuf/upb.h:473
upb_pb_native_wire_types
const uint8_t upb_pb_native_wire_types[]
Definition: php/ext/google/protobuf/upb.c:8708
upb_pb_encoder::limit
char * limit
Definition: php/ext/google/protobuf/upb.c:7906
upb_pb_encoder::top
int * top
Definition: php/ext/google/protobuf/upb.c:7917
next
static size_t next(const upb_table *t, size_t i)
Definition: php/ext/google/protobuf/upb.c:4889
MIX
#define MIX(h, k, m)
Definition: php/ext/google/protobuf/upb.c:5428
curbufleft
static size_t curbufleft(const upb_pbdecoder *d)
Definition: php/ext/google/protobuf/upb.c:6841
delim_remaining
size_t delim_remaining(const upb_pbdecoder *d)
Definition: php/ext/google/protobuf/upb.c:6857
f
GLfloat f
Definition: glcorearb.h:3964
upb_malloc
UPB_INLINE void * upb_malloc(upb_alloc *alloc, size_t size)
Definition: php/ext/google/protobuf/upb.h:249
maxalign
static const size_t maxalign
Definition: php/ext/google/protobuf/upb.c:5617
scalar_startstr
static void * scalar_startstr(void *closure, const void *handler_data, size_t size_hint)
Definition: php/ext/google/protobuf/upb.c:12739
upb_filedef::enum_count
int enum_count
Definition: php/ext/google/protobuf/upb.c:1198
end_day
static bool end_day(upb_json_parser *p, const char *ptr)
Definition: php/ext/google/protobuf/upb.c:10354
UPB_JSON_MAX_DEPTH
#define UPB_JSON_MAX_DEPTH
Definition: php/ext/google/protobuf/upb.c:8813
google_protobuf_DescriptorProto_msginit
const upb_msglayout google_protobuf_DescriptorProto_msginit
Definition: php/ext/google/protobuf/upb.c:103
upb_pbcodecache_new
upb_pbcodecache * upb_pbcodecache_new(upb_handlercache *dest)
Definition: php/ext/google/protobuf/upb.c:6666
UPB_PB_ENCODER_SIZE
#define UPB_PB_ENCODER_SIZE
Definition: php/ext/google/protobuf/upb.h:6922
value
GLsizei const GLfloat * value
Definition: glcorearb.h:3093
google_protobuf_FieldOptions_submsgs
static const upb_msglayout *const google_protobuf_FieldOptions_submsgs[1]
Definition: php/ext/google/protobuf/upb.c:321
encode_fixed32
static bool encode_fixed32(upb_pb_encoder *e, uint32_t val)
Definition: php/ext/google/protobuf/upb.c:8122
VMCASE
#define VMCASE(op, code)
UPB_STARTSTR_SELECTOR
#define UPB_STARTSTR_SELECTOR
Definition: php/ext/google/protobuf/upb.h:4071
google_protobuf_FileOptions_has_php_class_prefix
UPB_INLINE bool google_protobuf_FileOptions_has_php_class_prefix(const google_protobuf_FileOptions *msg)
Definition: php/ext/google/protobuf/upb.h:1908
upb_strtable_iter::t
const upb_strtable * t
Definition: php/ext/google/protobuf/upb.h:3062
newstrpc_str
strpc * newstrpc_str(upb_handlers *h, const char *str)
Definition: php/ext/google/protobuf/upb.c:12303
mgroup::bytecode
uint32_t * bytecode
Definition: php/ext/google/protobuf/upb.h:6524
uninit
static void uninit(upb_table *t, upb_alloc *a)
Definition: php/ext/google/protobuf/upb.c:4758
upb_strtable_lookup
UPB_INLINE bool upb_strtable_lookup(const upb_strtable *t, const char *key, upb_value *v)
Definition: php/ext/google/protobuf/upb.h:2940
upb_pb_encoder::input_
upb_sink input_
Definition: php/ext/google/protobuf/upb.c:7896
UPB_WELLKNOWN_FIELDMASK
@ UPB_WELLKNOWN_FIELDMASK
Definition: php/ext/google/protobuf/upb.h:3151
google_protobuf_EnumValueDescriptorProto_number
UPB_INLINE int32_t google_protobuf_EnumValueDescriptorProto_number(const google_protobuf_EnumValueDescriptorProto *msg)
Definition: php/ext/google/protobuf/upb.h:1723
UPB_WELLKNOWN_STRUCT
@ UPB_WELLKNOWN_STRUCT
Definition: php/ext/google/protobuf/upb.h:3167
scalar_startstr_nokey
static void * scalar_startstr_nokey(void *closure, const void *handler_data, size_t size_hint)
Definition: php/ext/google/protobuf/upb.c:12968
google_protobuf_FieldDescriptorProto_type
UPB_INLINE int32_t google_protobuf_FieldDescriptorProto_type(const google_protobuf_FieldDescriptorProto *msg)
Definition: php/ext/google/protobuf/upb.h:1499
google_protobuf_EnumDescriptorProto_EnumReservedRange_msginit
const upb_msglayout google_protobuf_EnumDescriptorProto_EnumReservedRange_msginit
Definition: php/ext/google/protobuf/upb.c:213
upb_inttable_insert2
bool upb_inttable_insert2(upb_inttable *t, uintptr_t key, upb_value val, upb_alloc *a)
Definition: php/ext/google/protobuf/upb.c:5133
upb_decode_tag
static bool upb_decode_tag(const char **ptr, const char *limit, int *field_number, int *wire_type)
Definition: php/ext/google/protobuf/upb.c:598
UPB_SIZE
#define UPB_SIZE(size32, size64)
Definition: php/ext/google/protobuf/upb.c:4602
google_protobuf_FileOptions_php_namespace
UPB_INLINE upb_strview google_protobuf_FileOptions_php_namespace(const google_protobuf_FileOptions *msg)
Definition: php/ext/google/protobuf/upb.h:1911
json_parser_any_frame_set_payload_type
static void json_parser_any_frame_set_payload_type(upb_json_parser *p, upb_jsonparser_any_frame *frame, const upb_msgdef *payload_type)
Definition: php/ext/google/protobuf/upb.c:9096
upb_encode_scalarfield
static bool upb_encode_scalarfield(upb_encstate *e, const char *field_mem, const upb_msglayout *m, const upb_msglayout_field *f, bool skip_zero_value)
Definition: php/ext/google/protobuf/upb.c:3117
upb_pbdecoder_resume
int32_t upb_pbdecoder_resume(upb_pbdecoder *d, void *p, const char *buf, size_t size, const upb_bufhandle *handle)
Definition: php/ext/google/protobuf/upb.c:6939
_json_trans_targs
static const char _json_trans_targs[]
Definition: php/ext/google/protobuf/upb.c:11548
upb_inttable_push
UPB_INLINE bool upb_inttable_push(upb_inttable *t, upb_value val)
Definition: php/ext/google/protobuf/upb.h:2972
parse_default
static bool parse_default(const symtab_addctx *ctx, const char *str, size_t len, upb_fielddef *f)
Definition: php/ext/google/protobuf/upb.c:2061
UPB_HANDLER_STARTSTR
@ UPB_HANDLER_STARTSTR
Definition: php/ext/google/protobuf/upb.h:4043
google_protobuf_FieldOptions_lazy
UPB_INLINE bool google_protobuf_FieldOptions_lazy(const google_protobuf_FieldOptions *msg)
Definition: php/ext/google/protobuf/upb.h:2079
end_text
static bool end_text(upb_json_parser *p, const char *ptr)
Definition: php/ext/google/protobuf/upb.c:9646
startmap_nokey
static void * startmap_nokey(void *closure, const void *handler_data)
Definition: php/ext/google/protobuf/upb.c:13047
upb_filedef_phpnamespace
const char * upb_filedef_phpnamespace(const upb_filedef *f)
Definition: php/ext/google/protobuf/upb.c:2708
upb_fielddef::str
str_t * str
Definition: php/ext/google/protobuf/upb.c:1128
upb_jsonparser_frame::is_repeated
bool is_repeated
Definition: php/ext/google/protobuf/upb.c:8964
EnumHandlerData
Definition: php/ext/google/protobuf/upb.c:12530
UPB_LIKELY
#define UPB_LIKELY(x)
Definition: php/ext/google/protobuf/upb.h:91
upb_symtab_lookupfile
const upb_filedef * upb_symtab_lookupfile(const upb_symtab *s, const char *name)
Definition: php/ext/google/protobuf/upb.c:2784
upb_filedef::package
const char * package
Definition: php/ext/google/protobuf/upb.c:1186
upb_strtable_lookup2
bool upb_strtable_lookup2(const upb_strtable *t, const char *key, size_t len, upb_value *v)
Definition: php/ext/google/protobuf/upb.c:4985
upb_stringsink::sink
upb_bytessink sink
Definition: php/ext/google/protobuf/upb.c:8881
decoder_push
static bool decoder_push(upb_pbdecoder *d, uint64_t end)
Definition: php/ext/google/protobuf/upb.c:7216
upb_strtable_iter
Definition: php/ext/google/protobuf/upb.h:3061
upb_pbdecodermethod::group
const mgroup * group
Definition: php/ext/google/protobuf/upb.h:6583
UPB_DESCRIPTOR_TYPE_GROUP
@ UPB_DESCRIPTOR_TYPE_GROUP
Definition: php/ext/google/protobuf/upb.h:446
google_protobuf_FileDescriptorProto_submsgs
static const upb_msglayout *const google_protobuf_FileDescriptorProto_submsgs[6]
Definition: php/ext/google/protobuf/upb.c:50
google_protobuf_FieldDescriptorProto_number
UPB_INLINE int32_t google_protobuf_FieldDescriptorProto_number(const google_protobuf_FieldDescriptorProto *msg)
Definition: php/ext/google/protobuf/upb.h:1495
top
static upb_pb_encoder_segment * top(upb_pb_encoder *e)
Definition: php/ext/google/protobuf/upb.c:7933
_upb_tabent::key
upb_tabkey key
Definition: php/ext/google/protobuf/upb.h:2783
output
const upb_json_parsermethod const upb_symtab upb_sink * output
Definition: ruby/ext/google/protobuf_c/upb.h:10503
UPB_PB_VARINT_MAX_LEN
#define UPB_PB_VARINT_MAX_LEN
Definition: php/ext/google/protobuf/upb.c:2869
upb_msglayout_free
static void upb_msglayout_free(upb_msglayout *l)
Definition: php/ext/google/protobuf/upb.c:4398
UPB_WELLKNOWN_UINT32VALUE
@ UPB_WELLKNOWN_UINT32VALUE
Definition: php/ext/google/protobuf/upb.h:3160
accumulate_append
static bool accumulate_append(upb_json_parser *p, const char *buf, size_t len, bool can_alias)
Definition: php/ext/google/protobuf/upb.c:9400
upb_handlercache_get
const upb_handlers * upb_handlercache_get(upb_handlercache *c, const upb_msgdef *md)
Definition: php/ext/google/protobuf/upb.c:3655
UPB_TIMESTAMP_MAX_JSON_LEN
#define UPB_TIMESTAMP_MAX_JSON_LEN
Definition: php/ext/google/protobuf/upb.c:13143
UPB_WELLKNOWN_DURATION
@ UPB_WELLKNOWN_DURATION
Definition: php/ext/google/protobuf/upb.h:3152
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: php/ext/google/protobuf/upb.h:1243
UPB_WELLKNOWN_VALUE
@ UPB_WELLKNOWN_VALUE
Definition: php/ext/google/protobuf/upb.h:3165
_upb_symtab_loaddefinit
bool _upb_symtab_loaddefinit(upb_symtab *s, const upb_def_init *init)
Definition: php/ext/google/protobuf/upb.c:2819
upb_arena_addblock
static void upb_arena_addblock(upb_arena *a, void *ptr, size_t size, bool owned)
Definition: php/ext/google/protobuf/upb.c:5657
upb_msgdef::itof
upb_inttable itof
Definition: php/ext/google/protobuf/upb.c:1153
upb_msg_oneof_next
void upb_msg_oneof_next(upb_msg_oneof_iter *iter)
Definition: php/ext/google/protobuf/upb.c:1855
upb_textprinter
Definition: php/ext/google/protobuf/upb.c:8385
UPB_TIMESTAMP_BEFORE_NANO_LEN
#define UPB_TIMESTAMP_BEFORE_NANO_LEN
Definition: php/ext/google/protobuf/upb.c:13144
benchmarks.python.py_benchmark.parser
parser
Definition: py_benchmark.py:10
TM_YEAR_BASE
#define TM_YEAR_BASE
Definition: php/ext/google/protobuf/upb.c:10464
upb_msgdef::selector_count
uint32_t selector_count
Definition: php/ext/google/protobuf/upb.c:1149
upb_msg_field_iter_isequal
bool upb_msg_field_iter_isequal(const upb_msg_field_iter *iter1, const upb_msg_field_iter *iter2)
Definition: php/ext/google/protobuf/upb.c:1841
is_top_level
static bool is_top_level(upb_json_parser *p)
Definition: php/ext/google/protobuf/upb.c:11290
upb_zzdecode_64
static int64_t upb_zzdecode_64(uint64_t n)
Definition: php/ext/google/protobuf/upb.c:611
upb_msgdef_syntax
upb_syntax_t upb_msgdef_syntax(const upb_msgdef *m)
Definition: php/ext/google/protobuf/upb.c:1745
google_protobuf_EnumOptions_msginit
const upb_msglayout google_protobuf_EnumOptions_msginit
Definition: php/ext/google/protobuf/upb.c:365
enumdef
const upb_enumdef * enumdef
Definition: php/ext/google/protobuf/protobuf.h:830
upb_fielddef_containingtype
const upb_msgdef * upb_fielddef_containingtype(const upb_fielddef *f)
Definition: php/ext/google/protobuf/upb.c:1615
_upb_noclosure
char _upb_noclosure
Definition: php/ext/google/protobuf/upb.c:3287
upb_json_printer::subc_
void * subc_
Definition: php/ext/google/protobuf/upb.c:12241
upb_alloc
Definition: php/ext/google/protobuf/upb.h:245
upb_uint32_handlerfunc
bool upb_uint32_handlerfunc(void *c, const void *hd, uint32_t val)
Definition: php/ext/google/protobuf/upb.h:4136
UPB_TYPE_BOOL
@ UPB_TYPE_BOOL
Definition: php/ext/google/protobuf/upb.h:412
compiler::group
mgroup * group
Definition: php/ext/google/protobuf/upb.c:5882
count
GLint GLsizei count
Definition: glcorearb.h:2830
upb_mapiter_new
upb_mapiter * upb_mapiter_new(const upb_map *t, upb_alloc *a)
Definition: php/ext/google/protobuf/upb.c:4310
upb_strtable_count
UPB_INLINE size_t upb_strtable_count(const upb_strtable *t)
Definition: php/ext/google/protobuf/upb.h:2894
upb_array_add
static void * upb_array_add(upb_array *arr, size_t elements)
Definition: php/ext/google/protobuf/upb.c:696
upb_msg_internal::arena
upb_arena * arena
Definition: php/ext/google/protobuf/upb.c:3956
upb_handlerattr::alwaysok
bool alwaysok
Definition: php/ext/google/protobuf/upb.h:4089
upb_pbcodecache_get
const upb_pbdecodermethod * upb_pbcodecache_get(upb_pbcodecache *c, const upb_msgdef *md)
Definition: php/ext/google/protobuf/upb.c:6710
scalar_enum
static bool scalar_enum(void *closure, const void *handler_data, int32_t val)
Definition: php/ext/google/protobuf/upb.c:12535
mgroup::methods
upb_inttable methods
Definition: php/ext/google/protobuf/upb.h:6521
lookupkey_t
Definition: php/ext/google/protobuf/upb.c:4697
upb_msg_getunknown
const char * upb_msg_getunknown(const upb_msg *msg, size_t *len)
Definition: php/ext/google/protobuf/upb.c:3999
upb_msglayout_field
Definition: php/ext/google/protobuf/upb.h:514
upb_fielddef::sint
int64_t sint
Definition: php/ext/google/protobuf/upb.c:1123
upb_pbdecoder_startjit
void * upb_pbdecoder_startjit(void *closure, const void *hd, size_t size_hint)
Definition: php/ext/google/protobuf/upb.c:7627
upb_json_parser::stack
upb_jsonparser_frame stack[UPB_JSON_MAX_DEPTH]
Definition: php/ext/google/protobuf/upb.c:9015
check_stack
static bool check_stack(upb_json_parser *p)
Definition: php/ext/google/protobuf/upb.c:9176
index
GLuint index
Definition: glcorearb.h:3055
google_protobuf_FieldDescriptorProto_type_name
UPB_INLINE upb_strview google_protobuf_FieldDescriptorProto_type_name(const google_protobuf_FieldDescriptorProto *msg)
Definition: php/ext/google/protobuf/upb.h:1501
upb_table::entries
const upb_tabent * entries
Definition: php/ext/google/protobuf/upb.h:2805
google_protobuf_EnumValueDescriptorProto__fields
static const upb_msglayout_field google_protobuf_EnumValueDescriptorProto__fields[3]
Definition: php/ext/google/protobuf/upb.c:223
upb_msgdef_fullname
const char * upb_msgdef_fullname(const upb_msgdef *m)
Definition: php/ext/google/protobuf/upb.c:1733
upb_ok
bool upb_ok(const upb_status *status)
Definition: php/ext/google/protobuf/upb.c:5573
end_year
static bool end_year(upb_json_parser *p, const char *ptr)
Definition: php/ext/google/protobuf/upb.c:10330
group
static uint32_t * group(tarjan *t, upb_refcounted *r)
Definition: ruby/ext/google/protobuf_c/upb.c:5943
UPB_DESCRIPTOR_TYPE_SFIXED64
@ UPB_DESCRIPTOR_TYPE_SFIXED64
Definition: php/ext/google/protobuf/upb.h:452
upb_handlers
Definition: php/ext/google/protobuf/upb.c:3269
a
GLboolean GLboolean GLboolean GLboolean a
Definition: glcorearb.h:3228
consumebytes
static UPB_FORCEINLINE void consumebytes(upb_pbdecoder *d, void *buf, size_t bytes)
Definition: php/ext/google/protobuf/upb.c:7059
upb_json_parser::status
upb_status * status
Definition: php/ext/google/protobuf/upb.c:9019
upb_msglayout_place
static size_t upb_msglayout_place(upb_msglayout *l, size_t size)
Definition: php/ext/google/protobuf/upb.c:4402
google_protobuf_EnumValueOptions_msginit
const upb_msglayout google_protobuf_EnumValueOptions_msginit
Definition: php/ext/google/protobuf/upb.c:380
end
static bool end(void *closure, const void *hd)
Definition: php/ext/google/protobuf/upb.c:12036
upb_pb_encoder::buf
char * buf
Definition: php/ext/google/protobuf/upb.c:7906
upb_filedef::name
const char * name
Definition: php/ext/google/protobuf/upb.c:1185
UPB_STARTMSG_SELECTOR
#define UPB_STARTMSG_SELECTOR
Definition: php/ext/google/protobuf/upb.h:4065
skip
static int32_t skip(upb_pbdecoder *d, size_t bytes)
Definition: php/ext/google/protobuf/upb.c:6915
upb_json_printer::seconds
int64_t seconds
Definition: php/ext/google/protobuf/upb.c:12261
upb_handlerattr::handler_data
const void * handler_data
Definition: php/ext/google/protobuf/upb.h:4086
check
static void check(upb_inttable *t)
Definition: php/ext/google/protobuf/upb.c:5088
resolvename
static bool resolvename(const upb_strtable *t, const upb_fielddef *f, const char *base, upb_strview sym, upb_deftype_t type, upb_status *status, const void **def)
Definition: php/ext/google/protobuf/upb.c:1994
start_day
static void start_day(upb_json_parser *p, const char *ptr)
Definition: php/ext/google/protobuf/upb.c:10350
upb_decode_64bit
static bool upb_decode_64bit(const char **ptr, const char *limit, uint64_t *val)
Definition: php/ext/google/protobuf/upb.c:582
upb_handlertype_t
upb_handlertype_t
Definition: php/ext/google/protobuf/upb.h:4035
upb_encstate::limit
char * limit
Definition: php/ext/google/protobuf/upb.c:2913
upb_pbdecoder_decode_varint_slow
UPB_NOINLINE int32_t upb_pbdecoder_decode_varint_slow(upb_pbdecoder *d, uint64_t *u64)
Definition: php/ext/google/protobuf/upb.c:7130
as_float
static float as_float(uint32_t n)
Definition: php/ext/google/protobuf/upb.c:7213
advance
static void advance(upb_pbdecoder *d, size_t len)
Definition: php/ext/google/protobuf/upb.c:6862
upb_json_parsermethod_inputhandler
const upb_byteshandler * upb_json_parsermethod_inputhandler(const upb_json_parsermethod *m)
Definition: php/ext/google/protobuf/upb.c:12168
run_decoder_vm
size_t run_decoder_vm(upb_pbdecoder *d, const mgroup *group, const upb_bufhandle *handle)
Definition: php/ext/google/protobuf/upb.c:7406
upb_startmsg_handlerfunc
bool upb_startmsg_handlerfunc(void *c, const void *)
Definition: php/ext/google/protobuf/upb.h:4130
upb_fielddef_index
uint32_t upb_fielddef_index(const upb_fielddef *f)
Definition: php/ext/google/protobuf/upb.c:1544
upb_strview::size
size_t size
Definition: php/ext/google/protobuf/upb.h:537
create_msgdef
static bool create_msgdef(const symtab_addctx *ctx, const char *prefix, const google_protobuf_DescriptorProto *msg_proto)
Definition: php/ext/google/protobuf/upb.c:2368
upb_decode_setpresent
static void upb_decode_setpresent(upb_decframe *frame, const upb_msglayout_field *field)
Definition: php/ext/google/protobuf/upb.c:750
kControlCharLimit
static const char kControlCharLimit
Definition: php/ext/google/protobuf/upb.c:12330
upb_msgfactory_free
void upb_msgfactory_free(upb_msgfactory *f)
Definition: php/ext/google/protobuf/upb.c:4557
upb_handlers_setendmsg
bool upb_handlers_setendmsg(upb_handlers *h, upb_endmsg_handlerfunc *func, const upb_handlerattr *attr)
Definition: php/ext/google/protobuf/upb.c:3496
google_protobuf_OneofOptions__fields
static const upb_msglayout_field google_protobuf_OneofOptions__fields[1]
Definition: php/ext/google/protobuf/upb.c:345
upb_inttable_compact2
void upb_inttable_compact2(upb_inttable *t, upb_alloc *a)
Definition: php/ext/google/protobuf/upb.c:5238
upb_pbdecoder_packdispatch
UPB_INLINE uint64_t upb_pbdecoder_packdispatch(uint64_t ofs, uint8_t wt1, uint8_t wt2)
Definition: php/ext/google/protobuf/upb.h:6710
upb_endmsg_handlerfunc
bool upb_endmsg_handlerfunc(void *c, const void *, upb_status *status)
Definition: php/ext/google/protobuf/upb.h:4131
it
MapIter it
Definition: php/ext/google/protobuf/map.c:205
tag_t::tag
char tag[7]
Definition: php/ext/google/protobuf/upb.c:8095
encode_strbuf
static size_t encode_strbuf(void *c, const void *hd, const char *buf, size_t len, const upb_bufhandle *h)
Definition: php/ext/google/protobuf/upb.c:8199
google_protobuf_GeneratedCodeInfo_submsgs
static const upb_msglayout *const google_protobuf_GeneratedCodeInfo_submsgs[1]
Definition: php/ext/google/protobuf/upb.c:476
upb_pbdecoder_frame::sink
upb_sink sink
Definition: php/ext/google/protobuf/upb.h:6554
compiler
Definition: plugin.pb.cc:22
upb_filedef_msg
const upb_msgdef * upb_filedef_msg(const upb_filedef *f, int i)
Definition: php/ext/google/protobuf/upb.c:2732
upb_fielddef::dbl
double dbl
Definition: php/ext/google/protobuf/upb.c:1125
google_protobuf_FieldDescriptorProto_oneof_index
UPB_INLINE int32_t google_protobuf_FieldDescriptorProto_oneof_index(const google_protobuf_FieldDescriptorProto *msg)
Definition: php/ext/google/protobuf/upb.h:1507
upb_msglayout_field::number
uint32_t number
Definition: php/ext/google/protobuf/upb.h:515
google_protobuf_FieldOptions_packed
UPB_INLINE bool google_protobuf_FieldOptions_packed(const google_protobuf_FieldOptions *msg)
Definition: php/ext/google/protobuf/upb.h:2075
OP_TAG1
@ OP_TAG1
Definition: php/ext/google/protobuf/upb.h:6484
upb_roundup_pow2
static size_t upb_roundup_pow2(size_t bytes)
Definition: php/ext/google/protobuf/upb.c:2916
upb_zzencode_64
static uint64_t upb_zzencode_64(int64_t n)
Definition: php/ext/google/protobuf/upb.c:2909
upb_descriptortype_t
upb_descriptortype_t
Definition: php/ext/google/protobuf/upb.h:436
upb_inttable_removeptr
bool upb_inttable_removeptr(upb_inttable *t, const void *key, upb_value *val)
Definition: php/ext/google/protobuf/upb.c:5234
upb_array_new
upb_array * upb_array_new(upb_fieldtype_t type, upb_arena *a)
Definition: php/ext/google/protobuf/upb.c:4095
upb_mapiter::key_type
upb_fieldtype_t key_type
Definition: php/ext/google/protobuf/upb.c:4298
UPB_DESCRIPTOR_TYPE_STRING
@ UPB_DESCRIPTOR_TYPE_STRING
Definition: php/ext/google/protobuf/upb.h:445
google_protobuf_FieldDescriptorProto_msginit
const upb_msglayout google_protobuf_FieldDescriptorProto_msginit
Definition: php/ext/google/protobuf/upb.c:167
upb_pbdecoder_startbc
void * upb_pbdecoder_startbc(void *closure, const void *pc, size_t size_hint)
Definition: php/ext/google/protobuf/upb.c:7615
upb_msgfactory_getlayout
const upb_msglayout * upb_msgfactory_getlayout(upb_msgfactory *f, const upb_msgdef *m)
Definition: php/ext/google/protobuf/upb.c:4573
switchtobuf
static void switchtobuf(upb_pbdecoder *d, const char *buf, const char *end)
Definition: php/ext/google/protobuf/upb.c:6888
does_fieldmask_end
static bool does_fieldmask_end(upb_json_parser *p)
Definition: php/ext/google/protobuf/upb.c:11339
upb_strdup2
char * upb_strdup2(const char *s, size_t len, upb_alloc *a)
Definition: php/ext/google/protobuf/upb.c:4679
shortname
static const char * shortname(const char *longname)
Definition: php/ext/google/protobuf/upb.c:8395
getofs
static int32_t getofs(uint32_t instruction)
Definition: php/ext/google/protobuf/upb.c:5939
upb_array_get
upb_msgval upb_array_get(const upb_array *arr, size_t i)
Definition: php/ext/google/protobuf/upb.c:4121
_upb_value_setval
UPB_INLINE void _upb_value_setval(upb_value *v, uint64_t val, upb_ctype_t ctype)
Definition: php/ext/google/protobuf/upb.h:2681
upb_msgdef
Definition: php/ext/google/protobuf/upb.c:1146
checkstart
bool checkstart(upb_handlers *h, const upb_fielddef *f, upb_handlertype_t type, upb_status *status)
Definition: php/ext/google/protobuf/upb.c:3414
start_array
static bool start_array(upb_json_parser *p)
Definition: php/ext/google/protobuf/upb.c:10948
upb_fielddef_haspresence
bool upb_fielddef_haspresence(const upb_fielddef *f)
Definition: php/ext/google/protobuf/upb.c:1713
UPB_DESCRIPTOR_TYPE_DOUBLE
@ UPB_DESCRIPTOR_TYPE_DOUBLE
Definition: php/ext/google/protobuf/upb.h:437
textprinter_endmsg
static bool textprinter_endmsg(void *c, const void *hd, upb_status *s)
Definition: php/ext/google/protobuf/upb.c:8500
create_enumdef
static bool create_enumdef(const symtab_addctx *ctx, const char *prefix, const google_protobuf_EnumDescriptorProto *enum_proto)
Definition: php/ext/google/protobuf/upb.c:2304
upb_handlers_setint64
bool upb_handlers_setint64(upb_handlers *h, const upb_fielddef *f, upb_int64_handlerfunc *func, const upb_handlerattr *attr)
upb_fielddef::selector_base
uint32_t selector_base
Definition: php/ext/google/protobuf/upb.c:1138
upb_pbdecoder_decode_f64
int32_t upb_pbdecoder_decode_f64(upb_pbdecoder *d, uint64_t *u64)
Definition: php/ext/google/protobuf/upb.c:7208
UPB_STRVIEW_FORMAT
#define UPB_STRVIEW_FORMAT
Definition: php/ext/google/protobuf/upb.h:557
upb_handlercache
Definition: php/ext/google/protobuf/upb.c:3648
upb_fielddef::flt
float flt
Definition: php/ext/google/protobuf/upb.c:1126
upb_fieldtype_t
upb_fieldtype_t
Definition: php/ext/google/protobuf/upb.h:410
pushtagdelim
static bool pushtagdelim(upb_pbdecoder *d, uint32_t arg)
Definition: php/ext/google/protobuf/upb.c:7235
b64lookup
int32_t b64lookup(unsigned char ch)
Definition: php/ext/google/protobuf/upb.c:9259
google::protobuf::method
const Descriptor::ReservedRange const EnumValueDescriptor method
Definition: src/google/protobuf/descriptor.h:1973
upb_status::ok
bool ok
Definition: php/ext/google/protobuf/upb.h:171
google_protobuf_MessageOptions_map_entry
UPB_INLINE bool google_protobuf_MessageOptions_map_entry(const google_protobuf_MessageOptions *msg)
Definition: php/ext/google/protobuf/upb.h:2024
h
GLfloat GLfloat GLfloat GLfloat h
Definition: glcorearb.h:4147
upb_fielddef_defaultuint32
uint32_t upb_fielddef_defaultuint32(const upb_fielddef *f)
Definition: php/ext/google/protobuf/upb.c:1643
CHK_OOM
#define CHK_OOM(x)
Definition: php/ext/google/protobuf/upb.c:1939
google::protobuf.internal.wire_format.INT32_MAX
INT32_MAX
Definition: wire_format.py:57
upb_skip_unknowngroup
static bool upb_skip_unknowngroup(upb_decstate *d, int field_number, const char *limit)
Definition: php/ext/google/protobuf/upb.c:1053
scalar_startstr_onlykey
static void * scalar_startstr_onlykey(void *closure, const void *handler_data, size_t size_hint)
Definition: php/ext/google/protobuf/upb.c:13252
start_hour
static void start_hour(upb_json_parser *p, const char *ptr)
Definition: php/ext/google/protobuf/upb.c:10362
descriptor_type
zend_class_entry * descriptor_type
mem_block::size
size_t size
Definition: php/ext/google/protobuf/upb.c:5645
benchmarks.python.py_benchmark.args
args
Definition: py_benchmark.py:24
tag_t::bytes
uint8_t bytes
Definition: php/ext/google/protobuf/upb.c:8094
upb_decode_varint
static bool upb_decode_varint(const char **ptr, const char *limit, uint64_t *val)
Definition: php/ext/google/protobuf/upb.c:555
UPB_CTYPE_DOUBLE
@ UPB_CTYPE_DOUBLE
Definition: php/ext/google/protobuf/upb.h:2653
UPB_TIMESTAMP_MAX_NANO_LEN
#define UPB_TIMESTAMP_MAX_NANO_LEN
Definition: php/ext/google/protobuf/upb.c:13145
upb_jsonparser_any_frame
Definition: php/ext/google/protobuf/upb.c:8932
upb_fielddef_defaultstr
const char * upb_fielddef_defaultstr(const upb_fielddef *f, size_t *len)
Definition: php/ext/google/protobuf/upb.c:1663
upb_msg_sizeof
static size_t upb_msg_sizeof(const upb_msglayout *l)
Definition: php/ext/google/protobuf/upb.c:4022
upb_filedef_enum
const upb_enumdef * upb_filedef_enum(const upb_filedef *f, int i)
Definition: php/ext/google/protobuf/upb.c:2736
upb_handlers_setuint64
bool upb_handlers_setuint64(upb_handlers *h, const upb_fielddef *f, upb_uint64_handlerfunc *func, const upb_handlerattr *attr)
upb_bufsrc_putbuf
bool upb_bufsrc_putbuf(const char *buf, size_t len, upb_bytessink sink)
Definition: php/ext/google/protobuf/upb.c:4623
onmreg
static void onmreg(const void *c, upb_handlers *h)
Definition: php/ext/google/protobuf/upb.c:8617
upb.h
upb_readhasbit
static bool upb_readhasbit(const char *msg, const upb_msglayout_field *f)
Definition: php/ext/google/protobuf/upb.c:2998
UPB_WELLKNOWN_DOUBLEVALUE
@ UPB_WELLKNOWN_DOUBLEVALUE
Definition: php/ext/google/protobuf/upb.h:3155
end_subobject_full
static void end_subobject_full(upb_json_parser *p)
Definition: php/ext/google/protobuf/upb.c:10930
upb_pbdecodermethod
Definition: php/ext/google/protobuf/upb.h:6574
upb_msgdef_ntof
const upb_fielddef * upb_msgdef_ntof(const upb_msgdef *m, const char *name, size_t len)
Definition: php/ext/google/protobuf/upb.c:1763
json_en_timestamp_machine
static const int json_en_timestamp_machine
Definition: php/ext/google/protobuf/upb.c:11617
google_protobuf_FieldDescriptorProto_default_value
UPB_INLINE upb_strview google_protobuf_FieldDescriptorProto_default_value(const google_protobuf_FieldDescriptorProto *msg)
Definition: php/ext/google/protobuf/upb.h:1503
upb_pbcodecache::allow_jit
bool allow_jit
Definition: php/ext/google/protobuf/upb.h:6507
symtab_addctx::file
upb_filedef * file
Definition: php/ext/google/protobuf/upb.c:1943
upb_json_parser::accumulated
const char * accumulated
Definition: php/ext/google/protobuf/upb.c:9030
upb_handlers_setstring
bool upb_handlers_setstring(upb_handlers *h, const upb_fielddef *f, upb_string_handlerfunc *func, const upb_handlerattr *attr)
upb_sink_endmsg
UPB_INLINE bool upb_sink_endmsg(upb_sink s, upb_status *status)
Definition: php/ext/google/protobuf/upb.h:5741
endmap
static bool endmap(void *closure, const void *handler_data)
Definition: php/ext/google/protobuf/upb.c:12658
upb_fielddef::oneof
const upb_oneofdef * oneof
Definition: php/ext/google/protobuf/upb.c:1130
encode_endgroup
static bool encode_endgroup(void *c, const void *hd)
Definition: php/ext/google/protobuf/upb.c:8190
upb_map_get
bool upb_map_get(const upb_map *map, upb_msgval key, upb_msgval *val)
Definition: php/ext/google/protobuf/upb.c:4250
upb_jsonparser_frame::name_table
const upb_strtable * name_table
Definition: php/ext/google/protobuf/upb.c:8959
upb_inttable_insertptr2
bool upb_inttable_insertptr2(upb_inttable *t, const void *key, upb_value val, upb_alloc *a)
Definition: php/ext/google/protobuf/upb.c:5223
upb_map
Definition: php/ext/google/protobuf/upb.c:4159


libaditof
Author(s):
autogenerated on Wed May 21 2025 02:07:00