google-protobuf 3.11.0 → 3.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of google-protobuf might be problematic. Click here for more details.

@@ -22,9 +22,7 @@
22
22
  *
23
23
  * This file is private and must not be included by users!
24
24
  */
25
- #ifndef UINTPTR_MAX
26
- #error must include stdint.h first
27
- #endif
25
+ #include <stdint.h>
28
26
 
29
27
  #if UINTPTR_MAX == 0xffffffff
30
28
  #define UPB_SIZE(size32, size64) size32
@@ -32,17 +30,21 @@
32
30
  #define UPB_SIZE(size32, size64) size64
33
31
  #endif
34
32
 
35
- #define UPB_FIELD_AT(msg, fieldtype, offset) \
36
- *(fieldtype*)((const char*)(msg) + offset)
33
+ /* If we always read/write as a consistent type to each address, this shouldn't
34
+ * violate aliasing.
35
+ */
36
+ #define UPB_PTR_AT(msg, ofs, type) ((type*)((char*)(msg) + (ofs)))
37
37
 
38
38
  #define UPB_READ_ONEOF(msg, fieldtype, offset, case_offset, case_val, default) \
39
- UPB_FIELD_AT(msg, int, case_offset) == case_val \
40
- ? UPB_FIELD_AT(msg, fieldtype, offset) \
39
+ *UPB_PTR_AT(msg, case_offset, int) == case_val \
40
+ ? *UPB_PTR_AT(msg, offset, fieldtype) \
41
41
  : default
42
42
 
43
43
  #define UPB_WRITE_ONEOF(msg, fieldtype, offset, value, case_offset, case_val) \
44
- UPB_FIELD_AT(msg, int, case_offset) = case_val; \
45
- UPB_FIELD_AT(msg, fieldtype, offset) = value;
44
+ *UPB_PTR_AT(msg, case_offset, int) = case_val; \
45
+ *UPB_PTR_AT(msg, offset, fieldtype) = value;
46
+
47
+ #define UPB_MAPTYPE_STRING 0
46
48
 
47
49
  /* UPB_INLINE: inline if possible, emit standalone code if required. */
48
50
  #ifdef __cplusplus
@@ -116,7 +118,7 @@ int msvc_vsnprintf(char* s, size_t n, const char* format, va_list arg);
116
118
  #ifdef __cplusplus
117
119
  #if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__) || \
118
120
  (defined(_MSC_VER) && _MSC_VER >= 1900)
119
- // C++11 is present
121
+ /* C++11 is present */
120
122
  #else
121
123
  #error upb requires C++11 for C++ support
122
124
  #endif
@@ -127,6 +129,18 @@ int msvc_vsnprintf(char* s, size_t n, const char* format, va_list arg);
127
129
 
128
130
  #define UPB_UNUSED(var) (void)var
129
131
 
132
+ /* UPB_ASSUME(): in release mode, we tell the compiler to assume this is true.
133
+ */
134
+ #ifdef NDEBUG
135
+ #ifdef __GNUC__
136
+ #define UPB_ASSUME(expr) if (!(expr)) __builtin_unreachable()
137
+ #else
138
+ #define UPB_ASSUME(expr) do {} if (false && (expr))
139
+ #endif
140
+ #else
141
+ #define UPB_ASSUME(expr) assert(expr)
142
+ #endif
143
+
130
144
  /* UPB_ASSERT(): in release mode, we use the expression without letting it be
131
145
  * evaluated. This prevents "unused variable" warnings. */
132
146
  #ifdef NDEBUG
@@ -153,606 +167,572 @@ int msvc_vsnprintf(char* s, size_t n, const char* format, va_list arg);
153
167
  #define UPB_INFINITY (1.0 / 0.0)
154
168
  #endif
155
169
 
170
+ #include <setjmp.h>
156
171
  #include <string.h>
157
172
 
158
173
 
174
+
159
175
  /* Maps descriptor type -> upb field type. */
