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.
- checksums.yaml +4 -4
- data/ext/google/protobuf_c/defs.c +96 -8
- data/ext/google/protobuf_c/encode_decode.c +74 -37
- data/ext/google/protobuf_c/extconf.rb +0 -0
- data/ext/google/protobuf_c/map.c +20 -46
- data/ext/google/protobuf_c/message.c +20 -11
- data/ext/google/protobuf_c/protobuf.h +1 -0
- data/ext/google/protobuf_c/storage.c +72 -23
- data/ext/google/protobuf_c/upb.c +1810 -1282
- data/ext/google/protobuf_c/upb.h +1031 -1339
- data/lib/google/protobuf/well_known_types.rb +0 -0
- data/tests/basic.rb +146 -48
- data/tests/generated_code_test.rb +0 -0
- data/tests/stress.rb +0 -0
- metadata +16 -10
data/ext/google/protobuf_c/upb.c
CHANGED
@@ -22,9 +22,7 @@
|
|
22
22
|
*
|
23
23
|
* This file is private and must not be included by users!
|
24
24
|
*/
|
25
|
-
#
|
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
|
-
|
36
|
-
|
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
|
-
|
40
|
-
?
|
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
|
-
|
45
|
-
|
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
|
-
|
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
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
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 *
|
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;
|
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
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
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
|
-
|
318
|
+
static const char *decode_msg(upb_decstate *d, const char *ptr, upb_msg *msg,
|
319
|
+
const upb_msglayout *layout);
|
200
320
|
|
201
|
-
static
|
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
|
206
|
-
|
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
|
-
|
210
|
-
*val = 0;
|
336
|
+
uint64_t out = 0;
|
211
337
|
|
212
338
|
do {
|
213
|
-
|
214
|
-
byte = *
|
215
|
-
|
216
|
-
|
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
|
-
*
|
221
|
-
return
|
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
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
}
|
247
|
-
|
248
|
-
|
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
|
273
|
-
|
274
|
-
|
275
|
-
|
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
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
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
|
295
|
-
|
296
|
-
|
297
|
-
|
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
|
321
|
-
|
322
|
-
|
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
|
-
|
330
|
-
|
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
|
-
|
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
|
344
|
-
|
345
|
-
|
346
|
-
|
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
|
-
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
|
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
|
-
|
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
|
363
|
-
|
364
|
-
|
365
|
-
|
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
|
369
|
-
|
370
|
-
|
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
|
-
|
374
|
-
|
375
|
-
|
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
|
-
|
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
|
-
|
390
|
-
|
391
|
-
|
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
|
398
|
-
|
399
|
-
|
400
|
-
|
401
|
-
|
402
|
-
|
403
|
-
*
|
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
|
-
|
412
|
-
|
413
|
-
|
414
|
-
|
415
|
-
|
416
|
-
|
417
|
-
|
418
|
-
|
419
|
-
|
420
|
-
|
421
|
-
|
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
|
-
|
438
|
-
|
439
|
-
}
|
551
|
+
/* Parse map entry. */
|
552
|
+
memset(&ent, 0, sizeof(ent));
|
440
553
|
|
441
|
-
|
442
|
-
|
443
|
-
|
444
|
-
|
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
|
-
|
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
|
-
|
467
|
-
|
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
|
478
|
-
|
479
|
-
|
480
|
-
|
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
|
-
|
483
|
-
|
484
|
-
case
|
485
|
-
|
486
|
-
|
487
|
-
|
488
|
-
|
489
|
-
|
490
|
-
|
491
|
-
|
492
|
-
|
493
|
-
|
494
|
-
case
|
495
|
-
|
496
|
-
|
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
|
500
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
529
|
-
|
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
|
-
|
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
|
-
|
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
|
671
|
-
|
672
|
-
|
673
|
-
|
674
|
-
|
675
|
-
|
676
|
-
|
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
|
-
|
684
|
-
|
685
|
-
|
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
|
-
|
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
|
-
|
694
|
-
switch (tag & 7) {
|
635
|
+
switch (wire_type) {
|
695
636
|
case UPB_WIRE_TYPE_VARINT:
|
696
|
-
|
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
|
-
|
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
|
-
|
701
|
-
|
702
|
-
|
703
|
-
|
704
|
-
|
705
|
-
|
706
|
-
|
707
|
-
|
708
|
-
|
709
|
-
|
710
|
-
|
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
|
-
|
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
|
676
|
+
return ptr;
|
718
677
|
default:
|
719
|
-
|
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
|
-
|
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
|
-
|
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
|
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
|
-
|
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
|
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
|
883
|
-
size_t bytes = arr->len *
|
884
|
-
|
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
|
-
|
901
|
-
|
902
|
-
|
903
|
-
|
904
|
-
|
905
|
-
|
906
|
-
|
907
|
-
|
908
|
-
|
909
|
-
|
910
|
-
|
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
|
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
|
955
|
-
void
|
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
|
968
|
-
void
|
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
|
-
|
983
|
-
|
984
|
-
|
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
|
989
|
-
|
990
|
-
|
991
|
-
|
992
|
-
|
993
|
-
|
994
|
-
|
995
|
-
|
996
|
-
|
997
|
-
|
998
|
-
|
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
|
-
|
1002
|
-
|
1003
|
-
|
1004
|
-
|
1005
|
-
|
1006
|
-
|
1007
|
-
|
1008
|
-
|
1009
|
-
|
1010
|
-
|
1011
|
-
|
1012
|
-
|
1013
|
-
|
1014
|
-
|
1015
|
-
|
1016
|
-
|
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
|
-
|
1060
|
-
|
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
|
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
|
-
|
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
|
-
|
1141
|
-
|
1142
|
-
|
1143
|
-
|
1144
|
-
|
1145
|
-
|
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
|
-
|
1148
|
-
|
1149
|
-
|
1150
|
-
|
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
|
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
|
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
|
1211
|
+
return UPB_PTR_AT(msg, -sizeof(upb_msg_internal_withext),
|
1212
|
+
upb_msg_internal_withext);
|
1173
1213
|
}
|
1174
1214
|
|
1175
|
-
upb_msg *
|
1176
|
-
|
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 =
|
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
|
-
|
1204
|
-
|
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
|
-
|
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*
|
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
|
-
|
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
|
-
|
1241
|
-
|
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
|
-
|
1249
|
-
|
1250
|
-
|
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
|
-
|
1297
|
+
|
1298
|
+
arr->data = tag_arrptr(ptr, elem_size_lg2);
|
1299
|
+
arr->size = new_size;
|
1300
|
+
return true;
|
1253
1301
|
}
|
1254
1302
|
|
1255
|
-
|
1256
|
-
|
1257
|
-
|
1258
|
-
|
1259
|
-
|
1260
|
-
|
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,
|
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
|
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
|
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
|
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,
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
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,
|
1733
|
-
|
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,
|
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,
|
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.
|
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
|
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
|
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
|
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,
|
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
|
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,
|
2211
|
-
|
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
|
-
|
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
|
-
|
2255
|
-
|
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
|
-
|
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[
|
2562
|
-
{1, UPB_SIZE(
|
2563
|
-
{2, UPB_SIZE(
|
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(
|
2568
|
-
{7, UPB_SIZE(
|
2569
|
-
{8, UPB_SIZE(
|
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(
|
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),
|
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,
|
2873
|
-
{2, UPB_SIZE(24, 48), 0, 0, 5,
|
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,
|
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
|
-
|
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
|
-
|
3028
|
-
|
3029
|
-
|
3030
|
-
|
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
|
-
|
3189
|
-
|
3190
|
-
|
3191
|
-
|
3192
|
-
|
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
|
-
|
3377
|
-
|
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
|
-
|
3516
|
-
|
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
|
-
|
3596
|
-
|
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
|
-
|
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
|
-
|
3606
|
-
|
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
|
-
|
3664
|
-
|
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
|
-
|
3668
|
-
|
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
|
-
|
3672
|
-
|
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
|
-
|
3676
|
-
|
3677
|
-
|
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
|
-
|
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
|
-
|
3683
|
-
|
3684
|
-
}
|
3993
|
+
/* Account for space used by hasbits. */
|
3994
|
+
l->size = div_round_up(hasbit, 8);
|
3685
3995
|
|
3686
|
-
|
3687
|
-
|
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
|
-
|
3691
|
-
|
3692
|
-
|
4003
|
+
if (upb_fielddef_realcontainingoneof(f)) {
|
4004
|
+
/* Oneofs are handled separately below. */
|
4005
|
+
continue;
|
4006
|
+
}
|
3693
4007
|
|
3694
|
-
|
3695
|
-
|
3696
|
-
}
|
4008
|
+
fields[index].offset = upb_msglayout_place(l, field_size);
|
4009
|
+
}
|
3697
4010
|
|
3698
|
-
|
3699
|
-
|
3700
|
-
|
3701
|
-
|
3702
|
-
|
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
|
-
|
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
|
-
|
3712
|
-
|
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
|
-
|
3716
|
-
|
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
|
-
|
3720
|
-
|
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
|
-
|
3724
|
-
|
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
|
-
|
3728
|
-
|
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;
|
3744
|
-
upb_alloc *alloc;
|
3745
|
-
upb_alloc *tmp;
|
3746
|
-
upb_strtable *addtab;
|
3747
|
-
|
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
|
-
|
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
|
-
|
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,
|
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
|
-
|
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 (
|
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(
|
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
|
-
|
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 '
|
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
|
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
|
-
|
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,
|
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
|
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
|
-
|
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
|
-
|
4717
|
-
|
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
|
4721
|
-
|
5152
|
+
static bool in_oneof(const upb_msglayout_field *field) {
|
5153
|
+
return field->presence < 0;
|
5154
|
+
}
|
4722
5155
|
|
4723
|
-
|
4724
|
-
|
4725
|
-
|
4726
|
-
return
|
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
|
4730
|
-
|
4731
|
-
|
4732
|
-
|
4733
|
-
|
4734
|
-
|
4735
|
-
|
4736
|
-
|
4737
|
-
|
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
|
-
|
4740
|
-
|
4741
|
-
|
4742
|
-
|
4743
|
-
|
4744
|
-
|
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
|
-
|
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
|
-
|
4751
|
-
|
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
|
-
|
4754
|
-
|
4755
|
-
|
4756
|
-
|
4757
|
-
|
4758
|
-
|
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
|
-
|
4762
|
-
|
4763
|
-
|
4764
|
-
|
4765
|
-
|
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
|
-
|
4783
|
-
field->descriptortype = upb_fielddef_descriptortype(f);
|
4784
|
-
field->label = upb_fielddef_label(f);
|
5246
|
+
memcpy(&ret, mem, sizeof(void*));
|
4785
5247
|
|
4786
|
-
|
4787
|
-
|
4788
|
-
|
4789
|
-
|
4790
|
-
|
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
|
-
|
4794
|
-
|
4795
|
-
|
4796
|
-
field
|
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
|
-
|
4801
|
-
|
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
|
-
|
4804
|
-
|
4805
|
-
|
4806
|
-
|
4807
|
-
|
4808
|
-
|
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
|
4811
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
4831
|
-
|
4832
|
-
|
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
|
-
|
4839
|
-
|
4840
|
-
|
5326
|
+
size_t upb_array_size(const upb_array *arr) {
|
5327
|
+
return arr->len;
|
5328
|
+
}
|
4841
5329
|
|
4842
|
-
|
4843
|
-
|
4844
|
-
|
4845
|
-
|
4846
|
-
|
4847
|
-
|
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
|
-
|
4852
|
-
|
4853
|
-
|
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
|
-
/**
|
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
|
-
|
4867
|
-
|
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
|
-
|
4870
|
-
|
5369
|
+
size_t upb_map_size(const upb_map *map) {
|
5370
|
+
return _upb_map_size(map);
|
5371
|
+
}
|
4871
5372
|
|
4872
|
-
|
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
|
-
|
4876
|
-
|
4877
|
-
|
4878
|
-
|
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
|
-
|
4884
|
-
|
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
|
4888
|
-
return
|
5386
|
+
bool upb_mapiter_next(const upb_map *map, size_t *iter) {
|
5387
|
+
return _upb_map_next(map, iter);
|
4889
5388
|
}
|
4890
5389
|
|
4891
|
-
|
4892
|
-
|
4893
|
-
|
4894
|
-
|
4895
|
-
|
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
|
-
|
4898
|
-
|
4899
|
-
|
4900
|
-
|
4901
|
-
|
4902
|
-
|
4903
|
-
|
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 =
|
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) {
|
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
|
-
|
6927
|
+
UPB_ASSUME(ok);
|
6402
6928
|
}
|
6403
6929
|
|
6404
6930
|
ok = upb_inttable_lookupptr(&g->methods, h, &v);
|
6405
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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 =
|
10126
|
-
|
10127
|
-
|
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
|
-
|
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
|
11535
|
+
#line 2780 "upb/json/parser.rl"
|
11003
11536
|
|
11004
11537
|
|
11005
11538
|
|
11006
|
-
#line
|
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
|
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
|
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
|
11892
|
+
#line 2588 "upb/json/parser.rl"
|
11360
11893
|
{ p--; {cs = stack[--top]; goto _again;} }
|
11361
11894
|
break;
|
11362
11895
|
case 2:
|
11363
|
-
#line
|
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
|
11900
|
+
#line 2594 "upb/json/parser.rl"
|
11368
11901
|
{ start_text(parser, p); }
|
11369
11902
|
break;
|
11370
11903
|
case 4:
|
11371
|
-
#line
|
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
|
11908
|
+
#line 2601 "upb/json/parser.rl"
|
11376
11909
|
{ start_hex(parser); }
|
11377
11910
|
break;
|
11378
11911
|
case 6:
|
11379
|
-
#line
|
11912
|
+
#line 2602 "upb/json/parser.rl"
|
11380
11913
|
{ hexdigit(parser, p); }
|
11381
11914
|
break;
|
11382
11915
|
case 7:
|
11383
|
-
#line
|
11916
|
+
#line 2603 "upb/json/parser.rl"
|
11384
11917
|
{ CHECK_RETURN_TOP(end_hex(parser)); }
|
11385
11918
|
break;
|
11386
11919
|
case 8:
|
11387
|
-
#line
|
11920
|
+
#line 2609 "upb/json/parser.rl"
|
11388
11921
|
{ CHECK_RETURN_TOP(escape(parser, p)); }
|
11389
11922
|
break;
|
11390
11923
|
case 9:
|
11391
|
-
#line
|
11924
|
+
#line 2615 "upb/json/parser.rl"
|
11392
11925
|
{ p--; {cs = stack[--top]; goto _again;} }
|
11393
11926
|
break;
|
11394
11927
|
case 10:
|
11395
|
-
#line
|
11928
|
+
#line 2620 "upb/json/parser.rl"
|
11396
11929
|
{ start_year(parser, p); }
|
11397
11930
|
break;
|
11398
11931
|
case 11:
|
11399
|
-
#line
|
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
|
11936
|
+
#line 2625 "upb/json/parser.rl"
|
11404
11937
|
{ start_month(parser, p); }
|
11405
11938
|
break;
|
11406
11939
|
case 13:
|
11407
|
-
#line
|
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
|
11944
|
+
#line 2630 "upb/json/parser.rl"
|
11412
11945
|
{ start_day(parser, p); }
|
11413
11946
|
break;
|
11414
11947
|
case 15:
|
11415
|
-
#line
|
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
|
11952
|
+
#line 2635 "upb/json/parser.rl"
|
11420
11953
|
{ start_hour(parser, p); }
|
11421
11954
|
break;
|
11422
11955
|
case 17:
|
11423
|
-
#line
|
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
|
11960
|
+
#line 2640 "upb/json/parser.rl"
|
11428
11961
|
{ start_minute(parser, p); }
|
11429
11962
|
break;
|
11430
11963
|
case 19:
|
11431
|
-
#line
|
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
|
11968
|
+
#line 2645 "upb/json/parser.rl"
|
11436
11969
|
{ start_second(parser, p); }
|
11437
11970
|
break;
|
11438
11971
|
case 21:
|
11439
|
-
#line
|
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
|
11976
|
+
#line 2651 "upb/json/parser.rl"
|
11444
11977
|
{ start_duration_base(parser, p); }
|
11445
11978
|
break;
|
11446
11979
|
case 23:
|
11447
|
-
#line
|
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
|
11984
|
+
#line 2654 "upb/json/parser.rl"
|
11452
11985
|
{ p--; {cs = stack[--top]; goto _again;} }
|
11453
11986
|
break;
|
11454
11987
|
case 25:
|
11455
|
-
#line
|
11988
|
+
#line 2659 "upb/json/parser.rl"
|
11456
11989
|
{ start_timestamp_base(parser); }
|
11457
11990
|
break;
|
11458
11991
|
case 26:
|
11459
|
-
#line
|
11992
|
+
#line 2661 "upb/json/parser.rl"
|
11460
11993
|
{ start_timestamp_fraction(parser, p); }
|
11461
11994
|
break;
|
11462
11995
|
case 27:
|
11463
|
-
#line
|
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
|
12000
|
+
#line 2664 "upb/json/parser.rl"
|
11468
12001
|
{ start_timestamp_zone(parser, p); }
|
11469
12002
|
break;
|
11470
12003
|
case 29:
|
11471
|
-
#line
|
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
|
12008
|
+
#line 2667 "upb/json/parser.rl"
|
11476
12009
|
{ p--; {cs = stack[--top]; goto _again;} }
|
11477
12010
|
break;
|
11478
12011
|
case 31:
|
11479
|
-
#line
|
12012
|
+
#line 2672 "upb/json/parser.rl"
|
11480
12013
|
{ start_fieldmask_path_text(parser, p); }
|
11481
12014
|
break;
|
11482
12015
|
case 32:
|
11483
|
-
#line
|
12016
|
+
#line 2673 "upb/json/parser.rl"
|
11484
12017
|
{ end_fieldmask_path_text(parser, p); }
|
11485
12018
|
break;
|
11486
12019
|
case 33:
|
11487
|
-
#line
|
12020
|
+
#line 2678 "upb/json/parser.rl"
|
11488
12021
|
{ start_fieldmask_path(parser); }
|
11489
12022
|
break;
|
11490
12023
|
case 34:
|
11491
|
-
#line
|
12024
|
+
#line 2679 "upb/json/parser.rl"
|
11492
12025
|
{ end_fieldmask_path(parser); }
|
11493
12026
|
break;
|
11494
12027
|
case 35:
|
11495
|
-
#line
|
12028
|
+
#line 2685 "upb/json/parser.rl"
|
11496
12029
|
{ p--; {cs = stack[--top]; goto _again;} }
|
11497
12030
|
break;
|
11498
12031
|
case 36:
|
11499
|
-
#line
|
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
|
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
|
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
|
12060
|
+
#line 2715 "upb/json/parser.rl"
|
11528
12061
|
{ CHECK_RETURN_TOP(end_membername(parser)); }
|
11529
12062
|
break;
|
11530
12063
|
case 40:
|
11531
|
-
#line
|
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
|
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
|
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
|
12094
|
+
#line 2750 "upb/json/parser.rl"
|
11562
12095
|
{ CHECK_RETURN_TOP(start_array(parser)); }
|
11563
12096
|
break;
|
11564
12097
|
case 44:
|
11565
|
-
#line
|
12098
|
+
#line 2754 "upb/json/parser.rl"
|
11566
12099
|
{ end_array(parser); }
|
11567
12100
|
break;
|
11568
12101
|
case 45:
|
11569
|
-
#line
|
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
|
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
|
12110
|
+
#line 2762 "upb/json/parser.rl"
|
11578
12111
|
{ CHECK_RETURN_TOP(start_stringval(parser)); }
|
11579
12112
|
break;
|
11580
12113
|
case 48:
|
11581
|
-
#line
|
12114
|
+
#line 2763 "upb/json/parser.rl"
|
11582
12115
|
{ CHECK_RETURN_TOP(end_stringval(parser)); }
|
11583
12116
|
break;
|
11584
12117
|
case 49:
|
11585
|
-
#line
|
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
|
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
|
12126
|
+
#line 2769 "upb/json/parser.rl"
|
11594
12127
|
{ CHECK_RETURN_TOP(end_null(parser)); }
|
11595
12128
|
break;
|
11596
12129
|
case 52:
|
11597
|
-
#line
|
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
|
12134
|
+
#line 2772 "upb/json/parser.rl"
|
11602
12135
|
{ end_subobject_full(parser); }
|
11603
12136
|
break;
|
11604
12137
|
case 54:
|
11605
|
-
#line
|
12138
|
+
#line 2777 "upb/json/parser.rl"
|
11606
12139
|
{ p--; {cs = stack[--top]; goto _again;} }
|
11607
12140
|
break;
|
11608
|
-
#line
|
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
|
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
|
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
|
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
|
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
|
12176
|
+
#line 2769 "upb/json/parser.rl"
|
11644
12177
|
{ CHECK_RETURN_TOP(end_null(parser)); }
|
11645
12178
|
break;
|
11646
12179
|
case 53:
|
11647
|
-
#line
|
12180
|
+
#line 2772 "upb/json/parser.rl"
|
11648
12181
|
{ end_subobject_full(parser); }
|
11649
12182
|
break;
|
11650
|
-
#line
|
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
|
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
|
12234
|
+
#line 3278 "upb/json/parser.c"
|
11702
12235
|
{
|
11703
12236
|
cs = json_start;
|
11704
12237
|
top = 0;
|
11705
12238
|
}
|
11706
12239
|
|
11707
|
-
#line
|
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 *
|
12271
|
+
const char *name;
|
11739
12272
|
|
11740
12273
|
/* Add an entry for the JSON name. */
|
11741
|
-
|
11742
|
-
|
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(
|
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
|
-
|
11930
|
-
ret->len =
|
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,
|
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,
|
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(
|
12074
|
-
size_t n = _upb_snprintf(buf, length, "%
|
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
|
-
|
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(
|
12087
|
-
size_t n = _upb_snprintf(buf, length, "\"%
|
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
|
-
|
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
|
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
|