google-protobuf 3.11.0 → 3.12.0

Sign up to get free protection for your applications and to get access to all the features.

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