160
- const uint8_t upb_desctype_to_fieldtype[] = {
161
- UPB_WIRE_TYPE_END_GROUP, /* ENDGROUP */
162
- UPB_TYPE_DOUBLE, /* DOUBLE */
163
- UPB_TYPE_FLOAT, /* FLOAT */
164
- UPB_TYPE_INT64, /* INT64 */
165
- UPB_TYPE_UINT64, /* UINT64 */
166
- UPB_TYPE_INT32, /* INT32 */
167
- UPB_TYPE_UINT64, /* FIXED64 */
168
- UPB_TYPE_UINT32, /* FIXED32 */
169
- UPB_TYPE_BOOL, /* BOOL */
170
- UPB_TYPE_STRING, /* STRING */
171
- UPB_TYPE_MESSAGE, /* GROUP */
172
- UPB_TYPE_MESSAGE, /* MESSAGE */
173
- UPB_TYPE_BYTES, /* BYTES */
174
- UPB_TYPE_UINT32, /* UINT32 */
175
- UPB_TYPE_ENUM, /* ENUM */
176
- UPB_TYPE_INT32, /* SFIXED32 */
177
- UPB_TYPE_INT64, /* SFIXED64 */
178
- UPB_TYPE_INT32, /* SINT32 */
179
- UPB_TYPE_INT64, /* SINT64 */
176
+ static const uint8_t desctype_to_fieldtype[] = {
177
+ -1, /* invalid descriptor type */
178
+ UPB_TYPE_DOUBLE, /* DOUBLE */
179
+ UPB_TYPE_FLOAT, /* FLOAT */
180
+ UPB_TYPE_INT64, /* INT64 */
181
+ UPB_TYPE_UINT64, /* UINT64 */
182
+ UPB_TYPE_INT32, /* INT32 */
183
+ UPB_TYPE_UINT64, /* FIXED64 */
184
+ UPB_TYPE_UINT32, /* FIXED32 */
185
+ UPB_TYPE_BOOL, /* BOOL */
186
+ UPB_TYPE_STRING, /* STRING */
187
+ UPB_TYPE_MESSAGE, /* GROUP */
188
+ UPB_TYPE_MESSAGE, /* MESSAGE */
189
+ UPB_TYPE_BYTES, /* BYTES */
190
+ UPB_TYPE_UINT32, /* UINT32 */
191
+ UPB_TYPE_ENUM, /* ENUM */
192
+ UPB_TYPE_INT32, /* SFIXED32 */
193
+ UPB_TYPE_INT64, /* SFIXED64 */
194
+ UPB_TYPE_INT32, /* SINT32 */
195
+ UPB_TYPE_INT64, /* SINT64 */
196
+ };
197
+
198
+ /* Maps descriptor type -> upb map size. */
199
+ static const uint8_t desctype_to_mapsize[] = {
200
+ -1, /* invalid descriptor type */
201
+ 8, /* DOUBLE */
202
+ 4, /* FLOAT */
203
+ 8, /* INT64 */
204
+ 8, /* UINT64 */
205
+ 4, /* INT32 */
206
+ 8, /* FIXED64 */
207
+ 4, /* FIXED32 */
208
+ 1, /* BOOL */
209
+ UPB_MAPTYPE_STRING, /* STRING */
210
+ sizeof(void *), /* GROUP */
211
+ sizeof(void *), /* MESSAGE */
212
+ UPB_MAPTYPE_STRING, /* BYTES */
213
+ 4, /* UINT32 */
214
+ 4, /* ENUM */
215
+ 4, /* SFIXED32 */
216
+ 8, /* SFIXED64 */
217
+ 4, /* SINT32 */
218
+ 8, /* SINT64 */
219
+ };
220
+
221
+ static const unsigned fixed32_ok = (1 << UPB_DTYPE_FLOAT) |
222
+ (1 << UPB_DTYPE_FIXED32) |
223
+ (1 << UPB_DTYPE_SFIXED32);
224
+
225
+ static const unsigned fixed64_ok = (1 << UPB_DTYPE_DOUBLE) |
226
+ (1 << UPB_DTYPE_FIXED64) |
227
+ (1 << UPB_DTYPE_SFIXED64);
228
+
229
+ /* Op: an action to be performed for a wire-type/field-type combination. */
230
+ #define OP_SCALAR_LG2(n) (n)
231
+ #define OP_FIXPCK_LG2(n) (n + 4)
232
+ #define OP_VARPCK_LG2(n) (n + 8)
233
+ #define OP_STRING 4
234
+ #define OP_SUBMSG 5
235
+
236
+ static const int8_t varint_ops[19] = {
237
+ -1, /* field not found */
238
+ -1, /* DOUBLE */
239
+ -1, /* FLOAT */
240
+ OP_SCALAR_LG2(3), /* INT64 */
241
+ OP_SCALAR_LG2(3), /* UINT64 */
242
+ OP_SCALAR_LG2(2), /* INT32 */
243
+ -1, /* FIXED64 */
244
+ -1, /* FIXED32 */
245
+ OP_SCALAR_LG2(0), /* BOOL */
246
+ -1, /* STRING */
247
+ -1, /* GROUP */
248
+ -1, /* MESSAGE */
249
+ -1, /* BYTES */
250
+ OP_SCALAR_LG2(2), /* UINT32 */
251
+ OP_SCALAR_LG2(2), /* ENUM */
252
+ -1, /* SFIXED32 */
253
+ -1, /* SFIXED64 */
254
+ OP_SCALAR_LG2(2), /* SINT32 */
255
+ OP_SCALAR_LG2(3), /* SINT64 */
256
+ };
257
+
258
+ static const int8_t delim_ops[37] = {
259
+ /* For non-repeated field type. */
260
+ -1, /* field not found */
261
+ -1, /* DOUBLE */
262
+ -1, /* FLOAT */
263
+ -1, /* INT64 */
264
+ -1, /* UINT64 */
265
+ -1, /* INT32 */
266
+ -1, /* FIXED64 */
267
+ -1, /* FIXED32 */
268
+ -1, /* BOOL */
269
+ OP_STRING, /* STRING */
270
+ -1, /* GROUP */
271
+ OP_SUBMSG, /* MESSAGE */
272
+ OP_STRING, /* BYTES */
273
+ -1, /* UINT32 */
274
+ -1, /* ENUM */
275
+ -1, /* SFIXED32 */
276
+ -1, /* SFIXED64 */
277
+ -1, /* SINT32 */
278
+ -1, /* SINT64 */
279
+ /* For repeated field type. */
280
+ OP_FIXPCK_LG2(3), /* REPEATED DOUBLE */
281
+ OP_FIXPCK_LG2(2), /* REPEATED FLOAT */
282
+ OP_VARPCK_LG2(3), /* REPEATED INT64 */
283
+ OP_VARPCK_LG2(3), /* REPEATED UINT64 */
284
+ OP_VARPCK_LG2(2), /* REPEATED INT32 */
285
+ OP_FIXPCK_LG2(3), /* REPEATED FIXED64 */
286
+ OP_FIXPCK_LG2(2), /* REPEATED FIXED32 */
287
+ OP_VARPCK_LG2(0), /* REPEATED BOOL */
288
+ OP_STRING, /* REPEATED STRING */
289
+ OP_SUBMSG, /* REPEATED GROUP */
290
+ OP_SUBMSG, /* REPEATED MESSAGE */
291
+ OP_STRING, /* REPEATED BYTES */
292
+ OP_VARPCK_LG2(2), /* REPEATED UINT32 */
293
+ OP_VARPCK_LG2(2), /* REPEATED ENUM */
294
+ OP_FIXPCK_LG2(2), /* REPEATED SFIXED32 */
295
+ OP_FIXPCK_LG2(3), /* REPEATED SFIXED64 */
296
+ OP_VARPCK_LG2(2), /* REPEATED SINT32 */
297
+ OP_VARPCK_LG2(3), /* REPEATED SINT64 */
180
298
  };
181
299
 
182
300
  /* Data pertaining to the parse. */
183
301
  typedef struct {
184
- const char *ptr; /* Current parsing position. */
185
- const char *field_start; /* Start of this field. */
186
- const char *limit; /* End of delimited region or end of buffer. */
302
+ const char *limit; /* End of delimited region or end of buffer. */
187
303
  upb_arena *arena;
188
304
  int depth;
189
- uint32_t end_group; /* Set to field number of END_GROUP tag, if any. */
305
+ uint32_t end_group; /* Set to field number of END_GROUP tag, if any. */
306
+ jmp_buf err;
190
307
  } upb_decstate;
191
308
 
192
- /* Data passed by value to each parsing function. */
193
- typedef struct {
194
- char *msg;
195
- const upb_msglayout *layout;
196
- upb_decstate *state;
197
- } upb_decframe;
309
+ typedef union {
310
+ bool bool_val;
311
+ int32_t int32_val;
312
+ int64_t int64_val;
313
+ uint32_t uint32_val;
314
+ uint64_t uint64_val;
315
+ upb_strview str_val;
316
+ } wireval;
198
317
 
199
- #define CHK(x) if (!(x)) { return 0; }
318
+ static const char *decode_msg(upb_decstate *d, const char *ptr, upb_msg *msg,
319
+ const upb_msglayout *layout);
200
320
 
201
- static bool upb_skip_unknowngroup(upb_decstate *d, int field_number);
202
- static bool upb_decode_message(upb_decstate *d, char *msg,
203
- const upb_msglayout *l);
321
+ UPB_NORETURN static void decode_err(upb_decstate *d) { longjmp(d->err, 1); }
204
322
 
205
- static bool upb_decode_varint(const char **ptr, const char *limit,
206
- uint64_t *val) {
323
+ static bool decode_reserve(upb_decstate *d, upb_array *arr, int elem) {
324
+ bool need_realloc = arr->size - arr->len < elem;
325
+ if (need_realloc && !_upb_array_realloc(arr, arr->len + elem, d->arena)) {
326
+ decode_err(d);
327
+ }
328
+ return need_realloc;
329
+ }
330
+
331
+ UPB_NOINLINE
332
+ static const char *decode_longvarint64(upb_decstate *d, const char *ptr,
333
+ const char *limit, uint64_t *val) {
207
334
  uint8_t byte;
208
335
  int bitpos = 0;
209
- const char *p = *ptr;
210
- *val = 0;
336
+ uint64_t out = 0;
211
337
 
212
338
  do {
213
- CHK(bitpos < 70 && p < limit);
214
- byte = *p;
215
- *val |= (uint64_t)(byte & 0x7F) << bitpos;
216
- p++;
339
+ if (bitpos >= 70 || ptr == limit) decode_err(d);
340
+ byte = *ptr;
341
+ out |= (uint64_t)(byte & 0x7F) << bitpos;
342
+ ptr++;
217
343
  bitpos += 7;
218
344
  } while (byte & 0x80);
219
345
 
220
- *ptr = p;
221
- return true;
222
- }
223
-
224
- static bool upb_decode_varint32(const char **ptr, const char *limit,
225
- uint32_t *val) {
226
- uint64_t u64;
227
- CHK(upb_decode_varint(ptr, limit, &u64) && u64 <= UINT32_MAX);
228
- *val = (uint32_t)u64;
229
- return true;
230
- }
231
-
232
- static bool upb_decode_64bit(const char **ptr, const char *limit,
233
- uint64_t *val) {
234
- CHK(limit - *ptr >= 8);
235
- memcpy(val, *ptr, 8);
236
- *ptr += 8;
237
- return true;
346
+ *val = out;
347
+ return ptr;
238
348
  }
239
349
 
240
- static bool upb_decode_32bit(const char **ptr, const char *limit,
241
- uint32_t *val) {
242
- CHK(limit - *ptr >= 4);
243
- memcpy(val, *ptr, 4);
244
- *ptr += 4;
245
- return true;
246
- }
247
-
248
- static int32_t upb_zzdecode_32(uint32_t n) {
249
- return (n >> 1) ^ -(int32_t)(n & 1);
250
- }
251
-
252
- static int64_t upb_zzdecode_64(uint64_t n) {
253
- return (n >> 1) ^ -(int64_t)(n & 1);
254
- }
255
-
256
- static bool upb_decode_string(const char **ptr, const char *limit,
257
- int *outlen) {
258
- uint32_t len;
259
-
260
- CHK(upb_decode_varint32(ptr, limit, &len) &&
261
- len < INT32_MAX &&
262
- limit - *ptr >= (int32_t)len);
263
-
264
- *outlen = len;
265
- return true;
266
- }
267
-
268
- static void upb_set32(void *msg, size_t ofs, uint32_t val) {
269
- memcpy((char*)msg + ofs, &val, sizeof(val));
350
+ UPB_FORCEINLINE
351
+ static const char *decode_varint64(upb_decstate *d, const char *ptr,
352
+ const char *limit, uint64_t *val) {
353
+ if (UPB_LIKELY(ptr < limit && (*ptr & 0x80) == 0)) {
354
+ *val = (uint8_t)*ptr;
355
+ return ptr + 1;
356
+ } else {
357
+ return decode_longvarint64(d, ptr, limit, val);
358
+ }
270
359
  }
271
360
 
272
- static bool upb_append_unknown(upb_decstate *d, upb_decframe *frame) {
273
- upb_msg_addunknown(frame->msg, d->field_start, d->ptr - d->field_start,
274
- d->arena);
275
- return true;
361
+ static const char *decode_varint32(upb_decstate *d, const char *ptr,
362
+ const char *limit, uint32_t *val) {
363
+ uint64_t u64;
364
+ ptr = decode_varint64(d, ptr, limit, &u64);
365
+ if (u64 > UINT32_MAX) decode_err(d);
366
+ *val = (uint32_t)u64;
367
+ return ptr;
276
368
  }
277
369
 
278
-
279
- static bool upb_skip_unknownfielddata(upb_decstate *d, uint32_t tag,
280
- uint32_t group_fieldnum) {
281
- switch (tag & 7) {
282
- case UPB_WIRE_TYPE_VARINT: {
283
- uint64_t val;
284
- return upb_decode_varint(&d->ptr, d->limit, &val);
285
- }
286
- case UPB_WIRE_TYPE_32BIT: {
287
- uint32_t val;
288
- return upb_decode_32bit(&d->ptr, d->limit, &val);
289
- }
290
- case UPB_WIRE_TYPE_64BIT: {
291
- uint64_t val;
292
- return upb_decode_64bit(&d->ptr, d->limit, &val);
370
+ static void decode_munge(int type, wireval *val) {
371
+ switch (type) {
372
+ case UPB_DESCRIPTOR_TYPE_BOOL:
373
+ val->bool_val = val->uint64_val != 0;
374
+ break;
375
+ case UPB_DESCRIPTOR_TYPE_SINT32: {
376
+ uint32_t n = val->uint32_val;
377
+ val->int32_val = (n >> 1) ^ -(int32_t)(n & 1);
378
+ break;
293
379
  }
294
- case UPB_WIRE_TYPE_DELIMITED: {
295
- int len;
296
- CHK(upb_decode_string(&d->ptr, d->limit, &len));
297
- d->ptr += len;
298
- return true;
380
+ case UPB_DESCRIPTOR_TYPE_SINT64: {
381
+ uint64_t n = val->uint64_val;
382
+ val->int64_val = (n >> 1) ^ -(int64_t)(n & 1);
383
+ break;
299
384
  }
300
- case UPB_WIRE_TYPE_START_GROUP:
301
- return upb_skip_unknowngroup(d, tag >> 3);
302
- case UPB_WIRE_TYPE_END_GROUP:
303
- return (tag >> 3) == group_fieldnum;
304
- }
305
- return false;
306
- }
307
-
308
- static bool upb_skip_unknowngroup(upb_decstate *d, int field_number) {
309
- while (d->ptr < d->limit && d->end_group == 0) {
310
- uint32_t tag = 0;
311
- CHK(upb_decode_varint32(&d->ptr, d->limit, &tag));
312
- CHK(upb_skip_unknownfielddata(d, tag, field_number));
313
385
  }
314
-
315
- CHK(d->end_group == field_number);
316
- d->end_group = 0;
317
- return true;
318
386
  }
319
387
 
320
- static bool upb_array_grow(upb_array *arr, size_t elements, size_t elem_size,
321
- upb_arena *arena) {
322
- size_t needed = arr->len + elements;
323
- size_t new_size = UPB_MAX(arr->size, 8);
324
- size_t new_bytes;
325
- size_t old_bytes;
326
- void *new_data;
327
- upb_alloc *alloc = upb_arena_alloc(arena);
388
+ static const upb_msglayout_field *upb_find_field(const upb_msglayout *l,
389
+ uint32_t field_number) {
390
+ static upb_msglayout_field none = {0};
328
391
 
329
- while (new_size < needed) {
330
- new_size *= 2;
392
+ /* Lots of optimization opportunities here. */
393
+ int i;
394
+ if (l == NULL) return &none;
395
+ for (i = 0; i < l->field_count; i++) {
396
+ if (l->fields[i].number == field_number) {
397
+ return &l->fields[i];
398
+ }
331
399
  }
332
400
 
333
- old_bytes = arr->len * elem_size;
334
- new_bytes = new_size * elem_size;
335
- new_data = upb_realloc(alloc, arr->data, old_bytes, new_bytes);
336
- CHK(new_data);
337
-
338
- arr->data = new_data;
339
- arr->size = new_size;
340
- return true;
401
+ return &none; /* Unknown field. */
341
402
  }
342
403
 
343
- static void *upb_array_reserve(upb_array *arr, size_t elements,
344
- size_t elem_size, upb_arena *arena) {
345
- if (arr->size - arr->len < elements) {
346
- CHK(upb_array_grow(arr, elements, elem_size, arena));
347
- }
348
- return (char*)arr->data + (arr->len * elem_size);
404
+ static upb_msg *decode_newsubmsg(upb_decstate *d, const upb_msglayout *layout,
405
+ const upb_msglayout_field *field) {
406
+ const upb_msglayout *subl = layout->submsgs[field->submsg_index];
407
+ return _upb_msg_new(subl, d->arena);
349
408
  }
350
409
 
351
- bool upb_array_add(upb_array *arr, size_t elements, size_t elem_size,
352
- const void *data, upb_arena *arena) {
353
- void *dest = upb_array_reserve(arr, elements, elem_size, arena);
354
-
355
- CHK(dest);
356
- arr->len += elements;
357
- memcpy(dest, data, elements * elem_size);
410
+ static void decode_tosubmsg(upb_decstate *d, upb_msg *submsg,
411
+ const upb_msglayout *layout,
412
+ const upb_msglayout_field *field, upb_strview val) {
413
+ const upb_msglayout *subl = layout->submsgs[field->submsg_index];
414
+ const char *saved_limit = d->limit;
415
+ if (--d->depth < 0) decode_err(d);
416
+ d->limit = val.data + val.size;
417
+ decode_msg(d, val.data, submsg, subl);
418
+ d->limit = saved_limit;
419
+ if (d->end_group != 0) decode_err(d);
420
+ d->depth++;
421
+ }
358
422
 
359
- return true;
423
+ static const char *decode_group(upb_decstate *d, const char *ptr,
424
+ upb_msg *submsg, const upb_msglayout *subl,
425
+ uint32_t number) {
426
+ if (--d->depth < 0) decode_err(d);
427
+ ptr = decode_msg(d, ptr, submsg, subl);
428
+ if (d->end_group != number) decode_err(d);
429
+ d->end_group = 0;
430
+ d->depth++;
431
+ return ptr;
360
432
  }
361
433
 
362
- static upb_array *upb_getarr(upb_decframe *frame,
363
- const upb_msglayout_field *field) {
364
- UPB_ASSERT(field->label == UPB_LABEL_REPEATED);
365
- return *(upb_array**)&frame->msg[field->offset];
434
+ static const char *decode_togroup(upb_decstate *d, const char *ptr,
435
+ upb_msg *submsg, const upb_msglayout *layout,
436
+ const upb_msglayout_field *field) {
437
+ const upb_msglayout *subl = layout->submsgs[field->submsg_index];
438
+ return decode_group(d, ptr, submsg, subl, field->number);
366
439
  }
367
440
 
368
- static upb_array *upb_getorcreatearr(upb_decframe *frame,
369
- const upb_msglayout_field *field) {
370
- upb_array *arr = upb_getarr(frame, field);
441
+ static const char *decode_toarray(upb_decstate *d, const char *ptr,
442
+ upb_msg *msg, const upb_msglayout *layout,
443
+ const upb_msglayout_field *field, wireval val,
444
+ int op) {
445
+ upb_array **arrp = UPB_PTR_AT(msg, field->offset, void);
446
+ upb_array *arr = *arrp;
447
+ void *mem;
371
448
 
372
449
  if (!arr) {
373
- arr = upb_array_new(frame->state->arena);
374
- CHK(arr);
375
- *(upb_array**)&frame->msg[field->offset] = arr;
450
+ upb_fieldtype_t type = desctype_to_fieldtype[field->descriptortype];
451
+ arr = _upb_array_new(d->arena, type);
452
+ if (!arr) decode_err(d);
453
+ *arrp = arr;
376
454
  }
377
455
 
378
- return arr;
379
- }
380
-
381
- static upb_msg *upb_getorcreatemsg(upb_decframe *frame,
382
- const upb_msglayout_field *field,
383
- const upb_msglayout **subm) {
384
- upb_msg **submsg = (void*)(frame->msg + field->offset);
385
- *subm = frame->layout->submsgs[field->submsg_index];
386
-
387
- UPB_ASSERT(field->label != UPB_LABEL_REPEATED);
456
+ decode_reserve(d, arr, 1);
388
457
 
389
- if (!*submsg) {
390
- *submsg = upb_msg_new(*subm, frame->state->arena);
391
- CHK(*submsg);
458
+ switch (op) {
459
+ case OP_SCALAR_LG2(0):
460
+ case OP_SCALAR_LG2(2):
461
+ case OP_SCALAR_LG2(3):
462
+ /* Append scalar value. */
463
+ mem = UPB_PTR_AT(_upb_array_ptr(arr), arr->len << op, void);
464
+ arr->len++;
465
+ memcpy(mem, &val, 1 << op);
466
+ return ptr;
467
+ case OP_STRING:
468
+ /* Append string. */
469
+ mem =
470
+ UPB_PTR_AT(_upb_array_ptr(arr), arr->len * sizeof(upb_strview), void);
471
+ arr->len++;
472
+ memcpy(mem, &val, sizeof(upb_strview));
473
+ return ptr;
474
+ case OP_SUBMSG: {
475
+ /* Append submessage / group. */
476
+ upb_msg *submsg = decode_newsubmsg(d, layout, field);
477
+ *UPB_PTR_AT(_upb_array_ptr(arr), arr->len * sizeof(void *), upb_msg *) =
478
+ submsg;
479
+ arr->len++;
480
+ if (UPB_UNLIKELY(field->descriptortype == UPB_DTYPE_GROUP)) {
481
+ ptr = decode_togroup(d, ptr, submsg, layout, field);
482
+ } else {
483
+ decode_tosubmsg(d, submsg, layout, field, val.str_val);
484
+ }
485
+ return ptr;
486
+ }
487
+ case OP_FIXPCK_LG2(2):
488
+ case OP_FIXPCK_LG2(3): {
489
+ /* Fixed packed. */
490
+ int lg2 = op - OP_FIXPCK_LG2(0);
491
+ int mask = (1 << lg2) - 1;
492
+ int count = val.str_val.size >> lg2;
493
+ if ((val.str_val.size & mask) != 0) {
494
+ decode_err(d); /* Length isn't a round multiple of elem size. */
495
+ }
496
+ decode_reserve(d, arr, count);
497
+ mem = UPB_PTR_AT(_upb_array_ptr(arr), arr->len << lg2, void);
498
+ arr->len += count;
499
+ memcpy(mem, val.str_val.data, count << op);
500
+ return ptr;
501
+ }
502
+ case OP_VARPCK_LG2(0):
503
+ case OP_VARPCK_LG2(2):
504
+ case OP_VARPCK_LG2(3): {
505
+ /* Varint packed. */
506
+ int lg2 = op - OP_VARPCK_LG2(0);
507
+ int scale = 1 << lg2;
508
+ const char *ptr = val.str_val.data;
509
+ const char *end = ptr + val.str_val.size;
510
+ char *out = UPB_PTR_AT(_upb_array_ptr(arr), arr->len << lg2, void);
511
+ while (ptr < end) {
512
+ wireval elem;
513
+ ptr = decode_varint64(d, ptr, end, &elem.uint64_val);
514
+ decode_munge(field->descriptortype, &elem);
515
+ if (decode_reserve(d, arr, 1)) {
516
+ out = UPB_PTR_AT(_upb_array_ptr(arr), arr->len << lg2, void);
517
+ }
518
+ arr->len++;
519
+ memcpy(out, &elem, scale);
520
+ out += scale;
521
+ }
522
+ if (ptr != end) decode_err(d);
523
+ return ptr;
524
+ }
525
+ default:
526
+ UPB_UNREACHABLE();
392
527
  }
393
-
394
- return *submsg;
395
528
  }
396
529
 
397
- static upb_msg *upb_addmsg(upb_decframe *frame,
398
- const upb_msglayout_field *field,
399
- const upb_msglayout **subm) {
400
- upb_msg *submsg;
401
- upb_array *arr = upb_getorcreatearr(frame, field);
402
-
403
- *subm = frame->layout->submsgs[field->submsg_index];
404
- submsg = upb_msg_new(*subm, frame->state->arena);
405
- CHK(submsg);
406
- upb_array_add(arr, 1, sizeof(submsg), &submsg, frame->state->arena);
407
-
408
- return submsg;
409
- }
530
+ static void decode_tomap(upb_decstate *d, upb_msg *msg,
531
+ const upb_msglayout *layout,
532
+ const upb_msglayout_field *field, wireval val) {
533
+ upb_map **map_p = UPB_PTR_AT(msg, field->offset, upb_map *);
534
+ upb_map *map = *map_p;
535
+ upb_map_entry ent;
536
+ const upb_msglayout *entry = layout->submsgs[field->submsg_index];
410
537
 
411
- static void upb_sethasbit(upb_decframe *frame,
412
- const upb_msglayout_field *field) {
413
- int32_t hasbit = field->presence;
414
- UPB_ASSERT(field->presence > 0);
415
- frame->msg[hasbit / 8] |= (1 << (hasbit % 8));
416
- }
417
-
418
- static void upb_setoneofcase(upb_decframe *frame,
419
- const upb_msglayout_field *field) {
420
- UPB_ASSERT(field->presence < 0);
421
- upb_set32(frame->msg, ~field->presence, field->number);
422
- }
423
-
424
- static bool upb_decode_addval(upb_decframe *frame,
425
- const upb_msglayout_field *field, void *val,
426
- size_t size) {
427
- char *field_mem = frame->msg + field->offset;
428
- upb_array *arr;
429
-
430
- if (field->label == UPB_LABEL_REPEATED) {
431
- arr = upb_getorcreatearr(frame, field);
432
- CHK(arr);
433
- field_mem = upb_array_reserve(arr, 1, size, frame->state->arena);
434
- CHK(field_mem);
538
+ if (!map) {
539
+ /* Lazily create map. */
540
+ const upb_msglayout *entry = layout->submsgs[field->submsg_index];
541
+ const upb_msglayout_field *key_field = &entry->fields[0];
542
+ const upb_msglayout_field *val_field = &entry->fields[1];
543
+ char key_size = desctype_to_mapsize[key_field->descriptortype];
544
+ char val_size = desctype_to_mapsize[val_field->descriptortype];
545
+ UPB_ASSERT(key_field->offset == 0);
546
+ UPB_ASSERT(val_field->offset == sizeof(upb_strview));
547
+ map = _upb_map_new(d->arena, key_size, val_size);
548
+ *map_p = map;
435
549
  }
436
550
 
437
- memcpy(field_mem, val, size);
438
- return true;
439
- }
551
+ /* Parse map entry. */
552
+ memset(&ent, 0, sizeof(ent));
440
553
 
441
- static void upb_decode_setpresent(upb_decframe *frame,
442
- const upb_msglayout_field *field) {
443
- if (field->label == UPB_LABEL_REPEATED) {
444
- upb_array *arr = upb_getarr(frame, field);
445
- UPB_ASSERT(arr->len < arr->size);
446
- arr->len++;
447
- } else if (field->presence < 0) {
448
- upb_setoneofcase(frame, field);
449
- } else if (field->presence > 0) {
450
- upb_sethasbit(frame, field);
554
+ if (entry->fields[1].descriptortype == UPB_DESCRIPTOR_TYPE_MESSAGE ||
555
+ entry->fields[1].descriptortype == UPB_DESCRIPTOR_TYPE_GROUP) {
556
+ /* Create proactively to handle the case where it doesn't appear. */
557
+ ent.v.val.val = (uint64_t)_upb_msg_new(entry->submsgs[0], d->arena);
451
558
  }
452
- }
453
559
 
454
- static bool upb_decode_msgfield(upb_decstate *d, upb_msg *msg,
455
- const upb_msglayout *layout, int limit) {
456
- const char* saved_limit = d->limit;
457
- d->limit = d->ptr + limit;
458
- CHK(--d->depth >= 0);
459
- upb_decode_message(d, msg, layout);
460
- d->depth++;
461
- d->limit = saved_limit;
462
- CHK(d->end_group == 0);
463
- return true;
464
- }
560
+ decode_tosubmsg(d, &ent.k, layout, field, val.str_val);
465
561
 
466
- static bool upb_decode_groupfield(upb_decstate *d, upb_msg *msg,
467
- const upb_msglayout *layout,
468
- int field_number) {
469
- CHK(--d->depth >= 0);
470
- upb_decode_message(d, msg, layout);
471
- d->depth++;
472
- CHK(d->end_group == field_number);
473
- d->end_group = 0;
474
- return true;
562
+ /* Insert into map. */
563
+ _upb_map_set(map, &ent.k, map->key_size, &ent.v, map->val_size, d->arena);
475
564
  }
476
565
 
477
- static bool upb_decode_varintfield(upb_decstate *d, upb_decframe *frame,
478
- const upb_msglayout_field *field) {
479
- uint64_t val;
480
- CHK(upb_decode_varint(&d->ptr, d->limit, &val));
566
+ static const char *decode_tomsg(upb_decstate *d, const char *ptr, upb_msg *msg,
567
+ const upb_msglayout *layout,
568
+ const upb_msglayout_field *field, wireval val,
569
+ int op) {
570
+ void *mem = UPB_PTR_AT(msg, field->offset, void);
571
+ int type = field->descriptortype;
481
572
 
482
- switch (field->descriptortype) {
483
- case UPB_DESCRIPTOR_TYPE_INT64:
484
- case UPB_DESCRIPTOR_TYPE_UINT64:
485
- CHK(upb_decode_addval(frame, field, &val, sizeof(val)));
486
- break;
487
- case UPB_DESCRIPTOR_TYPE_INT32:
488
- case UPB_DESCRIPTOR_TYPE_UINT32:
489
- case UPB_DESCRIPTOR_TYPE_ENUM: {
490
- uint32_t val32 = (uint32_t)val;
491
- CHK(upb_decode_addval(frame, field, &val32, sizeof(val32)));
492
- break;
493
- }
494
- case UPB_DESCRIPTOR_TYPE_BOOL: {
495
- bool valbool = val != 0;
496
- CHK(upb_decode_addval(frame, field, &valbool, sizeof(valbool)));
573
+ /* Set presence if necessary. */
574
+ if (field->presence < 0) {
575
+ /* Oneof case */
576
+ *UPB_PTR_AT(msg, -field->presence, int32_t) = field->number;
577
+ } else if (field->presence > 0) {
578
+ /* Hasbit */
579
+ uint32_t hasbit = field->presence;
580
+ *UPB_PTR_AT(msg, hasbit / 8, uint8_t) |= (1 << (hasbit % 8));
581
+ }
582
+
583
+ /* Store into message. */
584
+ switch (op) {
585
+ case OP_SUBMSG: {
586
+ upb_msg **submsgp = mem;
587
+ upb_msg *submsg = *submsgp;
588
+ if (!submsg) {
589
+ submsg = decode_newsubmsg(d, layout, field);
590
+ *submsgp = submsg;
591
+ }
592
+ if (UPB_UNLIKELY(type == UPB_DTYPE_GROUP)) {
593
+ ptr = decode_togroup(d, ptr, submsg, layout, field);
594
+ } else {
595
+ decode_tosubmsg(d, submsg, layout, field, val.str_val);
596
+ }
497
597
  break;
498
598
  }
499
- case UPB_DESCRIPTOR_TYPE_SINT32: {
500
- int32_t decoded = upb_zzdecode_32((uint32_t)val);
501
- CHK(upb_decode_addval(frame, field, &decoded, sizeof(decoded)));
599
+ case OP_STRING:
600
+ memcpy(mem, &val, sizeof(upb_strview));
502
601
  break;
503
- }
504
- case UPB_DESCRIPTOR_TYPE_SINT64: {
505
- int64_t decoded = upb_zzdecode_64(val);
506
- CHK(upb_decode_addval(frame, field, &decoded, sizeof(decoded)));
602
+ case OP_SCALAR_LG2(3):
603
+ memcpy(mem, &val, 8);
507
604
  break;
508
- }
509
- default:
510
- return upb_append_unknown(d, frame);
511
- }
512
-
513
- upb_decode_setpresent(frame, field);
514
- return true;
515
- }
516
-
517
- static bool upb_decode_64bitfield(upb_decstate *d, upb_decframe *frame,
518
- const upb_msglayout_field *field) {
519
- uint64_t val;
520
- CHK(upb_decode_64bit(&d->ptr, d->limit, &val));
521
-
522
- switch (field->descriptortype) {
523
- case UPB_DESCRIPTOR_TYPE_DOUBLE:
524
- case UPB_DESCRIPTOR_TYPE_FIXED64:
525
- case UPB_DESCRIPTOR_TYPE_SFIXED64:
526
- CHK(upb_decode_addval(frame, field, &val, sizeof(val)));
605
+ case OP_SCALAR_LG2(2):
606
+ memcpy(mem, &val, 4);
527
607
  break;
528
- default:
529
- return upb_append_unknown(d, frame);
530
- }
531
-
532
- upb_decode_setpresent(frame, field);
533
- return true;
534
- }
535
-
536
- static bool upb_decode_32bitfield(upb_decstate *d, upb_decframe *frame,
537
- const upb_msglayout_field *field) {
538
- uint32_t val;
539
- CHK(upb_decode_32bit(&d->ptr, d->limit, &val));
540
-
541
- switch (field->descriptortype) {
542
- case UPB_DESCRIPTOR_TYPE_FLOAT:
543
- case UPB_DESCRIPTOR_TYPE_FIXED32:
544
- case UPB_DESCRIPTOR_TYPE_SFIXED32:
545
- CHK(upb_decode_addval(frame, field, &val, sizeof(val)));
608
+ case OP_SCALAR_LG2(0):
609
+ memcpy(mem, &val, 1);
546
610
  break;
547
611
  default:
548
- return upb_append_unknown(d, frame);
549
- }
550
-
551
- upb_decode_setpresent(frame, field);
552
- return true;
553
- }
554
-
555
- static bool upb_decode_fixedpacked(upb_decstate *d, upb_array *arr,
556
- uint32_t len, int elem_size) {
557
- size_t elements = len / elem_size;
558
-
559
- CHK((size_t)(elements * elem_size) == len);
560
- CHK(upb_array_add(arr, elements, elem_size, d->ptr, d->arena));
561
- d->ptr += len;
562
-
563
- return true;
564
- }
565
-
566
- static upb_strview upb_decode_strfield(upb_decstate *d, uint32_t len) {
567
- upb_strview ret;
568
- ret.data = d->ptr;
569
- ret.size = len;
570
- d->ptr += len;
571
- return ret;
572
- }
573
-
574
- static bool upb_decode_toarray(upb_decstate *d, upb_decframe *frame,
575
- const upb_msglayout_field *field, int len) {
576
- upb_array *arr = upb_getorcreatearr(frame, field);
577
- CHK(arr);
578
-
579
- #define VARINT_CASE(ctype, decode) \
580
- VARINT_CASE_EX(ctype, decode, decode)
581
-
582
- #define VARINT_CASE_EX(ctype, decode, dtype) \
583
- { \
584
- const char *ptr = d->ptr; \
585
- const char *limit = ptr + len; \
586
- while (ptr < limit) { \
587
- uint64_t val; \
588
- ctype decoded; \
589
- CHK(upb_decode_varint(&ptr, limit, &val)); \
590
- decoded = (decode)((dtype)val); \
591
- CHK(upb_array_add(arr, 1, sizeof(decoded), &decoded, d->arena)); \
592
- } \
593
- d->ptr = ptr; \
594
- return true; \
595
- }
596
-
597
- switch (field->descriptortype) {
598
- case UPB_DESCRIPTOR_TYPE_STRING:
599
- case UPB_DESCRIPTOR_TYPE_BYTES: {
600
- upb_strview str = upb_decode_strfield(d, len);
601
- return upb_array_add(arr, 1, sizeof(str), &str, d->arena);
602
- }
603
- case UPB_DESCRIPTOR_TYPE_FLOAT:
604
- case UPB_DESCRIPTOR_TYPE_FIXED32:
605
- case UPB_DESCRIPTOR_TYPE_SFIXED32:
606
- return upb_decode_fixedpacked(d, arr, len, sizeof(int32_t));
607
- case UPB_DESCRIPTOR_TYPE_DOUBLE:
608
- case UPB_DESCRIPTOR_TYPE_FIXED64:
609
- case UPB_DESCRIPTOR_TYPE_SFIXED64:
610
- return upb_decode_fixedpacked(d, arr, len, sizeof(int64_t));
611
- case UPB_DESCRIPTOR_TYPE_INT32:
612
- case UPB_DESCRIPTOR_TYPE_UINT32:
613
- case UPB_DESCRIPTOR_TYPE_ENUM:
614
- VARINT_CASE(uint32_t, uint32_t);
615
- case UPB_DESCRIPTOR_TYPE_INT64:
616
- case UPB_DESCRIPTOR_TYPE_UINT64:
617
- VARINT_CASE(uint64_t, uint64_t);
618
- case UPB_DESCRIPTOR_TYPE_BOOL:
619
- VARINT_CASE(bool, bool);
620
- case UPB_DESCRIPTOR_TYPE_SINT32:
621
- VARINT_CASE_EX(int32_t, upb_zzdecode_32, uint32_t);
622
- case UPB_DESCRIPTOR_TYPE_SINT64:
623
- VARINT_CASE_EX(int64_t, upb_zzdecode_64, uint64_t);
624
- case UPB_DESCRIPTOR_TYPE_MESSAGE: {
625
- const upb_msglayout *subm;
626
- upb_msg *submsg = upb_addmsg(frame, field, &subm);
627
- CHK(submsg);
628
- return upb_decode_msgfield(d, submsg, subm, len);
629
- }
630
- case UPB_DESCRIPTOR_TYPE_GROUP:
631
- return upb_append_unknown(d, frame);
612
+ UPB_UNREACHABLE();
632
613
  }
633
- #undef VARINT_CASE
634
- UPB_UNREACHABLE();
635
- }
636
-
637
- static bool upb_decode_delimitedfield(upb_decstate *d, upb_decframe *frame,
638
- const upb_msglayout_field *field) {
639
- int len;
640
-
641
- CHK(upb_decode_string(&d->ptr, d->limit, &len));
642
614
 
643
- if (field->label == UPB_LABEL_REPEATED) {
644
- return upb_decode_toarray(d, frame, field, len);
645
- } else {
646
- switch (field->descriptortype) {
647
- case UPB_DESCRIPTOR_TYPE_STRING:
648
- case UPB_DESCRIPTOR_TYPE_BYTES: {
649
- upb_strview str = upb_decode_strfield(d, len);
650
- CHK(upb_decode_addval(frame, field, &str, sizeof(str)));
651
- break;
652
- }
653
- case UPB_DESCRIPTOR_TYPE_MESSAGE: {
654
- const upb_msglayout *subm;
655
- upb_msg *submsg = upb_getorcreatemsg(frame, field, &subm);
656
- CHK(submsg);
657
- CHK(upb_decode_msgfield(d, submsg, subm, len));
658
- break;
659
- }
660
- default:
661
- /* TODO(haberman): should we accept the last element of a packed? */
662
- d->ptr += len;
663
- return upb_append_unknown(d, frame);
664
- }
665
- upb_decode_setpresent(frame, field);
666
- return true;
667
- }
615
+ return ptr;
668
616
  }
669
617
 
670
- static const upb_msglayout_field *upb_find_field(const upb_msglayout *l,
671
- uint32_t field_number) {
672
- /* Lots of optimization opportunities here. */
673
- int i;
674
- for (i = 0; i < l->field_count; i++) {
675
- if (l->fields[i].number == field_number) {
676
- return &l->fields[i];
677
- }
678
- }
679
-
680
- return NULL; /* Unknown field. */
681
- }
618
+ static const char *decode_msg(upb_decstate *d, const char *ptr, upb_msg *msg,
619
+ const upb_msglayout *layout) {
620
+ while (ptr < d->limit) {
621
+ uint32_t tag;
622
+ const upb_msglayout_field *field;
623
+ int field_number;
624
+ int wire_type;
625
+ const char *field_start = ptr;
626
+ wireval val;
627
+ int op;
682
628
 
683
- static bool upb_decode_field(upb_decstate *d, upb_decframe *frame) {
684
- uint32_t tag;
685
- const upb_msglayout_field *field;
686
- int field_number;
629
+ ptr = decode_varint32(d, ptr, d->limit, &tag);
630
+ field_number = tag >> 3;
631
+ wire_type = tag & 7;
687
632
 
688
- d->field_start = d->ptr;
689
- CHK(upb_decode_varint32(&d->ptr, d->limit, &tag));
690
- field_number = tag >> 3;
691
- field = upb_find_field(frame->layout, field_number);
633
+ field = upb_find_field(layout, field_number);
692
634
 
693
- if (field) {
694
- switch (tag & 7) {
635
+ switch (wire_type) {
695
636
  case UPB_WIRE_TYPE_VARINT:
696
- return upb_decode_varintfield(d, frame, field);
637
+ ptr = decode_varint64(d, ptr, d->limit, &val.uint64_val);
638
+ op = varint_ops[field->descriptortype];
639
+ decode_munge(field->descriptortype, &val);
640
+ break;
697
641
  case UPB_WIRE_TYPE_32BIT:
698
- return upb_decode_32bitfield(d, frame, field);
642
+ if (d->limit - ptr < 4) decode_err(d);
643
+ memcpy(&val, ptr, 4);
644
+ ptr += 4;
645
+ op = OP_SCALAR_LG2(2);
646
+ if (((1 << field->descriptortype) & fixed32_ok) == 0) goto unknown;
647
+ break;
699
648
  case UPB_WIRE_TYPE_64BIT:
700
- return upb_decode_64bitfield(d, frame, field);
701
- case UPB_WIRE_TYPE_DELIMITED:
702
- return upb_decode_delimitedfield(d, frame, field);
703
- case UPB_WIRE_TYPE_START_GROUP: {
704
- const upb_msglayout *layout;
705
- upb_msg *group;
706
-
707
- if (field->label == UPB_LABEL_REPEATED) {
708
- group = upb_addmsg(frame, field, &layout);
709
- } else {
710
- group = upb_getorcreatemsg(frame, field, &layout);
649
+ if (d->limit - ptr < 8) decode_err(d);
650
+ memcpy(&val, ptr, 8);
651
+ ptr += 8;
652
+ op = OP_SCALAR_LG2(3);
653
+ if (((1 << field->descriptortype) & fixed64_ok) == 0) goto unknown;
654
+ break;
655
+ case UPB_WIRE_TYPE_DELIMITED: {
656
+ uint32_t size;
657
+ int ndx = field->descriptortype;
658
+ if (_upb_isrepeated(field)) ndx += 18;
659
+ ptr = decode_varint32(d, ptr, d->limit, &size);
660
+ if (size >= INT32_MAX || (size_t)(d->limit - ptr) < size) {
661
+ decode_err(d); /* Length overflow. */
711
662
  }
712
-
713
- return upb_decode_groupfield(d, group, layout, field_number);
663
+ val.str_val.data = ptr;
664
+ val.str_val.size = size;
665
+ ptr += size;
666
+ op = delim_ops[ndx];
667
+ break;
714
668
  }
669
+ case UPB_WIRE_TYPE_START_GROUP:
670
+ val.int32_val = field_number;
671
+ op = OP_SUBMSG;
672
+ if (field->descriptortype != UPB_DTYPE_GROUP) goto unknown;
673
+ break;
715
674
  case UPB_WIRE_TYPE_END_GROUP:
716
675
  d->end_group = field_number;
717
- return true;
676
+ return ptr;
718
677
  default:
719
- CHK(false);
678
+ decode_err(d);
679
+ }
680
+
681
+ if (op >= 0) {
682
+ /* Parse, using op for dispatch. */
683
+ switch (field->label) {
684
+ case UPB_LABEL_REPEATED:
685
+ case _UPB_LABEL_PACKED:
686
+ ptr = decode_toarray(d, ptr, msg, layout, field, val, op);
687
+ break;
688
+ case _UPB_LABEL_MAP:
689
+ decode_tomap(d, msg, layout, field, val);
690
+ break;
691
+ default:
692
+ ptr = decode_tomsg(d, ptr, msg, layout, field, val, op);
693
+ break;
694
+ }
695
+ } else {
696
+ unknown:
697
+ /* Skip unknown field. */
698
+ if (field_number == 0) decode_err(d);
699
+ if (wire_type == UPB_WIRE_TYPE_START_GROUP) {
700
+ ptr = decode_group(d, ptr, NULL, NULL, field_number);
701
+ }
702
+ if (msg) {
703
+ if (!_upb_msg_addunknown(msg, field_start, ptr - field_start,
704
+ d->arena)) {
705
+ decode_err(d);
706
+ }
707
+ }
720
708
  }
721
- } else {
722
- CHK(field_number != 0);
723
- CHK(upb_skip_unknownfielddata(d, tag, -1));
724
- CHK(upb_append_unknown(d, frame));
725
- return true;
726
- }
727
- }
728
-
729
- static bool upb_decode_message(upb_decstate *d, char *msg, const upb_msglayout *l) {
730
- upb_decframe frame;
731
- frame.msg = msg;
732
- frame.layout = l;
733
- frame.state = d;
734
-
735
- while (d->ptr < d->limit) {
736
- CHK(upb_decode_field(d, &frame));
737
709
  }
738
710
 
739
- return true;
711
+ if (ptr != d->limit) decode_err(d);
712
+ return ptr;
740
713
  }
741
714
 
742
715
  bool upb_decode(const char *buf, size_t size, void *msg, const upb_msglayout *l,
743
716
  upb_arena *arena) {
744
717
  upb_decstate state;
745
- state.ptr = buf;
746
718
  state.limit = buf + size;
747
719
  state.arena = arena;
748
720
  state.depth = 64;
749
721
  state.end_group = 0;
750
722
 
751
- CHK(upb_decode_message(&state, msg, l));
723
+ if (setjmp(state.err)) return false;
724
+
725
+ if (size == 0) return true;
726
+ decode_msg(&state, buf, msg, l);
727
+
752
728
  return state.end_group == 0;
753
729
  }
754
730
 
755
- #undef CHK
731
+ #undef OP_SCALAR_LG2
732
+ #undef OP_FIXPCK_LG2
733
+ #undef OP_VARPCK_LG2
734
+ #undef OP_STRING
735
+ #undef OP_SUBMSG
756
736
  /* We encode backwards, to avoid pre-computing lengths (one-pass encode). */
757
737
 
758
738
 
@@ -821,6 +801,7 @@ static bool upb_encode_reserve(upb_encstate *e, size_t bytes) {
821
801
 
822
802
  /* Writes the given bytes to the buffer, handling reserve/advance. */
823
803
  static bool upb_put_bytes(upb_encstate *e, const void *data, size_t len) {
804
+ if (len == 0) return true;
824
805
  CHK(upb_encode_reserve(e, len));
825
806
  memcpy(e->ptr, data, len);
826
807
  return true;
@@ -863,15 +844,14 @@ static bool upb_put_float(upb_encstate *e, float d) {
863
844
 
864
845
  static uint32_t upb_readcase(const char *msg, const upb_msglayout_field *f) {
865
846
  uint32_t ret;
866
- uint32_t offset = ~f->presence;
867
- memcpy(&ret, msg + offset, sizeof(ret));
847
+ memcpy(&ret, msg - f->presence, sizeof(ret));
868
848
  return ret;
869
849
  }
870
850
 
871
851
  static bool upb_readhasbit(const char *msg, const upb_msglayout_field *f) {
872
852
  uint32_t hasbit = f->presence;
873
853
  UPB_ASSERT(f->presence > 0);
874
- return msg[hasbit / 8] & (1 << (hasbit % 8));
854
+ return (*UPB_PTR_AT(msg, hasbit / 8, uint8_t)) & (1 << (hasbit % 8));
875
855
  }
876
856
 
877
857
  static bool upb_put_tag(upb_encstate *e, int field_number, int wire_type) {
@@ -879,50 +859,145 @@ static bool upb_put_tag(upb_encstate *e, int field_number, int wire_type) {
879
859
  }
880
860
 
881
861
  static bool upb_put_fixedarray(upb_encstate *e, const upb_array *arr,
882
- size_t size) {
883
- size_t bytes = arr->len * size;
884
- return upb_put_bytes(e, arr->data, bytes) && upb_put_varint(e, bytes);
862
+ size_t elem_size, uint32_t tag) {
863
+ size_t bytes = arr->len * elem_size;
864
+ const char* data = _upb_array_constptr(arr);
865
+ const char* ptr = data + bytes - elem_size;
866
+ if (tag) {
867
+ while (true) {
868
+ CHK(upb_put_bytes(e, ptr, elem_size) && upb_put_varint(e, tag));
869
+ if (ptr == data) break;
870
+ ptr -= elem_size;
871
+ }
872
+ return true;
873
+ } else {
874
+ return upb_put_bytes(e, data, bytes) && upb_put_varint(e, bytes);
875
+ }
885
876
  }
886
877
 
887
878
  bool upb_encode_message(upb_encstate *e, const char *msg,
888
879
  const upb_msglayout *m, size_t *size);
889
880
 
881
+ static bool upb_encode_scalarfield(upb_encstate *e, const void *_field_mem,
882
+ const upb_msglayout *m,
883
+ const upb_msglayout_field *f,
884
+ bool skip_zero_value) {
885
+ const char *field_mem = _field_mem;
886
+ #define CASE(ctype, type, wire_type, encodeval) do { \
887
+ ctype val = *(ctype*)field_mem; \
888
+ if (skip_zero_value && val == 0) { \
889
+ return true; \
890
+ } \
891
+ return upb_put_ ## type(e, encodeval) && \
892
+ upb_put_tag(e, f->number, wire_type); \
893
+ } while(0)
894
+
895
+ switch (f->descriptortype) {
896
+ case UPB_DESCRIPTOR_TYPE_DOUBLE:
897
+ CASE(double, double, UPB_WIRE_TYPE_64BIT, val);
898
+ case UPB_DESCRIPTOR_TYPE_FLOAT:
899
+ CASE(float, float, UPB_WIRE_TYPE_32BIT, val);
900
+ case UPB_DESCRIPTOR_TYPE_INT64:
901
+ case UPB_DESCRIPTOR_TYPE_UINT64:
902
+ CASE(uint64_t, varint, UPB_WIRE_TYPE_VARINT, val);
903
+ case UPB_DESCRIPTOR_TYPE_UINT32:
904
+ CASE(uint32_t, varint, UPB_WIRE_TYPE_VARINT, val);
905
+ case UPB_DESCRIPTOR_TYPE_INT32:
906
+ case UPB_DESCRIPTOR_TYPE_ENUM:
907
+ CASE(int32_t, varint, UPB_WIRE_TYPE_VARINT, (int64_t)val);
908
+ case UPB_DESCRIPTOR_TYPE_SFIXED64:
909
+ case UPB_DESCRIPTOR_TYPE_FIXED64:
910
+ CASE(uint64_t, fixed64, UPB_WIRE_TYPE_64BIT, val);
911
+ case UPB_DESCRIPTOR_TYPE_FIXED32:
912
+ case UPB_DESCRIPTOR_TYPE_SFIXED32:
913
+ CASE(uint32_t, fixed32, UPB_WIRE_TYPE_32BIT, val);
914
+ case UPB_DESCRIPTOR_TYPE_BOOL:
915
+ CASE(bool, varint, UPB_WIRE_TYPE_VARINT, val);
916
+ case UPB_DESCRIPTOR_TYPE_SINT32:
917
+ CASE(int32_t, varint, UPB_WIRE_TYPE_VARINT, upb_zzencode_32(val));
918
+ case UPB_DESCRIPTOR_TYPE_SINT64:
919
+ CASE(int64_t, varint, UPB_WIRE_TYPE_VARINT, upb_zzencode_64(val));
920
+ case UPB_DESCRIPTOR_TYPE_STRING:
921
+ case UPB_DESCRIPTOR_TYPE_BYTES: {
922
+ upb_strview view = *(upb_strview*)field_mem;
923
+ if (skip_zero_value && view.size == 0) {
924
+ return true;
925
+ }
926
+ return upb_put_bytes(e, view.data, view.size) &&
927
+ upb_put_varint(e, view.size) &&
928
+ upb_put_tag(e, f->number, UPB_WIRE_TYPE_DELIMITED);
929
+ }
930
+ case UPB_DESCRIPTOR_TYPE_GROUP: {
931
+ size_t size;
932
+ void *submsg = *(void **)field_mem;
933
+ const upb_msglayout *subm = m->submsgs[f->submsg_index];
934
+ if (submsg == NULL) {
935
+ return true;
936
+ }
937
+ return upb_put_tag(e, f->number, UPB_WIRE_TYPE_END_GROUP) &&
938
+ upb_encode_message(e, submsg, subm, &size) &&
939
+ upb_put_tag(e, f->number, UPB_WIRE_TYPE_START_GROUP);
940
+ }
941
+ case UPB_DESCRIPTOR_TYPE_MESSAGE: {
942
+ size_t size;
943
+ void *submsg = *(void **)field_mem;
944
+ const upb_msglayout *subm = m->submsgs[f->submsg_index];
945
+ if (submsg == NULL) {
946
+ return true;
947
+ }
948
+ return upb_encode_message(e, submsg, subm, &size) &&
949
+ upb_put_varint(e, size) &&
950
+ upb_put_tag(e, f->number, UPB_WIRE_TYPE_DELIMITED);
951
+ }
952
+ }
953
+ #undef CASE
954
+ UPB_UNREACHABLE();
955
+ }
956
+
890
957
  static bool upb_encode_array(upb_encstate *e, const char *field_mem,
891
958
  const upb_msglayout *m,
892
959
  const upb_msglayout_field *f) {
893
960
  const upb_array *arr = *(const upb_array**)field_mem;
961
+ bool packed = f->label == _UPB_LABEL_PACKED;
894
962
 
895
963
  if (arr == NULL || arr->len == 0) {
896
964
  return true;
897
965
  }
898
966
 
899
- #define VARINT_CASE(ctype, encode) { \
900
- ctype *start = arr->data; \
901
- ctype *ptr = start + arr->len; \
902
- size_t pre_len = e->limit - e->ptr; \
903
- do { \
904
- ptr--; \
905
- CHK(upb_put_varint(e, encode)); \
906
- } while (ptr != start); \
907
- CHK(upb_put_varint(e, e->limit - e->ptr - pre_len)); \
908
- } \
909
- break; \
910
- do { ; } while(0)
967
+ #define VARINT_CASE(ctype, encode) \
968
+ { \
969
+ const ctype *start = _upb_array_constptr(arr); \
970
+ const ctype *ptr = start + arr->len; \
971
+ size_t pre_len = e->limit - e->ptr; \
972
+ uint32_t tag = packed ? 0 : (f->number << 3) | UPB_WIRE_TYPE_VARINT; \
973
+ do { \
974
+ ptr--; \
975
+ CHK(upb_put_varint(e, encode)); \
976
+ if (tag) CHK(upb_put_varint(e, tag)); \
977
+ } while (ptr != start); \
978
+ if (!tag) CHK(upb_put_varint(e, e->limit - e->ptr - pre_len)); \
979
+ } \
980
+ break; \
981
+ do { \
982
+ ; \
983
+ } while (0)
984
+
985
+ #define TAG(wire_type) (packed ? 0 : (f->number << 3 | wire_type))
911
986
 
912
987
  switch (f->descriptortype) {
913
988
  case UPB_DESCRIPTOR_TYPE_DOUBLE:
914
- CHK(upb_put_fixedarray(e, arr, sizeof(double)));
989
+ CHK(upb_put_fixedarray(e, arr, sizeof(double), TAG(UPB_WIRE_TYPE_64BIT)));
915
990
  break;
916
991
  case UPB_DESCRIPTOR_TYPE_FLOAT:
917
- CHK(upb_put_fixedarray(e, arr, sizeof(float)));
992
+ CHK(upb_put_fixedarray(e, arr, sizeof(float), TAG(UPB_WIRE_TYPE_32BIT)));
918
993
  break;
919
994
  case UPB_DESCRIPTOR_TYPE_SFIXED64:
920
995
  case UPB_DESCRIPTOR_TYPE_FIXED64:
921
- CHK(upb_put_fixedarray(e, arr, sizeof(uint64_t)));
996
+ CHK(upb_put_fixedarray(e, arr, sizeof(uint64_t), TAG(UPB_WIRE_TYPE_64BIT)));
922
997
  break;
923
998
  case UPB_DESCRIPTOR_TYPE_FIXED32:
924
999
  case UPB_DESCRIPTOR_TYPE_SFIXED32:
925
- CHK(upb_put_fixedarray(e, arr, sizeof(uint32_t)));
1000
+ CHK(upb_put_fixedarray(e, arr, sizeof(uint32_t), TAG(UPB_WIRE_TYPE_32BIT)));
926
1001
  break;
927
1002
  case UPB_DESCRIPTOR_TYPE_INT64:
928
1003
  case UPB_DESCRIPTOR_TYPE_UINT64:
@@ -940,8 +1015,8 @@ do { ; } while(0)
940
1015
  VARINT_CASE(int64_t, upb_zzencode_64(*ptr));
941
1016
  case UPB_DESCRIPTOR_TYPE_STRING:
942
1017
  case UPB_DESCRIPTOR_TYPE_BYTES: {
943
- upb_strview *start = arr->data;
944
- upb_strview *ptr = start + arr->len;
1018
+ const upb_strview *start = _upb_array_constptr(arr);
1019
+ const upb_strview *ptr = start + arr->len;
945
1020
  do {
946
1021
  ptr--;
947
1022
  CHK(upb_put_bytes(e, ptr->data, ptr->size) &&
@@ -951,8 +1026,8 @@ do { ; } while(0)
951
1026
  return true;
952
1027
  }
953
1028
  case UPB_DESCRIPTOR_TYPE_GROUP: {
954
- void **start = arr->data;
955
- void **ptr = start + arr->len;
1029
+ const void *const*start = _upb_array_constptr(arr);
1030
+ const void *const*ptr = start + arr->len;
956
1031
  const upb_msglayout *subm = m->submsgs[f->submsg_index];
957
1032
  do {
958
1033
  size_t size;
@@ -964,8 +1039,8 @@ do { ; } while(0)
964
1039
  return true;
965
1040
  }
966
1041
  case UPB_DESCRIPTOR_TYPE_MESSAGE: {
967
- void **start = arr->data;
968
- void **ptr = start + arr->len;
1042
+ const void *const*start = _upb_array_constptr(arr);
1043
+ const void *const*ptr = start + arr->len;
969
1044
  const upb_msglayout *subm = m->submsgs[f->submsg_index];
970
1045
  do {
971
1046
  size_t size;
@@ -979,87 +1054,46 @@ do { ; } while(0)
979
1054
  }
980
1055
  #undef VARINT_CASE
981
1056
 
982
- /* We encode all primitive arrays as packed, regardless of what was specified
983
- * in the .proto file. Could special case 1-sized arrays. */
984
- CHK(upb_put_tag(e, f->number, UPB_WIRE_TYPE_DELIMITED));
1057
+ if (packed) {
1058
+ CHK(upb_put_tag(e, f->number, UPB_WIRE_TYPE_DELIMITED));
1059
+ }
985
1060
  return true;
986
1061
  }
987
1062
 
988
- static bool upb_encode_scalarfield(upb_encstate *e, const char *field_mem,
989
- const upb_msglayout *m,
990
- const upb_msglayout_field *f,
991
- bool skip_zero_value) {
992
- #define CASE(ctype, type, wire_type, encodeval) do { \
993
- ctype val = *(ctype*)field_mem; \
994
- if (skip_zero_value && val == 0) { \
995
- return true; \
996
- } \
997
- return upb_put_ ## type(e, encodeval) && \
998
- upb_put_tag(e, f->number, wire_type); \
999
- } while(0)
1063
+ static bool upb_encode_map(upb_encstate *e, const char *field_mem,
1064
+ const upb_msglayout *m,
1065
+ const upb_msglayout_field *f) {
1066
+ const upb_map *map = *(const upb_map**)field_mem;
1067
+ const upb_msglayout *entry = m->submsgs[f->submsg_index];
1068
+ const upb_msglayout_field *key_field = &entry->fields[0];
1069
+ const upb_msglayout_field *val_field = &entry->fields[1];
1070
+ upb_strtable_iter i;
1071
+ if (map == NULL) {
1072
+ return true;
1073
+ }
1000
1074
 
1001
- switch (f->descriptortype) {
1002
- case UPB_DESCRIPTOR_TYPE_DOUBLE:
1003
- CASE(double, double, UPB_WIRE_TYPE_64BIT, val);
1004
- case UPB_DESCRIPTOR_TYPE_FLOAT:
1005
- CASE(float, float, UPB_WIRE_TYPE_32BIT, val);
1006
- case UPB_DESCRIPTOR_TYPE_INT64:
1007
- case UPB_DESCRIPTOR_TYPE_UINT64:
1008
- CASE(uint64_t, varint, UPB_WIRE_TYPE_VARINT, val);
1009
- case UPB_DESCRIPTOR_TYPE_UINT32:
1010
- CASE(uint32_t, varint, UPB_WIRE_TYPE_VARINT, val);
1011
- case UPB_DESCRIPTOR_TYPE_INT32:
1012
- case UPB_DESCRIPTOR_TYPE_ENUM:
1013
- CASE(int32_t, varint, UPB_WIRE_TYPE_VARINT, (int64_t)val);
1014
- case UPB_DESCRIPTOR_TYPE_SFIXED64:
1015
- case UPB_DESCRIPTOR_TYPE_FIXED64:
1016
- CASE(uint64_t, fixed64, UPB_WIRE_TYPE_64BIT, val);
1017
- case UPB_DESCRIPTOR_TYPE_FIXED32:
1018
- case UPB_DESCRIPTOR_TYPE_SFIXED32:
1019
- CASE(uint32_t, fixed32, UPB_WIRE_TYPE_32BIT, val);
1020
- case UPB_DESCRIPTOR_TYPE_BOOL:
1021
- CASE(bool, varint, UPB_WIRE_TYPE_VARINT, val);
1022
- case UPB_DESCRIPTOR_TYPE_SINT32:
1023
- CASE(int32_t, varint, UPB_WIRE_TYPE_VARINT, upb_zzencode_32(val));
1024
- case UPB_DESCRIPTOR_TYPE_SINT64:
1025
- CASE(int64_t, varint, UPB_WIRE_TYPE_VARINT, upb_zzencode_64(val));
1026
- case UPB_DESCRIPTOR_TYPE_STRING:
1027
- case UPB_DESCRIPTOR_TYPE_BYTES: {
1028
- upb_strview view = *(upb_strview*)field_mem;
1029
- if (skip_zero_value && view.size == 0) {
1030
- return true;
1031
- }
1032
- return upb_put_bytes(e, view.data, view.size) &&
1033
- upb_put_varint(e, view.size) &&
1034
- upb_put_tag(e, f->number, UPB_WIRE_TYPE_DELIMITED);
1035
- }
1036
- case UPB_DESCRIPTOR_TYPE_GROUP: {
1037
- size_t size;
1038
- void *submsg = *(void **)field_mem;
1039
- const upb_msglayout *subm = m->submsgs[f->submsg_index];
1040
- if (submsg == NULL) {
1041
- return true;
1042
- }
1043
- return upb_put_tag(e, f->number, UPB_WIRE_TYPE_END_GROUP) &&
1044
- upb_encode_message(e, submsg, subm, &size) &&
1045
- upb_put_tag(e, f->number, UPB_WIRE_TYPE_START_GROUP);
1046
- }
1047
- case UPB_DESCRIPTOR_TYPE_MESSAGE: {
1048
- size_t size;
1049
- void *submsg = *(void **)field_mem;
1050
- const upb_msglayout *subm = m->submsgs[f->submsg_index];
1051
- if (submsg == NULL) {
1052
- return true;
1053
- }
1054
- return upb_encode_message(e, submsg, subm, &size) &&
1055
- upb_put_varint(e, size) &&
1056
- upb_put_tag(e, f->number, UPB_WIRE_TYPE_DELIMITED);
1057
- }
1075
+ upb_strtable_begin(&i, &map->table);
1076
+ for(; !upb_strtable_done(&i); upb_strtable_next(&i)) {
1077
+ size_t pre_len = e->limit - e->ptr;
1078
+ size_t size;
1079
+ upb_strview key = upb_strtable_iter_key(&i);
1080
+ const upb_value val = upb_strtable_iter_value(&i);
1081
+ const void *keyp =
1082
+ map->key_size == UPB_MAPTYPE_STRING ? (void *)&key : key.data;
1083
+ const void *valp =
1084
+ map->val_size == UPB_MAPTYPE_STRING ? upb_value_getptr(val) : &val;
1085
+
1086
+ CHK(upb_encode_scalarfield(e, valp, entry, val_field, false));
1087
+ CHK(upb_encode_scalarfield(e, keyp, entry, key_field, false));
1088
+ size = (e->limit - e->ptr) - pre_len;
1089
+ CHK(upb_put_varint(e, size));
1090
+ CHK(upb_put_tag(e, f->number, UPB_WIRE_TYPE_DELIMITED));
1058
1091
  }
1059
- #undef CASE
1060
- UPB_UNREACHABLE();
1092
+
1093
+ return true;
1061
1094
  }
1062
1095
 
1096
+
1063
1097
  bool upb_encode_message(upb_encstate *e, const char *msg,
1064
1098
  const upb_msglayout *m, size_t *size) {
1065
1099
  int i;
@@ -1067,11 +1101,19 @@ bool upb_encode_message(upb_encstate *e, const char *msg,
1067
1101
  const char *unknown;
1068
1102
  size_t unknown_size;
1069
1103
 
1104
+ unknown = upb_msg_getunknown(msg, &unknown_size);
1105
+
1106
+ if (unknown) {
1107
+ upb_put_bytes(e, unknown, unknown_size);
1108
+ }
1109
+
1070
1110
  for (i = m->field_count - 1; i >= 0; i--) {
1071
1111
  const upb_msglayout_field *f = &m->fields[i];
1072
1112
 
1073
- if (f->label == UPB_LABEL_REPEATED) {
1113
+ if (_upb_isrepeated(f)) {
1074
1114
  CHK(upb_encode_array(e, msg + f->offset, m, f));
1115
+ } else if (f->label == _UPB_LABEL_MAP) {
1116
+ CHK(upb_encode_map(e, msg + f->offset, m, f));
1075
1117
  } else {
1076
1118
  bool skip_empty = false;
1077
1119
  if (f->presence == 0) {
@@ -1092,12 +1134,6 @@ bool upb_encode_message(upb_encstate *e, const char *msg,
1092
1134
  }
1093
1135
  }
1094
1136
 
1095
- unknown = upb_msg_getunknown(msg, &unknown_size);
1096
-
1097
- if (unknown) {
1098
- upb_put_bytes(e, unknown, unknown_size);
1099
- }
1100
-
1101
1137
  *size = (e->limit - e->ptr) - pre_len;
1102
1138
  return true;
1103
1139
  }
@@ -1131,24 +1167,27 @@ char *upb_encode(const void *msg, const upb_msglayout *m, upb_arena *arena,
1131
1167
 
1132
1168
 
1133
1169
 
1134
- #define VOIDPTR_AT(msg, ofs) (void*)((char*)msg + (int)ofs)
1135
-
1136
- /* Internal members of a upb_msg. We can change this without breaking binary
1137
- * compatibility. We put these before the user's data. The user's upb_msg*
1138
- * points after the upb_msg_internal. */
1170
+ /** upb_msg *******************************************************************/
1139
1171
 
1140
- /* Used when a message is not extendable. */
1141
- typedef struct {
1142
- char *unknown;
1143
- size_t unknown_len;
1144
- size_t unknown_size;
1145
- } upb_msg_internal;
1172
+ static const char _upb_fieldtype_to_sizelg2[12] = {
1173
+ 0,
1174
+ 0, /* UPB_TYPE_BOOL */
1175
+ 2, /* UPB_TYPE_FLOAT */
1176
+ 2, /* UPB_TYPE_INT32 */
1177
+ 2, /* UPB_TYPE_UINT32 */
1178
+ 2, /* UPB_TYPE_ENUM */
1179
+ UPB_SIZE(2, 3), /* UPB_TYPE_MESSAGE */
1180
+ 3, /* UPB_TYPE_DOUBLE */
1181
+ 3, /* UPB_TYPE_INT64 */
1182
+ 3, /* UPB_TYPE_UINT64 */
1183
+ UPB_SIZE(3, 4), /* UPB_TYPE_STRING */
1184
+ UPB_SIZE(3, 4), /* UPB_TYPE_BYTES */
1185
+ };
1146
1186
 
1147
- /* Used when a message is extendable. */
1148
- typedef struct {
1149
- upb_inttable *extdict;
1150
- upb_msg_internal base;
1151
- } upb_msg_internal_withext;
1187
+ static uintptr_t tag_arrptr(void* ptr, int elem_size_lg2) {
1188
+ UPB_ASSERT(elem_size_lg2 <= 4);
1189
+ return (uintptr_t)ptr | elem_size_lg2;
1190
+ }
1152
1191
 
1153
1192
  static int upb_msg_internalsize(const upb_msglayout *l) {
1154
1193
  return sizeof(upb_msg_internal) - l->extendable * sizeof(void *);
@@ -1159,22 +1198,22 @@ static size_t upb_msg_sizeof(const upb_msglayout *l) {
1159
1198
  }
1160
1199
 
1161
1200
  static upb_msg_internal *upb_msg_getinternal(upb_msg *msg) {
1162
- return VOIDPTR_AT(msg, -sizeof(upb_msg_internal));
1201
+ return UPB_PTR_AT(msg, -sizeof(upb_msg_internal), upb_msg_internal);
1163
1202
  }
1164
1203
 
1165
1204
  static const upb_msg_internal *upb_msg_getinternal_const(const upb_msg *msg) {
1166
- return VOIDPTR_AT(msg, -sizeof(upb_msg_internal));
1205
+ return UPB_PTR_AT(msg, -sizeof(upb_msg_internal), upb_msg_internal);
1167
1206
  }
1168
1207
 
1169
1208
  static upb_msg_internal_withext *upb_msg_getinternalwithext(
1170
1209
  upb_msg *msg, const upb_msglayout *l) {
1171
1210
  UPB_ASSERT(l->extendable);
1172
- return VOIDPTR_AT(msg, -sizeof(upb_msg_internal_withext));
1211
+ return UPB_PTR_AT(msg, -sizeof(upb_msg_internal_withext),
1212
+ upb_msg_internal_withext);
1173
1213
  }
1174
1214
 
1175
- upb_msg *upb_msg_new(const upb_msglayout *l, upb_arena *a) {
1176
- upb_alloc *alloc = upb_arena_alloc(a);
1177
- void *mem = upb_malloc(alloc, upb_msg_sizeof(l));
1215
+ upb_msg *_upb_msg_new(const upb_msglayout *l, upb_arena *a) {
1216
+ void *mem = upb_arena_malloc(a, upb_msg_sizeof(l));
1178
1217
  upb_msg_internal *in;
1179
1218
  upb_msg *msg;
1180
1219
 
@@ -1182,7 +1221,7 @@ upb_msg *upb_msg_new(const upb_msglayout *l, upb_arena *a) {
1182
1221
  return NULL;
1183
1222
  }
1184
1223
 
1185
- msg = VOIDPTR_AT(mem, upb_msg_internalsize(l));
1224
+ msg = UPB_PTR_AT(mem, upb_msg_internalsize(l), upb_msg);
1186
1225
 
1187
1226
  /* Initialize normal members. */
1188
1227
  memset(msg, 0, l->size);
@@ -1200,66 +1239,122 @@ upb_msg *upb_msg_new(const upb_msglayout *l, upb_arena *a) {
1200
1239
  return msg;
1201
1240
  }
1202
1241
 
1203
- upb_array *upb_array_new(upb_arena *a) {
1204
- upb_array *ret = upb_arena_malloc(a, sizeof(upb_array));
1205
-
1206
- if (!ret) {
1207
- return NULL;
1208
- }
1209
-
1210
- ret->data = NULL;
1211
- ret->len = 0;
1212
- ret->size = 0;
1213
-
1214
- return ret;
1215
- }
1216
-
1217
- void upb_msg_addunknown(upb_msg *msg, const char *data, size_t len,
1218
- upb_arena *arena) {
1242
+ bool _upb_msg_addunknown(upb_msg *msg, const char *data, size_t len,
1243
+ upb_arena *arena) {
1219
1244
  upb_msg_internal *in = upb_msg_getinternal(msg);
1220
1245
  if (len > in->unknown_size - in->unknown_len) {
1221
1246
  upb_alloc *alloc = upb_arena_alloc(arena);
1222
1247
  size_t need = in->unknown_size + len;
1223
1248
  size_t newsize = UPB_MAX(in->unknown_size * 2, need);
1224
- in->unknown = upb_realloc(alloc, in->unknown, in->unknown_size, newsize);
1249
+ void *mem = upb_realloc(alloc, in->unknown, in->unknown_size, newsize);
1250
+ if (!mem) return false;
1251
+ in->unknown = mem;
1225
1252
  in->unknown_size = newsize;
1226
1253
  }
1227
1254
  memcpy(in->unknown + in->unknown_len, data, len);
1228
1255
  in->unknown_len += len;
1256
+ return true;
1229
1257
  }
1230
1258
 
1231
1259
  const char *upb_msg_getunknown(const upb_msg *msg, size_t *len) {
1232
- const upb_msg_internal* in = upb_msg_getinternal_const(msg);
1260
+ const upb_msg_internal *in = upb_msg_getinternal_const(msg);
1233
1261
  *len = in->unknown_len;
1234
1262
  return in->unknown;
1235
1263
  }
1236
1264
 
1237
- #undef VOIDPTR_AT
1265
+ /** upb_array *****************************************************************/
1238
1266
 
1267
+ upb_array *_upb_array_new(upb_arena *a, upb_fieldtype_t type) {
1268
+ upb_array *arr = upb_arena_malloc(a, sizeof(upb_array));
1239
1269
 
1240
- #ifdef UPB_MSVC_VSNPRINTF
1241
- /* Visual C++ earlier than 2015 doesn't have standard C99 snprintf and
1242
- * vsnprintf. To support them, missing functions are manually implemented
1243
- * using the existing secure functions. */
1244
- int msvc_vsnprintf(char* s, size_t n, const char* format, va_list arg) {
1245
- if (!s) {
1246
- return _vscprintf(format, arg);
1270
+ if (!arr) {
1271
+ return NULL;
1247
1272
  }
1248
- int ret = _vsnprintf_s(s, n, _TRUNCATE, format, arg);
1249
- if (ret < 0) {
1250
- ret = _vscprintf(format, arg);
1273
+
1274
+ arr->data = tag_arrptr(NULL, _upb_fieldtype_to_sizelg2[type]);
1275
+ arr->len = 0;
1276
+ arr->size = 0;
1277
+
1278
+ return arr;
1279
+ }
1280
+
1281
+ bool _upb_array_realloc(upb_array *arr, size_t min_size, upb_arena *arena) {
1282
+ size_t new_size = UPB_MAX(arr->size, 4);
1283
+ int elem_size_lg2 = arr->data & 7;
1284
+ size_t old_bytes = arr->size << elem_size_lg2;
1285
+ size_t new_bytes;
1286
+ void* ptr = _upb_array_ptr(arr);
1287
+
1288
+ /* Log2 ceiling of size. */
1289
+ while (new_size < min_size) new_size *= 2;
1290
+
1291
+ new_bytes = new_size << elem_size_lg2;
1292
+ ptr = upb_arena_realloc(arena, ptr, old_bytes, new_bytes);
1293
+
1294
+ if (!ptr) {
1295
+ return false;
1251
1296
  }
1252
- return ret;
1297
+
1298
+ arr->data = tag_arrptr(ptr, elem_size_lg2);
1299
+ arr->size = new_size;
1300
+ return true;
1253
1301
  }
1254
1302
 
1255
- int msvc_snprintf(char* s, size_t n, const char* format, ...) {
1256
- va_list arg;
1257
- va_start(arg, format);
1258
- int ret = msvc_vsnprintf(s, n, format, arg);
1259
- va_end(arg);
1260
- return ret;
1303
+ static upb_array *getorcreate_array(upb_array **arr_ptr, upb_fieldtype_t type,
1304
+ upb_arena *arena) {
1305
+ upb_array *arr = *arr_ptr;
1306
+ if (!arr) {
1307
+ arr = _upb_array_new(arena, type);
1308
+ if (!arr) return NULL;
1309
+ *arr_ptr = arr;
1310
+ }
1311
+ return arr;
1312
+ }
1313
+
1314
+ static bool resize_array(upb_array *arr, size_t size, upb_arena *arena) {
1315
+ if (size > arr->size && !_upb_array_realloc(arr, size, arena)) {
1316
+ return false;
1317
+ }
1318
+
1319
+ arr->len = size;
1320
+ return true;
1321
+ }
1322
+
1323
+ void *_upb_array_resize_fallback(upb_array **arr_ptr, size_t size,
1324
+ upb_fieldtype_t type, upb_arena *arena) {
1325
+ upb_array *arr = getorcreate_array(arr_ptr, type, arena);
1326
+ return arr && resize_array(arr, size, arena) ? _upb_array_ptr(arr) : NULL;
1327
+ }
1328
+
1329
+ bool _upb_array_append_fallback(upb_array **arr_ptr, const void *value,
1330
+ upb_fieldtype_t type, upb_arena *arena) {
1331
+ upb_array *arr = getorcreate_array(arr_ptr, type, arena);
1332
+ size_t elem = arr->len;
1333
+ int lg2 = _upb_fieldtype_to_sizelg2[type];
1334
+ char *data;
1335
+
1336
+ if (!arr || !resize_array(arr, elem + 1, arena)) return false;
1337
+
1338
+ data = _upb_array_ptr(arr);
1339
+ memcpy(data + (elem << lg2), value, 1 << lg2);
1340
+ return true;
1341
+ }
1342
+
1343
+ /** upb_map *******************************************************************/
1344
+
1345
+ upb_map *_upb_map_new(upb_arena *a, size_t key_size, size_t value_size) {
1346
+ upb_map *map = upb_arena_malloc(a, sizeof(upb_map));
1347
+
1348
+ if (!map) {
1349
+ return NULL;
1350
+ }
1351
+
1352
+ upb_strtable_init2(&map->table, UPB_CTYPE_INT32, upb_arena_alloc(a));
1353
+ map->key_size = key_size;
1354
+ map->val_size = value_size;
1355
+
1356
+ return map;
1261
1357
  }
1262
- #endif
1263
1358
  /*
1264
1359
  ** upb_table Implementation
1265
1360
  **
@@ -1276,12 +1371,6 @@ int msvc_snprintf(char* s, size_t n, const char* format, ...) {
1276
1371
  #define ARRAY_SIZE(x) \
1277
1372
  ((sizeof(x)/sizeof(0[x])) / ((size_t)(!(sizeof(x) % sizeof(0[x])))))
1278
1373
 
1279
- static void upb_check_alloc(upb_table *t, upb_alloc *a) {
1280
- UPB_UNUSED(t);
1281
- UPB_UNUSED(a);
1282
- UPB_ASSERT_DEBUGVAR(t->alloc == a);
1283
- }
1284
-
1285
1374
  static const double MAX_LOAD = 0.85;
1286
1375
 
1287
1376
  /* The minimum utilization of the array part of a mixed hash/array table. This
@@ -1360,17 +1449,12 @@ static bool isfull(upb_table *t) {
1360
1449
  }
1361
1450
  }
1362
1451
 
1363
- static bool init(upb_table *t, upb_ctype_t ctype, uint8_t size_lg2,
1364
- upb_alloc *a) {
1452
+ static bool init(upb_table *t, uint8_t size_lg2, upb_alloc *a) {
1365
1453
  size_t bytes;
1366
1454
 
1367
1455
  t->count = 0;
1368
- t->ctype = ctype;
1369
1456
  t->size_lg2 = size_lg2;
1370
1457
  t->mask = upb_table_size(t) ? upb_table_size(t) - 1 : 0;
1371
- #ifndef NDEBUG
1372
- t->alloc = a;
1373
- #endif
1374
1458
  bytes = upb_table_size(t) * sizeof(upb_tabent);
1375
1459
  if (bytes > 0) {
1376
1460
  t->entries = upb_malloc(a, bytes);
@@ -1383,7 +1467,6 @@ static bool init(upb_table *t, upb_ctype_t ctype, uint8_t size_lg2,
1383
1467
  }
1384
1468
 
1385
1469
  static void uninit(upb_table *t, upb_alloc *a) {
1386
- upb_check_alloc(t, a);
1387
1470
  upb_free(a, mutable_entries(t));
1388
1471
  }
1389
1472
 
@@ -1419,7 +1502,7 @@ static bool lookup(const upb_table *t, lookupkey_t key, upb_value *v,
1419
1502
  const upb_tabent *e = findentry(t, key, hash, eql);
1420
1503
  if (e) {
1421
1504
  if (v) {
1422
- _upb_value_setval(v, e->val.val, t->ctype);
1505
+ _upb_value_setval(v, e->val.val);
1423
1506
  }
1424
1507
  return true;
1425
1508
  } else {
@@ -1435,7 +1518,6 @@ static void insert(upb_table *t, lookupkey_t key, upb_tabkey tabkey,
1435
1518
  upb_tabent *our_e;
1436
1519
 
1437
1520
  UPB_ASSERT(findentry(t, key, hash, eql) == NULL);
1438
- UPB_ASSERT_DEBUGVAR(val.ctype == t->ctype);
1439
1521
 
1440
1522
  t->count++;
1441
1523
  mainpos_e = getentry_mutable(t, hash);
@@ -1481,7 +1563,7 @@ static bool rm(upb_table *t, lookupkey_t key, upb_value *val,
1481
1563
  if (eql(chain->key, key)) {
1482
1564
  /* Element to remove is at the head of its chain. */
1483
1565
  t->count--;
1484
- if (val) _upb_value_setval(val, chain->val.val, t->ctype);
1566
+ if (val) _upb_value_setval(val, chain->val.val);
1485
1567
  if (removed) *removed = chain->key;
1486
1568
  if (chain->next) {
1487
1569
  upb_tabent *move = (upb_tabent*)chain->next;
@@ -1501,7 +1583,7 @@ static bool rm(upb_table *t, lookupkey_t key, upb_value *val,
1501
1583
  /* Found element to remove. */
1502
1584
  upb_tabent *rm = (upb_tabent*)chain->next;
1503
1585
  t->count--;
1504
- if (val) _upb_value_setval(val, chain->next->val.val, t->ctype);
1586
+ if (val) _upb_value_setval(val, chain->next->val.val);
1505
1587
  if (removed) *removed = rm->key;
1506
1588
  rm->key = 0; /* Make the slot empty. */
1507
1589
  chain->next = rm->next;
@@ -1554,7 +1636,13 @@ static bool streql(upb_tabkey k1, lookupkey_t k2) {
1554
1636
  }
1555
1637
 
1556
1638
  bool upb_strtable_init2(upb_strtable *t, upb_ctype_t ctype, upb_alloc *a) {
1557
- return init(&t->t, ctype, 2, a);
1639
+ return init(&t->t, 2, a);
1640
+ }
1641
+
1642
+ void upb_strtable_clear(upb_strtable *t) {
1643
+ size_t bytes = upb_table_size(&t->t) * sizeof(upb_tabent);
1644
+ t->t.count = 0;
1645
+ memset((char*)t->t.entries, 0, bytes);
1558
1646
  }
1559
1647
 
1560
1648
  void upb_strtable_uninit2(upb_strtable *t, upb_alloc *a) {
@@ -1568,18 +1656,14 @@ bool upb_strtable_resize(upb_strtable *t, size_t size_lg2, upb_alloc *a) {
1568
1656
  upb_strtable new_table;
1569
1657
  upb_strtable_iter i;
1570
1658
 
1571
- upb_check_alloc(&t->t, a);
1572
-
1573
- if (!init(&new_table.t, t->t.ctype, size_lg2, a))
1659
+ if (!init(&new_table.t, size_lg2, a))
1574
1660
  return false;
1575
1661
  upb_strtable_begin(&i, t);
1576
1662
  for ( ; !upb_strtable_done(&i); upb_strtable_next(&i)) {
1663
+ upb_strview key = upb_strtable_iter_key(&i);
1577
1664
  upb_strtable_insert3(
1578
- &new_table,
1579
- upb_strtable_iter_key(&i),
1580
- upb_strtable_iter_keylength(&i),
1581
- upb_strtable_iter_value(&i),
1582
- a);
1665
+ &new_table, key.data, key.size,
1666
+ upb_strtable_iter_value(&i), a);
1583
1667
  }
1584
1668
  upb_strtable_uninit2(t, a);
1585
1669
  *t = new_table;
@@ -1592,8 +1676,6 @@ bool upb_strtable_insert3(upb_strtable *t, const char *k, size_t len,
1592
1676
  upb_tabkey tabkey;
1593
1677
  uint32_t hash;
1594
1678
 
1595
- upb_check_alloc(&t->t, a);
1596
-
1597
1679
  if (isfull(&t->t)) {
1598
1680
  /* Need to resize. New table of double the size, add old elements to it. */
1599
1681
  if (!upb_strtable_resize(t, t->t.size_lg2 + 1, a)) {
@@ -1621,7 +1703,10 @@ bool upb_strtable_remove3(upb_strtable *t, const char *key, size_t len,
1621
1703
  uint32_t hash = upb_murmur_hash2(key, len, 0);
1622
1704
  upb_tabkey tabkey;
1623
1705
  if (rm(&t->t, strkey2(key, len), val, &tabkey, hash, &streql)) {
1624
- upb_free(alloc, (void*)tabkey);
1706
+ if (alloc) {
1707
+ /* Arena-based allocs don't need to free and won't pass this. */
1708
+ upb_free(alloc, (void*)tabkey);
1709
+ }
1625
1710
  return true;
1626
1711
  } else {
1627
1712
  return false;
@@ -1630,10 +1715,6 @@ bool upb_strtable_remove3(upb_strtable *t, const char *key, size_t len,
1630
1715
 
1631
1716
  /* Iteration */
1632
1717
 
1633
- static const upb_tabent *str_tabent(const upb_strtable_iter *i) {
1634
- return &i->t->t.entries[i->index];
1635
- }
1636
-
1637
1718
  void upb_strtable_begin(upb_strtable_iter *i, const upb_strtable *t) {
1638
1719
  i->t = t;
1639
1720
  i->index = begin(&t->t);
@@ -1646,24 +1727,21 @@ void upb_strtable_next(upb_strtable_iter *i) {
1646
1727
  bool upb_strtable_done(const upb_strtable_iter *i) {
1647
1728
  if (!i->t) return true;
1648
1729
  return i->index >= upb_table_size(&i->t->t) ||
1649
- upb_tabent_isempty(str_tabent(i));
1650
- }
1651
-
1652
- const char *upb_strtable_iter_key(const upb_strtable_iter *i) {
1653
- UPB_ASSERT(!upb_strtable_done(i));
1654
- return upb_tabstr(str_tabent(i)->key, NULL);
1730
+ upb_tabent_isempty(str_tabent(i));
1655
1731
  }
1656
1732
 
1657
- size_t upb_strtable_iter_keylength(const upb_strtable_iter *i) {
1733
+ upb_strview upb_strtable_iter_key(const upb_strtable_iter *i) {
1734
+ upb_strview key;
1658
1735
  uint32_t len;
1659
1736
  UPB_ASSERT(!upb_strtable_done(i));
1660
- upb_tabstr(str_tabent(i)->key, &len);
1661
- return len;
1737
+ key.data = upb_tabstr(str_tabent(i)->key, &len);
1738
+ key.size = len;
1739
+ return key;
1662
1740
  }
1663
1741
 
1664
1742
  upb_value upb_strtable_iter_value(const upb_strtable_iter *i) {
1665
1743
  UPB_ASSERT(!upb_strtable_done(i));
1666
- return _upb_value_val(str_tabent(i)->val.val, i->t->t.ctype);
1744
+ return _upb_value_val(str_tabent(i)->val.val);
1667
1745
  }
1668
1746
 
1669
1747
  void upb_strtable_iter_setdone(upb_strtable_iter *i) {
@@ -1729,11 +1807,11 @@ static void check(upb_inttable *t) {
1729
1807
  #endif
1730
1808
  }
1731
1809
 
1732
- bool upb_inttable_sizedinit(upb_inttable *t, upb_ctype_t ctype,
1733
- size_t asize, int hsize_lg2, upb_alloc *a) {
1810
+ bool upb_inttable_sizedinit(upb_inttable *t, size_t asize, int hsize_lg2,
1811
+ upb_alloc *a) {
1734
1812
  size_t array_bytes;
1735
1813
 
1736
- if (!init(&t->t, ctype, hsize_lg2, a)) return false;
1814
+ if (!init(&t->t, hsize_lg2, a)) return false;
1737
1815
  /* Always make the array part at least 1 long, so that we know key 0
1738
1816
  * won't be in the hash part, which simplifies things. */
1739
1817
  t->array_size = UPB_MAX(1, asize);
@@ -1750,7 +1828,7 @@ bool upb_inttable_sizedinit(upb_inttable *t, upb_ctype_t ctype,
1750
1828
  }
1751
1829
 
1752
1830
  bool upb_inttable_init2(upb_inttable *t, upb_ctype_t ctype, upb_alloc *a) {
1753
- return upb_inttable_sizedinit(t, ctype, 0, 4, a);
1831
+ return upb_inttable_sizedinit(t, 0, 4, a);
1754
1832
  }
1755
1833
 
1756
1834
  void upb_inttable_uninit2(upb_inttable *t, upb_alloc *a) {
@@ -1764,8 +1842,6 @@ bool upb_inttable_insert2(upb_inttable *t, uintptr_t key, upb_value val,
1764
1842
  tabval.val = val.val;
1765
1843
  UPB_ASSERT(upb_arrhas(tabval)); /* This will reject (uint64_t)-1. Fix this. */
1766
1844
 
1767
- upb_check_alloc(&t->t, a);
1768
-
1769
1845
  if (key < t->array_size) {
1770
1846
  UPB_ASSERT(!upb_arrhas(t->array[key]));
1771
1847
  t->array_count++;
@@ -1776,7 +1852,7 @@ bool upb_inttable_insert2(upb_inttable *t, uintptr_t key, upb_value val,
1776
1852
  size_t i;
1777
1853
  upb_table new_table;
1778
1854
 
1779
- if (!init(&new_table, t->t.ctype, t->t.size_lg2 + 1, a)) {
1855
+ if (!init(&new_table, t->t.size_lg2 + 1, a)) {
1780
1856
  return false;
1781
1857
  }
1782
1858
 
@@ -1785,7 +1861,7 @@ bool upb_inttable_insert2(upb_inttable *t, uintptr_t key, upb_value val,
1785
1861
  uint32_t hash;
1786
1862
  upb_value v;
1787
1863
 
1788
- _upb_value_setval(&v, e->val.val, t->t.ctype);
1864
+ _upb_value_setval(&v, e->val.val);
1789
1865
  hash = upb_inthash(e->key);
1790
1866
  insert(&new_table, intkey(e->key), e->key, v, hash, &inthash, &inteql);
1791
1867
  }
@@ -1804,7 +1880,7 @@ bool upb_inttable_insert2(upb_inttable *t, uintptr_t key, upb_value val,
1804
1880
  bool upb_inttable_lookup(const upb_inttable *t, uintptr_t key, upb_value *v) {
1805
1881
  const upb_tabval *table_v = inttable_val_const(t, key);
1806
1882
  if (!table_v) return false;
1807
- if (v) _upb_value_setval(v, table_v->val, t->t.ctype);
1883
+ if (v) _upb_value_setval(v, table_v->val);
1808
1884
  return true;
1809
1885
  }
1810
1886
 
@@ -1822,7 +1898,7 @@ bool upb_inttable_remove(upb_inttable *t, uintptr_t key, upb_value *val) {
1822
1898
  upb_tabval empty = UPB_TABVALUE_EMPTY_INIT;
1823
1899
  t->array_count--;
1824
1900
  if (val) {
1825
- _upb_value_setval(val, t->array[key].val, t->t.ctype);
1901
+ _upb_value_setval(val, t->array[key].val);
1826
1902
  }
1827
1903
  mutable_array(t)[key] = empty;
1828
1904
  success = true;
@@ -1837,7 +1913,6 @@ bool upb_inttable_remove(upb_inttable *t, uintptr_t key, upb_value *val) {
1837
1913
  }
1838
1914
 
1839
1915
  bool upb_inttable_push2(upb_inttable *t, upb_value val, upb_alloc *a) {
1840
- upb_check_alloc(&t->t, a);
1841
1916
  return upb_inttable_insert2(t, upb_inttable_count(t), val, a);
1842
1917
  }
1843
1918
 
@@ -1850,7 +1925,6 @@ upb_value upb_inttable_pop(upb_inttable *t) {
1850
1925
 
1851
1926
  bool upb_inttable_insertptr2(upb_inttable *t, const void *key, upb_value val,
1852
1927
  upb_alloc *a) {
1853
- upb_check_alloc(&t->t, a);
1854
1928
  return upb_inttable_insert2(t, (uintptr_t)key, val, a);
1855
1929
  }
1856
1930
 
@@ -1875,8 +1949,6 @@ void upb_inttable_compact2(upb_inttable *t, upb_alloc *a) {
1875
1949
  int size_lg2;
1876
1950
  upb_inttable new_t;
1877
1951
 
1878
- upb_check_alloc(&t->t, a);
1879
-
1880
1952
  upb_inttable_begin(&i, t);
1881
1953
  for (; !upb_inttable_done(&i); upb_inttable_next(&i)) {
1882
1954
  uintptr_t key = upb_inttable_iter_key(&i);
@@ -1909,7 +1981,7 @@ void upb_inttable_compact2(upb_inttable *t, upb_alloc *a) {
1909
1981
  size_t hash_size = hash_count ? (hash_count / MAX_LOAD) + 1 : 0;
1910
1982
  int hashsize_lg2 = log2ceil(hash_size);
1911
1983
 
1912
- upb_inttable_sizedinit(&new_t, t->t.ctype, arr_size, hashsize_lg2, a);
1984
+ upb_inttable_sizedinit(&new_t, arr_size, hashsize_lg2, a);
1913
1985
  upb_inttable_begin(&i, t);
1914
1986
  for (; !upb_inttable_done(&i); upb_inttable_next(&i)) {
1915
1987
  uintptr_t k = upb_inttable_iter_key(&i);
@@ -1975,8 +2047,7 @@ uintptr_t upb_inttable_iter_key(const upb_inttable_iter *i) {
1975
2047
  upb_value upb_inttable_iter_value(const upb_inttable_iter *i) {
1976
2048
  UPB_ASSERT(!upb_inttable_done(i));
1977
2049
  return _upb_value_val(
1978
- i->array_part ? i->t->array[i->index].val : int_tabent(i)->val.val,
1979
- i->t->t.ctype);
2050
+ i->array_part ? i->t->array[i->index].val : int_tabent(i)->val.val);
1980
2051
  }
1981
2052
 
1982
2053
  void upb_inttable_iter_setdone(upb_inttable_iter *i) {
@@ -2016,7 +2087,8 @@ uint32_t upb_murmur_hash2(const void *key, size_t len, uint32_t seed) {
2016
2087
  /* Mix 4 bytes at a time into the hash */
2017
2088
  const uint8_t * data = (const uint8_t *)key;
2018
2089
  while(len >= 4) {
2019
- uint32_t k = *(uint32_t *)data;
2090
+ uint32_t k;
2091
+ memcpy(&k, data, sizeof(k));
2020
2092
 
2021
2093
  k *= m;
2022
2094
  k ^= k >> r;
@@ -2181,17 +2253,6 @@ uint32_t upb_murmur_hash2(const void * key, size_t len, uint32_t seed) {
2181
2253
  #include <string.h>
2182
2254
 
2183
2255
 
2184
- /* Guarantee null-termination and provide ellipsis truncation.
2185
- * It may be tempting to "optimize" this by initializing these final
2186
- * four bytes up-front and then being careful never to overwrite them,
2187
- * this is safer and simpler. */
2188
- static void nullz(upb_status *status) {
2189
- const char *ellipsis = "...";
2190
- size_t len = strlen(ellipsis);
2191
- UPB_ASSERT(sizeof(status->msg) > len);
2192
- memcpy(status->msg + sizeof(status->msg) - len, ellipsis, len);
2193
- }
2194
-
2195
2256
  /* upb_status *****************************************************************/
2196
2257
 
2197
2258
  void upb_status_clear(upb_status *status) {
@@ -2207,8 +2268,8 @@ const char *upb_status_errmsg(const upb_status *status) { return status->msg; }
2207
2268
  void upb_status_seterrmsg(upb_status *status, const char *msg) {
2208
2269
  if (!status) return;
2209
2270
  status->ok = false;
2210
- strncpy(status->msg, msg, sizeof(status->msg));
2211
- nullz(status);
2271
+ strncpy(status->msg, msg, UPB_STATUS_MAX_MESSAGE - 1);
2272
+ status->msg[UPB_STATUS_MAX_MESSAGE - 1] = '\0';
2212
2273
  }
2213
2274
 
2214
2275
  void upb_status_seterrf(upb_status *status, const char *fmt, ...) {
@@ -2222,7 +2283,7 @@ void upb_status_vseterrf(upb_status *status, const char *fmt, va_list args) {
2222
2283
  if (!status) return;
2223
2284
  status->ok = false;
2224
2285
  _upb_vsnprintf(status->msg, sizeof(status->msg), fmt, args);
2225
- nullz(status);
2286
+ status->msg[UPB_STATUS_MAX_MESSAGE - 1] = '\0';
2226
2287
  }
2227
2288
 
2228
2289
  /* upb_alloc ******************************************************************/
@@ -2244,16 +2305,10 @@ upb_alloc upb_alloc_global = {&upb_global_allocfunc};
2244
2305
  /* upb_arena ******************************************************************/
2245
2306
 
2246
2307
  /* Be conservative and choose 16 in case anyone is using SSE. */
2247
- static const size_t maxalign = 16;
2248
-
2249
- static size_t align_up_max(size_t size) {
2250
- return ((size + maxalign - 1) / maxalign) * maxalign;
2251
- }
2252
2308
 
2253
2309
  struct upb_arena {
2254
- /* We implement the allocator interface.
2255
- * This must be the first member of upb_arena! */
2256
- upb_alloc alloc;
2310
+ _upb_arena_head head;
2311
+ char *start;
2257
2312
 
2258
2313
  /* Allocator to allocate arena blocks. We are responsible for freeing these
2259
2314
  * when we are destroyed. */
@@ -2272,8 +2327,6 @@ struct upb_arena {
2272
2327
 
2273
2328
  typedef struct mem_block {
2274
2329
  struct mem_block *next;
2275
- size_t size;
2276
- size_t used;
2277
2330
  bool owned;
2278
2331
  /* Data follows. */
2279
2332
  } mem_block;
@@ -2288,12 +2341,17 @@ static void upb_arena_addblock(upb_arena *a, void *ptr, size_t size,
2288
2341
  bool owned) {
2289
2342
  mem_block *block = ptr;
2290
2343
 
2344
+ if (a->block_head) {
2345
+ a->bytes_allocated += a->head.ptr - a->start;
2346
+ }
2347
+
2291
2348
  block->next = a->block_head;
2292
- block->size = size;
2293
- block->used = align_up_max(sizeof(mem_block));
2294
2349
  block->owned = owned;
2295
2350
 
2296
2351
  a->block_head = block;
2352
+ a->start = (char*)block + _upb_arena_alignup(sizeof(mem_block));
2353
+ a->head.ptr = a->start;
2354
+ a->head.end = (char*)block + size;
2297
2355
 
2298
2356
  /* TODO(haberman): ASAN poison. */
2299
2357
  }
@@ -2312,39 +2370,31 @@ static mem_block *upb_arena_allocblock(upb_arena *a, size_t size) {
2312
2370
  return block;
2313
2371
  }
2314
2372
 
2373
+ void *_upb_arena_slowmalloc(upb_arena *a, size_t size) {
2374
+ mem_block *block = upb_arena_allocblock(a, size);
2375
+ if (!block) return NULL; /* Out of memory. */
2376
+ return upb_arena_malloc(a, size);
2377
+ }
2378
+
2315
2379
  static void *upb_arena_doalloc(upb_alloc *alloc, void *ptr, size_t oldsize,
2316
2380
  size_t size) {
2317
2381
  upb_arena *a = (upb_arena*)alloc; /* upb_alloc is initial member. */
2318
- mem_block *block = a->block_head;
2319
2382
  void *ret;
2320
2383
 
2321
2384
  if (size == 0) {
2322
2385
  return NULL; /* We are an arena, don't need individual frees. */
2323
2386
  }
2324
2387
 
2325
- size = align_up_max(size);
2388
+ ret = upb_arena_malloc(a, size);
2389
+ if (!ret) return NULL;
2326
2390
 
2327
2391
  /* TODO(haberman): special-case if this is a realloc of the last alloc? */
2328
2392
 
2329
- if (!block || block->size - block->used < size) {
2330
- /* Slow path: have to allocate a new block. */
2331
- block = upb_arena_allocblock(a, size);
2332
-
2333
- if (!block) {
2334
- return NULL; /* Out of memory. */
2335
- }
2336
- }
2337
-
2338
- ret = (char*)block + block->used;
2339
- block->used += size;
2340
-
2341
2393
  if (oldsize > 0) {
2342
2394
  memcpy(ret, ptr, oldsize); /* Preserve existing data. */
2343
2395
  }
2344
2396
 
2345
2397
  /* TODO(haberman): ASAN unpoison. */
2346
-
2347
- a->bytes_allocated += size;
2348
2398
  return ret;
2349
2399
  }
2350
2400
 
@@ -2373,7 +2423,10 @@ upb_arena *upb_arena_init(void *mem, size_t n, upb_alloc *alloc) {
2373
2423
  a = (void*)((char*)mem + n - sizeof(*a));
2374
2424
  n -= sizeof(*a);
2375
2425
 
2376
- a->alloc.func = &upb_arena_doalloc;
2426
+ a->head.alloc.func = &upb_arena_doalloc;
2427
+ a->head.ptr = NULL;
2428
+ a->head.end = NULL;
2429
+ a->start = NULL;
2377
2430
  a->block_alloc = &upb_alloc_global;
2378
2431
  a->bytes_allocated = 0;
2379
2432
  a->next_block_size = 256;
@@ -2413,7 +2466,7 @@ void upb_arena_free(upb_arena *a) {
2413
2466
  }
2414
2467
 
2415
2468
  bool upb_arena_addcleanup(upb_arena *a, void *ud, upb_cleanup_func *func) {
2416
- cleanup_ent *ent = upb_malloc(&a->alloc, sizeof(cleanup_ent));
2469
+ cleanup_ent *ent = upb_malloc(&a->head.alloc, sizeof(cleanup_ent));
2417
2470
  if (!ent) {
2418
2471
  return false; /* Out of memory. */
2419
2472
  }
@@ -2427,7 +2480,7 @@ bool upb_arena_addcleanup(upb_arena *a, void *ud, upb_cleanup_func *func) {
2427
2480
  }
2428
2481
 
2429
2482
  size_t upb_arena_bytesallocated(const upb_arena *a) {
2430
- return a->bytes_allocated;
2483
+ return a->bytes_allocated + (a->head.ptr - a->start);
2431
2484
  }
2432
2485
  /* This file was generated by upbc (the upb compiler) from the input
2433
2486
  * file:
@@ -2558,23 +2611,24 @@ static const upb_msglayout *const google_protobuf_FieldDescriptorProto_submsgs[1
2558
2611
  &google_protobuf_FieldOptions_msginit,
2559
2612
  };
2560
2613
 
2561
- static const upb_msglayout_field google_protobuf_FieldDescriptorProto__fields[10] = {
2562
- {1, UPB_SIZE(32, 32), 5, 0, 9, 1},
2563
- {2, UPB_SIZE(40, 48), 6, 0, 9, 1},
2614
+ static const upb_msglayout_field google_protobuf_FieldDescriptorProto__fields[11] = {
2615
+ {1, UPB_SIZE(36, 40), 6, 0, 9, 1},
2616
+ {2, UPB_SIZE(44, 56), 7, 0, 9, 1},
2564
2617
  {3, UPB_SIZE(24, 24), 3, 0, 5, 1},
2565
2618
  {4, UPB_SIZE(8, 8), 1, 0, 14, 1},
2566
2619
  {5, UPB_SIZE(16, 16), 2, 0, 14, 1},
2567
- {6, UPB_SIZE(48, 64), 7, 0, 9, 1},
2568
- {7, UPB_SIZE(56, 80), 8, 0, 9, 1},
2569
- {8, UPB_SIZE(72, 112), 10, 0, 11, 1},
2620
+ {6, UPB_SIZE(52, 72), 8, 0, 9, 1},
2621
+ {7, UPB_SIZE(60, 88), 9, 0, 9, 1},
2622
+ {8, UPB_SIZE(76, 120), 11, 0, 11, 1},
2570
2623
  {9, UPB_SIZE(28, 28), 4, 0, 5, 1},
2571
- {10, UPB_SIZE(64, 96), 9, 0, 9, 1},
2624
+ {10, UPB_SIZE(68, 104), 10, 0, 9, 1},
2625
+ {17, UPB_SIZE(32, 32), 5, 0, 8, 1},
2572
2626
  };
2573
2627
 
2574
2628
  const upb_msglayout google_protobuf_FieldDescriptorProto_msginit = {
2575
2629
  &google_protobuf_FieldDescriptorProto_submsgs[0],
2576
2630
  &google_protobuf_FieldDescriptorProto__fields[0],
2577
- UPB_SIZE(80, 128), 10, false,
2631
+ UPB_SIZE(80, 128), 11, false,
2578
2632
  };
2579
2633
 
2580
2634
  static const upb_msglayout *const google_protobuf_OneofDescriptorProto_submsgs[1] = {
@@ -2869,8 +2923,8 @@ const upb_msglayout google_protobuf_SourceCodeInfo_msginit = {
2869
2923
  };
2870
2924
 
2871
2925
  static const upb_msglayout_field google_protobuf_SourceCodeInfo_Location__fields[5] = {
2872
- {1, UPB_SIZE(20, 40), 0, 0, 5, 3},
2873
- {2, UPB_SIZE(24, 48), 0, 0, 5, 3},
2926
+ {1, UPB_SIZE(20, 40), 0, 0, 5, _UPB_LABEL_PACKED},
2927
+ {2, UPB_SIZE(24, 48), 0, 0, 5, _UPB_LABEL_PACKED},
2874
2928
  {3, UPB_SIZE(4, 8), 1, 0, 9, 1},
2875
2929
  {4, UPB_SIZE(12, 24), 2, 0, 9, 1},
2876
2930
  {6, UPB_SIZE(28, 56), 0, 0, 9, 3},
@@ -2897,7 +2951,7 @@ const upb_msglayout google_protobuf_GeneratedCodeInfo_msginit = {
2897
2951
  };
2898
2952
 
2899
2953
  static const upb_msglayout_field google_protobuf_GeneratedCodeInfo_Annotation__fields[4] = {
2900
- {1, UPB_SIZE(20, 32), 0, 0, 5, 3},
2954
+ {1, UPB_SIZE(20, 32), 0, 0, 5, _UPB_LABEL_PACKED},
2901
2955
  {2, UPB_SIZE(12, 16), 3, 0, 9, 1},
2902
2956
  {3, UPB_SIZE(4, 4), 1, 0, 5, 1},
2903
2957
  {4, UPB_SIZE(8, 8), 2, 0, 5, 1},
@@ -2936,6 +2990,7 @@ struct upb_fielddef {
2936
2990
  const upb_filedef *file;
2937
2991
  const upb_msgdef *msgdef;
2938
2992
  const char *full_name;
2993
+ const char *json_name;
2939
2994
  union {
2940
2995
  int64_t sint;
2941
2996
  uint64_t uint;
@@ -2951,16 +3006,19 @@ struct upb_fielddef {
2951
3006
  const google_protobuf_FieldDescriptorProto *unresolved;
2952
3007
  } sub;
2953
3008
  uint32_t number_;
2954
- uint32_t index_;
3009
+ uint16_t index_;
3010
+ uint16_t layout_index;
2955
3011
  uint32_t selector_base; /* Used to index into a upb::Handlers table. */
2956
3012
  bool is_extension_;
2957
3013
  bool lazy_;
2958
3014
  bool packed_;
3015
+ bool proto3_optional_;
2959
3016
  upb_descriptortype_t type_;
2960
3017
  upb_label_t label_;
2961
3018
  };
2962
3019
 
2963
3020
  struct upb_msgdef {
3021
+ const upb_msglayout *layout;
2964
3022
  const upb_filedef *file;
2965
3023
  const char *full_name;
2966
3024
  uint32_t selector_count;
@@ -2974,6 +3032,7 @@ struct upb_msgdef {
2974
3032
  const upb_oneofdef *oneofs;
2975
3033
  int field_count;
2976
3034
  int oneof_count;
3035
+ int real_oneof_count;
2977
3036
 
2978
3037
  /* Is this a map-entry message? */
2979
3038
  bool map_entry;
@@ -3024,10 +3083,15 @@ struct upb_symtab {
3024
3083
 
3025
3084
  /* Inside a symtab we store tagged pointers to specific def types. */
3026
3085
  typedef enum {
3027
- UPB_DEFTYPE_MSG = 0,
3028
- UPB_DEFTYPE_ENUM = 1,
3029
- UPB_DEFTYPE_FIELD = 2,
3030
- UPB_DEFTYPE_ONEOF = 3
3086
+ UPB_DEFTYPE_FIELD = 0,
3087
+
3088
+ /* Only inside symtab table. */
3089
+ UPB_DEFTYPE_MSG = 1,
3090
+ UPB_DEFTYPE_ENUM = 2,
3091
+
3092
+ /* Only inside message table. */
3093
+ UPB_DEFTYPE_ONEOF = 1,
3094
+ UPB_DEFTYPE_FIELD_JSONNAME = 2
3031
3095
  } upb_deftype_t;
3032
3096
 
3033
3097
  static const void *unpack_def(upb_value v, upb_deftype_t type) {
@@ -3140,11 +3204,14 @@ static uint32_t upb_handlers_selectorcount(const upb_fielddef *f) {
3140
3204
  return ret;
3141
3205
  }
3142
3206
 
3207
+ static void upb_status_setoom(upb_status *status) {
3208
+ upb_status_seterrmsg(status, "out of memory");
3209
+ }
3210
+
3143
3211
  static bool assign_msg_indices(upb_msgdef *m, upb_status *s) {
3144
3212
  /* Sort fields. upb internally relies on UPB_TYPE_MESSAGE fields having the
3145
3213
  * lowest indexes, but we do not publicly guarantee this. */
3146
3214
  upb_msg_field_iter j;
3147
- upb_msg_oneof_iter k;
3148
3215
  int i;
3149
3216
  uint32_t selector;
3150
3217
  int n = upb_msgdef_numfields(m);
@@ -3185,14 +3252,38 @@ static bool assign_msg_indices(upb_msgdef *m, upb_status *s) {
3185
3252
  }
3186
3253
  m->selector_count = selector;
3187
3254
 
3188
- for(upb_msg_oneof_begin(&k, m), i = 0;
3189
- !upb_msg_oneof_done(&k);
3190
- upb_msg_oneof_next(&k), i++) {
3191
- upb_oneofdef *o = (upb_oneofdef*)upb_msg_iter_oneof(&k);
3192
- o->index = i;
3255
+ upb_gfree(fields);
3256
+ return true;
3257
+ }
3258
+
3259
+ static bool check_oneofs(upb_msgdef *m, upb_status *s) {
3260
+ int i;
3261
+ int first_synthetic = -1;
3262
+ upb_oneofdef *mutable_oneofs = (upb_oneofdef*)m->oneofs;
3263
+
3264
+ for (i = 0; i < m->oneof_count; i++) {
3265
+ mutable_oneofs[i].index = i;
3266
+
3267
+ if (upb_oneofdef_issynthetic(&mutable_oneofs[i])) {
3268
+ if (first_synthetic == -1) {
3269
+ first_synthetic = i;
3270
+ }
3271
+ } else {
3272
+ if (first_synthetic != -1) {
3273
+ upb_status_seterrf(
3274
+ s, "Synthetic oneofs must be after all other oneofs: %s",
3275
+ upb_oneofdef_name(&mutable_oneofs[i]));
3276
+ return false;
3277
+ }
3278
+ }
3279
+ }
3280
+
3281
+ if (first_synthetic == -1) {
3282
+ m->real_oneof_count = m->oneof_count;
3283
+ } else {
3284
+ m->real_oneof_count = first_synthetic;
3193
3285
  }
3194
3286
 
3195
- upb_gfree(fields);
3196
3287
  return true;
3197
3288
  }
3198
3289
 
@@ -3260,7 +3351,7 @@ int32_t upb_enumdef_default(const upb_enumdef *e) {
3260
3351
  }
3261
3352
 
3262
3353
  int upb_enumdef_numvals(const upb_enumdef *e) {
3263
- return upb_strtable_count(&e->ntoi);
3354
+ return (int)upb_strtable_count(&e->ntoi);
3264
3355
  }
3265
3356
 
3266
3357
  void upb_enum_begin(upb_enum_iter *i, const upb_enumdef *e) {
@@ -3288,7 +3379,7 @@ const char *upb_enumdef_iton(const upb_enumdef *def, int32_t num) {
3288
3379
  }
3289
3380
 
3290
3381
  const char *upb_enum_iter_name(upb_enum_iter *iter) {
3291
- return upb_strtable_iter_key(iter);
3382
+ return upb_strtable_iter_key(iter).data;
3292
3383
  }
3293
3384
 
3294
3385
  int32_t upb_enum_iter_number(upb_enum_iter *iter) {
@@ -3369,47 +3460,16 @@ const char *upb_fielddef_name(const upb_fielddef *f) {
3369
3460
  return shortdefname(f->full_name);
3370
3461
  }
3371
3462
 
3463
+ const char *upb_fielddef_jsonname(const upb_fielddef *f) {
3464
+ return f->json_name;
3465
+ }
3466
+
3372
3467
  uint32_t upb_fielddef_selectorbase(const upb_fielddef *f) {
3373
3468
  return f->selector_base;
3374
3469
  }
3375
3470
 
3376
- size_t upb_fielddef_getjsonname(const upb_fielddef *f, char *buf, size_t len) {
3377
- const char *name = upb_fielddef_name(f);
3378
- size_t src, dst = 0;
3379
- bool ucase_next = false;
3380
-
3381
- #define WRITE(byte) \
3382
- ++dst; \
3383
- if (dst < len) buf[dst - 1] = byte; \
3384
- else if (dst == len) buf[dst - 1] = '\0'
3385
-
3386
- if (!name) {
3387
- WRITE('\0');
3388
- return 0;
3389
- }
3390
-
3391
- /* Implement the transformation as described in the spec:
3392
- * 1. upper case all letters after an underscore.
3393
- * 2. remove all underscores.
3394
- */
3395
- for (src = 0; name[src]; src++) {
3396
- if (name[src] == '_') {
3397
- ucase_next = true;
3398
- continue;
3399
- }
3400
-
3401
- if (ucase_next) {
3402
- WRITE(toupper(name[src]));
3403
- ucase_next = false;
3404
- } else {
3405
- WRITE(name[src]);
3406
- }
3407
- }
3408
-
3409
- WRITE('\0');
3410
- return dst;
3411
-
3412
- #undef WRITE
3471
+ const upb_filedef *upb_fielddef_file(const upb_fielddef *f) {
3472
+ return f->file;
3413
3473
  }
3414
3474
 
3415
3475
  const upb_msgdef *upb_fielddef_containingtype(const upb_fielddef *f) {
@@ -3420,6 +3480,11 @@ const upb_oneofdef *upb_fielddef_containingoneof(const upb_fielddef *f) {
3420
3480
  return f->oneof;
3421
3481
  }
3422
3482
 
3483
+ const upb_oneofdef *upb_fielddef_realcontainingoneof(const upb_fielddef *f) {
3484
+ if (!f->oneof || upb_oneofdef_issynthetic(f->oneof)) return NULL;
3485
+ return f->oneof;
3486
+ }
3487
+
3423
3488
  static void chkdefaulttype(const upb_fielddef *f, int ctype) {
3424
3489
  UPB_UNUSED(f);
3425
3490
  UPB_UNUSED(ctype);
@@ -3432,7 +3497,7 @@ int64_t upb_fielddef_defaultint64(const upb_fielddef *f) {
3432
3497
 
3433
3498
  int32_t upb_fielddef_defaultint32(const upb_fielddef *f) {
3434
3499
  chkdefaulttype(f, UPB_TYPE_INT32);
3435
- return f->defaultval.sint;
3500
+ return (int32_t)f->defaultval.sint;
3436
3501
  }
3437
3502
 
3438
3503
  uint64_t upb_fielddef_defaultuint64(const upb_fielddef *f) {
@@ -3442,7 +3507,7 @@ uint64_t upb_fielddef_defaultuint64(const upb_fielddef *f) {
3442
3507
 
3443
3508
  uint32_t upb_fielddef_defaultuint32(const upb_fielddef *f) {
3444
3509
  chkdefaulttype(f, UPB_TYPE_UINT32);
3445
- return f->defaultval.uint;
3510
+ return (uint32_t)f->defaultval.uint;
3446
3511
  }
3447
3512
 
3448
3513
  bool upb_fielddef_defaultbool(const upb_fielddef *f) {
@@ -3484,6 +3549,10 @@ const upb_enumdef *upb_fielddef_enumsubdef(const upb_fielddef *f) {
3484
3549
  return f->sub.enumdef;
3485
3550
  }
3486
3551
 
3552
+ const upb_msglayout_field *upb_fielddef_layout(const upb_fielddef *f) {
3553
+ return &f->msgdef->layout->fields[f->layout_index];
3554
+ }
3555
+
3487
3556
  bool upb_fielddef_issubmsg(const upb_fielddef *f) {
3488
3557
  return upb_fielddef_type(f) == UPB_TYPE_MESSAGE;
3489
3558
  }
@@ -3512,8 +3581,8 @@ bool upb_fielddef_hassubdef(const upb_fielddef *f) {
3512
3581
 
3513
3582
  bool upb_fielddef_haspresence(const upb_fielddef *f) {
3514
3583
  if (upb_fielddef_isseq(f)) return false;
3515
- if (upb_fielddef_issubmsg(f)) return true;
3516
- return f->file->syntax == UPB_SYNTAX_PROTO2;
3584
+ return upb_fielddef_issubmsg(f) || upb_fielddef_containingoneof(f) ||
3585
+ f->file->syntax == UPB_SYNTAX_PROTO2;
3517
3586
  }
3518
3587
 
3519
3588
  static bool between(int32_t x, int32_t low, int32_t high) {
@@ -3592,18 +3661,43 @@ bool upb_msgdef_lookupname(const upb_msgdef *m, const char *name, size_t len,
3592
3661
 
3593
3662
  *o = unpack_def(val, UPB_DEFTYPE_ONEOF);
3594
3663
  *f = unpack_def(val, UPB_DEFTYPE_FIELD);
3595
- UPB_ASSERT((*o != NULL) ^ (*f != NULL)); /* Exactly one of the two should be set. */
3596
- return true;
3664
+ return *o || *f; /* False if this was a JSON name. */
3665
+ }
3666
+
3667
+ const upb_fielddef *upb_msgdef_lookupjsonname(const upb_msgdef *m,
3668
+ const char *name, size_t len) {
3669
+ upb_value val;
3670
+ const upb_fielddef* f;
3671
+
3672
+ if (!upb_strtable_lookup2(&m->ntof, name, len, &val)) {
3673
+ return NULL;
3674
+ }
3675
+
3676
+ f = unpack_def(val, UPB_DEFTYPE_FIELD);
3677
+ if (!f) f = unpack_def(val, UPB_DEFTYPE_FIELD_JSONNAME);
3678
+
3679
+ return f;
3597
3680
  }
3598
3681
 
3599
3682
  int upb_msgdef_numfields(const upb_msgdef *m) {
3600
- /* The number table contains only fields. */
3601
- return upb_inttable_count(&m->itof);
3683
+ return m->field_count;
3602
3684
  }
3603
3685
 
3604
3686
  int upb_msgdef_numoneofs(const upb_msgdef *m) {
3605
- /* The name table includes oneofs, and the number table does not. */
3606
- return upb_strtable_count(&m->ntof) - upb_inttable_count(&m->itof);
3687
+ return m->oneof_count;
3688
+ }
3689
+
3690
+ int upb_msgdef_numrealoneofs(const upb_msgdef *m) {
3691
+ return m->real_oneof_count;
3692
+ }
3693
+
3694
+ const upb_msglayout *upb_msgdef_layout(const upb_msgdef *m) {
3695
+ return m->layout;
3696
+ }
3697
+
3698
+ const upb_fielddef *_upb_msgdef_field(const upb_msgdef *m, int i) {
3699
+ if (i >= m->field_count) return NULL;
3700
+ return &m->fields[i];
3607
3701
  }
3608
3702
 
3609
3703
  bool upb_msgdef_mapentry(const upb_msgdef *m) {
@@ -3652,80 +3746,308 @@ void upb_msg_oneof_begin(upb_msg_oneof_iter *iter, const upb_msgdef *m) {
3652
3746
  }
3653
3747
  }
3654
3748
 
3655
- void upb_msg_oneof_next(upb_msg_oneof_iter *iter) {
3656
- /* We need to skip past fields to return only oneofs. */
3657
- do {
3658
- upb_strtable_next(iter);
3659
- } while (!upb_strtable_done(iter) &&
3660
- !unpack_def(upb_strtable_iter_value(iter), UPB_DEFTYPE_ONEOF));
3661
- }
3749
+ void upb_msg_oneof_next(upb_msg_oneof_iter *iter) {
3750
+ /* We need to skip past fields to return only oneofs. */
3751
+ do {
3752
+ upb_strtable_next(iter);
3753
+ } while (!upb_strtable_done(iter) &&
3754
+ !unpack_def(upb_strtable_iter_value(iter), UPB_DEFTYPE_ONEOF));
3755
+ }
3756
+
3757
+ bool upb_msg_oneof_done(const upb_msg_oneof_iter *iter) {
3758
+ return upb_strtable_done(iter);
3759
+ }
3760
+
3761
+ const upb_oneofdef *upb_msg_iter_oneof(const upb_msg_oneof_iter *iter) {
3762
+ return unpack_def(upb_strtable_iter_value(iter), UPB_DEFTYPE_ONEOF);
3763
+ }
3764
+
3765
+ void upb_msg_oneof_iter_setdone(upb_msg_oneof_iter *iter) {
3766
+ upb_strtable_iter_setdone(iter);
3767
+ }
3768
+
3769
+ bool upb_msg_oneof_iter_isequal(const upb_msg_oneof_iter *iter1,
3770
+ const upb_msg_oneof_iter *iter2) {
3771
+ return upb_strtable_iter_isequal(iter1, iter2);
3772
+ }
3773
+
3774
+ /* upb_oneofdef ***************************************************************/
3775
+
3776
+ const char *upb_oneofdef_name(const upb_oneofdef *o) {
3777
+ return shortdefname(o->full_name);
3778
+ }
3779
+
3780
+ const upb_msgdef *upb_oneofdef_containingtype(const upb_oneofdef *o) {
3781
+ return o->parent;
3782
+ }
3783
+
3784
+ int upb_oneofdef_numfields(const upb_oneofdef *o) {
3785
+ return (int)upb_strtable_count(&o->ntof);
3786
+ }
3787
+
3788
+ uint32_t upb_oneofdef_index(const upb_oneofdef *o) {
3789
+ return o->index;
3790
+ }
3791
+
3792
+ bool upb_oneofdef_issynthetic(const upb_oneofdef *o) {
3793
+ upb_inttable_iter iter;
3794
+ const upb_fielddef *f;
3795
+ upb_inttable_begin(&iter, &o->itof);
3796
+ if (upb_oneofdef_numfields(o) != 1) return false;
3797
+ f = upb_value_getptr(upb_inttable_iter_value(&iter));
3798
+ UPB_ASSERT(f);
3799
+ return f->proto3_optional_;
3800
+ }
3801
+
3802
+ const upb_fielddef *upb_oneofdef_ntof(const upb_oneofdef *o,
3803
+ const char *name, size_t length) {
3804
+ upb_value val;
3805
+ return upb_strtable_lookup2(&o->ntof, name, length, &val) ?
3806
+ upb_value_getptr(val) : NULL;
3807
+ }
3808
+
3809
+ const upb_fielddef *upb_oneofdef_itof(const upb_oneofdef *o, uint32_t num) {
3810
+ upb_value val;
3811
+ return upb_inttable_lookup32(&o->itof, num, &val) ?
3812
+ upb_value_getptr(val) : NULL;
3813
+ }
3814
+
3815
+ void upb_oneof_begin(upb_oneof_iter *iter, const upb_oneofdef *o) {
3816
+ upb_inttable_begin(iter, &o->itof);
3817
+ }
3818
+
3819
+ void upb_oneof_next(upb_oneof_iter *iter) {
3820
+ upb_inttable_next(iter);
3821
+ }
3822
+
3823
+ bool upb_oneof_done(upb_oneof_iter *iter) {
3824
+ return upb_inttable_done(iter);
3825
+ }
3826
+
3827
+ upb_fielddef *upb_oneof_iter_field(const upb_oneof_iter *iter) {
3828
+ return (upb_fielddef *)upb_value_getconstptr(upb_inttable_iter_value(iter));
3829
+ }
3830
+
3831
+ void upb_oneof_iter_setdone(upb_oneof_iter *iter) {
3832
+ upb_inttable_iter_setdone(iter);
3833
+ }
3834
+
3835
+ /* Dynamic Layout Generation. *************************************************/
3836
+
3837
+ static bool is_power_of_two(size_t val) {
3838
+ return (val & (val - 1)) == 0;
3839
+ }
3840
+
3841
+ /* Align up to the given power of 2. */
3842
+ static size_t align_up(size_t val, size_t align) {
3843
+ UPB_ASSERT(is_power_of_two(align));
3844
+ return (val + align - 1) & ~(align - 1);
3845
+ }
3846
+
3847
+ static size_t div_round_up(size_t n, size_t d) {
3848
+ return (n + d - 1) / d;
3849
+ }
3850
+
3851
+ static size_t upb_msgval_sizeof(upb_fieldtype_t type) {
3852
+ switch (type) {
3853
+ case UPB_TYPE_DOUBLE:
3854
+ case UPB_TYPE_INT64:
3855
+ case UPB_TYPE_UINT64:
3856
+ return 8;
3857
+ case UPB_TYPE_ENUM:
3858
+ case UPB_TYPE_INT32:
3859
+ case UPB_TYPE_UINT32:
3860
+ case UPB_TYPE_FLOAT:
3861
+ return 4;
3862
+ case UPB_TYPE_BOOL:
3863
+ return 1;
3864
+ case UPB_TYPE_MESSAGE:
3865
+ return sizeof(void*);
3866
+ case UPB_TYPE_BYTES:
3867
+ case UPB_TYPE_STRING:
3868
+ return sizeof(upb_strview);
3869
+ }
3870
+ UPB_UNREACHABLE();
3871
+ }
3872
+
3873
+ static uint8_t upb_msg_fielddefsize(const upb_fielddef *f) {
3874
+ if (upb_msgdef_mapentry(upb_fielddef_containingtype(f))) {
3875
+ upb_map_entry ent;
3876
+ UPB_ASSERT(sizeof(ent.k) == sizeof(ent.v));
3877
+ return sizeof(ent.k);
3878
+ } else if (upb_fielddef_isseq(f)) {
3879
+ return sizeof(void*);
3880
+ } else {
3881
+ return upb_msgval_sizeof(upb_fielddef_type(f));
3882
+ }
3883
+ }
3884
+
3885
+ static uint32_t upb_msglayout_place(upb_msglayout *l, size_t size) {
3886
+ uint32_t ret;
3887
+
3888
+ l->size = align_up(l->size, size);
3889
+ ret = l->size;
3890
+ l->size += size;
3891
+ return ret;
3892
+ }
3893
+
3894
+ /* This function is the dynamic equivalent of message_layout.{cc,h} in upbc.
3895
+ * It computes a dynamic layout for all of the fields in |m|. */
3896
+ static bool make_layout(const upb_symtab *symtab, const upb_msgdef *m) {
3897
+ upb_msglayout *l = (upb_msglayout*)m->layout;
3898
+ upb_msg_field_iter it;
3899
+ upb_msg_oneof_iter oit;
3900
+ size_t hasbit;
3901
+ size_t submsg_count = m->submsg_field_count;
3902
+ const upb_msglayout **submsgs;
3903
+ upb_msglayout_field *fields;
3904
+ upb_alloc *alloc = upb_arena_alloc(symtab->arena);
3905
+
3906
+ memset(l, 0, sizeof(*l));
3907
+
3908
+ fields = upb_malloc(alloc, upb_msgdef_numfields(m) * sizeof(*fields));
3909
+ submsgs = upb_malloc(alloc, submsg_count * sizeof(*submsgs));
3910
+
3911
+ if ((!fields && upb_msgdef_numfields(m)) ||
3912
+ (!submsgs && submsg_count)) {
3913
+ /* OOM. */
3914
+ return false;
3915
+ }
3916
+
3917
+ l->field_count = upb_msgdef_numfields(m);
3918
+ l->fields = fields;
3919
+ l->submsgs = submsgs;
3920
+
3921
+ if (upb_msgdef_mapentry(m)) {
3922
+ /* TODO(haberman): refactor this method so this special case is more
3923
+ * elegant. */
3924
+ const upb_fielddef *key = upb_msgdef_itof(m, 1);
3925
+ const upb_fielddef *val = upb_msgdef_itof(m, 2);
3926
+ fields[0].number = 1;
3927
+ fields[1].number = 2;
3928
+ fields[0].label = UPB_LABEL_OPTIONAL;
3929
+ fields[1].label = UPB_LABEL_OPTIONAL;
3930
+ fields[0].presence = 0;
3931
+ fields[1].presence = 0;
3932
+ fields[0].descriptortype = upb_fielddef_descriptortype(key);
3933
+ fields[1].descriptortype = upb_fielddef_descriptortype(val);
3934
+ fields[0].offset = 0;
3935
+ fields[1].offset = sizeof(upb_strview);
3936
+ fields[1].submsg_index = 0;
3937
+
3938
+ if (upb_fielddef_type(val) == UPB_TYPE_MESSAGE) {
3939
+ submsgs[0] = upb_fielddef_msgsubdef(val)->layout;
3940
+ }
3941
+
3942
+ l->field_count = 2;
3943
+ l->size = 2 * sizeof(upb_strview);align_up(l->size, 8);
3944
+ return true;
3945
+ }
3946
+
3947
+ /* Allocate data offsets in three stages:
3948
+ *
3949
+ * 1. hasbits.
3950
+ * 2. regular fields.
3951
+ * 3. oneof fields.
3952
+ *
3953
+ * OPT: There is a lot of room for optimization here to minimize the size.
3954
+ */
3955
+
3956
+ /* Allocate hasbits and set basic field attributes. */
3957
+ submsg_count = 0;
3958
+ for (upb_msg_field_begin(&it, m), hasbit = 0;
3959
+ !upb_msg_field_done(&it);
3960
+ upb_msg_field_next(&it)) {
3961
+ upb_fielddef* f = upb_msg_iter_field(&it);
3962
+ upb_msglayout_field *field = &fields[upb_fielddef_index(f)];
3662
3963
 
3663
- bool upb_msg_oneof_done(const upb_msg_oneof_iter *iter) {
3664
- return upb_strtable_done(iter);
3665
- }
3964
+ field->number = upb_fielddef_number(f);
3965
+ field->descriptortype = upb_fielddef_descriptortype(f);
3966
+ field->label = upb_fielddef_label(f);
3666
3967
 
3667
- const upb_oneofdef *upb_msg_iter_oneof(const upb_msg_oneof_iter *iter) {
3668
- return unpack_def(upb_strtable_iter_value(iter), UPB_DEFTYPE_ONEOF);
3669
- }
3968
+ if (upb_fielddef_ismap(f)) {
3969
+ field->label = _UPB_LABEL_MAP;
3970
+ } else if (upb_fielddef_packed(f)) {
3971
+ field->label = _UPB_LABEL_PACKED;
3972
+ }
3670
3973
 
3671
- void upb_msg_oneof_iter_setdone(upb_msg_oneof_iter *iter) {
3672
- upb_strtable_iter_setdone(iter);
3673
- }
3974
+ /* TODO: we probably should sort the fields by field number to match the
3975
+ * output of upbc, and to improve search speed for the table parser. */
3976
+ f->layout_index = f->index_;
3674
3977
 
3675
- bool upb_msg_oneof_iter_isequal(const upb_msg_oneof_iter *iter1,
3676
- const upb_msg_oneof_iter *iter2) {
3677
- return upb_strtable_iter_isequal(iter1, iter2);
3678
- }
3978
+ if (upb_fielddef_issubmsg(f)) {
3979
+ const upb_msgdef *subm = upb_fielddef_msgsubdef(f);
3980
+ field->submsg_index = submsg_count++;
3981
+ submsgs[field->submsg_index] = subm->layout;
3982
+ }
3679
3983
 
3680
- /* upb_oneofdef ***************************************************************/
3984
+ if (upb_fielddef_haspresence(f) && !upb_fielddef_realcontainingoneof(f)) {
3985
+ /* We don't use hasbit 0, so that 0 can indicate "no presence" in the
3986
+ * table. This wastes one hasbit, but we don't worry about it for now. */
3987
+ field->presence = ++hasbit;
3988
+ } else {
3989
+ field->presence = 0;
3990
+ }
3991
+ }
3681
3992
 
3682
- const char *upb_oneofdef_name(const upb_oneofdef *o) {
3683
- return shortdefname(o->full_name);
3684
- }
3993
+ /* Account for space used by hasbits. */
3994
+ l->size = div_round_up(hasbit, 8);
3685
3995
 
3686
- const upb_msgdef *upb_oneofdef_containingtype(const upb_oneofdef *o) {
3687
- return o->parent;
3688
- }
3996
+ /* Allocate non-oneof fields. */
3997
+ for (upb_msg_field_begin(&it, m); !upb_msg_field_done(&it);
3998
+ upb_msg_field_next(&it)) {
3999
+ const upb_fielddef* f = upb_msg_iter_field(&it);
4000
+ size_t field_size = upb_msg_fielddefsize(f);
4001
+ size_t index = upb_fielddef_index(f);
3689
4002
 
3690
- int upb_oneofdef_numfields(const upb_oneofdef *o) {
3691
- return upb_strtable_count(&o->ntof);
3692
- }
4003
+ if (upb_fielddef_realcontainingoneof(f)) {
4004
+ /* Oneofs are handled separately below. */
4005
+ continue;
4006
+ }
3693
4007
 
3694
- uint32_t upb_oneofdef_index(const upb_oneofdef *o) {
3695
- return o->index;
3696
- }
4008
+ fields[index].offset = upb_msglayout_place(l, field_size);
4009
+ }
3697
4010
 
3698
- const upb_fielddef *upb_oneofdef_ntof(const upb_oneofdef *o,
3699
- const char *name, size_t length) {
3700
- upb_value val;
3701
- return upb_strtable_lookup2(&o->ntof, name, length, &val) ?
3702
- upb_value_getptr(val) : NULL;
3703
- }
4011
+ /* Allocate oneof fields. Each oneof field consists of a uint32 for the case
4012
+ * and space for the actual data. */
4013
+ for (upb_msg_oneof_begin(&oit, m); !upb_msg_oneof_done(&oit);
4014
+ upb_msg_oneof_next(&oit)) {
4015
+ const upb_oneofdef* o = upb_msg_iter_oneof(&oit);
4016
+ upb_oneof_iter fit;
3704
4017
 
3705
- const upb_fielddef *upb_oneofdef_itof(const upb_oneofdef *o, uint32_t num) {
3706
- upb_value val;
3707
- return upb_inttable_lookup32(&o->itof, num, &val) ?
3708
- upb_value_getptr(val) : NULL;
3709
- }
4018
+ if (upb_oneofdef_issynthetic(o)) continue;
3710
4019
 
3711
- void upb_oneof_begin(upb_oneof_iter *iter, const upb_oneofdef *o) {
3712
- upb_inttable_begin(iter, &o->itof);
3713
- }
4020
+ size_t case_size = sizeof(uint32_t); /* Could potentially optimize this. */
4021
+ size_t field_size = 0;
4022
+ uint32_t case_offset;
4023
+ uint32_t data_offset;
3714
4024
 
3715
- void upb_oneof_next(upb_oneof_iter *iter) {
3716
- upb_inttable_next(iter);
3717
- }
4025
+ /* Calculate field size: the max of all field sizes. */
4026
+ for (upb_oneof_begin(&fit, o);
4027
+ !upb_oneof_done(&fit);
4028
+ upb_oneof_next(&fit)) {
4029
+ const upb_fielddef* f = upb_oneof_iter_field(&fit);
4030
+ field_size = UPB_MAX(field_size, upb_msg_fielddefsize(f));
4031
+ }
3718
4032
 
3719
- bool upb_oneof_done(upb_oneof_iter *iter) {
3720
- return upb_inttable_done(iter);
3721
- }
4033
+ /* Align and allocate case offset. */
4034
+ case_offset = upb_msglayout_place(l, case_size);
4035
+ data_offset = upb_msglayout_place(l, field_size);
3722
4036
 
3723
- upb_fielddef *upb_oneof_iter_field(const upb_oneof_iter *iter) {
3724
- return (upb_fielddef *)upb_value_getconstptr(upb_inttable_iter_value(iter));
3725
- }
4037
+ for (upb_oneof_begin(&fit, o);
4038
+ !upb_oneof_done(&fit);
4039
+ upb_oneof_next(&fit)) {
4040
+ const upb_fielddef* f = upb_oneof_iter_field(&fit);
4041
+ fields[upb_fielddef_index(f)].offset = data_offset;
4042
+ fields[upb_fielddef_index(f)].presence = ~case_offset;
4043
+ }
4044
+ }
3726
4045
 
3727
- void upb_oneof_iter_setdone(upb_oneof_iter *iter) {
3728
- upb_inttable_iter_setdone(iter);
4046
+ /* Size of the entire structure should be a multiple of its greatest
4047
+ * alignment. TODO: track overall alignment for real? */
4048
+ l->size = align_up(l->size, 8);
4049
+
4050
+ return true;
3729
4051
  }
3730
4052
 
3731
4053
  /* Code to build defs from descriptor protos. *********************************/
@@ -3740,11 +4062,12 @@ void upb_oneof_iter_setdone(upb_oneof_iter *iter) {
3740
4062
 
3741
4063
  typedef struct {
3742
4064
  const upb_symtab *symtab;
3743
- upb_filedef *file; /* File we are building. */
3744
- upb_alloc *alloc; /* Allocate defs here. */
3745
- upb_alloc *tmp; /* Alloc for addtab and any other tmp data. */
3746
- upb_strtable *addtab; /* full_name -> packed def ptr for new defs. */
3747
- upb_status *status; /* Record errors here. */
4065
+ upb_filedef *file; /* File we are building. */
4066
+ upb_alloc *alloc; /* Allocate defs here. */
4067
+ upb_alloc *tmp; /* Alloc for addtab and any other tmp data. */
4068
+ upb_strtable *addtab; /* full_name -> packed def ptr for new defs */
4069
+ const upb_msglayout **layouts; /* NULL if we should build layouts. */
4070
+ upb_status *status; /* Record errors here. */
3748
4071
  } symtab_addctx;
3749
4072
 
3750
4073
  static char* strviewdup(const symtab_addctx *ctx, upb_strview view) {
@@ -3776,6 +4099,51 @@ static const char *makefullname(const symtab_addctx *ctx, const char *prefix,
3776
4099
  }
3777
4100
  }
3778
4101
 
4102
+ size_t getjsonname(const char *name, char *buf, size_t len) {
4103
+ size_t src, dst = 0;
4104
+ bool ucase_next = false;
4105
+
4106
+ #define WRITE(byte) \
4107
+ ++dst; \
4108
+ if (dst < len) buf[dst - 1] = byte; \
4109
+ else if (dst == len) buf[dst - 1] = '\0'
4110
+
4111
+ if (!name) {
4112
+ WRITE('\0');
4113
+ return 0;
4114
+ }
4115
+
4116
+ /* Implement the transformation as described in the spec:
4117
+ * 1. upper case all letters after an underscore.
4118
+ * 2. remove all underscores.
4119
+ */
4120
+ for (src = 0; name[src]; src++) {
4121
+ if (name[src] == '_') {
4122
+ ucase_next = true;
4123
+ continue;
4124
+ }
4125
+
4126
+ if (ucase_next) {
4127
+ WRITE(toupper(name[src]));
4128
+ ucase_next = false;
4129
+ } else {
4130
+ WRITE(name[src]);
4131
+ }
4132
+ }
4133
+
4134
+ WRITE('\0');
4135
+ return dst;
4136
+
4137
+ #undef WRITE
4138
+ }
4139
+
4140
+ static char* makejsonname(const char* name, upb_alloc *alloc) {
4141
+ size_t size = getjsonname(name, NULL, 0);
4142
+ char* json_name = upb_malloc(alloc, size);
4143
+ getjsonname(name, json_name, size);
4144
+ return json_name;
4145
+ }
4146
+
3779
4147
  static bool symtab_add(const symtab_addctx *ctx, const char *name,
3780
4148
  upb_value v) {
3781
4149
  upb_value tmp;
@@ -3899,7 +4267,7 @@ static bool parse_default(const symtab_addctx *ctx, const char *str, size_t len,
3899
4267
  }
3900
4268
  case UPB_TYPE_INT64: {
3901
4269
  /* XXX: Need to write our own strtoll, since it's not available in c89. */
3902
- long long val = strtol(str, &end, 0);
4270
+ int64_t val = strtol(str, &end, 0);
3903
4271
  CHK(val <= INT64_MAX && val >= INT64_MIN && errno != ERANGE && !*end);
3904
4272
  f->defaultval.sint = val;
3905
4273
  break;
@@ -3912,7 +4280,7 @@ static bool parse_default(const symtab_addctx *ctx, const char *str, size_t len,
3912
4280
  }
3913
4281
  case UPB_TYPE_UINT64: {
3914
4282
  /* XXX: Need to write our own strtoull, since it's not available in c89. */
3915
- unsigned long long val = strtoul(str, &end, 0);
4283
+ uint64_t val = strtoul(str, &end, 0);
3916
4284
  CHK(val <= UINT64_MAX && errno != ERANGE && !*end);
3917
4285
  f->defaultval.uint = val;
3918
4286
  break;
@@ -3989,6 +4357,7 @@ static bool create_fielddef(
3989
4357
  const google_protobuf_FieldOptions *options;
3990
4358
  upb_strview name;
3991
4359
  const char *full_name;
4360
+ const char *json_name;
3992
4361
  const char *shortname;
3993
4362
  uint32_t field_number;
3994
4363
 
@@ -4002,6 +4371,13 @@ static bool create_fielddef(
4002
4371
  full_name = makefullname(ctx, prefix, name);
4003
4372
  shortname = shortdefname(full_name);
4004
4373
 
4374
+ if (google_protobuf_FieldDescriptorProto_has_json_name(field_proto)) {
4375
+ json_name = strviewdup(
4376
+ ctx, google_protobuf_FieldDescriptorProto_json_name(field_proto));
4377
+ } else {
4378
+ json_name = makejsonname(shortname, ctx->alloc);
4379
+ }
4380
+
4005
4381
  field_number = google_protobuf_FieldDescriptorProto_number(field_proto);
4006
4382
 
4007
4383
  if (field_number == 0 || field_number > UPB_MAX_FIELDNUMBER) {
@@ -4011,38 +4387,72 @@ static bool create_fielddef(
4011
4387
 
4012
4388
  if (m) {
4013
4389
  /* direct message field. */
4014
- upb_value v, packed_v;
4390
+ upb_value v, field_v, json_v;
4391
+ size_t json_size;
4015
4392
 
4016
4393
  f = (upb_fielddef*)&m->fields[m->field_count++];
4017
4394
  f->msgdef = m;
4018
4395
  f->is_extension_ = false;
4019
4396
 
4020
- packed_v = pack_def(f, UPB_DEFTYPE_FIELD);
4021
- v = upb_value_constptr(f);
4022
-
4023
- if (!upb_strtable_insert3(&m->ntof, name.data, name.size, packed_v, alloc)) {
4397
+ if (upb_strtable_lookup(&m->ntof, shortname, NULL)) {
4024
4398
  upb_status_seterrf(ctx->status, "duplicate field name (%s)", shortname);
4025
4399
  return false;
4026
4400
  }
4027
4401
 
4028
- if (!upb_inttable_insert2(&m->itof, field_number, v, alloc)) {
4402
+ if (upb_strtable_lookup(&m->ntof, json_name, NULL)) {
4403
+ upb_status_seterrf(ctx->status, "duplicate json_name (%s)", json_name);
4404
+ return false;
4405
+ }
4406
+
4407
+ if (upb_inttable_lookup(&m->itof, field_number, NULL)) {
4029
4408
  upb_status_seterrf(ctx->status, "duplicate field number (%u)",
4030
4409
  field_number);
4031
4410
  return false;
4032
4411
  }
4412
+
4413
+ field_v = pack_def(f, UPB_DEFTYPE_FIELD);
4414
+ json_v = pack_def(f, UPB_DEFTYPE_FIELD_JSONNAME);
4415
+ v = upb_value_constptr(f);
4416
+ json_size = strlen(json_name);
4417
+
4418
+ CHK_OOM(
4419
+ upb_strtable_insert3(&m->ntof, name.data, name.size, field_v, alloc));
4420
+ CHK_OOM(upb_inttable_insert2(&m->itof, field_number, v, alloc));
4421
+
4422
+ if (strcmp(shortname, json_name) != 0) {
4423
+ upb_strtable_insert3(&m->ntof, json_name, json_size, json_v, alloc);
4424
+ }
4425
+
4426
+ if (ctx->layouts) {
4427
+ const upb_msglayout_field *fields = m->layout->fields;
4428
+ int count = m->layout->field_count;
4429
+ bool found = false;
4430
+ int i;
4431
+ for (i = 0; i < count; i++) {
4432
+ if (fields[i].number == field_number) {
4433
+ f->layout_index = i;
4434
+ found = true;
4435
+ break;
4436
+ }
4437
+ }
4438
+ UPB_ASSERT(found);
4439
+ }
4033
4440
  } else {
4034
4441
  /* extension field. */
4035
- f = (upb_fielddef*)&ctx->file->exts[ctx->file->ext_count];
4442
+ f = (upb_fielddef*)&ctx->file->exts[ctx->file->ext_count++];
4036
4443
  f->is_extension_ = true;
4037
4444
  CHK_OOM(symtab_add(ctx, full_name, pack_def(f, UPB_DEFTYPE_FIELD)));
4038
4445
  }
4039
4446
 
4040
4447
  f->full_name = full_name;
4448
+ f->json_name = json_name;
4041
4449
  f->file = ctx->file;
4042
4450
  f->type_ = (int)google_protobuf_FieldDescriptorProto_type(field_proto);
4043
4451
  f->label_ = (int)google_protobuf_FieldDescriptorProto_label(field_proto);
4044
4452
  f->number_ = field_number;
4045
4453
  f->oneof = NULL;
4454
+ f->proto3_optional_ =
4455
+ google_protobuf_FieldDescriptorProto_proto3_optional(field_proto);
4046
4456
 
4047
4457
  /* We can't resolve the subdef or (in the case of extensions) the containing
4048
4458
  * message yet, because it may not have been defined yet. We stash a pointer
@@ -4166,7 +4576,7 @@ static bool create_enumdef(
4166
4576
  return true;
4167
4577
  }
4168
4578
 
4169
- static bool create_msgdef(const symtab_addctx *ctx, const char *prefix,
4579
+ static bool create_msgdef(symtab_addctx *ctx, const char *prefix,
4170
4580
  const google_protobuf_DescriptorProto *msg_proto) {
4171
4581
  upb_msgdef *m;
4172
4582
  const google_protobuf_MessageOptions *options;
@@ -4196,6 +4606,14 @@ static bool create_msgdef(const symtab_addctx *ctx, const char *prefix,
4196
4606
  m->map_entry = google_protobuf_MessageOptions_map_entry(options);
4197
4607
  }
4198
4608
 
4609
+ if (ctx->layouts) {
4610
+ m->layout = *ctx->layouts;
4611
+ ctx->layouts++;
4612
+ } else {
4613
+ /* Allocate now (to allow cross-linking), populate later. */
4614
+ m->layout = upb_malloc(ctx->alloc, sizeof(*m->layout));
4615
+ }
4616
+
4199
4617
  oneofs = google_protobuf_DescriptorProto_oneof_decl(msg_proto, &n);
4200
4618
  m->oneof_count = 0;
4201
4619
  m->oneofs = upb_malloc(ctx->alloc, sizeof(*m->oneofs) * n);
@@ -4211,6 +4629,7 @@ static bool create_msgdef(const symtab_addctx *ctx, const char *prefix,
4211
4629
  }
4212
4630
 
4213
4631
  CHK(assign_msg_indices(m, ctx->status));
4632
+ CHK(check_oneofs(m, ctx->status));
4214
4633
  assign_msg_wellknowntype(m);
4215
4634
  upb_inttable_compact2(&m->itof, ctx->alloc);
4216
4635
 
@@ -4342,7 +4761,7 @@ static bool resolve_fielddef(const symtab_addctx *ctx, const char *prefix,
4342
4761
  }
4343
4762
 
4344
4763
  static bool build_filedef(
4345
- const symtab_addctx *ctx, upb_filedef *file,
4764
+ symtab_addctx *ctx, upb_filedef *file,
4346
4765
  const google_protobuf_FileDescriptorProto *file_proto) {
4347
4766
  upb_alloc *alloc = ctx->alloc;
4348
4767
  const google_protobuf_FileOptions *file_options_proto;
@@ -4396,7 +4815,8 @@ static bool build_filedef(
4396
4815
  } else if (streql_view(syntax, "proto3")) {
4397
4816
  file->syntax = UPB_SYNTAX_PROTO3;
4398
4817
  } else {
4399
- upb_status_seterrf(ctx->status, "Invalid syntax '%s'", syntax);
4818
+ upb_status_seterrf(ctx->status, "Invalid syntax '" UPB_STRVIEW_FORMAT "'",
4819
+ UPB_STRVIEW_ARGS(syntax));
4400
4820
  return false;
4401
4821
  }
4402
4822
  } else {
@@ -4456,7 +4876,7 @@ static bool build_filedef(
4456
4876
  CHK(create_fielddef(ctx, file->package, NULL, exts[i]));
4457
4877
  }
4458
4878
 
4459
- /* Now that all names are in the table, resolve references. */
4879
+ /* Now that all names are in the table, build layouts and resolve refs. */
4460
4880
  for (i = 0; i < file->ext_count; i++) {
4461
4881
  CHK(resolve_fielddef(ctx, file->package, (upb_fielddef*)&file->exts[i]));
4462
4882
  }
@@ -4469,6 +4889,13 @@ static bool build_filedef(
4469
4889
  }
4470
4890
  }
4471
4891
 
4892
+ if (!ctx->layouts) {
4893
+ for (i = 0; i < file->msg_count; i++) {
4894
+ const upb_msgdef *m = &file->msgs[i];
4895
+ make_layout(ctx->symtab, m);
4896
+ }
4897
+ }
4898
+
4472
4899
  return true;
4473
4900
  }
4474
4901
 
@@ -4483,10 +4910,9 @@ static bool upb_symtab_addtotabs(upb_symtab *s, symtab_addctx *ctx,
4483
4910
 
4484
4911
  upb_strtable_begin(&iter, ctx->addtab);
4485
4912
  for (; !upb_strtable_done(&iter); upb_strtable_next(&iter)) {
4486
- const char *key = upb_strtable_iter_key(&iter);
4487
- size_t keylen = upb_strtable_iter_keylength(&iter);
4913
+ upb_strview key = upb_strtable_iter_key(&iter);
4488
4914
  upb_value value = upb_strtable_iter_value(&iter);
4489
- CHK_OOM(upb_strtable_insert3(&s->syms, key, keylen, value, alloc));
4915
+ CHK_OOM(upb_strtable_insert3(&s->syms, key.data, key.size, value, alloc));
4490
4916
  }
4491
4917
 
4492
4918
  return true;
@@ -4588,9 +5014,13 @@ const upb_filedef *upb_symtab_lookupfile(const upb_symtab *s, const char *name)
4588
5014
  : NULL;
4589
5015
  }
4590
5016
 
4591
- const upb_filedef *upb_symtab_addfile(
5017
+ int upb_symtab_filecount(const upb_symtab *s) {
5018
+ return (int)upb_strtable_count(&s->files);
5019
+ }
5020
+
5021
+ static const upb_filedef *_upb_symtab_addfile(
4592
5022
  upb_symtab *s, const google_protobuf_FileDescriptorProto *file_proto,
4593
- upb_status *status) {
5023
+ const upb_msglayout **layouts, upb_status *status) {
4594
5024
  upb_arena *tmparena = upb_arena_new();
4595
5025
  upb_strtable addtab;
4596
5026
  upb_alloc *alloc = upb_arena_alloc(s->arena);
@@ -4603,6 +5033,7 @@ const upb_filedef *upb_symtab_addfile(
4603
5033
  ctx.alloc = alloc;
4604
5034
  ctx.tmp = upb_arena_alloc(tmparena);
4605
5035
  ctx.addtab = &addtab;
5036
+ ctx.layouts = layouts;
4606
5037
  ctx.status = status;
4607
5038
 
4608
5039
  ok = file &&
@@ -4614,6 +5045,12 @@ const upb_filedef *upb_symtab_addfile(
4614
5045
  return ok ? file : NULL;
4615
5046
  }
4616
5047
 
5048
+ const upb_filedef *upb_symtab_addfile(
5049
+ upb_symtab *s, const google_protobuf_FileDescriptorProto *file_proto,
5050
+ upb_status *status) {
5051
+ return _upb_symtab_addfile(s, file_proto, NULL, status);
5052
+ }
5053
+
4617
5054
  /* Include here since we want most of this file to be stdio-free. */
4618
5055
  #include <stdio.h>
4619
5056
 
@@ -4645,270 +5082,331 @@ bool _upb_symtab_loaddefinit(upb_symtab *s, const upb_def_init *init) {
4645
5082
  &status,
4646
5083
  "Failed to parse compiled-in descriptor for file '%s'. This should "
4647
5084
  "never happen.",
4648
- init->filename);
4649
- goto err;
4650
- }
4651
-
4652
- if (!upb_symtab_addfile(s, file, &status)) goto err;
4653
-
4654
- upb_arena_free(arena);
4655
- return true;
4656
-
4657
- err:
4658
- fprintf(stderr, "Error loading compiled-in descriptor: %s\n",
4659
- upb_status_errmsg(&status));
4660
- upb_arena_free(arena);
4661
- return false;
4662
- }
4663
-
4664
- #undef CHK
4665
- #undef CHK_OOM
4666
-
4667
-
4668
-
4669
- static bool is_power_of_two(size_t val) {
4670
- return (val & (val - 1)) == 0;
4671
- }
4672
-
4673
- /* Align up to the given power of 2. */
4674
- static size_t align_up(size_t val, size_t align) {
4675
- UPB_ASSERT(is_power_of_two(align));
4676
- return (val + align - 1) & ~(align - 1);
4677
- }
4678
-
4679
- static size_t div_round_up(size_t n, size_t d) {
4680
- return (n + d - 1) / d;
4681
- }
4682
-
4683
- static size_t upb_msgval_sizeof2(upb_fieldtype_t type) {
4684
- switch (type) {
4685
- case UPB_TYPE_DOUBLE:
4686
- case UPB_TYPE_INT64:
4687
- case UPB_TYPE_UINT64:
4688
- return 8;
4689
- case UPB_TYPE_ENUM:
4690
- case UPB_TYPE_INT32:
4691
- case UPB_TYPE_UINT32:
4692
- case UPB_TYPE_FLOAT:
4693
- return 4;
4694
- case UPB_TYPE_BOOL:
4695
- return 1;
4696
- case UPB_TYPE_MESSAGE:
4697
- return sizeof(void*);
4698
- case UPB_TYPE_BYTES:
4699
- case UPB_TYPE_STRING:
4700
- return sizeof(upb_strview);
4701
- }
4702
- UPB_UNREACHABLE();
4703
- }
4704
-
4705
- static uint8_t upb_msg_fielddefsize(const upb_fielddef *f) {
4706
- if (upb_fielddef_isseq(f)) {
4707
- return sizeof(void*);
4708
- } else {
4709
- return upb_msgval_sizeof2(upb_fielddef_type(f));
5085
+ init->filename);
5086
+ goto err;
4710
5087
  }
5088
+
5089
+ if (!_upb_symtab_addfile(s, file, init->layouts, &status)) goto err;
5090
+
5091
+ upb_arena_free(arena);
5092
+ return true;
5093
+
5094
+ err:
5095
+ fprintf(stderr, "Error loading compiled-in descriptor: %s\n",
5096
+ upb_status_errmsg(&status));
5097
+ upb_arena_free(arena);
5098
+ return false;
4711
5099
  }
4712
5100
 
5101
+ #undef CHK
5102
+ #undef CHK_OOM
5103
+
5104
+
5105
+ #include <string.h>
5106
+
5107
+
5108
+ static char field_size[] = {
5109
+ 0,/* 0 */
5110
+ 8, /* UPB_DESCRIPTOR_TYPE_DOUBLE */
5111
+ 4, /* UPB_DESCRIPTOR_TYPE_FLOAT */
5112
+ 8, /* UPB_DESCRIPTOR_TYPE_INT64 */
5113
+ 8, /* UPB_DESCRIPTOR_TYPE_UINT64 */
5114
+ 4, /* UPB_DESCRIPTOR_TYPE_INT32 */
5115
+ 8, /* UPB_DESCRIPTOR_TYPE_FIXED64 */
5116
+ 4, /* UPB_DESCRIPTOR_TYPE_FIXED32 */
5117
+ 1, /* UPB_DESCRIPTOR_TYPE_BOOL */
5118
+ sizeof(upb_strview), /* UPB_DESCRIPTOR_TYPE_STRING */
5119
+ sizeof(void*), /* UPB_DESCRIPTOR_TYPE_GROUP */
5120
+ sizeof(void*), /* UPB_DESCRIPTOR_TYPE_MESSAGE */
5121
+ sizeof(upb_strview), /* UPB_DESCRIPTOR_TYPE_BYTES */
5122
+ 4, /* UPB_DESCRIPTOR_TYPE_UINT32 */
5123
+ 4, /* UPB_DESCRIPTOR_TYPE_ENUM */
5124
+ 4, /* UPB_DESCRIPTOR_TYPE_SFIXED32 */
5125
+ 8, /* UPB_DESCRIPTOR_TYPE_SFIXED64 */
5126
+ 4, /* UPB_DESCRIPTOR_TYPE_SINT32 */
5127
+ 8, /* UPB_DESCRIPTOR_TYPE_SINT64 */
5128
+ };
4713
5129
 
4714
- /** upb_msglayout *************************************************************/
5130
+ /* Strings/bytes are special-cased in maps. */
5131
+ static char _upb_fieldtype_to_mapsize[12] = {
5132
+ 0,
5133
+ 1, /* UPB_TYPE_BOOL */
5134
+ 4, /* UPB_TYPE_FLOAT */
5135
+ 4, /* UPB_TYPE_INT32 */
5136
+ 4, /* UPB_TYPE_UINT32 */
5137
+ 4, /* UPB_TYPE_ENUM */
5138
+ sizeof(void*), /* UPB_TYPE_MESSAGE */
5139
+ 8, /* UPB_TYPE_DOUBLE */
5140
+ 8, /* UPB_TYPE_INT64 */
5141
+ 8, /* UPB_TYPE_UINT64 */
5142
+ 0, /* UPB_TYPE_STRING */
5143
+ 0, /* UPB_TYPE_BYTES */
5144
+ };
5145
+
5146
+ /** upb_msg *******************************************************************/
4715
5147
 
4716
- static void upb_msglayout_free(upb_msglayout *l) {
4717
- upb_gfree(l);
5148
+ upb_msg *upb_msg_new(const upb_msgdef *m, upb_arena *a) {
5149
+ return _upb_msg_new(upb_msgdef_layout(m), a);
4718
5150
  }
4719
5151
 
4720
- static size_t upb_msglayout_place(upb_msglayout *l, size_t size) {
4721
- size_t ret;
5152
+ static bool in_oneof(const upb_msglayout_field *field) {
5153
+ return field->presence < 0;
5154
+ }
4722
5155
 
4723
- l->size = align_up(l->size, size);
4724
- ret = l->size;
4725
- l->size += size;
4726
- return ret;
5156
+ static uint32_t *oneofcase(const upb_msg *msg,
5157
+ const upb_msglayout_field *field) {
5158
+ UPB_ASSERT(in_oneof(field));
5159
+ return UPB_PTR_AT(msg, -field->presence, uint32_t);
4727
5160
  }
4728
5161
 
4729
- static bool upb_msglayout_init(const upb_msgdef *m,
4730
- upb_msglayout *l,
4731
- upb_msgfactory *factory) {
4732
- upb_msg_field_iter it;
4733
- upb_msg_oneof_iter oit;
4734
- size_t hasbit;
4735
- size_t submsg_count = 0;
4736
- const upb_msglayout **submsgs;
4737
- upb_msglayout_field *fields;
5162
+ static upb_msgval _upb_msg_getraw(const upb_msg *msg, const upb_fielddef *f) {
5163
+ const upb_msglayout_field *field = upb_fielddef_layout(f);
5164
+ const char *mem = UPB_PTR_AT(msg, field->offset, char);
5165
+ upb_msgval val = {0};
5166
+ int size = upb_fielddef_isseq(f) ? sizeof(void *)
5167
+ : field_size[field->descriptortype];
5168
+ memcpy(&val, mem, size);
5169
+ return val;
5170
+ }
4738
5171
 
4739
- for (upb_msg_field_begin(&it, m);
4740
- !upb_msg_field_done(&it);
4741
- upb_msg_field_next(&it)) {
4742
- const upb_fielddef* f = upb_msg_iter_field(&it);
4743
- if (upb_fielddef_issubmsg(f)) {
4744
- submsg_count++;
4745
- }
5172
+ bool upb_msg_has(const upb_msg *msg, const upb_fielddef *f) {
5173
+ const upb_msglayout_field *field = upb_fielddef_layout(f);
5174
+ if (in_oneof(field)) {
5175
+ return *oneofcase(msg, field) == field->number;
5176
+ } else if (field->presence > 0) {
5177
+ uint32_t hasbit = field->presence;
5178
+ return *UPB_PTR_AT(msg, hasbit / 8, uint8_t) & (1 << (hasbit % 8));
5179
+ } else {
5180
+ UPB_ASSERT(field->descriptortype == UPB_DESCRIPTOR_TYPE_MESSAGE ||
5181
+ field->descriptortype == UPB_DESCRIPTOR_TYPE_GROUP);
5182
+ return _upb_msg_getraw(msg, f).msg_val != NULL;
4746
5183
  }
5184
+ }
4747
5185
 
4748
- memset(l, 0, sizeof(*l));
5186
+ bool upb_msg_hasoneof(const upb_msg *msg, const upb_oneofdef *o) {
5187
+ upb_oneof_iter i;
5188
+ const upb_fielddef *f;
5189
+ const upb_msglayout_field *field;
4749
5190
 
4750
- fields = upb_gmalloc(upb_msgdef_numfields(m) * sizeof(*fields));
4751
- submsgs = upb_gmalloc(submsg_count * sizeof(*submsgs));
5191
+ upb_oneof_begin(&i, o);
5192
+ if (upb_oneof_done(&i)) return false;
5193
+ f = upb_oneof_iter_field(&i);
5194
+ field = upb_fielddef_layout(f);
5195
+ return *oneofcase(msg, field) != 0;
5196
+ }
4752
5197
 
4753
- if ((!fields && upb_msgdef_numfields(m)) ||
4754
- (!submsgs && submsg_count)) {
4755
- /* OOM. */
4756
- upb_gfree(fields);
4757
- upb_gfree(submsgs);
4758
- return false;
5198
+ upb_msgval upb_msg_get(const upb_msg *msg, const upb_fielddef *f) {
5199
+ if (!upb_fielddef_haspresence(f) || upb_msg_has(msg, f)) {
5200
+ return _upb_msg_getraw(msg, f);
5201
+ } else {
5202
+ /* TODO(haberman): change upb_fielddef to not require this switch(). */
5203
+ upb_msgval val = {0};
5204
+ switch (upb_fielddef_type(f)) {
5205
+ case UPB_TYPE_INT32:
5206
+ case UPB_TYPE_ENUM:
5207
+ val.int32_val = upb_fielddef_defaultint32(f);
5208
+ break;
5209
+ case UPB_TYPE_INT64:
5210
+ val.int64_val = upb_fielddef_defaultint64(f);
5211
+ break;
5212
+ case UPB_TYPE_UINT32:
5213
+ val.uint32_val = upb_fielddef_defaultuint32(f);
5214
+ break;
5215
+ case UPB_TYPE_UINT64:
5216
+ val.uint64_val = upb_fielddef_defaultuint64(f);
5217
+ break;
5218
+ case UPB_TYPE_FLOAT:
5219
+ val.float_val = upb_fielddef_defaultfloat(f);
5220
+ break;
5221
+ case UPB_TYPE_DOUBLE:
5222
+ val.double_val = upb_fielddef_defaultdouble(f);
5223
+ break;
5224
+ case UPB_TYPE_BOOL:
5225
+ val.double_val = upb_fielddef_defaultbool(f);
5226
+ break;
5227
+ case UPB_TYPE_STRING:
5228
+ case UPB_TYPE_BYTES:
5229
+ val.str_val.data = upb_fielddef_defaultstr(f, &val.str_val.size);
5230
+ break;
5231
+ case UPB_TYPE_MESSAGE:
5232
+ val.msg_val = NULL;
5233
+ break;
5234
+ }
5235
+ return val;
4759
5236
  }
5237
+ }
4760
5238
 
4761
- l->field_count = upb_msgdef_numfields(m);
4762
- l->fields = fields;
4763
- l->submsgs = submsgs;
4764
-
4765
- /* Allocate data offsets in three stages:
4766
- *
4767
- * 1. hasbits.
4768
- * 2. regular fields.
4769
- * 3. oneof fields.
4770
- *
4771
- * OPT: There is a lot of room for optimization here to minimize the size.
4772
- */
4773
-
4774
- /* Allocate hasbits and set basic field attributes. */
4775
- submsg_count = 0;
4776
- for (upb_msg_field_begin(&it, m), hasbit = 0;
4777
- !upb_msg_field_done(&it);
4778
- upb_msg_field_next(&it)) {
4779
- const upb_fielddef* f = upb_msg_iter_field(&it);
4780
- upb_msglayout_field *field = &fields[upb_fielddef_index(f)];
5239
+ upb_mutmsgval upb_msg_mutable(upb_msg *msg, const upb_fielddef *f,
5240
+ upb_arena *a) {
5241
+ const upb_msglayout_field *field = upb_fielddef_layout(f);
5242
+ upb_mutmsgval ret;
5243
+ char *mem = UPB_PTR_AT(msg, field->offset, char);
5244
+ bool wrong_oneof = in_oneof(field) && *oneofcase(msg, field) != field->number;
4781
5245
 
4782
- field->number = upb_fielddef_number(f);
4783
- field->descriptortype = upb_fielddef_descriptortype(f);
4784
- field->label = upb_fielddef_label(f);
5246
+ memcpy(&ret, mem, sizeof(void*));
4785
5247
 
4786
- if (upb_fielddef_issubmsg(f)) {
4787
- const upb_msglayout *sub_layout =
4788
- upb_msgfactory_getlayout(factory, upb_fielddef_msgsubdef(f));
4789
- field->submsg_index = submsg_count++;
4790
- submsgs[field->submsg_index] = sub_layout;
5248
+ if (a && (!ret.msg || wrong_oneof)) {
5249
+ if (upb_fielddef_ismap(f)) {
5250
+ const upb_msgdef *entry = upb_fielddef_msgsubdef(f);
5251
+ const upb_fielddef *key = upb_msgdef_itof(entry, UPB_MAPENTRY_KEY);
5252
+ const upb_fielddef *value = upb_msgdef_itof(entry, UPB_MAPENTRY_VALUE);
5253
+ ret.map = upb_map_new(a, upb_fielddef_type(key), upb_fielddef_type(value));
5254
+ } else if (upb_fielddef_isseq(f)) {
5255
+ ret.array = upb_array_new(a, upb_fielddef_type(f));
5256
+ } else {
5257
+ UPB_ASSERT(upb_fielddef_issubmsg(f));
5258
+ ret.msg = upb_msg_new(upb_fielddef_msgsubdef(f), a);
4791
5259
  }
4792
5260
 
4793
- if (upb_fielddef_haspresence(f) && !upb_fielddef_containingoneof(f)) {
4794
- field->presence = (hasbit++);
4795
- } else {
4796
- field->presence = 0;
5261
+ memcpy(mem, &ret, sizeof(void*));
5262
+
5263
+ if (wrong_oneof) {
5264
+ *oneofcase(msg, field) = field->number;
4797
5265
  }
4798
5266
  }
5267
+ return ret;
5268
+ }
4799
5269
 
4800
- /* Account for space used by hasbits. */
4801
- l->size = div_round_up(hasbit, 8);
5270
+ void upb_msg_set(upb_msg *msg, const upb_fielddef *f, upb_msgval val,
5271
+ upb_arena *a) {
5272
+ const upb_msglayout_field *field = upb_fielddef_layout(f);
5273
+ char *mem = UPB_PTR_AT(msg, field->offset, char);
5274
+ int size = upb_fielddef_isseq(f) ? sizeof(void *)
5275
+ : field_size[field->descriptortype];
5276
+ memcpy(mem, &val, size);
5277
+ if (in_oneof(field)) {
5278
+ *oneofcase(msg, field) = field->number;
5279
+ }
5280
+ }
4802
5281
 
4803
- /* Allocate non-oneof fields. */
4804
- for (upb_msg_field_begin(&it, m); !upb_msg_field_done(&it);
4805
- upb_msg_field_next(&it)) {
4806
- const upb_fielddef* f = upb_msg_iter_field(&it);
4807
- size_t field_size = upb_msg_fielddefsize(f);
4808
- size_t index = upb_fielddef_index(f);
5282
+ bool upb_msg_next(const upb_msg *msg, const upb_msgdef *m,
5283
+ const upb_symtab *ext_pool, const upb_fielddef **out_f,
5284
+ upb_msgval *out_val, size_t *iter) {
5285
+ size_t i = *iter;
5286
+ const upb_msgval zero = {0};
5287
+ const upb_fielddef *f;
5288
+ while ((f = _upb_msgdef_field(m, (int)++i)) != NULL) {
5289
+ upb_msgval val = _upb_msg_getraw(msg, f);
4809
5290
 
4810
- if (upb_fielddef_containingoneof(f)) {
4811
- /* Oneofs are handled separately below. */
4812
- continue;
5291
+ /* Skip field if unset or empty. */
5292
+ if (upb_fielddef_haspresence(f)) {
5293
+ if (!upb_msg_has(msg, f)) continue;
5294
+ } else {
5295
+ upb_msgval test = val;
5296
+ if (upb_fielddef_isstring(f) && !upb_fielddef_isseq(f)) {
5297
+ /* Clear string pointer, only size matters (ptr could be non-NULL). */
5298
+ test.str_val.data = NULL;
5299
+ }
5300
+ /* Continue if NULL or 0. */
5301
+ if (memcmp(&test, &zero, sizeof(test)) == 0) continue;
5302
+
5303
+ /* Continue on empty array or map. */
5304
+ if (upb_fielddef_ismap(f)) {
5305
+ if (upb_map_size(test.map_val) == 0) continue;
5306
+ } else if (upb_fielddef_isseq(f)) {
5307
+ if (upb_array_size(test.array_val) == 0) continue;
5308
+ }
4813
5309
  }
4814
5310
 
4815
- fields[index].offset = upb_msglayout_place(l, field_size);
5311
+ *out_val = val;
5312
+ *out_f = f;
5313
+ *iter = i;
5314
+ return true;
4816
5315
  }
5316
+ *iter = i;
5317
+ return false;
5318
+ }
4817
5319
 
4818
- /* Allocate oneof fields. Each oneof field consists of a uint32 for the case
4819
- * and space for the actual data. */
4820
- for (upb_msg_oneof_begin(&oit, m); !upb_msg_oneof_done(&oit);
4821
- upb_msg_oneof_next(&oit)) {
4822
- const upb_oneofdef* o = upb_msg_iter_oneof(&oit);
4823
- upb_oneof_iter fit;
4824
-
4825
- size_t case_size = sizeof(uint32_t); /* Could potentially optimize this. */
4826
- size_t field_size = 0;
4827
- uint32_t case_offset;
4828
- uint32_t data_offset;
5320
+ /** upb_array *****************************************************************/
4829
5321
 
4830
- /* Calculate field size: the max of all field sizes. */
4831
- for (upb_oneof_begin(&fit, o);
4832
- !upb_oneof_done(&fit);
4833
- upb_oneof_next(&fit)) {
4834
- const upb_fielddef* f = upb_oneof_iter_field(&fit);
4835
- field_size = UPB_MAX(field_size, upb_msg_fielddefsize(f));
4836
- }
5322
+ upb_array *upb_array_new(upb_arena *a, upb_fieldtype_t type) {
5323
+ return _upb_array_new(a, type);
5324
+ }
4837
5325
 
4838
- /* Align and allocate case offset. */
4839
- case_offset = upb_msglayout_place(l, case_size);
4840
- data_offset = upb_msglayout_place(l, field_size);
5326
+ size_t upb_array_size(const upb_array *arr) {
5327
+ return arr->len;
5328
+ }
4841
5329
 
4842
- for (upb_oneof_begin(&fit, o);
4843
- !upb_oneof_done(&fit);
4844
- upb_oneof_next(&fit)) {
4845
- const upb_fielddef* f = upb_oneof_iter_field(&fit);
4846
- fields[upb_fielddef_index(f)].offset = data_offset;
4847
- fields[upb_fielddef_index(f)].presence = ~case_offset;
4848
- }
4849
- }
5330
+ upb_msgval upb_array_get(const upb_array *arr, size_t i) {
5331
+ upb_msgval ret;
5332
+ const char* data = _upb_array_constptr(arr);
5333
+ int lg2 = arr->data & 7;
5334
+ UPB_ASSERT(i < arr->len);
5335
+ memcpy(&ret, data + (i << lg2), 1 << lg2);
5336
+ return ret;
5337
+ }
4850
5338
 
4851
- /* Size of the entire structure should be a multiple of its greatest
4852
- * alignment. TODO: track overall alignment for real? */
4853
- l->size = align_up(l->size, 8);
5339
+ void upb_array_set(upb_array *arr, size_t i, upb_msgval val) {
5340
+ char* data = _upb_array_ptr(arr);
5341
+ int lg2 = arr->data & 7;
5342
+ UPB_ASSERT(i < arr->len);
5343
+ memcpy(data + (i << lg2), &val, 1 << lg2);
5344
+ }
4854
5345
 
5346
+ bool upb_array_append(upb_array *arr, upb_msgval val, upb_arena *arena) {
5347
+ if (!_upb_array_realloc(arr, arr->len + 1, arena)) {
5348
+ return false;
5349
+ }
5350
+ arr->len++;
5351
+ upb_array_set(arr, arr->len - 1, val);
4855
5352
  return true;
4856
5353
  }
4857
5354
 
5355
+ /* Resizes the array to the given size, reallocating if necessary, and returns a
5356
+ * pointer to the new array elements. */
5357
+ bool upb_array_resize(upb_array *arr, size_t size, upb_arena *arena) {
5358
+ return _upb_array_realloc(arr, size, arena);
5359
+ }
4858
5360
 
4859
- /** upb_msgfactory ************************************************************/
4860
-
4861
- struct upb_msgfactory {
4862
- const upb_symtab *symtab; /* We own a ref. */
4863
- upb_inttable layouts;
4864
- };
5361
+ /** upb_map *******************************************************************/
4865
5362
 
4866
- upb_msgfactory *upb_msgfactory_new(const upb_symtab *symtab) {
4867
- upb_msgfactory *ret = upb_gmalloc(sizeof(*ret));
5363
+ upb_map *upb_map_new(upb_arena *a, upb_fieldtype_t key_type,
5364
+ upb_fieldtype_t value_type) {
5365
+ return _upb_map_new(a, _upb_fieldtype_to_mapsize[key_type],
5366
+ _upb_fieldtype_to_mapsize[value_type]);
5367
+ }
4868
5368
 
4869
- ret->symtab = symtab;
4870
- upb_inttable_init(&ret->layouts, UPB_CTYPE_PTR);
5369
+ size_t upb_map_size(const upb_map *map) {
5370
+ return _upb_map_size(map);
5371
+ }
4871
5372
 
4872
- return ret;
5373
+ bool upb_map_get(const upb_map *map, upb_msgval key, upb_msgval *val) {
5374
+ return _upb_map_get(map, &key, map->key_size, val, map->val_size);
4873
5375
  }
4874
5376
 
4875
- void upb_msgfactory_free(upb_msgfactory *f) {
4876
- upb_inttable_iter i;
4877
- upb_inttable_begin(&i, &f->layouts);
4878
- for(; !upb_inttable_done(&i); upb_inttable_next(&i)) {
4879
- upb_msglayout *l = upb_value_getptr(upb_inttable_iter_value(&i));
4880
- upb_msglayout_free(l);
4881
- }
5377
+ bool upb_map_set(upb_map *map, upb_msgval key, upb_msgval val,
5378
+ upb_arena *arena) {
5379
+ return _upb_map_set(map, &key, map->key_size, &val, map->val_size, arena);
5380
+ }
4882
5381
 
4883
- upb_inttable_uninit(&f->layouts);
4884
- upb_gfree(f);
5382
+ bool upb_map_delete(upb_map *map, upb_msgval key) {
5383
+ return _upb_map_delete(map, &key, map->key_size);
4885
5384
  }
4886
5385
 
4887
- const upb_symtab *upb_msgfactory_symtab(const upb_msgfactory *f) {
4888
- return f->symtab;
5386
+ bool upb_mapiter_next(const upb_map *map, size_t *iter) {
5387
+ return _upb_map_next(map, iter);
4889
5388
  }
4890
5389
 
4891
- const upb_msglayout *upb_msgfactory_getlayout(upb_msgfactory *f,
4892
- const upb_msgdef *m) {
4893
- upb_value v;
4894
- UPB_ASSERT(upb_symtab_lookupmsg(f->symtab, upb_msgdef_fullname(m)) == m);
4895
- UPB_ASSERT(!upb_msgdef_mapentry(m));
5390
+ /* Returns the key and value for this entry of the map. */
5391
+ upb_msgval upb_mapiter_key(const upb_map *map, size_t iter) {
5392
+ upb_strtable_iter i;
5393
+ upb_msgval ret;
5394
+ i.t = &map->table;
5395
+ i.index = iter;
5396
+ _upb_map_fromkey(upb_strtable_iter_key(&i), &ret, map->key_size);
5397
+ return ret;
5398
+ }
4896
5399
 
4897
- if (upb_inttable_lookupptr(&f->layouts, m, &v)) {
4898
- UPB_ASSERT(upb_value_getptr(v));
4899
- return upb_value_getptr(v);
4900
- } else {
4901
- /* In case of circular dependency, layout has to be inserted first. */
4902
- upb_msglayout *l = upb_gmalloc(sizeof(*l));
4903
- upb_msgfactory *mutable_f = (void*)f;
4904
- upb_inttable_insertptr(&mutable_f->layouts, m, upb_value_ptr(l));
4905
- UPB_ASSERT(l);
4906
- if (!upb_msglayout_init(m, l, f)) {
4907
- upb_msglayout_free(l);
4908
- }
4909
- return l;
4910
- }
5400
+ upb_msgval upb_mapiter_value(const upb_map *map, size_t iter) {
5401
+ upb_strtable_iter i;
5402
+ upb_msgval ret;
5403
+ i.t = &map->table;
5404
+ i.index = iter;
5405
+ _upb_map_fromvalue(upb_strtable_iter_value(&i), &ret, map->val_size);
5406
+ return ret;
4911
5407
  }
5408
+
5409
+ /* void upb_mapiter_setvalue(upb_map *map, size_t iter, upb_msgval value); */
4912
5410
  /*
4913
5411
  ** TODO(haberman): it's unclear whether a lot of the consistency checks should
4914
5412
  ** UPB_ASSERT() or return false.
@@ -5088,7 +5586,8 @@ static upb_handlers *upb_handlers_new(const upb_msgdef *md,
5088
5586
  int extra;
5089
5587
  upb_handlers *h;
5090
5588
 
5091
- extra = sizeof(upb_handlers_tabent) * (upb_msgdef_selectorcount(md) - 1);
5589
+ extra =
5590
+ (int)(sizeof(upb_handlers_tabent) * (upb_msgdef_selectorcount(md) - 1));
5092
5591
  h = upb_calloc(arena, sizeof(*h) + extra);
5093
5592
  if (!h) return NULL;
5094
5593
 
@@ -5489,6 +5988,31 @@ bool upb_bufsrc_putbuf(const char *buf, size_t len, upb_bytessink sink) {
5489
5988
  }
5490
5989
  return ret;
5491
5990
  }
5991
+
5992
+
5993
+ #ifdef UPB_MSVC_VSNPRINTF
5994
+ /* Visual C++ earlier than 2015 doesn't have standard C99 snprintf and
5995
+ * vsnprintf. To support them, missing functions are manually implemented
5996
+ * using the existing secure functions. */
5997
+ int msvc_vsnprintf(char* s, size_t n, const char* format, va_list arg) {
5998
+ if (!s) {
5999
+ return _vscprintf(format, arg);
6000
+ }
6001
+ int ret = _vsnprintf_s(s, n, _TRUNCATE, format, arg);
6002
+ if (ret < 0) {
6003
+ ret = _vscprintf(format, arg);
6004
+ }
6005
+ return ret;
6006
+ }
6007
+
6008
+ int msvc_snprintf(char* s, size_t n, const char* format, ...) {
6009
+ va_list arg;
6010
+ va_start(arg, format);
6011
+ int ret = msvc_vsnprintf(s, n, format, arg);
6012
+ va_end(arg);
6013
+ return ret;
6014
+ }
6015
+ #endif
5492
6016
  /*
5493
6017
  ** protobuf decoder bytecode compiler
5494
6018
  **
@@ -5644,7 +6168,9 @@ static void setofs(uint32_t *instruction, int32_t ofs) {
5644
6168
  UPB_ASSERT(getofs(*instruction) == ofs); /* Would fail in cases of overflow. */
5645
6169
  }
5646
6170
 
5647
- static uint32_t pcofs(compiler *c) { return c->pc - c->group->bytecode; }
6171
+ static uint32_t pcofs(compiler *c) {
6172
+ return (uint32_t)(c->pc - c->group->bytecode);
6173
+ }
5648
6174
 
5649
6175
  /* Defines a local label at the current PC location. All previous forward
5650
6176
  * references are updated to point to this location. The location is noted
@@ -5658,7 +6184,7 @@ static void label(compiler *c, unsigned int label) {
5658
6184
  codep = (val == EMPTYLABEL) ? NULL : c->group->bytecode + val;
5659
6185
  while (codep) {
5660
6186
  int ofs = getofs(*codep);
5661
- setofs(codep, c->pc - codep - instruction_len(*codep));
6187
+ setofs(codep, (int32_t)(c->pc - codep - instruction_len(*codep)));
5662
6188
  codep = ofs ? codep + ofs : NULL;
5663
6189
  }
5664
6190
  c->fwd_labels[label] = EMPTYLABEL;
@@ -5680,7 +6206,7 @@ static int32_t labelref(compiler *c, int label) {
5680
6206
  return 0;
5681
6207
  } else if (label < 0) {
5682
6208
  /* Backward local label. Relative to the next instruction. */
5683
- uint32_t from = (c->pc + 1) - c->group->bytecode;
6209
+ uint32_t from = (uint32_t)((c->pc + 1) - c->group->bytecode);
5684
6210
  return c->back_labels[-label] - from;
5685
6211
  } else {
5686
6212
  /* Forward local label: prepend to (possibly-empty) linked list. */
@@ -5714,7 +6240,7 @@ static void putop(compiler *c, int op, ...) {
5714
6240
  case OP_SETDISPATCH: {
5715
6241
  uintptr_t ptr = (uintptr_t)va_arg(ap, void*);
5716
6242
  put32(c, OP_SETDISPATCH);
5717
- put32(c, ptr);
6243
+ put32(c, (uint32_t)ptr);
5718
6244
  if (sizeof(uintptr_t) > sizeof(uint32_t))
5719
6245
  put32(c, (uint64_t)ptr >> 32);
5720
6246
  break;
@@ -5773,7 +6299,7 @@ static void putop(compiler *c, int op, ...) {
5773
6299
  case OP_TAG2: {
5774
6300
  int label = va_arg(ap, int);
5775
6301
  uint64_t tag = va_arg(ap, uint64_t);
5776
- uint32_t instruction = op | (tag << 16);
6302
+ uint32_t instruction = (uint32_t)(op | (tag << 16));
5777
6303
  UPB_ASSERT(tag <= 0xffff);
5778
6304
  setofs(&instruction, labelref(c, label));
5779
6305
  put32(c, instruction);
@@ -5785,7 +6311,7 @@ static void putop(compiler *c, int op, ...) {
5785
6311
  uint32_t instruction = op | (upb_value_size(tag) << 16);
5786
6312
  setofs(&instruction, labelref(c, label));
5787
6313
  put32(c, instruction);
5788
- put32(c, tag);
6314
+ put32(c, (uint32_t)tag);
5789
6315
  put32(c, tag >> 32);
5790
6316
  break;
5791
6317
  }
@@ -6398,11 +6924,11 @@ const upb_pbdecodermethod *upb_pbcodecache_get(upb_pbcodecache *c,
6398
6924
  } else {
6399
6925
  g = mgroup_new(h, c->lazy);
6400
6926
  ok = upb_inttable_insertptr(&c->groups, md, upb_value_constptr(g));
6401
- UPB_ASSERT(ok);
6927
+ UPB_ASSUME(ok);
6402
6928
  }
6403
6929
 
6404
6930
  ok = upb_inttable_lookupptr(&g->methods, h, &v);
6405
- UPB_ASSERT(ok);
6931
+ UPB_ASSUME(ok);
6406
6932
  return upb_value_getptr(v);
6407
6933
  }
6408
6934
  /*
@@ -6589,7 +7115,7 @@ static int32_t skip(upb_pbdecoder *d, size_t bytes) {
6589
7115
  UPB_ASSERT(d->skip == 0);
6590
7116
  if (bytes > delim_remaining(d)) {
6591
7117
  seterr(d, "Skipped value extended beyond enclosing submessage.");
6592
- return upb_pbdecoder_suspend(d);
7118
+ return (int32_t)upb_pbdecoder_suspend(d);
6593
7119
  } else if (bufleft(d) >= bytes) {
6594
7120
  /* Skipped data is all in current buffer, and more is still available. */
6595
7121
  advance(d, bytes);
@@ -6602,7 +7128,7 @@ static int32_t skip(upb_pbdecoder *d, size_t bytes) {
6602
7128
  d->bufstart_ofs += (d->end - d->buf);
6603
7129
  d->residual_end = d->residual;
6604
7130
  switchtobuf(d, d->residual, d->residual_end);
6605
- return d->size_param + d->skip;
7131
+ return (int32_t)(d->size_param + d->skip);
6606
7132
  }
6607
7133
  }
6608
7134
 
@@ -6642,7 +7168,7 @@ int32_t upb_pbdecoder_resume(upb_pbdecoder *d, void *p, const char *buf,
6642
7168
  /* NULL buf is ok if its entire span is covered by the "skip" above, but
6643
7169
  * by this point we know that "skip" doesn't cover the buffer. */
6644
7170
  seterr(d, "Passed NULL buffer over non-skippable region.");
6645
- return upb_pbdecoder_suspend(d);
7171
+ return (int32_t)upb_pbdecoder_suspend(d);
6646
7172
  }
6647
7173
 
6648
7174
  if (d->residual_end > d->residual) {
@@ -6752,9 +7278,9 @@ UPB_NOINLINE static int32_t getbytes_slow(upb_pbdecoder *d, void *buf,
6752
7278
  return DECODE_OK;
6753
7279
  } else if (d->data_end == d->delim_end) {
6754
7280
  seterr(d, "Submessage ended in the middle of a value or group");
6755
- return upb_pbdecoder_suspend(d);
7281
+ return (int32_t)upb_pbdecoder_suspend(d);
6756
7282
  } else {
6757
- return suspend_save(d);
7283
+ return (int32_t)suspend_save(d);
6758
7284
  }
6759
7285
  }
6760
7286
 
@@ -6810,7 +7336,7 @@ UPB_NOINLINE int32_t upb_pbdecoder_decode_varint_slow(upb_pbdecoder *d,
6810
7336
  }
6811
7337
  if(bitpos == 70 && (byte & 0x80)) {
6812
7338
  seterr(d, kUnterminatedVarint);
6813
- return upb_pbdecoder_suspend(d);
7339
+ return (int32_t)upb_pbdecoder_suspend(d);
6814
7340
  }
6815
7341
  return DECODE_OK;
6816
7342
  }
@@ -6827,7 +7353,7 @@ UPB_FORCEINLINE static int32_t decode_varint(upb_pbdecoder *d, uint64_t *u64) {
6827
7353
  upb_decoderet r = upb_vdecode_fast(d->ptr);
6828
7354
  if (r.p == NULL) {
6829
7355
  seterr(d, kUnterminatedVarint);
6830
- return upb_pbdecoder_suspend(d);
7356
+ return (int32_t)upb_pbdecoder_suspend(d);
6831
7357
  }
6832
7358
  advance(d, r.p - d->ptr);
6833
7359
  *u64 = r.val;
@@ -6851,9 +7377,9 @@ UPB_FORCEINLINE static int32_t decode_v32(upb_pbdecoder *d, uint32_t *u32) {
6851
7377
  * Right now the size_t -> int32_t can overflow and produce negative values.
6852
7378
  */
6853
7379
  *u32 = 0;
6854
- return upb_pbdecoder_suspend(d);
7380
+ return (int32_t)upb_pbdecoder_suspend(d);
6855
7381
  }
6856
- *u32 = u64;
7382
+ *u32 = (uint32_t)u64;
6857
7383
  return DECODE_OK;
6858
7384
  }
6859
7385
 
@@ -6929,7 +7455,7 @@ UPB_NOINLINE int32_t upb_pbdecoder_checktag_slow(upb_pbdecoder *d,
6929
7455
  UPB_ASSERT(ok < 0);
6930
7456
  return DECODE_OK;
6931
7457
  } else if (read < bytes && memcmp(&data, &expected, read) == 0) {
6932
- return suspend_save(d);
7458
+ return (int32_t)suspend_save(d);
6933
7459
  } else {
6934
7460
  return DECODE_MISMATCH;
6935
7461
  }
@@ -6949,7 +7475,7 @@ int32_t upb_pbdecoder_skipunknown(upb_pbdecoder *d, int32_t fieldnum,
6949
7475
  have_tag:
6950
7476
  if (fieldnum == 0) {
6951
7477
  seterr(d, "Saw invalid field number (0)");
6952
- return upb_pbdecoder_suspend(d);
7478
+ return (int32_t)upb_pbdecoder_suspend(d);
6953
7479
  }
6954
7480
 
6955
7481
  switch (wire_type) {
@@ -6971,7 +7497,9 @@ have_tag:
6971
7497
  break;
6972
7498
  }
6973
7499
  case UPB_WIRE_TYPE_START_GROUP:
6974
- CHECK_SUSPEND(pushtagdelim(d, -fieldnum));
7500
+ if (!pushtagdelim(d, -fieldnum)) {
7501
+ return (int32_t)upb_pbdecoder_suspend(d);
7502
+ }
6975
7503
  break;
6976
7504
  case UPB_WIRE_TYPE_END_GROUP:
6977
7505
  if (fieldnum == -d->top->groupnum) {
@@ -6980,12 +7508,12 @@ have_tag:
6980
7508
  return DECODE_ENDGROUP;
6981
7509
  } else {
6982
7510
  seterr(d, "Unmatched ENDGROUP tag.");
6983
- return upb_pbdecoder_suspend(d);
7511
+ return (int32_t)upb_pbdecoder_suspend(d);
6984
7512
  }
6985
7513
  break;
6986
7514
  default:
6987
7515
  seterr(d, "Invalid wire type");
6988
- return upb_pbdecoder_suspend(d);
7516
+ return (int32_t)upb_pbdecoder_suspend(d);
6989
7517
  }
6990
7518
 
6991
7519
  if (d->top->groupnum >= 0) {
@@ -7153,10 +7681,11 @@ size_t run_decoder_vm(upb_pbdecoder *d, const mgroup *group,
7153
7681
  CHECK_SUSPEND(upb_sink_startsubmsg(outer->sink, arg, &d->top->sink));
7154
7682
  )
7155
7683
  VMCASE(OP_ENDSUBMSG,
7156
- CHECK_SUSPEND(upb_sink_endsubmsg(d->top->sink, arg));
7684
+ upb_sink subsink = (d->top + 1)->sink;
7685
+ CHECK_SUSPEND(upb_sink_endsubmsg(d->top->sink, subsink, arg));
7157
7686
  )
7158
7687
  VMCASE(OP_STARTSTR,
7159
- uint32_t len = delim_remaining(d);
7688
+ uint32_t len = (uint32_t)delim_remaining(d);
7160
7689
  upb_pbdecoder_frame *outer = outer_frame(d);
7161
7690
  CHECK_SUSPEND(upb_sink_startstr(outer->sink, arg, len, &d->top->sink));
7162
7691
  if (len == 0) {
@@ -7164,7 +7693,7 @@ size_t run_decoder_vm(upb_pbdecoder *d, const mgroup *group,
7164
7693
  }
7165
7694
  )
7166
7695
  VMCASE(OP_STRING,
7167
- uint32_t len = curbufleft(d);
7696
+ uint32_t len = (uint32_t)curbufleft(d);
7168
7697
  size_t n = upb_sink_putstring(d->top->sink, arg, d->ptr, len, handle);
7169
7698
  if (n > len) {
7170
7699
  if (n > delim_remaining(d)) {
@@ -7699,7 +8228,7 @@ static bool start_delim(upb_pb_encoder *e) {
7699
8228
  e->runbegin = e->ptr;
7700
8229
  }
7701
8230
 
7702
- *e->top = e->segptr - e->segbuf;
8231
+ *e->top = (int)(e->segptr - e->segbuf);
7703
8232
  e->segptr->seglen = 0;
7704
8233
  e->segptr->msglen = 0;
7705
8234
 
@@ -8819,7 +9348,7 @@ static upb_selector_t getsel_for_handlertype(upb_json_parser *p,
8819
9348
  upb_handlertype_t type) {
8820
9349
  upb_selector_t sel;
8821
9350
  bool ok = upb_handlers_getselector(p->top->f, type, &sel);
8822
- UPB_ASSERT(ok);
9351
+ UPB_ASSUME(ok);
8823
9352
  return sel;
8824
9353
  }
8825
9354
 
@@ -8844,7 +9373,7 @@ static void set_name_table(upb_json_parser *p, upb_jsonparser_frame *frame) {
8844
9373
  const upb_json_parsermethod *method;
8845
9374
 
8846
9375
  ok = upb_inttable_lookupptr(&cache->methods, frame->m, &v);
8847
- UPB_ASSERT(ok);
9376
+ UPB_ASSUME(ok);
8848
9377
  method = upb_value_getconstptr(v);
8849
9378
 
8850
9379
  frame->name_table = &method->name_table;
@@ -9163,7 +9692,7 @@ static bool multipart_text(upb_json_parser *p, const char *buf, size_t len,
9163
9692
  /* Note: this invalidates the accumulate buffer! Call only after reading its
9164
9693
  * contents. */
9165
9694
  static void multipart_end(upb_json_parser *p) {
9166
- UPB_ASSERT(p->multipart_state != MULTIPART_INACTIVE);
9695
+ /* UPB_ASSERT(p->multipart_state != MULTIPART_INACTIVE); */
9167
9696
  p->multipart_state = MULTIPART_INACTIVE;
9168
9697
  accumulate_clear(p);
9169
9698
  }
@@ -9398,7 +9927,7 @@ static bool parse_number_from_buffer(upb_json_parser *p, const char *buf,
9398
9927
  } else if (val > INT32_MAX || val < INT32_MIN) {
9399
9928
  return false;
9400
9929
  } else {
9401
- upb_sink_putint32(p->top->sink, parser_getsel(p), val);
9930
+ upb_sink_putint32(p->top->sink, parser_getsel(p), (int32_t)val);
9402
9931
  return true;
9403
9932
  }
9404
9933
  }
@@ -9409,7 +9938,7 @@ static bool parse_number_from_buffer(upb_json_parser *p, const char *buf,
9409
9938
  } else if (val > UINT32_MAX || errno == ERANGE) {
9410
9939
  return false;
9411
9940
  } else {
9412
- upb_sink_putuint32(p->top->sink, parser_getsel(p), val);
9941
+ upb_sink_putuint32(p->top->sink, parser_getsel(p), (uint32_t)val);
9413
9942
  return true;
9414
9943
  }
9415
9944
  }
@@ -10117,14 +10646,18 @@ static void start_timestamp_zone(upb_json_parser *p, const char *ptr) {
10117
10646
  capture_begin(p, ptr);
10118
10647
  }
10119
10648
 
10649
+ static int div_round_up2(int n, int d) {
10650
+ return (n + d - 1) / d;
10651
+ }
10652
+
10120
10653
  /* epoch_days(1970, 1, 1) == 1970-01-01 == 0. */
10121
10654
  static int epoch_days(int year, int month, int day) {
10122
10655
  static const uint16_t month_yday[12] = {0, 31, 59, 90, 120, 151,
10123
10656
  181, 212, 243, 273, 304, 334};
10124
10657
  int febs_since_0 = month > 2 ? year + 1 : year;
10125
- int leap_days_since_0 = div_round_up(febs_since_0, 4) -
10126
- div_round_up(febs_since_0, 100) +
10127
- div_round_up(febs_since_0, 400);
10658
+ int leap_days_since_0 = div_round_up2(febs_since_0, 4) -
10659
+ div_round_up2(febs_since_0, 100) +
10660
+ div_round_up2(febs_since_0, 400);
10128
10661
  int days_since_0 =
10129
10662
  365 * year + month_yday[month - 1] + (day - 1) + leap_days_since_0;
10130
10663
 
@@ -10445,8 +10978,8 @@ static void end_member(upb_json_parser *p) {
10445
10978
  /* send ENDSUBMSG in repeated-field-of-mapentries frame. */
10446
10979
  p->top--;
10447
10980
  ok = upb_handlers_getselector(mapfield, UPB_HANDLER_ENDSUBMSG, &sel);
10448
- UPB_ASSERT(ok);
10449
- upb_sink_endsubmsg(p->top->sink, sel);
10981
+ UPB_ASSUME(ok);
10982
+ upb_sink_endsubmsg(p->top->sink, (p->top + 1)->sink, sel);
10450
10983
  }
10451
10984
 
10452
10985
  p->top->f = NULL;
@@ -10560,7 +11093,7 @@ static void end_subobject(upb_json_parser *p) {
10560
11093
  p->top--;
10561
11094
  if (!is_unknown) {
10562
11095
  sel = getsel_for_handlertype(p, UPB_HANDLER_ENDSUBMSG);
10563
- upb_sink_endsubmsg(p->top->sink, sel);
11096
+ upb_sink_endsubmsg(p->top->sink, (p->top + 1)->sink, sel);
10564
11097
  }
10565
11098
  }
10566
11099
  }
@@ -10999,11 +11532,11 @@ static bool does_fieldmask_end(upb_json_parser *p) {
10999
11532
  * final state once, when the closing '"' is seen. */
11000
11533
 
11001
11534
 
11002
- #line 2794 "upb/json/parser.rl"
11535
+ #line 2780 "upb/json/parser.rl"
11003
11536
 
11004
11537
 
11005
11538
 
11006
- #line 2597 "upb/json/parser.c"
11539
+ #line 2583 "upb/json/parser.c"
11007
11540
  static const char _json_actions[] = {
11008
11541
  0, 1, 0, 1, 1, 1, 3, 1,
11009
11542
  4, 1, 6, 1, 7, 1, 8, 1,
@@ -11258,7 +11791,7 @@ static const int json_en_value_machine = 78;
11258
11791
  static const int json_en_main = 1;
11259
11792
 
11260
11793
 
11261
- #line 2797 "upb/json/parser.rl"
11794
+ #line 2783 "upb/json/parser.rl"
11262
11795
 
11263
11796
  size_t parse(void *closure, const void *hd, const char *buf, size_t size,
11264
11797
  const upb_bufhandle *handle) {
@@ -11281,7 +11814,7 @@ size_t parse(void *closure, const void *hd, const char *buf, size_t size,
11281
11814
  capture_resume(parser, buf);
11282
11815
 
11283
11816
 
11284
- #line 2875 "upb/json/parser.c"
11817
+ #line 2861 "upb/json/parser.c"
11285
11818
  {
11286
11819
  int _klen;
11287
11820
  unsigned int _trans;
@@ -11356,147 +11889,147 @@ _match:
11356
11889
  switch ( *_acts++ )
11357
11890
  {
11358
11891
  case 1:
11359
- #line 2602 "upb/json/parser.rl"
11892
+ #line 2588 "upb/json/parser.rl"
11360
11893
  { p--; {cs = stack[--top]; goto _again;} }
11361
11894
  break;
11362
11895
  case 2:
11363
- #line 2604 "upb/json/parser.rl"
11896
+ #line 2590 "upb/json/parser.rl"
11364
11897
  { p--; {stack[top++] = cs; cs = 23;goto _again;} }
11365
11898
  break;
11366
11899
  case 3:
11367
- #line 2608 "upb/json/parser.rl"
11900
+ #line 2594 "upb/json/parser.rl"
11368
11901
  { start_text(parser, p); }
11369
11902
  break;
11370
11903
  case 4:
11371
- #line 2609 "upb/json/parser.rl"
11904
+ #line 2595 "upb/json/parser.rl"
11372
11905
  { CHECK_RETURN_TOP(end_text(parser, p)); }
11373
11906
  break;
11374
11907
  case 5:
11375
- #line 2615 "upb/json/parser.rl"
11908
+ #line 2601 "upb/json/parser.rl"
11376
11909
  { start_hex(parser); }
11377
11910
  break;
11378
11911
  case 6:
11379
- #line 2616 "upb/json/parser.rl"
11912
+ #line 2602 "upb/json/parser.rl"
11380
11913
  { hexdigit(parser, p); }
11381
11914
  break;
11382
11915
  case 7:
11383
- #line 2617 "upb/json/parser.rl"
11916
+ #line 2603 "upb/json/parser.rl"
11384
11917
  { CHECK_RETURN_TOP(end_hex(parser)); }
11385
11918
  break;
11386
11919
  case 8:
11387
- #line 2623 "upb/json/parser.rl"
11920
+ #line 2609 "upb/json/parser.rl"
11388
11921
  { CHECK_RETURN_TOP(escape(parser, p)); }
11389
11922
  break;
11390
11923
  case 9:
11391
- #line 2629 "upb/json/parser.rl"
11924
+ #line 2615 "upb/json/parser.rl"
11392
11925
  { p--; {cs = stack[--top]; goto _again;} }
11393
11926
  break;
11394
11927
  case 10:
11395
- #line 2634 "upb/json/parser.rl"
11928
+ #line 2620 "upb/json/parser.rl"
11396
11929
  { start_year(parser, p); }
11397
11930
  break;
11398
11931
  case 11:
11399
- #line 2635 "upb/json/parser.rl"
11932
+ #line 2621 "upb/json/parser.rl"
11400
11933
  { CHECK_RETURN_TOP(end_year(parser, p)); }
11401
11934
  break;
11402
11935
  case 12:
11403
- #line 2639 "upb/json/parser.rl"
11936
+ #line 2625 "upb/json/parser.rl"
11404
11937
  { start_month(parser, p); }
11405
11938
  break;
11406
11939
  case 13:
11407
- #line 2640 "upb/json/parser.rl"
11940
+ #line 2626 "upb/json/parser.rl"
11408
11941
  { CHECK_RETURN_TOP(end_month(parser, p)); }
11409
11942
  break;
11410
11943
  case 14:
11411
- #line 2644 "upb/json/parser.rl"
11944
+ #line 2630 "upb/json/parser.rl"
11412
11945
  { start_day(parser, p); }
11413
11946
  break;
11414
11947
  case 15:
11415
- #line 2645 "upb/json/parser.rl"
11948
+ #line 2631 "upb/json/parser.rl"
11416
11949
  { CHECK_RETURN_TOP(end_day(parser, p)); }
11417
11950
  break;
11418
11951
  case 16:
11419
- #line 2649 "upb/json/parser.rl"
11952
+ #line 2635 "upb/json/parser.rl"
11420
11953
  { start_hour(parser, p); }
11421
11954
  break;
11422
11955
  case 17:
11423
- #line 2650 "upb/json/parser.rl"
11956
+ #line 2636 "upb/json/parser.rl"
11424
11957
  { CHECK_RETURN_TOP(end_hour(parser, p)); }
11425
11958
  break;
11426
11959
  case 18:
11427
- #line 2654 "upb/json/parser.rl"
11960
+ #line 2640 "upb/json/parser.rl"
11428
11961
  { start_minute(parser, p); }
11429
11962
  break;
11430
11963
  case 19:
11431
- #line 2655 "upb/json/parser.rl"
11964
+ #line 2641 "upb/json/parser.rl"
11432
11965
  { CHECK_RETURN_TOP(end_minute(parser, p)); }
11433
11966
  break;
11434
11967
  case 20:
11435
- #line 2659 "upb/json/parser.rl"
11968
+ #line 2645 "upb/json/parser.rl"
11436
11969
  { start_second(parser, p); }
11437
11970
  break;
11438
11971
  case 21:
11439
- #line 2660 "upb/json/parser.rl"
11972
+ #line 2646 "upb/json/parser.rl"
11440
11973
  { CHECK_RETURN_TOP(end_second(parser, p)); }
11441
11974
  break;
11442
11975
  case 22:
11443
- #line 2665 "upb/json/parser.rl"
11976
+ #line 2651 "upb/json/parser.rl"
11444
11977
  { start_duration_base(parser, p); }
11445
11978
  break;
11446
11979
  case 23:
11447
- #line 2666 "upb/json/parser.rl"
11980
+ #line 2652 "upb/json/parser.rl"
11448
11981
  { CHECK_RETURN_TOP(end_duration_base(parser, p)); }
11449
11982
  break;
11450
11983
  case 24:
11451
- #line 2668 "upb/json/parser.rl"
11984
+ #line 2654 "upb/json/parser.rl"
11452
11985
  { p--; {cs = stack[--top]; goto _again;} }
11453
11986
  break;
11454
11987
  case 25:
11455
- #line 2673 "upb/json/parser.rl"
11988
+ #line 2659 "upb/json/parser.rl"
11456
11989
  { start_timestamp_base(parser); }
11457
11990
  break;
11458
11991
  case 26:
11459
- #line 2675 "upb/json/parser.rl"
11992
+ #line 2661 "upb/json/parser.rl"
11460
11993
  { start_timestamp_fraction(parser, p); }
11461
11994
  break;
11462
11995
  case 27:
11463
- #line 2676 "upb/json/parser.rl"
11996
+ #line 2662 "upb/json/parser.rl"
11464
11997
  { CHECK_RETURN_TOP(end_timestamp_fraction(parser, p)); }
11465
11998
  break;
11466
11999
  case 28:
11467
- #line 2678 "upb/json/parser.rl"
12000
+ #line 2664 "upb/json/parser.rl"
11468
12001
  { start_timestamp_zone(parser, p); }
11469
12002
  break;
11470
12003
  case 29:
11471
- #line 2679 "upb/json/parser.rl"
12004
+ #line 2665 "upb/json/parser.rl"
11472
12005
  { CHECK_RETURN_TOP(end_timestamp_zone(parser, p)); }
11473
12006
  break;
11474
12007
  case 30:
11475
- #line 2681 "upb/json/parser.rl"
12008
+ #line 2667 "upb/json/parser.rl"
11476
12009
  { p--; {cs = stack[--top]; goto _again;} }
11477
12010
  break;
11478
12011
  case 31:
11479
- #line 2686 "upb/json/parser.rl"
12012
+ #line 2672 "upb/json/parser.rl"
11480
12013
  { start_fieldmask_path_text(parser, p); }
11481
12014
  break;
11482
12015
  case 32:
11483
- #line 2687 "upb/json/parser.rl"
12016
+ #line 2673 "upb/json/parser.rl"
11484
12017
  { end_fieldmask_path_text(parser, p); }
11485
12018
  break;
11486
12019
  case 33:
11487
- #line 2692 "upb/json/parser.rl"
12020
+ #line 2678 "upb/json/parser.rl"
11488
12021
  { start_fieldmask_path(parser); }
11489
12022
  break;
11490
12023
  case 34:
11491
- #line 2693 "upb/json/parser.rl"
12024
+ #line 2679 "upb/json/parser.rl"
11492
12025
  { end_fieldmask_path(parser); }
11493
12026
  break;
11494
12027
  case 35:
11495
- #line 2699 "upb/json/parser.rl"
12028
+ #line 2685 "upb/json/parser.rl"
11496
12029
  { p--; {cs = stack[--top]; goto _again;} }
11497
12030
  break;
11498
12031
  case 36:
11499
- #line 2704 "upb/json/parser.rl"
12032
+ #line 2690 "upb/json/parser.rl"
11500
12033
  {
11501
12034
  if (is_wellknown_msg(parser, UPB_WELLKNOWN_TIMESTAMP)) {
11502
12035
  {stack[top++] = cs; cs = 47;goto _again;}
@@ -11510,11 +12043,11 @@ _match:
11510
12043
  }
11511
12044
  break;
11512
12045
  case 37:
11513
- #line 2717 "upb/json/parser.rl"
12046
+ #line 2703 "upb/json/parser.rl"
11514
12047
  { p--; {stack[top++] = cs; cs = 78;goto _again;} }
11515
12048
  break;
11516
12049
  case 38:
11517
- #line 2722 "upb/json/parser.rl"
12050
+ #line 2708 "upb/json/parser.rl"
11518
12051
  {
11519
12052
  if (is_wellknown_msg(parser, UPB_WELLKNOWN_ANY)) {
11520
12053
  start_any_member(parser, p);
@@ -11524,11 +12057,11 @@ _match:
11524
12057
  }
11525
12058
  break;
11526
12059
  case 39:
11527
- #line 2729 "upb/json/parser.rl"
12060
+ #line 2715 "upb/json/parser.rl"
11528
12061
  { CHECK_RETURN_TOP(end_membername(parser)); }
11529
12062
  break;
11530
12063
  case 40:
11531
- #line 2732 "upb/json/parser.rl"
12064
+ #line 2718 "upb/json/parser.rl"
11532
12065
  {
11533
12066
  if (is_wellknown_msg(parser, UPB_WELLKNOWN_ANY)) {
11534
12067
  end_any_member(parser, p);
@@ -11538,7 +12071,7 @@ _match:
11538
12071
  }
11539
12072
  break;
11540
12073
  case 41:
11541
- #line 2743 "upb/json/parser.rl"
12074
+ #line 2729 "upb/json/parser.rl"
11542
12075
  {
11543
12076
  if (is_wellknown_msg(parser, UPB_WELLKNOWN_ANY)) {
11544
12077
  start_any_object(parser, p);
@@ -11548,7 +12081,7 @@ _match:
11548
12081
  }
11549
12082
  break;
11550
12083
  case 42:
11551
- #line 2752 "upb/json/parser.rl"
12084
+ #line 2738 "upb/json/parser.rl"
11552
12085
  {
11553
12086
  if (is_wellknown_msg(parser, UPB_WELLKNOWN_ANY)) {
11554
12087
  CHECK_RETURN_TOP(end_any_object(parser, p));
@@ -11558,54 +12091,54 @@ _match:
11558
12091
  }
11559
12092
  break;
11560
12093
  case 43:
11561
- #line 2764 "upb/json/parser.rl"
12094
+ #line 2750 "upb/json/parser.rl"
11562
12095
  { CHECK_RETURN_TOP(start_array(parser)); }
11563
12096
  break;
11564
12097
  case 44:
11565
- #line 2768 "upb/json/parser.rl"
12098
+ #line 2754 "upb/json/parser.rl"
11566
12099
  { end_array(parser); }
11567
12100
  break;
11568
12101
  case 45:
11569
- #line 2773 "upb/json/parser.rl"
12102
+ #line 2759 "upb/json/parser.rl"
11570
12103
  { CHECK_RETURN_TOP(start_number(parser, p)); }
11571
12104
  break;
11572
12105
  case 46:
11573
- #line 2774 "upb/json/parser.rl"
12106
+ #line 2760 "upb/json/parser.rl"
11574
12107
  { CHECK_RETURN_TOP(end_number(parser, p)); }
11575
12108
  break;
11576
12109
  case 47:
11577
- #line 2776 "upb/json/parser.rl"
12110
+ #line 2762 "upb/json/parser.rl"
11578
12111
  { CHECK_RETURN_TOP(start_stringval(parser)); }
11579
12112
  break;
11580
12113
  case 48:
11581
- #line 2777 "upb/json/parser.rl"
12114
+ #line 2763 "upb/json/parser.rl"
11582
12115
  { CHECK_RETURN_TOP(end_stringval(parser)); }
11583
12116
  break;
11584
12117
  case 49:
11585
- #line 2779 "upb/json/parser.rl"
12118
+ #line 2765 "upb/json/parser.rl"
11586
12119
  { CHECK_RETURN_TOP(end_bool(parser, true)); }
11587
12120
  break;
11588
12121
  case 50:
11589
- #line 2781 "upb/json/parser.rl"
12122
+ #line 2767 "upb/json/parser.rl"
11590
12123
  { CHECK_RETURN_TOP(end_bool(parser, false)); }
11591
12124
  break;
11592
12125
  case 51:
11593
- #line 2783 "upb/json/parser.rl"
12126
+ #line 2769 "upb/json/parser.rl"
11594
12127
  { CHECK_RETURN_TOP(end_null(parser)); }
11595
12128
  break;
11596
12129
  case 52:
11597
- #line 2785 "upb/json/parser.rl"
12130
+ #line 2771 "upb/json/parser.rl"
11598
12131
  { CHECK_RETURN_TOP(start_subobject_full(parser)); }
11599
12132
  break;
11600
12133
  case 53:
11601
- #line 2786 "upb/json/parser.rl"
12134
+ #line 2772 "upb/json/parser.rl"
11602
12135
  { end_subobject_full(parser); }
11603
12136
  break;
11604
12137
  case 54:
11605
- #line 2791 "upb/json/parser.rl"
12138
+ #line 2777 "upb/json/parser.rl"
11606
12139
  { p--; {cs = stack[--top]; goto _again;} }
11607
12140
  break;
11608
- #line 3199 "upb/json/parser.c"
12141
+ #line 3185 "upb/json/parser.c"
11609
12142
  }
11610
12143
  }
11611
12144
 
@@ -11622,32 +12155,32 @@ _again:
11622
12155
  while ( __nacts-- > 0 ) {
11623
12156
  switch ( *__acts++ ) {
11624
12157
  case 0:
11625
- #line 2600 "upb/json/parser.rl"
12158
+ #line 2586 "upb/json/parser.rl"
11626
12159
  { p--; {cs = stack[--top]; if ( p == pe )
11627
12160
  goto _test_eof;
11628
12161
  goto _again;} }
11629
12162
  break;
11630
12163
  case 46:
11631
- #line 2774 "upb/json/parser.rl"
12164
+ #line 2760 "upb/json/parser.rl"
11632
12165
  { CHECK_RETURN_TOP(end_number(parser, p)); }
11633
12166
  break;
11634
12167
  case 49:
11635
- #line 2779 "upb/json/parser.rl"
12168
+ #line 2765 "upb/json/parser.rl"
11636
12169
  { CHECK_RETURN_TOP(end_bool(parser, true)); }
11637
12170
  break;
11638
12171
  case 50:
11639
- #line 2781 "upb/json/parser.rl"
12172
+ #line 2767 "upb/json/parser.rl"
11640
12173
  { CHECK_RETURN_TOP(end_bool(parser, false)); }
11641
12174
  break;
11642
12175
  case 51:
11643
- #line 2783 "upb/json/parser.rl"
12176
+ #line 2769 "upb/json/parser.rl"
11644
12177
  { CHECK_RETURN_TOP(end_null(parser)); }
11645
12178
  break;
11646
12179
  case 53:
11647
- #line 2786 "upb/json/parser.rl"
12180
+ #line 2772 "upb/json/parser.rl"
11648
12181
  { end_subobject_full(parser); }
11649
12182
  break;
11650
- #line 3241 "upb/json/parser.c"
12183
+ #line 3227 "upb/json/parser.c"
11651
12184
  }
11652
12185
  }
11653
12186
  }
@@ -11655,7 +12188,7 @@ goto _again;} }
11655
12188
  _out: {}
11656
12189
  }
11657
12190
 
11658
- #line 2819 "upb/json/parser.rl"
12191
+ #line 2805 "upb/json/parser.rl"
11659
12192
 
11660
12193
  if (p != pe) {
11661
12194
  upb_status_seterrf(parser->status, "Parse error at '%.*s'\n", pe - p, p);
@@ -11698,13 +12231,13 @@ static void json_parser_reset(upb_json_parser *p) {
11698
12231
 
11699
12232
  /* Emit Ragel initialization of the parser. */
11700
12233
 
11701
- #line 3292 "upb/json/parser.c"
12234
+ #line 3278 "upb/json/parser.c"
11702
12235
  {
11703
12236
  cs = json_start;
11704
12237
  top = 0;
11705
12238
  }
11706
12239
 
11707
- #line 2861 "upb/json/parser.rl"
12240
+ #line 2847 "upb/json/parser.rl"
11708
12241
  p->current_state = cs;
11709
12242
  p->parser_top = top;
11710
12243
  accumulate_clear(p);
@@ -11735,15 +12268,13 @@ static upb_json_parsermethod *parsermethod_new(upb_json_codecache *c,
11735
12268
  upb_msg_field_next(&i)) {
11736
12269
  const upb_fielddef *f = upb_msg_iter_field(&i);
11737
12270
  upb_value v = upb_value_constptr(f);
11738
- char *buf;
12271
+ const char *name;
11739
12272
 
11740
12273
  /* Add an entry for the JSON name. */
11741
- size_t len = upb_fielddef_getjsonname(f, NULL, 0);
11742
- buf = upb_malloc(alloc, len);
11743
- upb_fielddef_getjsonname(f, buf, len);
11744
- upb_strtable_insert3(&m->name_table, buf, strlen(buf), v, alloc);
12274
+ name = upb_fielddef_jsonname(f);
12275
+ upb_strtable_insert3(&m->name_table, name, strlen(name), v, alloc);
11745
12276
 
11746
- if (strcmp(buf, upb_fielddef_name(f)) != 0) {
12277
+ if (strcmp(name, upb_fielddef_name(f)) != 0) {
11747
12278
  /* Since the JSON name is different from the regular field name, add an
11748
12279
  * entry for the raw name (compliant proto3 JSON parsers must accept
11749
12280
  * both). */
@@ -11869,6 +12400,7 @@ const upb_json_parsermethod *upb_json_codecache_get(upb_json_codecache *c,
11869
12400
 
11870
12401
 
11871
12402
  #include <ctype.h>
12403
+ #include <inttypes.h>
11872
12404
  #include <stdint.h>
11873
12405
  #include <string.h>
11874
12406
  #include <time.h>
@@ -11926,12 +12458,8 @@ strpc *newstrpc(upb_handlers *h, const upb_fielddef *f,
11926
12458
  ret->ptr = upb_gstrdup(upb_fielddef_name(f));
11927
12459
  ret->len = strlen(ret->ptr);
11928
12460
  } else {
11929
- size_t len;
11930
- ret->len = upb_fielddef_getjsonname(f, NULL, 0);
11931
- ret->ptr = upb_gmalloc(ret->len);
11932
- len = upb_fielddef_getjsonname(f, ret->ptr, ret->len);
11933
- UPB_ASSERT(len == ret->len);
11934
- ret->len--; /* NULL */
12461
+ ret->ptr = upb_gstrdup(upb_fielddef_jsonname(f));
12462
+ ret->len = strlen(ret->ptr);
11935
12463
  }
11936
12464
 
11937
12465
  upb_handlers_addcleanup(h, ret, freestrpc);
@@ -11950,7 +12478,7 @@ strpc *newstrpc_str(upb_handlers *h, const char * str) {
11950
12478
  /* ------------ JSON string printing: values, maps, arrays ------------------ */
11951
12479
 
11952
12480
  static void print_data(
11953
- upb_json_printer *p, const char *buf, unsigned int len) {
12481
+ upb_json_printer *p, const char *buf, size_t len) {
11954
12482
  /* TODO: Will need to change if we support pushback from the sink. */
11955
12483
  size_t n = upb_bytessink_putbuf(p->output_, p->subc_, buf, len, NULL);
11956
12484
  UPB_ASSERT(n == len);
@@ -11990,7 +12518,7 @@ UPB_INLINE const char* json_nice_escape(char c) {
11990
12518
  /* Write a properly escaped string chunk. The surrounding quotes are *not*
11991
12519
  * printed; this is so that the caller has the option of emitting the string
11992
12520
  * content in chunks. */
11993
- static void putstring(upb_json_printer *p, const char *buf, unsigned int len) {
12521
+ static void putstring(upb_json_printer *p, const char *buf, size_t len) {
11994
12522
  const char* unescaped_run = NULL;
11995
12523
  unsigned int i;
11996
12524
  for (i = 0; i < len; i++) {
@@ -12070,28 +12598,26 @@ static size_t fmt_bool(bool val, char* buf, size_t length) {
12070
12598
  return n;
12071
12599
  }
12072
12600
 
12073
- static size_t fmt_int64_as_number(long long val, char* buf, size_t length) {
12074
- size_t n = _upb_snprintf(buf, length, "%lld", val);
12601
+ static size_t fmt_int64_as_number(int64_t val, char* buf, size_t length) {
12602
+ size_t n = _upb_snprintf(buf, length, "%" PRId64, val);
12075
12603
  CHKLENGTH(n > 0 && n < length);
12076
12604
  return n;
12077
12605
  }
12078
12606
 
12079
- static size_t fmt_uint64_as_number(
12080
- unsigned long long val, char* buf, size_t length) {
12081
- size_t n = _upb_snprintf(buf, length, "%llu", val);
12607
+ static size_t fmt_uint64_as_number(uint64_t val, char* buf, size_t length) {
12608
+ size_t n = _upb_snprintf(buf, length, "%" PRIu64, val);
12082
12609
  CHKLENGTH(n > 0 && n < length);
12083
12610
  return n;
12084
12611
  }
12085
12612
 
12086
- static size_t fmt_int64_as_string(long long val, char* buf, size_t length) {
12087
- size_t n = _upb_snprintf(buf, length, "\"%lld\"", val);
12613
+ static size_t fmt_int64_as_string(int64_t val, char* buf, size_t length) {
12614
+ size_t n = _upb_snprintf(buf, length, "\"%" PRId64 "\"", val);
12088
12615
  CHKLENGTH(n > 0 && n < length);
12089
12616
  return n;
12090
12617
  }
12091
12618
 
12092
- static size_t fmt_uint64_as_string(
12093
- unsigned long long val, char* buf, size_t length) {
12094
- size_t n = _upb_snprintf(buf, length, "\"%llu\"", val);
12619
+ static size_t fmt_uint64_as_string(uint64_t val, char* buf, size_t length) {
12620
+ size_t n = _upb_snprintf(buf, length, "\"%" PRIu64 "\"", val);
12095
12621
  CHKLENGTH(n > 0 && n < length);
12096
12622
  return n;
12097
12623
  }
@@ -13268,8 +13794,9 @@ upb_handlercache *upb_json_printer_newcache(bool preserve_proto_fieldnames) {
13268
13794
  }
13269
13795
  /* See port_def.inc. This should #undef all macros #defined there. */
13270
13796
 
13797
+ #undef UPB_MAPTYPE_STRING
13271
13798
  #undef UPB_SIZE
13272
- #undef UPB_FIELD_AT
13799
+ #undef UPB_PTR_AT
13273
13800
  #undef UPB_READ_ONEOF
13274
13801
  #undef UPB_WRITE_ONEOF
13275
13802
  #undef UPB_INLINE
@@ -13279,6 +13806,7 @@ upb_handlercache *upb_json_printer_newcache(bool preserve_proto_fieldnames) {
13279
13806
  #undef UPB_MAX
13280
13807
  #undef UPB_MIN
13281
13808
  #undef UPB_UNUSED
13809
+ #undef UPB_ASSUME
13282
13810
  #undef UPB_ASSERT
13283
13811
  #undef UPB_ASSERT_DEBUGVAR
13284
13812
  #undef UPB_UNREACHABLE