google-protobuf 3.11.0 → 3.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of google-protobuf might be problematic. Click here for more details.
- 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
|