google-protobuf 3.0.0.alpha.1.1 → 3.0.0.alpha.2.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of google-protobuf might be problematic. Click here for more details.
- checksums.yaml +5 -13
- data/ext/google/protobuf_c/defs.c +298 -9
- data/ext/google/protobuf_c/encode_decode.c +204 -29
- data/ext/google/protobuf_c/map.c +1 -1
- data/ext/google/protobuf_c/message.c +44 -0
- data/ext/google/protobuf_c/protobuf.c +2 -0
- data/ext/google/protobuf_c/protobuf.h +61 -2
- data/ext/google/protobuf_c/repeated_field.c +28 -31
- data/ext/google/protobuf_c/storage.c +230 -66
- data/ext/google/protobuf_c/upb.c +938 -153
- data/ext/google/protobuf_c/upb.h +607 -55
- data/tests/basic.rb +114 -2
- data/tests/generated_code_test.rb +17 -0
- metadata +7 -5
data/ext/google/protobuf_c/upb.c
CHANGED
@@ -210,6 +210,21 @@ static bool upb_validate_field(upb_fielddef *f, upb_status *s) {
|
|
210
210
|
upb_fielddef_setdefaultint32(f, upb_fielddef_defaultint32(f));
|
211
211
|
}
|
212
212
|
|
213
|
+
// Ensure that MapEntry submessages only appear as repeated fields, not
|
214
|
+
// optional/required (singular) fields.
|
215
|
+
if (upb_fielddef_type(f) == UPB_TYPE_MESSAGE &&
|
216
|
+
upb_fielddef_msgsubdef(f) != NULL) {
|
217
|
+
const upb_msgdef *subdef = upb_fielddef_msgsubdef(f);
|
218
|
+
if (upb_msgdef_mapentry(subdef) && !upb_fielddef_isseq(f)) {
|
219
|
+
upb_status_seterrf(s,
|
220
|
+
"Field %s refers to mapentry message but is not "
|
221
|
+
"a repeated field",
|
222
|
+
upb_fielddef_name(f) ? upb_fielddef_name(f) :
|
223
|
+
"(unnamed)");
|
224
|
+
return false;
|
225
|
+
}
|
226
|
+
}
|
227
|
+
|
213
228
|
return true;
|
214
229
|
}
|
215
230
|
|
@@ -247,10 +262,12 @@ static bool assign_msg_indices(upb_msgdef *m, upb_status *s) {
|
|
247
262
|
upb_fielddef **fields = malloc(n * sizeof(*fields));
|
248
263
|
if (!fields) return false;
|
249
264
|
|
250
|
-
|
265
|
+
upb_msg_field_iter j;
|
251
266
|
int i;
|
252
267
|
m->submsg_field_count = 0;
|
253
|
-
for(i = 0,
|
268
|
+
for(i = 0, upb_msg_field_begin(&j, m);
|
269
|
+
!upb_msg_field_done(&j);
|
270
|
+
upb_msg_field_next(&j), i++) {
|
254
271
|
upb_fielddef *f = upb_msg_iter_field(&j);
|
255
272
|
assert(f->msg.def == m);
|
256
273
|
if (!upb_validate_field(f, s)) {
|
@@ -286,7 +303,9 @@ static bool assign_msg_indices(upb_msgdef *m, upb_status *s) {
|
|
286
303
|
upb_selector_t sel;
|
287
304
|
upb_inttable_insert(&t, UPB_STARTMSG_SELECTOR, v);
|
288
305
|
upb_inttable_insert(&t, UPB_ENDMSG_SELECTOR, v);
|
289
|
-
for(
|
306
|
+
for(upb_msg_field_begin(&j, m);
|
307
|
+
!upb_msg_field_done(&j);
|
308
|
+
upb_msg_field_next(&j)) {
|
290
309
|
upb_fielddef *f = upb_msg_iter_field(&j);
|
291
310
|
// These calls will assert-fail in upb_table if the value already exists.
|
292
311
|
TRY(UPB_HANDLER_INT32);
|
@@ -544,6 +563,9 @@ static void visitfield(const upb_refcounted *r, upb_refcounted_visit *visit,
|
|
544
563
|
if (upb_fielddef_containingtype(f)) {
|
545
564
|
visit(r, UPB_UPCAST2(upb_fielddef_containingtype(f)), closure);
|
546
565
|
}
|
566
|
+
if (upb_fielddef_containingoneof(f)) {
|
567
|
+
visit(r, UPB_UPCAST2(upb_fielddef_containingoneof(f)), closure);
|
568
|
+
}
|
547
569
|
if (upb_fielddef_subdef(f)) {
|
548
570
|
visit(r, UPB_UPCAST(upb_fielddef_subdef(f)), closure);
|
549
571
|
}
|
@@ -619,6 +641,7 @@ upb_fielddef *upb_fielddef_new(const void *owner) {
|
|
619
641
|
}
|
620
642
|
f->msg.def = NULL;
|
621
643
|
f->sub.def = NULL;
|
644
|
+
f->oneof = NULL;
|
622
645
|
f->subdef_is_symbolic = false;
|
623
646
|
f->msg_is_symbolic = false;
|
624
647
|
f->label_ = UPB_LABEL_OPTIONAL;
|
@@ -748,6 +771,10 @@ const upb_msgdef *upb_fielddef_containingtype(const upb_fielddef *f) {
|
|
748
771
|
return f->msg_is_symbolic ? NULL : f->msg.def;
|
749
772
|
}
|
750
773
|
|
774
|
+
const upb_oneofdef *upb_fielddef_containingoneof(const upb_fielddef *f) {
|
775
|
+
return f->oneof;
|
776
|
+
}
|
777
|
+
|
751
778
|
upb_msgdef *upb_fielddef_containingtype_mutable(upb_fielddef *f) {
|
752
779
|
return (upb_msgdef*)upb_fielddef_containingtype(f);
|
753
780
|
}
|
@@ -776,6 +803,10 @@ bool upb_fielddef_setcontainingtypename(upb_fielddef *f, const char *name,
|
|
776
803
|
}
|
777
804
|
|
778
805
|
bool upb_fielddef_setname(upb_fielddef *f, const char *name, upb_status *s) {
|
806
|
+
if (upb_fielddef_containingtype(f) || upb_fielddef_containingoneof(f)) {
|
807
|
+
upb_status_seterrmsg(s, "Already added to message or oneof");
|
808
|
+
return false;
|
809
|
+
}
|
779
810
|
return upb_def_setfullname(UPB_UPCAST(f), name, s);
|
780
811
|
}
|
781
812
|
|
@@ -1226,6 +1257,11 @@ bool upb_fielddef_isprimitive(const upb_fielddef *f) {
|
|
1226
1257
|
return !upb_fielddef_isstring(f) && !upb_fielddef_issubmsg(f);
|
1227
1258
|
}
|
1228
1259
|
|
1260
|
+
bool upb_fielddef_ismap(const upb_fielddef *f) {
|
1261
|
+
return upb_fielddef_isseq(f) && upb_fielddef_issubmsg(f) &&
|
1262
|
+
upb_msgdef_mapentry(upb_fielddef_msgsubdef(f));
|
1263
|
+
}
|
1264
|
+
|
1229
1265
|
bool upb_fielddef_hassubdef(const upb_fielddef *f) {
|
1230
1266
|
return upb_fielddef_issubmsg(f) || upb_fielddef_type(f) == UPB_TYPE_ENUM;
|
1231
1267
|
}
|
@@ -1247,15 +1283,25 @@ bool upb_fielddef_checkdescriptortype(int32_t type) {
|
|
1247
1283
|
static void visitmsg(const upb_refcounted *r, upb_refcounted_visit *visit,
|
1248
1284
|
void *closure) {
|
1249
1285
|
const upb_msgdef *m = (const upb_msgdef*)r;
|
1250
|
-
|
1251
|
-
for(
|
1286
|
+
upb_msg_field_iter i;
|
1287
|
+
for(upb_msg_field_begin(&i, m);
|
1288
|
+
!upb_msg_field_done(&i);
|
1289
|
+
upb_msg_field_next(&i)) {
|
1252
1290
|
upb_fielddef *f = upb_msg_iter_field(&i);
|
1253
1291
|
visit(r, UPB_UPCAST2(f), closure);
|
1254
1292
|
}
|
1293
|
+
upb_msg_oneof_iter o;
|
1294
|
+
for(upb_msg_oneof_begin(&o, m);
|
1295
|
+
!upb_msg_oneof_done(&o);
|
1296
|
+
upb_msg_oneof_next(&o)) {
|
1297
|
+
upb_oneofdef *f = upb_msg_iter_oneof(&o);
|
1298
|
+
visit(r, UPB_UPCAST2(f), closure);
|
1299
|
+
}
|
1255
1300
|
}
|
1256
1301
|
|
1257
1302
|
static void freemsg(upb_refcounted *r) {
|
1258
1303
|
upb_msgdef *m = (upb_msgdef*)r;
|
1304
|
+
upb_strtable_uninit(&m->ntoo);
|
1259
1305
|
upb_strtable_uninit(&m->ntof);
|
1260
1306
|
upb_inttable_uninit(&m->itof);
|
1261
1307
|
upb_def_uninit(UPB_UPCAST(m));
|
@@ -1267,14 +1313,17 @@ upb_msgdef *upb_msgdef_new(const void *owner) {
|
|
1267
1313
|
upb_msgdef *m = malloc(sizeof(*m));
|
1268
1314
|
if (!m) return NULL;
|
1269
1315
|
if (!upb_def_init(UPB_UPCAST(m), UPB_DEF_MSG, &vtbl, owner)) goto err2;
|
1270
|
-
if (!upb_inttable_init(&m->itof, UPB_CTYPE_PTR)) goto
|
1271
|
-
if (!upb_strtable_init(&m->ntof, UPB_CTYPE_PTR)) goto
|
1316
|
+
if (!upb_inttable_init(&m->itof, UPB_CTYPE_PTR)) goto err3;
|
1317
|
+
if (!upb_strtable_init(&m->ntof, UPB_CTYPE_PTR)) goto err2;
|
1318
|
+
if (!upb_strtable_init(&m->ntoo, UPB_CTYPE_PTR)) goto err1;
|
1272
1319
|
m->map_entry = false;
|
1273
1320
|
return m;
|
1274
1321
|
|
1275
1322
|
err1:
|
1276
|
-
|
1323
|
+
upb_strtable_uninit(&m->ntof);
|
1277
1324
|
err2:
|
1325
|
+
upb_inttable_uninit(&m->itof);
|
1326
|
+
err3:
|
1278
1327
|
free(m);
|
1279
1328
|
return NULL;
|
1280
1329
|
}
|
@@ -1286,14 +1335,28 @@ upb_msgdef *upb_msgdef_dup(const upb_msgdef *m, const void *owner) {
|
|
1286
1335
|
upb_def_fullname(UPB_UPCAST(m)), NULL);
|
1287
1336
|
newm->map_entry = m->map_entry;
|
1288
1337
|
UPB_ASSERT_VAR(ok, ok);
|
1289
|
-
|
1290
|
-
for(
|
1338
|
+
upb_msg_field_iter i;
|
1339
|
+
for(upb_msg_field_begin(&i, m);
|
1340
|
+
!upb_msg_field_done(&i);
|
1341
|
+
upb_msg_field_next(&i)) {
|
1291
1342
|
upb_fielddef *f = upb_fielddef_dup(upb_msg_iter_field(&i), &f);
|
1343
|
+
// Fields in oneofs are dup'd below.
|
1344
|
+
if (upb_fielddef_containingoneof(f)) continue;
|
1292
1345
|
if (!f || !upb_msgdef_addfield(newm, f, &f, NULL)) {
|
1293
1346
|
upb_msgdef_unref(newm, owner);
|
1294
1347
|
return NULL;
|
1295
1348
|
}
|
1296
1349
|
}
|
1350
|
+
upb_msg_oneof_iter o;
|
1351
|
+
for(upb_msg_oneof_begin(&o, m);
|
1352
|
+
!upb_msg_oneof_done(&o);
|
1353
|
+
upb_msg_oneof_next(&o)) {
|
1354
|
+
upb_oneofdef *f = upb_oneofdef_dup(upb_msg_iter_oneof(&o), &f);
|
1355
|
+
if (!f || !upb_msgdef_addoneof(newm, f, &f, NULL)) {
|
1356
|
+
upb_msgdef_unref(newm, owner);
|
1357
|
+
return NULL;
|
1358
|
+
}
|
1359
|
+
}
|
1297
1360
|
return newm;
|
1298
1361
|
}
|
1299
1362
|
|
@@ -1332,6 +1395,35 @@ bool upb_msgdef_setfullname(upb_msgdef *m, const char *fullname,
|
|
1332
1395
|
return upb_def_setfullname(UPB_UPCAST(m), fullname, s);
|
1333
1396
|
}
|
1334
1397
|
|
1398
|
+
// Helper: check that the field |f| is safe to add to msgdef |m|. Set an error
|
1399
|
+
// on status |s| and return false if not.
|
1400
|
+
static bool check_field_add(const upb_msgdef *m, const upb_fielddef *f,
|
1401
|
+
upb_status *s) {
|
1402
|
+
if (upb_fielddef_containingtype(f) != NULL) {
|
1403
|
+
upb_status_seterrmsg(s, "fielddef already belongs to a message");
|
1404
|
+
return false;
|
1405
|
+
} else if (upb_fielddef_name(f) == NULL || upb_fielddef_number(f) == 0) {
|
1406
|
+
upb_status_seterrmsg(s, "field name or number were not set");
|
1407
|
+
return false;
|
1408
|
+
} else if (upb_msgdef_ntofz(m, upb_fielddef_name(f)) ||
|
1409
|
+
upb_msgdef_itof(m, upb_fielddef_number(f))) {
|
1410
|
+
upb_status_seterrmsg(s, "duplicate field name or number for field");
|
1411
|
+
return false;
|
1412
|
+
}
|
1413
|
+
return true;
|
1414
|
+
}
|
1415
|
+
|
1416
|
+
static void add_field(upb_msgdef *m, upb_fielddef *f, const void *ref_donor) {
|
1417
|
+
release_containingtype(f);
|
1418
|
+
f->msg.def = m;
|
1419
|
+
f->msg_is_symbolic = false;
|
1420
|
+
upb_inttable_insert(&m->itof, upb_fielddef_number(f), upb_value_ptr(f));
|
1421
|
+
upb_strtable_insert(&m->ntof, upb_fielddef_name(f), upb_value_ptr(f));
|
1422
|
+
upb_ref2(f, m);
|
1423
|
+
upb_ref2(m, f);
|
1424
|
+
if (ref_donor) upb_fielddef_unref(f, ref_donor);
|
1425
|
+
}
|
1426
|
+
|
1335
1427
|
bool upb_msgdef_addfield(upb_msgdef *m, upb_fielddef *f, const void *ref_donor,
|
1336
1428
|
upb_status *s) {
|
1337
1429
|
// TODO: extensions need to have a separate namespace, because proto2 allows a
|
@@ -1345,28 +1437,65 @@ bool upb_msgdef_addfield(upb_msgdef *m, upb_fielddef *f, const void *ref_donor,
|
|
1345
1437
|
// We also need to validate that the field number is in an extension range iff
|
1346
1438
|
// it is an extension.
|
1347
1439
|
|
1440
|
+
// This method is idempotent. Check if |f| is already part of this msgdef and
|
1441
|
+
// return immediately if so.
|
1442
|
+
if (upb_fielddef_containingtype(f) == m) {
|
1443
|
+
return true;
|
1444
|
+
}
|
1445
|
+
|
1348
1446
|
// Check constraints for all fields before performing any action.
|
1349
|
-
if (
|
1350
|
-
upb_status_seterrmsg(s, "fielddef already belongs to a message");
|
1447
|
+
if (!check_field_add(m, f, s)) {
|
1351
1448
|
return false;
|
1352
|
-
} else if (
|
1353
|
-
|
1354
|
-
|
1355
|
-
} else if(upb_msgdef_itof(m, upb_fielddef_number(f)) ||
|
1356
|
-
upb_msgdef_ntofz(m, upb_fielddef_name(f))) {
|
1357
|
-
upb_status_seterrmsg(s, "duplicate field name or number");
|
1449
|
+
} else if (upb_fielddef_containingoneof(f) != NULL) {
|
1450
|
+
// Fields in a oneof can only be added by adding the oneof to the msgdef.
|
1451
|
+
upb_status_seterrmsg(s, "fielddef is part of a oneof");
|
1358
1452
|
return false;
|
1359
1453
|
}
|
1360
1454
|
|
1361
1455
|
// Constraint checks ok, perform the action.
|
1362
|
-
|
1363
|
-
|
1364
|
-
|
1365
|
-
|
1366
|
-
|
1367
|
-
|
1368
|
-
|
1369
|
-
if (
|
1456
|
+
add_field(m, f, ref_donor);
|
1457
|
+
return true;
|
1458
|
+
}
|
1459
|
+
|
1460
|
+
bool upb_msgdef_addoneof(upb_msgdef *m, upb_oneofdef *o, const void *ref_donor,
|
1461
|
+
upb_status *s) {
|
1462
|
+
// Check various conditions that would prevent this oneof from being added.
|
1463
|
+
if (upb_oneofdef_containingtype(o)) {
|
1464
|
+
upb_status_seterrmsg(s, "oneofdef already belongs to a message");
|
1465
|
+
return false;
|
1466
|
+
} else if (upb_oneofdef_name(o) == NULL) {
|
1467
|
+
upb_status_seterrmsg(s, "oneofdef name was not set");
|
1468
|
+
return false;
|
1469
|
+
} else if (upb_msgdef_ntooz(m, upb_oneofdef_name(o))) {
|
1470
|
+
upb_status_seterrmsg(s, "duplicate oneof name");
|
1471
|
+
return false;
|
1472
|
+
}
|
1473
|
+
|
1474
|
+
// Check that all of the oneof's fields do not conflict with names or numbers
|
1475
|
+
// of fields already in the message.
|
1476
|
+
upb_oneof_iter it;
|
1477
|
+
for (upb_oneof_begin(&it, o); !upb_oneof_done(&it); upb_oneof_next(&it)) {
|
1478
|
+
const upb_fielddef *f = upb_oneof_iter_field(&it);
|
1479
|
+
if (!check_field_add(m, f, s)) {
|
1480
|
+
return false;
|
1481
|
+
}
|
1482
|
+
}
|
1483
|
+
|
1484
|
+
// Everything checks out -- commit now.
|
1485
|
+
|
1486
|
+
// Add oneof itself first.
|
1487
|
+
o->parent = m;
|
1488
|
+
upb_strtable_insert(&m->ntoo, upb_oneofdef_name(o), upb_value_ptr(o));
|
1489
|
+
upb_ref2(o, m);
|
1490
|
+
upb_ref2(m, o);
|
1491
|
+
|
1492
|
+
// Add each field of the oneof directly to the msgdef.
|
1493
|
+
for (upb_oneof_begin(&it, o); !upb_oneof_done(&it); upb_oneof_next(&it)) {
|
1494
|
+
upb_fielddef *f = upb_oneof_iter_field(&it);
|
1495
|
+
add_field(m, f, NULL);
|
1496
|
+
}
|
1497
|
+
|
1498
|
+
if (ref_donor) upb_oneofdef_unref(o, ref_donor);
|
1370
1499
|
|
1371
1500
|
return true;
|
1372
1501
|
}
|
@@ -1384,10 +1513,21 @@ const upb_fielddef *upb_msgdef_ntof(const upb_msgdef *m, const char *name,
|
|
1384
1513
|
upb_value_getptr(val) : NULL;
|
1385
1514
|
}
|
1386
1515
|
|
1516
|
+
const upb_oneofdef *upb_msgdef_ntoo(const upb_msgdef *m, const char *name,
|
1517
|
+
size_t len) {
|
1518
|
+
upb_value val;
|
1519
|
+
return upb_strtable_lookup2(&m->ntoo, name, len, &val) ?
|
1520
|
+
upb_value_getptr(val) : NULL;
|
1521
|
+
}
|
1522
|
+
|
1387
1523
|
int upb_msgdef_numfields(const upb_msgdef *m) {
|
1388
1524
|
return upb_strtable_count(&m->ntof);
|
1389
1525
|
}
|
1390
1526
|
|
1527
|
+
int upb_msgdef_numoneofs(const upb_msgdef *m) {
|
1528
|
+
return upb_strtable_count(&m->ntoo);
|
1529
|
+
}
|
1530
|
+
|
1391
1531
|
void upb_msgdef_setmapentry(upb_msgdef *m, bool map_entry) {
|
1392
1532
|
assert(!upb_msgdef_isfrozen(m));
|
1393
1533
|
m->map_entry = map_entry;
|
@@ -1397,19 +1537,246 @@ bool upb_msgdef_mapentry(const upb_msgdef *m) {
|
|
1397
1537
|
return m->map_entry;
|
1398
1538
|
}
|
1399
1539
|
|
1400
|
-
void
|
1540
|
+
void upb_msg_field_begin(upb_msg_field_iter *iter, const upb_msgdef *m) {
|
1401
1541
|
upb_inttable_begin(iter, &m->itof);
|
1402
1542
|
}
|
1403
1543
|
|
1404
|
-
void
|
1544
|
+
void upb_msg_field_next(upb_msg_field_iter *iter) { upb_inttable_next(iter); }
|
1545
|
+
|
1546
|
+
bool upb_msg_field_done(const upb_msg_field_iter *iter) {
|
1547
|
+
return upb_inttable_done(iter);
|
1548
|
+
}
|
1549
|
+
|
1550
|
+
upb_fielddef *upb_msg_iter_field(const upb_msg_field_iter *iter) {
|
1551
|
+
return (upb_fielddef*)upb_value_getptr(upb_inttable_iter_value(iter));
|
1552
|
+
}
|
1553
|
+
|
1554
|
+
void upb_msg_field_iter_setdone(upb_msg_field_iter *iter) {
|
1555
|
+
upb_inttable_iter_setdone(iter);
|
1556
|
+
}
|
1557
|
+
|
1558
|
+
void upb_msg_oneof_begin(upb_msg_oneof_iter *iter, const upb_msgdef *m) {
|
1559
|
+
upb_strtable_begin(iter, &m->ntoo);
|
1560
|
+
}
|
1561
|
+
|
1562
|
+
void upb_msg_oneof_next(upb_msg_oneof_iter *iter) { upb_strtable_next(iter); }
|
1563
|
+
|
1564
|
+
bool upb_msg_oneof_done(const upb_msg_oneof_iter *iter) {
|
1565
|
+
return upb_strtable_done(iter);
|
1566
|
+
}
|
1567
|
+
|
1568
|
+
upb_oneofdef *upb_msg_iter_oneof(const upb_msg_oneof_iter *iter) {
|
1569
|
+
return (upb_oneofdef*)upb_value_getptr(upb_strtable_iter_value(iter));
|
1570
|
+
}
|
1571
|
+
|
1572
|
+
void upb_msg_oneof_iter_setdone(upb_msg_oneof_iter *iter) {
|
1573
|
+
upb_strtable_iter_setdone(iter);
|
1574
|
+
}
|
1575
|
+
|
1576
|
+
/* upb_oneofdef ***************************************************************/
|
1577
|
+
|
1578
|
+
static void visitoneof(const upb_refcounted *r, upb_refcounted_visit *visit,
|
1579
|
+
void *closure) {
|
1580
|
+
const upb_oneofdef *o = (const upb_oneofdef*)r;
|
1581
|
+
upb_oneof_iter i;
|
1582
|
+
for (upb_oneof_begin(&i, o); !upb_oneof_done(&i); upb_oneof_next(&i)) {
|
1583
|
+
const upb_fielddef *f = upb_oneof_iter_field(&i);
|
1584
|
+
visit(r, UPB_UPCAST2(f), closure);
|
1585
|
+
}
|
1586
|
+
if (o->parent) {
|
1587
|
+
visit(r, UPB_UPCAST2(o->parent), closure);
|
1588
|
+
}
|
1589
|
+
}
|
1590
|
+
|
1591
|
+
static void freeoneof(upb_refcounted *r) {
|
1592
|
+
upb_oneofdef *o = (upb_oneofdef*)r;
|
1593
|
+
upb_strtable_uninit(&o->ntof);
|
1594
|
+
upb_inttable_uninit(&o->itof);
|
1595
|
+
upb_def_uninit(UPB_UPCAST(o));
|
1596
|
+
free(o);
|
1597
|
+
}
|
1598
|
+
|
1599
|
+
upb_oneofdef *upb_oneofdef_new(const void *owner) {
|
1600
|
+
static const struct upb_refcounted_vtbl vtbl = {visitoneof, freeoneof};
|
1601
|
+
upb_oneofdef *o = malloc(sizeof(*o));
|
1602
|
+
o->parent = NULL;
|
1603
|
+
if (!o) return NULL;
|
1604
|
+
if (!upb_def_init(UPB_UPCAST(o), UPB_DEF_ONEOF, &vtbl, owner)) goto err2;
|
1605
|
+
if (!upb_inttable_init(&o->itof, UPB_CTYPE_PTR)) goto err2;
|
1606
|
+
if (!upb_strtable_init(&o->ntof, UPB_CTYPE_PTR)) goto err1;
|
1607
|
+
return o;
|
1608
|
+
|
1609
|
+
err1:
|
1610
|
+
upb_inttable_uninit(&o->itof);
|
1611
|
+
err2:
|
1612
|
+
free(o);
|
1613
|
+
return NULL;
|
1614
|
+
}
|
1615
|
+
|
1616
|
+
upb_oneofdef *upb_oneofdef_dup(const upb_oneofdef *o, const void *owner) {
|
1617
|
+
upb_oneofdef *newo = upb_oneofdef_new(owner);
|
1618
|
+
if (!newo) return NULL;
|
1619
|
+
bool ok = upb_def_setfullname(UPB_UPCAST(newo),
|
1620
|
+
upb_def_fullname(UPB_UPCAST(o)), NULL);
|
1621
|
+
UPB_ASSERT_VAR(ok, ok);
|
1622
|
+
upb_oneof_iter i;
|
1623
|
+
for (upb_oneof_begin(&i, o); !upb_oneof_done(&i); upb_oneof_next(&i)) {
|
1624
|
+
upb_fielddef *f = upb_fielddef_dup(upb_oneof_iter_field(&i), &f);
|
1625
|
+
if (!f || !upb_oneofdef_addfield(newo, f, &f, NULL)) {
|
1626
|
+
upb_oneofdef_unref(newo, owner);
|
1627
|
+
return NULL;
|
1628
|
+
}
|
1629
|
+
}
|
1630
|
+
return newo;
|
1631
|
+
}
|
1632
|
+
|
1633
|
+
bool upb_oneofdef_isfrozen(const upb_oneofdef *o) {
|
1634
|
+
return upb_def_isfrozen(UPB_UPCAST(o));
|
1635
|
+
}
|
1636
|
+
|
1637
|
+
void upb_oneofdef_ref(const upb_oneofdef *o, const void *owner) {
|
1638
|
+
upb_def_ref(UPB_UPCAST(o), owner);
|
1639
|
+
}
|
1640
|
+
|
1641
|
+
void upb_oneofdef_unref(const upb_oneofdef *o, const void *owner) {
|
1642
|
+
upb_def_unref(UPB_UPCAST(o), owner);
|
1643
|
+
}
|
1644
|
+
|
1645
|
+
void upb_oneofdef_donateref(const upb_oneofdef *o, const void *from,
|
1646
|
+
const void *to) {
|
1647
|
+
upb_def_donateref(UPB_UPCAST(o), from, to);
|
1648
|
+
}
|
1649
|
+
|
1650
|
+
void upb_oneofdef_checkref(const upb_oneofdef *o, const void *owner) {
|
1651
|
+
upb_def_checkref(UPB_UPCAST(o), owner);
|
1652
|
+
}
|
1653
|
+
|
1654
|
+
const char *upb_oneofdef_name(const upb_oneofdef *o) {
|
1655
|
+
return upb_def_fullname(UPB_UPCAST(o));
|
1656
|
+
}
|
1657
|
+
|
1658
|
+
bool upb_oneofdef_setname(upb_oneofdef *o, const char *fullname,
|
1659
|
+
upb_status *s) {
|
1660
|
+
if (upb_oneofdef_containingtype(o)) {
|
1661
|
+
upb_status_seterrmsg(s, "oneof already added to a message");
|
1662
|
+
return false;
|
1663
|
+
}
|
1664
|
+
return upb_def_setfullname(UPB_UPCAST(o), fullname, s);
|
1665
|
+
}
|
1666
|
+
|
1667
|
+
const upb_msgdef *upb_oneofdef_containingtype(const upb_oneofdef *o) {
|
1668
|
+
return o->parent;
|
1669
|
+
}
|
1670
|
+
|
1671
|
+
int upb_oneofdef_numfields(const upb_oneofdef *o) {
|
1672
|
+
return upb_strtable_count(&o->ntof);
|
1673
|
+
}
|
1674
|
+
|
1675
|
+
bool upb_oneofdef_addfield(upb_oneofdef *o, upb_fielddef *f,
|
1676
|
+
const void *ref_donor,
|
1677
|
+
upb_status *s) {
|
1678
|
+
assert(!upb_oneofdef_isfrozen(o));
|
1679
|
+
assert(!o->parent || !upb_msgdef_isfrozen(o->parent));
|
1680
|
+
|
1681
|
+
// This method is idempotent. Check if |f| is already part of this oneofdef
|
1682
|
+
// and return immediately if so.
|
1683
|
+
if (upb_fielddef_containingoneof(f) == o) {
|
1684
|
+
return true;
|
1685
|
+
}
|
1686
|
+
|
1687
|
+
// The field must have an OPTIONAL label.
|
1688
|
+
if (upb_fielddef_label(f) != UPB_LABEL_OPTIONAL) {
|
1689
|
+
upb_status_seterrmsg(s, "fields in oneof must have OPTIONAL label");
|
1690
|
+
return false;
|
1691
|
+
}
|
1692
|
+
|
1693
|
+
// Check that no field with this name or number exists already in the oneof.
|
1694
|
+
// Also check that the field is not already part of a oneof.
|
1695
|
+
if (upb_fielddef_name(f) == NULL || upb_fielddef_number(f) == 0) {
|
1696
|
+
upb_status_seterrmsg(s, "field name or number were not set");
|
1697
|
+
return false;
|
1698
|
+
} else if (upb_oneofdef_itof(o, upb_fielddef_number(f)) ||
|
1699
|
+
upb_oneofdef_ntofz(o, upb_fielddef_name(f))) {
|
1700
|
+
upb_status_seterrmsg(s, "duplicate field name or number");
|
1701
|
+
return false;
|
1702
|
+
} else if (upb_fielddef_containingoneof(f) != NULL) {
|
1703
|
+
upb_status_seterrmsg(s, "fielddef already belongs to a oneof");
|
1704
|
+
return false;
|
1705
|
+
}
|
1706
|
+
|
1707
|
+
// We allow adding a field to the oneof either if the field is not part of a
|
1708
|
+
// msgdef, or if it is and we are also part of the same msgdef.
|
1709
|
+
if (o->parent == NULL) {
|
1710
|
+
// If we're not in a msgdef, the field cannot be either. Otherwise we would
|
1711
|
+
// need to magically add this oneof to a msgdef to remain consistent, which
|
1712
|
+
// is surprising behavior.
|
1713
|
+
if (upb_fielddef_containingtype(f) != NULL) {
|
1714
|
+
upb_status_seterrmsg(s, "fielddef already belongs to a message, but "
|
1715
|
+
"oneof does not");
|
1716
|
+
return false;
|
1717
|
+
}
|
1718
|
+
} else {
|
1719
|
+
// If we're in a msgdef, the user can add fields that either aren't in any
|
1720
|
+
// msgdef (in which case they're added to our msgdef) or already a part of
|
1721
|
+
// our msgdef.
|
1722
|
+
if (upb_fielddef_containingtype(f) != NULL &&
|
1723
|
+
upb_fielddef_containingtype(f) != o->parent) {
|
1724
|
+
upb_status_seterrmsg(s, "fielddef belongs to a different message "
|
1725
|
+
"than oneof");
|
1726
|
+
return false;
|
1727
|
+
}
|
1728
|
+
}
|
1729
|
+
|
1730
|
+
// Commit phase. First add the field to our parent msgdef, if any, because
|
1731
|
+
// that may fail; then add the field to our own tables.
|
1732
|
+
|
1733
|
+
if (o->parent != NULL && upb_fielddef_containingtype(f) == NULL) {
|
1734
|
+
if (!upb_msgdef_addfield((upb_msgdef*)o->parent, f, NULL, s)) {
|
1735
|
+
return false;
|
1736
|
+
}
|
1737
|
+
}
|
1738
|
+
|
1739
|
+
release_containingtype(f);
|
1740
|
+
f->oneof = o;
|
1741
|
+
upb_inttable_insert(&o->itof, upb_fielddef_number(f), upb_value_ptr(f));
|
1742
|
+
upb_strtable_insert(&o->ntof, upb_fielddef_name(f), upb_value_ptr(f));
|
1743
|
+
upb_ref2(f, o);
|
1744
|
+
upb_ref2(o, f);
|
1745
|
+
if (ref_donor) upb_fielddef_unref(f, ref_donor);
|
1746
|
+
|
1747
|
+
return true;
|
1748
|
+
}
|
1749
|
+
|
1750
|
+
const upb_fielddef *upb_oneofdef_ntof(const upb_oneofdef *o,
|
1751
|
+
const char *name, size_t length) {
|
1752
|
+
upb_value val;
|
1753
|
+
return upb_strtable_lookup2(&o->ntof, name, length, &val) ?
|
1754
|
+
upb_value_getptr(val) : NULL;
|
1755
|
+
}
|
1756
|
+
|
1757
|
+
const upb_fielddef *upb_oneofdef_itof(const upb_oneofdef *o, uint32_t num) {
|
1758
|
+
upb_value val;
|
1759
|
+
return upb_inttable_lookup32(&o->itof, num, &val) ?
|
1760
|
+
upb_value_getptr(val) : NULL;
|
1761
|
+
}
|
1762
|
+
|
1763
|
+
void upb_oneof_begin(upb_oneof_iter *iter, const upb_oneofdef *o) {
|
1764
|
+
upb_inttable_begin(iter, &o->itof);
|
1765
|
+
}
|
1766
|
+
|
1767
|
+
void upb_oneof_next(upb_oneof_iter *iter) {
|
1768
|
+
upb_inttable_next(iter);
|
1769
|
+
}
|
1405
1770
|
|
1406
|
-
bool
|
1771
|
+
bool upb_oneof_done(upb_oneof_iter *iter) {
|
1772
|
+
return upb_inttable_done(iter);
|
1773
|
+
}
|
1407
1774
|
|
1408
|
-
upb_fielddef *
|
1775
|
+
upb_fielddef *upb_oneof_iter_field(const upb_oneof_iter *iter) {
|
1409
1776
|
return (upb_fielddef*)upb_value_getptr(upb_inttable_iter_value(iter));
|
1410
1777
|
}
|
1411
1778
|
|
1412
|
-
void
|
1779
|
+
void upb_oneof_iter_setdone(upb_oneof_iter *iter) {
|
1413
1780
|
upb_inttable_iter_setdone(iter);
|
1414
1781
|
}
|
1415
1782
|
/*
|
@@ -1452,8 +1819,10 @@ static void freehandlers(upb_refcounted *r) {
|
|
1452
1819
|
static void visithandlers(const upb_refcounted *r, upb_refcounted_visit *visit,
|
1453
1820
|
void *closure) {
|
1454
1821
|
const upb_handlers *h = (const upb_handlers*)r;
|
1455
|
-
|
1456
|
-
for(
|
1822
|
+
upb_msg_field_iter i;
|
1823
|
+
for(upb_msg_field_begin(&i, h->msg);
|
1824
|
+
!upb_msg_field_done(&i);
|
1825
|
+
upb_msg_field_next(&i)) {
|
1457
1826
|
upb_fielddef *f = upb_msg_iter_field(&i);
|
1458
1827
|
if (!upb_fielddef_issubmsg(f)) continue;
|
1459
1828
|
const upb_handlers *sub = upb_handlers_getsubhandlers(h, f);
|
@@ -1482,8 +1851,10 @@ static upb_handlers *newformsg(const upb_msgdef *m, const void *owner,
|
|
1482
1851
|
|
1483
1852
|
// For each submessage field, get or create a handlers object and set it as
|
1484
1853
|
// the subhandlers.
|
1485
|
-
|
1486
|
-
for(
|
1854
|
+
upb_msg_field_iter i;
|
1855
|
+
for(upb_msg_field_begin(&i, m);
|
1856
|
+
!upb_msg_field_done(&i);
|
1857
|
+
upb_msg_field_next(&i)) {
|
1487
1858
|
upb_fielddef *f = upb_msg_iter_field(&i);
|
1488
1859
|
if (!upb_fielddef_issubmsg(f)) continue;
|
1489
1860
|
|
@@ -1840,8 +2211,10 @@ bool upb_handlers_freeze(upb_handlers *const*handlers, int n, upb_status *s) {
|
|
1840
2211
|
|
1841
2212
|
// Check that there are no closure mismatches due to missing Start* handlers
|
1842
2213
|
// or subhandlers with different type-level types.
|
1843
|
-
|
1844
|
-
for(
|
2214
|
+
upb_msg_field_iter j;
|
2215
|
+
for(upb_msg_field_begin(&j, h->msg);
|
2216
|
+
!upb_msg_field_done(&j);
|
2217
|
+
upb_msg_field_next(&j)) {
|
1845
2218
|
|
1846
2219
|
const upb_fielddef *f = upb_msg_iter_field(&j);
|
1847
2220
|
if (upb_fielddef_isseq(f)) {
|
@@ -3114,8 +3487,10 @@ static bool upb_resolve_dfs(const upb_def *def, upb_strtable *addtab,
|
|
3114
3487
|
// For messages, continue the recursion by visiting all subdefs.
|
3115
3488
|
const upb_msgdef *m = upb_dyncast_msgdef(def);
|
3116
3489
|
if (m) {
|
3117
|
-
|
3118
|
-
for(
|
3490
|
+
upb_msg_field_iter i;
|
3491
|
+
for(upb_msg_field_begin(&i, m);
|
3492
|
+
!upb_msg_field_done(&i);
|
3493
|
+
upb_msg_field_next(&i)) {
|
3119
3494
|
upb_fielddef *f = upb_msg_iter_field(&i);
|
3120
3495
|
if (!upb_fielddef_hassubdef(f)) continue;
|
3121
3496
|
// |= to avoid short-circuit; we need its side-effects.
|
@@ -3268,8 +3643,10 @@ bool upb_symtab_add(upb_symtab *s, upb_def *const*defs, int n, void *ref_donor,
|
|
3268
3643
|
// Type names are resolved relative to the message in which they appear.
|
3269
3644
|
const char *base = upb_msgdef_fullname(m);
|
3270
3645
|
|
3271
|
-
|
3272
|
-
for(
|
3646
|
+
upb_msg_field_iter j;
|
3647
|
+
for(upb_msg_field_begin(&j, m);
|
3648
|
+
!upb_msg_field_done(&j);
|
3649
|
+
upb_msg_field_next(&j)) {
|
3273
3650
|
upb_fielddef *f = upb_msg_iter_field(&j);
|
3274
3651
|
const char *name = upb_fielddef_subdefname(f);
|
3275
3652
|
if (name && !upb_fielddef_subdef(f)) {
|
@@ -6462,8 +6839,10 @@ static void compile_method(compiler *c, upb_pbdecodermethod *method) {
|
|
6462
6839
|
putsel(c, OP_STARTMSG, UPB_STARTMSG_SELECTOR, h);
|
6463
6840
|
label(c, LABEL_FIELD);
|
6464
6841
|
uint32_t* start_pc = c->pc;
|
6465
|
-
|
6466
|
-
for(
|
6842
|
+
upb_msg_field_iter i;
|
6843
|
+
for(upb_msg_field_begin(&i, md);
|
6844
|
+
!upb_msg_field_done(&i);
|
6845
|
+
upb_msg_field_next(&i)) {
|
6467
6846
|
const upb_fielddef *f = upb_msg_iter_field(&i);
|
6468
6847
|
upb_fieldtype_t type = upb_fielddef_type(f);
|
6469
6848
|
|
@@ -6513,9 +6892,11 @@ static void find_methods(compiler *c, const upb_handlers *h) {
|
|
6513
6892
|
newmethod(h, c->group);
|
6514
6893
|
|
6515
6894
|
// Find submethods.
|
6516
|
-
|
6895
|
+
upb_msg_field_iter i;
|
6517
6896
|
const upb_msgdef *md = upb_handlers_msgdef(h);
|
6518
|
-
for(
|
6897
|
+
for(upb_msg_field_begin(&i, md);
|
6898
|
+
!upb_msg_field_done(&i);
|
6899
|
+
upb_msg_field_next(&i)) {
|
6519
6900
|
const upb_fielddef *f = upb_msg_iter_field(&i);
|
6520
6901
|
const upb_handlers *sub_h;
|
6521
6902
|
if (upb_fielddef_type(f) == UPB_TYPE_MESSAGE &&
|
@@ -6557,7 +6938,7 @@ static void set_bytecode_handlers(mgroup *g) {
|
|
6557
6938
|
}
|
6558
6939
|
|
6559
6940
|
|
6560
|
-
/* JIT setup.
|
6941
|
+
/* JIT setup. *****************************************************************/
|
6561
6942
|
|
6562
6943
|
#ifdef UPB_USE_JIT_X64
|
6563
6944
|
|
@@ -7980,8 +8361,10 @@ static void newhandlers_callback(const void *closure, upb_handlers *h) {
|
|
7980
8361
|
upb_handlers_setendmsg(h, endmsg, NULL);
|
7981
8362
|
|
7982
8363
|
const upb_msgdef *m = upb_handlers_msgdef(h);
|
7983
|
-
|
7984
|
-
for(
|
8364
|
+
upb_msg_field_iter i;
|
8365
|
+
for(upb_msg_field_begin(&i, m);
|
8366
|
+
!upb_msg_field_done(&i);
|
8367
|
+
upb_msg_field_next(&i)) {
|
7985
8368
|
const upb_fielddef *f = upb_msg_iter_field(&i);
|
7986
8369
|
bool packed = upb_fielddef_isseq(f) && upb_fielddef_isprimitive(f) &&
|
7987
8370
|
upb_fielddef_packed(f);
|
@@ -8443,8 +8826,10 @@ static void onmreg(const void *c, upb_handlers *h) {
|
|
8443
8826
|
upb_handlers_setstartmsg(h, textprinter_startmsg, NULL);
|
8444
8827
|
upb_handlers_setendmsg(h, textprinter_endmsg, NULL);
|
8445
8828
|
|
8446
|
-
|
8447
|
-
for(
|
8829
|
+
upb_msg_field_iter i;
|
8830
|
+
for(upb_msg_field_begin(&i, m);
|
8831
|
+
!upb_msg_field_done(&i);
|
8832
|
+
upb_msg_field_next(&i)) {
|
8448
8833
|
upb_fielddef *f = upb_msg_iter_field(&i);
|
8449
8834
|
upb_handlerattr attr = UPB_HANDLERATTR_INITIALIZER;
|
8450
8835
|
upb_handlerattr_sethandlerdata(&attr, f);
|
@@ -8857,6 +9242,7 @@ badpadding:
|
|
8857
9242
|
// the true value in a contiguous buffer.
|
8858
9243
|
|
8859
9244
|
static void assert_accumulate_empty(upb_json_parser *p) {
|
9245
|
+
UPB_UNUSED(p);
|
8860
9246
|
assert(p->accumulated == NULL);
|
8861
9247
|
assert(p->accumulated_len == 0);
|
8862
9248
|
}
|
@@ -9141,11 +9527,17 @@ static void start_number(upb_json_parser *p, const char *ptr) {
|
|
9141
9527
|
capture_begin(p, ptr);
|
9142
9528
|
}
|
9143
9529
|
|
9530
|
+
static bool parse_number(upb_json_parser *p);
|
9531
|
+
|
9144
9532
|
static bool end_number(upb_json_parser *p, const char *ptr) {
|
9145
9533
|
if (!capture_end(p, ptr)) {
|
9146
9534
|
return false;
|
9147
9535
|
}
|
9148
9536
|
|
9537
|
+
return parse_number(p);
|
9538
|
+
}
|
9539
|
+
|
9540
|
+
static bool parse_number(upb_json_parser *p) {
|
9149
9541
|
// strtol() and friends unfortunately do not support specifying the length of
|
9150
9542
|
// the input string, so we need to force a copy into a NULL-terminated buffer.
|
9151
9543
|
if (!multipart_text(p, "\0", 1, false)) {
|
@@ -9155,8 +9547,8 @@ static bool end_number(upb_json_parser *p, const char *ptr) {
|
|
9155
9547
|
size_t len;
|
9156
9548
|
const char *buf = accumulate_getptr(p, &len);
|
9157
9549
|
const char *myend = buf + len - 1; // One for NULL.
|
9158
|
-
char *end;
|
9159
9550
|
|
9551
|
+
char *end;
|
9160
9552
|
switch (upb_fielddef_type(p->top->f)) {
|
9161
9553
|
case UPB_TYPE_ENUM:
|
9162
9554
|
case UPB_TYPE_INT32: {
|
@@ -9212,6 +9604,7 @@ static bool end_number(upb_json_parser *p, const char *ptr) {
|
|
9212
9604
|
}
|
9213
9605
|
|
9214
9606
|
multipart_end(p);
|
9607
|
+
|
9215
9608
|
return true;
|
9216
9609
|
|
9217
9610
|
err:
|
@@ -9230,6 +9623,7 @@ static bool parser_putbool(upb_json_parser *p, bool val) {
|
|
9230
9623
|
|
9231
9624
|
bool ok = upb_sink_putbool(&p->top->sink, parser_getsel(p), val);
|
9232
9625
|
UPB_ASSERT_VAR(ok, ok);
|
9626
|
+
|
9233
9627
|
return true;
|
9234
9628
|
}
|
9235
9629
|
|
@@ -9246,6 +9640,8 @@ static bool start_stringval(upb_json_parser *p) {
|
|
9246
9640
|
upb_sink_startstr(&p->top->sink, sel, 0, &inner->sink);
|
9247
9641
|
inner->m = p->top->m;
|
9248
9642
|
inner->f = p->top->f;
|
9643
|
+
inner->is_map = false;
|
9644
|
+
inner->is_mapentry = false;
|
9249
9645
|
p->top = inner;
|
9250
9646
|
|
9251
9647
|
if (upb_fielddef_type(p->top->f) == UPB_TYPE_STRING) {
|
@@ -9323,6 +9719,7 @@ static bool end_stringval(upb_json_parser *p) {
|
|
9323
9719
|
}
|
9324
9720
|
|
9325
9721
|
multipart_end(p);
|
9722
|
+
|
9326
9723
|
return ok;
|
9327
9724
|
}
|
9328
9725
|
|
@@ -9331,54 +9728,217 @@ static void start_member(upb_json_parser *p) {
|
|
9331
9728
|
multipart_startaccum(p);
|
9332
9729
|
}
|
9333
9730
|
|
9334
|
-
|
9335
|
-
|
9731
|
+
// Helper: invoked during parse_mapentry() to emit the mapentry message's key
|
9732
|
+
// field based on the current contents of the accumulate buffer.
|
9733
|
+
static bool parse_mapentry_key(upb_json_parser *p) {
|
9734
|
+
|
9336
9735
|
size_t len;
|
9337
9736
|
const char *buf = accumulate_getptr(p, &len);
|
9338
9737
|
|
9339
|
-
|
9738
|
+
// Emit the key field. We do a bit of ad-hoc parsing here because the
|
9739
|
+
// parser state machine has already decided that this is a string field
|
9740
|
+
// name, and we are reinterpreting it as some arbitrary key type. In
|
9741
|
+
// particular, integer and bool keys are quoted, so we need to parse the
|
9742
|
+
// quoted string contents here.
|
9340
9743
|
|
9341
|
-
|
9342
|
-
|
9343
|
-
|
9744
|
+
p->top->f = upb_msgdef_itof(p->top->m, UPB_MAPENTRY_KEY);
|
9745
|
+
if (p->top->f == NULL) {
|
9746
|
+
upb_status_seterrmsg(p->status, "mapentry message has no key");
|
9344
9747
|
return false;
|
9345
9748
|
}
|
9749
|
+
switch (upb_fielddef_type(p->top->f)) {
|
9750
|
+
case UPB_TYPE_INT32:
|
9751
|
+
case UPB_TYPE_INT64:
|
9752
|
+
case UPB_TYPE_UINT32:
|
9753
|
+
case UPB_TYPE_UINT64:
|
9754
|
+
// Invoke end_number. The accum buffer has the number's text already.
|
9755
|
+
if (!parse_number(p)) {
|
9756
|
+
return false;
|
9757
|
+
}
|
9758
|
+
break;
|
9759
|
+
case UPB_TYPE_BOOL:
|
9760
|
+
if (len == 4 && !strncmp(buf, "true", 4)) {
|
9761
|
+
if (!parser_putbool(p, true)) {
|
9762
|
+
return false;
|
9763
|
+
}
|
9764
|
+
} else if (len == 5 && !strncmp(buf, "false", 5)) {
|
9765
|
+
if (!parser_putbool(p, false)) {
|
9766
|
+
return false;
|
9767
|
+
}
|
9768
|
+
} else {
|
9769
|
+
upb_status_seterrmsg(p->status,
|
9770
|
+
"Map bool key not 'true' or 'false'");
|
9771
|
+
return false;
|
9772
|
+
}
|
9773
|
+
multipart_end(p);
|
9774
|
+
break;
|
9775
|
+
case UPB_TYPE_STRING:
|
9776
|
+
case UPB_TYPE_BYTES: {
|
9777
|
+
upb_sink subsink;
|
9778
|
+
upb_selector_t sel = getsel_for_handlertype(p, UPB_HANDLER_STARTSTR);
|
9779
|
+
upb_sink_startstr(&p->top->sink, sel, len, &subsink);
|
9780
|
+
sel = getsel_for_handlertype(p, UPB_HANDLER_STRING);
|
9781
|
+
upb_sink_putstring(&subsink, sel, buf, len, NULL);
|
9782
|
+
sel = getsel_for_handlertype(p, UPB_HANDLER_ENDSTR);
|
9783
|
+
upb_sink_endstr(&subsink, sel);
|
9784
|
+
multipart_end(p);
|
9785
|
+
break;
|
9786
|
+
}
|
9787
|
+
default:
|
9788
|
+
upb_status_seterrmsg(p->status, "Invalid field type for map key");
|
9789
|
+
return false;
|
9790
|
+
}
|
9346
9791
|
|
9347
|
-
|
9348
|
-
|
9792
|
+
return true;
|
9793
|
+
}
|
9794
|
+
|
9795
|
+
// Helper: emit one map entry (as a submessage in the map field sequence). This
|
9796
|
+
// is invoked from end_membername(), at the end of the map entry's key string,
|
9797
|
+
// with the map key in the accumulate buffer. It parses the key from that
|
9798
|
+
// buffer, emits the handler calls to start the mapentry submessage (setting up
|
9799
|
+
// its subframe in the process), and sets up state in the subframe so that the
|
9800
|
+
// value parser (invoked next) will emit the mapentry's value field and then
|
9801
|
+
// end the mapentry message.
|
9802
|
+
|
9803
|
+
static bool handle_mapentry(upb_json_parser *p) {
|
9804
|
+
// Map entry: p->top->sink is the seq frame, so we need to start a frame
|
9805
|
+
// for the mapentry itself, and then set |f| in that frame so that the map
|
9806
|
+
// value field is parsed, and also set a flag to end the frame after the
|
9807
|
+
// map-entry value is parsed.
|
9808
|
+
if (!check_stack(p)) return false;
|
9809
|
+
|
9810
|
+
const upb_fielddef *mapfield = p->top->mapfield;
|
9811
|
+
const upb_msgdef *mapentrymsg = upb_fielddef_msgsubdef(mapfield);
|
9812
|
+
|
9813
|
+
upb_jsonparser_frame *inner = p->top + 1;
|
9814
|
+
p->top->f = mapfield;
|
9815
|
+
upb_selector_t sel = getsel_for_handlertype(p, UPB_HANDLER_STARTSUBMSG);
|
9816
|
+
upb_sink_startsubmsg(&p->top->sink, sel, &inner->sink);
|
9817
|
+
inner->m = mapentrymsg;
|
9818
|
+
inner->mapfield = mapfield;
|
9819
|
+
inner->is_map = false;
|
9820
|
+
|
9821
|
+
// Don't set this to true *yet* -- we reuse parsing handlers below to push
|
9822
|
+
// the key field value to the sink, and these handlers will pop the frame
|
9823
|
+
// if they see is_mapentry (when invoked by the parser state machine, they
|
9824
|
+
// would have just seen the map-entry value, not key).
|
9825
|
+
inner->is_mapentry = false;
|
9826
|
+
p->top = inner;
|
9827
|
+
|
9828
|
+
// send STARTMSG in submsg frame.
|
9829
|
+
upb_sink_startmsg(&p->top->sink);
|
9830
|
+
|
9831
|
+
parse_mapentry_key(p);
|
9832
|
+
|
9833
|
+
// Set up the value field to receive the map-entry value.
|
9834
|
+
p->top->f = upb_msgdef_itof(p->top->m, UPB_MAPENTRY_VALUE);
|
9835
|
+
p->top->is_mapentry = true; // set up to pop frame after value is parsed.
|
9836
|
+
p->top->mapfield = mapfield;
|
9837
|
+
if (p->top->f == NULL) {
|
9838
|
+
upb_status_seterrmsg(p->status, "mapentry message has no value");
|
9839
|
+
return false;
|
9840
|
+
}
|
9349
9841
|
|
9350
9842
|
return true;
|
9351
9843
|
}
|
9352
9844
|
|
9353
|
-
static
|
9845
|
+
static bool end_membername(upb_json_parser *p) {
|
9846
|
+
assert(!p->top->f);
|
9847
|
+
|
9848
|
+
if (p->top->is_map) {
|
9849
|
+
return handle_mapentry(p);
|
9850
|
+
} else {
|
9851
|
+
size_t len;
|
9852
|
+
const char *buf = accumulate_getptr(p, &len);
|
9853
|
+
const upb_fielddef *f = upb_msgdef_ntof(p->top->m, buf, len);
|
9854
|
+
|
9855
|
+
if (!f) {
|
9856
|
+
// TODO(haberman): Ignore unknown fields if requested/configured to do so.
|
9857
|
+
upb_status_seterrf(p->status, "No such field: %.*s\n", (int)len, buf);
|
9858
|
+
return false;
|
9859
|
+
}
|
9860
|
+
|
9861
|
+
p->top->f = f;
|
9862
|
+
multipart_end(p);
|
9863
|
+
|
9864
|
+
return true;
|
9865
|
+
}
|
9866
|
+
}
|
9867
|
+
|
9868
|
+
static void end_member(upb_json_parser *p) {
|
9869
|
+
// If we just parsed a map-entry value, end that frame too.
|
9870
|
+
if (p->top->is_mapentry) {
|
9871
|
+
assert(p->top > p->stack);
|
9872
|
+
// send ENDMSG on submsg.
|
9873
|
+
upb_status s = UPB_STATUS_INIT;
|
9874
|
+
upb_sink_endmsg(&p->top->sink, &s);
|
9875
|
+
const upb_fielddef* mapfield = p->top->mapfield;
|
9876
|
+
|
9877
|
+
// send ENDSUBMSG in repeated-field-of-mapentries frame.
|
9878
|
+
p->top--;
|
9879
|
+
upb_selector_t sel;
|
9880
|
+
bool ok = upb_handlers_getselector(mapfield,
|
9881
|
+
UPB_HANDLER_ENDSUBMSG, &sel);
|
9882
|
+
UPB_ASSERT_VAR(ok, ok);
|
9883
|
+
upb_sink_endsubmsg(&p->top->sink, sel);
|
9884
|
+
}
|
9885
|
+
|
9886
|
+
p->top->f = NULL;
|
9887
|
+
}
|
9354
9888
|
|
9355
9889
|
static bool start_subobject(upb_json_parser *p) {
|
9356
9890
|
assert(p->top->f);
|
9357
9891
|
|
9358
|
-
if (
|
9892
|
+
if (upb_fielddef_ismap(p->top->f)) {
|
9893
|
+
// Beginning of a map. Start a new parser frame in a repeated-field
|
9894
|
+
// context.
|
9895
|
+
if (!check_stack(p)) return false;
|
9896
|
+
|
9897
|
+
upb_jsonparser_frame *inner = p->top + 1;
|
9898
|
+
upb_selector_t sel = getsel_for_handlertype(p, UPB_HANDLER_STARTSEQ);
|
9899
|
+
upb_sink_startseq(&p->top->sink, sel, &inner->sink);
|
9900
|
+
inner->m = upb_fielddef_msgsubdef(p->top->f);
|
9901
|
+
inner->mapfield = p->top->f;
|
9902
|
+
inner->f = NULL;
|
9903
|
+
inner->is_map = true;
|
9904
|
+
inner->is_mapentry = false;
|
9905
|
+
p->top = inner;
|
9906
|
+
|
9907
|
+
return true;
|
9908
|
+
} else if (upb_fielddef_issubmsg(p->top->f)) {
|
9909
|
+
// Beginning of a subobject. Start a new parser frame in the submsg
|
9910
|
+
// context.
|
9911
|
+
if (!check_stack(p)) return false;
|
9912
|
+
|
9913
|
+
upb_jsonparser_frame *inner = p->top + 1;
|
9914
|
+
|
9915
|
+
upb_selector_t sel = getsel_for_handlertype(p, UPB_HANDLER_STARTSUBMSG);
|
9916
|
+
upb_sink_startsubmsg(&p->top->sink, sel, &inner->sink);
|
9917
|
+
inner->m = upb_fielddef_msgsubdef(p->top->f);
|
9918
|
+
inner->f = NULL;
|
9919
|
+
inner->is_map = false;
|
9920
|
+
inner->is_mapentry = false;
|
9921
|
+
p->top = inner;
|
9922
|
+
|
9923
|
+
return true;
|
9924
|
+
} else {
|
9359
9925
|
upb_status_seterrf(p->status,
|
9360
9926
|
"Object specified for non-message/group field: %s",
|
9361
9927
|
upb_fielddef_name(p->top->f));
|
9362
9928
|
return false;
|
9363
9929
|
}
|
9364
|
-
|
9365
|
-
if (!check_stack(p)) return false;
|
9366
|
-
|
9367
|
-
upb_jsonparser_frame *inner = p->top + 1;
|
9368
|
-
|
9369
|
-
upb_selector_t sel = getsel_for_handlertype(p, UPB_HANDLER_STARTSUBMSG);
|
9370
|
-
upb_sink_startsubmsg(&p->top->sink, sel, &inner->sink);
|
9371
|
-
inner->m = upb_fielddef_msgsubdef(p->top->f);
|
9372
|
-
inner->f = NULL;
|
9373
|
-
p->top = inner;
|
9374
|
-
|
9375
|
-
return true;
|
9376
9930
|
}
|
9377
9931
|
|
9378
9932
|
static void end_subobject(upb_json_parser *p) {
|
9379
|
-
p->top
|
9380
|
-
|
9381
|
-
|
9933
|
+
if (p->top->is_map) {
|
9934
|
+
p->top--;
|
9935
|
+
upb_selector_t sel = getsel_for_handlertype(p, UPB_HANDLER_ENDSEQ);
|
9936
|
+
upb_sink_endseq(&p->top->sink, sel);
|
9937
|
+
} else {
|
9938
|
+
p->top--;
|
9939
|
+
upb_selector_t sel = getsel_for_handlertype(p, UPB_HANDLER_ENDSUBMSG);
|
9940
|
+
upb_sink_endsubmsg(&p->top->sink, sel);
|
9941
|
+
}
|
9382
9942
|
}
|
9383
9943
|
|
9384
9944
|
static bool start_array(upb_json_parser *p) {
|
@@ -9398,6 +9958,8 @@ static bool start_array(upb_json_parser *p) {
|
|
9398
9958
|
upb_sink_startseq(&p->top->sink, sel, &inner->sink);
|
9399
9959
|
inner->m = p->top->m;
|
9400
9960
|
inner->f = p->top->f;
|
9961
|
+
inner->is_map = false;
|
9962
|
+
inner->is_mapentry = false;
|
9401
9963
|
p->top = inner;
|
9402
9964
|
|
9403
9965
|
return true;
|
@@ -9412,12 +9974,16 @@ static void end_array(upb_json_parser *p) {
|
|
9412
9974
|
}
|
9413
9975
|
|
9414
9976
|
static void start_object(upb_json_parser *p) {
|
9415
|
-
|
9977
|
+
if (!p->top->is_map) {
|
9978
|
+
upb_sink_startmsg(&p->top->sink);
|
9979
|
+
}
|
9416
9980
|
}
|
9417
9981
|
|
9418
9982
|
static void end_object(upb_json_parser *p) {
|
9419
|
-
|
9420
|
-
|
9983
|
+
if (!p->top->is_map) {
|
9984
|
+
upb_status status;
|
9985
|
+
upb_sink_endmsg(&p->top->sink, &status);
|
9986
|
+
}
|
9421
9987
|
}
|
9422
9988
|
|
9423
9989
|
|
@@ -9442,11 +10008,11 @@ static void end_object(upb_json_parser *p) {
|
|
9442
10008
|
// final state once, when the closing '"' is seen.
|
9443
10009
|
|
9444
10010
|
|
9445
|
-
#line
|
10011
|
+
#line 1085 "upb/json/parser.rl"
|
9446
10012
|
|
9447
10013
|
|
9448
10014
|
|
9449
|
-
#line
|
10015
|
+
#line 997 "upb/json/parser.c"
|
9450
10016
|
static const char _json_actions[] = {
|
9451
10017
|
0, 1, 0, 1, 2, 1, 3, 1,
|
9452
10018
|
5, 1, 6, 1, 7, 1, 8, 1,
|
@@ -9597,7 +10163,7 @@ static const int json_en_value_machine = 27;
|
|
9597
10163
|
static const int json_en_main = 1;
|
9598
10164
|
|
9599
10165
|
|
9600
|
-
#line
|
10166
|
+
#line 1088 "upb/json/parser.rl"
|
9601
10167
|
|
9602
10168
|
size_t parse(void *closure, const void *hd, const char *buf, size_t size,
|
9603
10169
|
const upb_bufhandle *handle) {
|
@@ -9617,7 +10183,7 @@ size_t parse(void *closure, const void *hd, const char *buf, size_t size,
|
|
9617
10183
|
capture_resume(parser, buf);
|
9618
10184
|
|
9619
10185
|
|
9620
|
-
#line
|
10186
|
+
#line 1168 "upb/json/parser.c"
|
9621
10187
|
{
|
9622
10188
|
int _klen;
|
9623
10189
|
unsigned int _trans;
|
@@ -9692,118 +10258,118 @@ _match:
|
|
9692
10258
|
switch ( *_acts++ )
|
9693
10259
|
{
|
9694
10260
|
case 0:
|
9695
|
-
#line
|
10261
|
+
#line 1000 "upb/json/parser.rl"
|
9696
10262
|
{ p--; {cs = stack[--top]; goto _again;} }
|
9697
10263
|
break;
|
9698
10264
|
case 1:
|
9699
|
-
#line
|
10265
|
+
#line 1001 "upb/json/parser.rl"
|
9700
10266
|
{ p--; {stack[top++] = cs; cs = 10; goto _again;} }
|
9701
10267
|
break;
|
9702
10268
|
case 2:
|
9703
|
-
#line
|
10269
|
+
#line 1005 "upb/json/parser.rl"
|
9704
10270
|
{ start_text(parser, p); }
|
9705
10271
|
break;
|
9706
10272
|
case 3:
|
9707
|
-
#line
|
10273
|
+
#line 1006 "upb/json/parser.rl"
|
9708
10274
|
{ CHECK_RETURN_TOP(end_text(parser, p)); }
|
9709
10275
|
break;
|
9710
10276
|
case 4:
|
9711
|
-
#line
|
10277
|
+
#line 1012 "upb/json/parser.rl"
|
9712
10278
|
{ start_hex(parser); }
|
9713
10279
|
break;
|
9714
10280
|
case 5:
|
9715
|
-
#line
|
10281
|
+
#line 1013 "upb/json/parser.rl"
|
9716
10282
|
{ hexdigit(parser, p); }
|
9717
10283
|
break;
|
9718
10284
|
case 6:
|
9719
|
-
#line
|
10285
|
+
#line 1014 "upb/json/parser.rl"
|
9720
10286
|
{ CHECK_RETURN_TOP(end_hex(parser)); }
|
9721
10287
|
break;
|
9722
10288
|
case 7:
|
9723
|
-
#line
|
10289
|
+
#line 1020 "upb/json/parser.rl"
|
9724
10290
|
{ CHECK_RETURN_TOP(escape(parser, p)); }
|
9725
10291
|
break;
|
9726
10292
|
case 8:
|
9727
|
-
#line
|
10293
|
+
#line 1026 "upb/json/parser.rl"
|
9728
10294
|
{ p--; {cs = stack[--top]; goto _again;} }
|
9729
10295
|
break;
|
9730
10296
|
case 9:
|
9731
|
-
#line
|
10297
|
+
#line 1029 "upb/json/parser.rl"
|
9732
10298
|
{ {stack[top++] = cs; cs = 19; goto _again;} }
|
9733
10299
|
break;
|
9734
10300
|
case 10:
|
9735
|
-
#line
|
10301
|
+
#line 1031 "upb/json/parser.rl"
|
9736
10302
|
{ p--; {stack[top++] = cs; cs = 27; goto _again;} }
|
9737
10303
|
break;
|
9738
10304
|
case 11:
|
9739
|
-
#line
|
10305
|
+
#line 1036 "upb/json/parser.rl"
|
9740
10306
|
{ start_member(parser); }
|
9741
10307
|
break;
|
9742
10308
|
case 12:
|
9743
|
-
#line
|
9744
|
-
{ CHECK_RETURN_TOP(
|
10309
|
+
#line 1037 "upb/json/parser.rl"
|
10310
|
+
{ CHECK_RETURN_TOP(end_membername(parser)); }
|
9745
10311
|
break;
|
9746
10312
|
case 13:
|
9747
|
-
#line
|
9748
|
-
{
|
10313
|
+
#line 1040 "upb/json/parser.rl"
|
10314
|
+
{ end_member(parser); }
|
9749
10315
|
break;
|
9750
10316
|
case 14:
|
9751
|
-
#line
|
10317
|
+
#line 1046 "upb/json/parser.rl"
|
9752
10318
|
{ start_object(parser); }
|
9753
10319
|
break;
|
9754
10320
|
case 15:
|
9755
|
-
#line
|
10321
|
+
#line 1049 "upb/json/parser.rl"
|
9756
10322
|
{ end_object(parser); }
|
9757
10323
|
break;
|
9758
10324
|
case 16:
|
9759
|
-
#line
|
10325
|
+
#line 1055 "upb/json/parser.rl"
|
9760
10326
|
{ CHECK_RETURN_TOP(start_array(parser)); }
|
9761
10327
|
break;
|
9762
10328
|
case 17:
|
9763
|
-
#line
|
10329
|
+
#line 1059 "upb/json/parser.rl"
|
9764
10330
|
{ end_array(parser); }
|
9765
10331
|
break;
|
9766
10332
|
case 18:
|
9767
|
-
#line
|
10333
|
+
#line 1064 "upb/json/parser.rl"
|
9768
10334
|
{ start_number(parser, p); }
|
9769
10335
|
break;
|
9770
10336
|
case 19:
|
9771
|
-
#line
|
10337
|
+
#line 1065 "upb/json/parser.rl"
|
9772
10338
|
{ CHECK_RETURN_TOP(end_number(parser, p)); }
|
9773
10339
|
break;
|
9774
10340
|
case 20:
|
9775
|
-
#line
|
10341
|
+
#line 1067 "upb/json/parser.rl"
|
9776
10342
|
{ CHECK_RETURN_TOP(start_stringval(parser)); }
|
9777
10343
|
break;
|
9778
10344
|
case 21:
|
9779
|
-
#line
|
10345
|
+
#line 1068 "upb/json/parser.rl"
|
9780
10346
|
{ CHECK_RETURN_TOP(end_stringval(parser)); }
|
9781
10347
|
break;
|
9782
10348
|
case 22:
|
9783
|
-
#line
|
10349
|
+
#line 1070 "upb/json/parser.rl"
|
9784
10350
|
{ CHECK_RETURN_TOP(parser_putbool(parser, true)); }
|
9785
10351
|
break;
|
9786
10352
|
case 23:
|
9787
|
-
#line
|
10353
|
+
#line 1072 "upb/json/parser.rl"
|
9788
10354
|
{ CHECK_RETURN_TOP(parser_putbool(parser, false)); }
|
9789
10355
|
break;
|
9790
10356
|
case 24:
|
9791
|
-
#line
|
10357
|
+
#line 1074 "upb/json/parser.rl"
|
9792
10358
|
{ /* null value */ }
|
9793
10359
|
break;
|
9794
10360
|
case 25:
|
9795
|
-
#line
|
10361
|
+
#line 1076 "upb/json/parser.rl"
|
9796
10362
|
{ CHECK_RETURN_TOP(start_subobject(parser)); }
|
9797
10363
|
break;
|
9798
10364
|
case 26:
|
9799
|
-
#line
|
10365
|
+
#line 1077 "upb/json/parser.rl"
|
9800
10366
|
{ end_subobject(parser); }
|
9801
10367
|
break;
|
9802
10368
|
case 27:
|
9803
|
-
#line
|
10369
|
+
#line 1082 "upb/json/parser.rl"
|
9804
10370
|
{ p--; {cs = stack[--top]; goto _again;} }
|
9805
10371
|
break;
|
9806
|
-
#line
|
10372
|
+
#line 1354 "upb/json/parser.c"
|
9807
10373
|
}
|
9808
10374
|
}
|
9809
10375
|
|
@@ -9816,7 +10382,7 @@ _again:
|
|
9816
10382
|
_out: {}
|
9817
10383
|
}
|
9818
10384
|
|
9819
|
-
#line
|
10385
|
+
#line 1107 "upb/json/parser.rl"
|
9820
10386
|
|
9821
10387
|
if (p != pe) {
|
9822
10388
|
upb_status_seterrf(parser->status, "Parse error at %s\n", p);
|
@@ -9860,18 +10426,20 @@ void upb_json_parser_uninit(upb_json_parser *p) {
|
|
9860
10426
|
void upb_json_parser_reset(upb_json_parser *p) {
|
9861
10427
|
p->top = p->stack;
|
9862
10428
|
p->top->f = NULL;
|
10429
|
+
p->top->is_map = false;
|
10430
|
+
p->top->is_mapentry = false;
|
9863
10431
|
|
9864
10432
|
int cs;
|
9865
10433
|
int top;
|
9866
10434
|
// Emit Ragel initialization of the parser.
|
9867
10435
|
|
9868
|
-
#line
|
10436
|
+
#line 1418 "upb/json/parser.c"
|
9869
10437
|
{
|
9870
10438
|
cs = json_start;
|
9871
10439
|
top = 0;
|
9872
10440
|
}
|
9873
10441
|
|
9874
|
-
#line
|
10442
|
+
#line 1157 "upb/json/parser.rl"
|
9875
10443
|
p->current_state = cs;
|
9876
10444
|
p->parser_top = top;
|
9877
10445
|
accumulate_clear(p);
|
@@ -10072,13 +10640,23 @@ static bool putkey(void *closure, const void *handler_data) {
|
|
10072
10640
|
return true; \
|
10073
10641
|
} \
|
10074
10642
|
static bool repeated_##type(void *closure, const void *handler_data, \
|
10075
|
-
|
10643
|
+
type val) { \
|
10076
10644
|
upb_json_printer *p = closure; \
|
10077
10645
|
print_comma(p); \
|
10078
10646
|
CHK(put##type(closure, handler_data, val)); \
|
10079
10647
|
return true; \
|
10080
10648
|
}
|
10081
10649
|
|
10650
|
+
#define TYPE_HANDLERS_MAPKEY(type, fmt_func) \
|
10651
|
+
static bool putmapkey_##type(void *closure, const void *handler_data, \
|
10652
|
+
type val) { \
|
10653
|
+
upb_json_printer *p = closure; \
|
10654
|
+
print_data(p, "\"", 1); \
|
10655
|
+
CHK(put##type(closure, handler_data, val)); \
|
10656
|
+
print_data(p, "\":", 2); \
|
10657
|
+
return true; \
|
10658
|
+
}
|
10659
|
+
|
10082
10660
|
TYPE_HANDLERS(double, fmt_double);
|
10083
10661
|
TYPE_HANDLERS(float, fmt_float);
|
10084
10662
|
TYPE_HANDLERS(bool, fmt_bool);
|
@@ -10087,7 +10665,15 @@ TYPE_HANDLERS(uint32_t, fmt_int64);
|
|
10087
10665
|
TYPE_HANDLERS(int64_t, fmt_int64);
|
10088
10666
|
TYPE_HANDLERS(uint64_t, fmt_uint64);
|
10089
10667
|
|
10668
|
+
// double and float are not allowed to be map keys.
|
10669
|
+
TYPE_HANDLERS_MAPKEY(bool, fmt_bool);
|
10670
|
+
TYPE_HANDLERS_MAPKEY(int32_t, fmt_int64);
|
10671
|
+
TYPE_HANDLERS_MAPKEY(uint32_t, fmt_int64);
|
10672
|
+
TYPE_HANDLERS_MAPKEY(int64_t, fmt_int64);
|
10673
|
+
TYPE_HANDLERS_MAPKEY(uint64_t, fmt_uint64);
|
10674
|
+
|
10090
10675
|
#undef TYPE_HANDLERS
|
10676
|
+
#undef TYPE_HANDLERS_MAPKEY
|
10091
10677
|
|
10092
10678
|
typedef struct {
|
10093
10679
|
void *keyname;
|
@@ -10112,20 +10698,36 @@ static bool scalar_enum(void *closure, const void *handler_data,
|
|
10112
10698
|
return true;
|
10113
10699
|
}
|
10114
10700
|
|
10115
|
-
static
|
10116
|
-
|
10117
|
-
|
10118
|
-
|
10119
|
-
print_comma(p);
|
10120
|
-
|
10121
|
-
const char *symbolic_name = upb_enumdef_iton(hd->enumdef, val);
|
10701
|
+
static void print_enum_symbolic_name(upb_json_printer *p,
|
10702
|
+
const upb_enumdef *def,
|
10703
|
+
int32_t val) {
|
10704
|
+
const char *symbolic_name = upb_enumdef_iton(def, val);
|
10122
10705
|
if (symbolic_name) {
|
10123
10706
|
print_data(p, "\"", 1);
|
10124
10707
|
putstring(p, symbolic_name, strlen(symbolic_name));
|
10125
10708
|
print_data(p, "\"", 1);
|
10126
10709
|
} else {
|
10127
|
-
putint32_t(
|
10710
|
+
putint32_t(p, NULL, val);
|
10128
10711
|
}
|
10712
|
+
}
|
10713
|
+
|
10714
|
+
static bool repeated_enum(void *closure, const void *handler_data,
|
10715
|
+
int32_t val) {
|
10716
|
+
const EnumHandlerData *hd = handler_data;
|
10717
|
+
upb_json_printer *p = closure;
|
10718
|
+
print_comma(p);
|
10719
|
+
|
10720
|
+
print_enum_symbolic_name(p, hd->enumdef, val);
|
10721
|
+
|
10722
|
+
return true;
|
10723
|
+
}
|
10724
|
+
|
10725
|
+
static bool mapvalue_enum(void *closure, const void *handler_data,
|
10726
|
+
int32_t val) {
|
10727
|
+
const EnumHandlerData *hd = handler_data;
|
10728
|
+
upb_json_printer *p = closure;
|
10729
|
+
|
10730
|
+
print_enum_symbolic_name(p, hd->enumdef, val);
|
10129
10731
|
|
10130
10732
|
return true;
|
10131
10733
|
}
|
@@ -10141,25 +10743,35 @@ static void *repeated_startsubmsg(void *closure, const void *handler_data) {
|
|
10141
10743
|
return closure;
|
10142
10744
|
}
|
10143
10745
|
|
10144
|
-
static
|
10746
|
+
static void start_frame(upb_json_printer *p) {
|
10747
|
+
p->depth_++;
|
10748
|
+
p->first_elem_[p->depth_] = true;
|
10749
|
+
print_data(p, "{", 1);
|
10750
|
+
}
|
10751
|
+
|
10752
|
+
static void end_frame(upb_json_printer *p) {
|
10753
|
+
print_data(p, "}", 1);
|
10754
|
+
p->depth_--;
|
10755
|
+
}
|
10756
|
+
|
10757
|
+
static bool printer_startmsg(void *closure, const void *handler_data) {
|
10145
10758
|
UPB_UNUSED(handler_data);
|
10146
10759
|
upb_json_printer *p = closure;
|
10147
|
-
if (p->depth_
|
10760
|
+
if (p->depth_ == 0) {
|
10148
10761
|
upb_bytessink_start(p->output_, 0, &p->subc_);
|
10149
10762
|
}
|
10150
|
-
p
|
10151
|
-
print_data(p, "{", 1);
|
10763
|
+
start_frame(p);
|
10152
10764
|
return true;
|
10153
10765
|
}
|
10154
10766
|
|
10155
|
-
static bool
|
10767
|
+
static bool printer_endmsg(void *closure, const void *handler_data, upb_status *s) {
|
10156
10768
|
UPB_UNUSED(handler_data);
|
10157
10769
|
UPB_UNUSED(s);
|
10158
10770
|
upb_json_printer *p = closure;
|
10159
|
-
|
10771
|
+
end_frame(p);
|
10772
|
+
if (p->depth_ == 0) {
|
10160
10773
|
upb_bytessink_end(p->output_);
|
10161
10774
|
}
|
10162
|
-
print_data(p, "}", 1);
|
10163
10775
|
return true;
|
10164
10776
|
}
|
10165
10777
|
|
@@ -10180,6 +10792,23 @@ static bool endseq(void *closure, const void *handler_data) {
|
|
10180
10792
|
return true;
|
10181
10793
|
}
|
10182
10794
|
|
10795
|
+
static void *startmap(void *closure, const void *handler_data) {
|
10796
|
+
upb_json_printer *p = closure;
|
10797
|
+
CHK(putkey(closure, handler_data));
|
10798
|
+
p->depth_++;
|
10799
|
+
p->first_elem_[p->depth_] = true;
|
10800
|
+
print_data(p, "{", 1);
|
10801
|
+
return closure;
|
10802
|
+
}
|
10803
|
+
|
10804
|
+
static bool endmap(void *closure, const void *handler_data) {
|
10805
|
+
UPB_UNUSED(handler_data);
|
10806
|
+
upb_json_printer *p = closure;
|
10807
|
+
print_data(p, "}", 1);
|
10808
|
+
p->depth_--;
|
10809
|
+
return true;
|
10810
|
+
}
|
10811
|
+
|
10183
10812
|
static size_t putstr(void *closure, const void *handler_data, const char *str,
|
10184
10813
|
size_t len, const upb_bufhandle *handle) {
|
10185
10814
|
UPB_UNUSED(handler_data);
|
@@ -10294,6 +10923,36 @@ static bool repeated_endstr(void *closure, const void *handler_data) {
|
|
10294
10923
|
return true;
|
10295
10924
|
}
|
10296
10925
|
|
10926
|
+
static void *mapkeyval_startstr(void *closure, const void *handler_data,
|
10927
|
+
size_t size_hint) {
|
10928
|
+
UPB_UNUSED(handler_data);
|
10929
|
+
UPB_UNUSED(size_hint);
|
10930
|
+
upb_json_printer *p = closure;
|
10931
|
+
print_data(p, "\"", 1);
|
10932
|
+
return p;
|
10933
|
+
}
|
10934
|
+
|
10935
|
+
static size_t mapkey_str(void *closure, const void *handler_data,
|
10936
|
+
const char *str, size_t len,
|
10937
|
+
const upb_bufhandle *handle) {
|
10938
|
+
CHK(putstr(closure, handler_data, str, len, handle));
|
10939
|
+
return len;
|
10940
|
+
}
|
10941
|
+
|
10942
|
+
static bool mapkey_endstr(void *closure, const void *handler_data) {
|
10943
|
+
UPB_UNUSED(handler_data);
|
10944
|
+
upb_json_printer *p = closure;
|
10945
|
+
print_data(p, "\":", 2);
|
10946
|
+
return true;
|
10947
|
+
}
|
10948
|
+
|
10949
|
+
static bool mapvalue_endstr(void *closure, const void *handler_data) {
|
10950
|
+
UPB_UNUSED(handler_data);
|
10951
|
+
upb_json_printer *p = closure;
|
10952
|
+
print_data(p, "\"", 1);
|
10953
|
+
return true;
|
10954
|
+
}
|
10955
|
+
|
10297
10956
|
static size_t scalar_bytes(void *closure, const void *handler_data,
|
10298
10957
|
const char *str, size_t len,
|
10299
10958
|
const upb_bufhandle *handle) {
|
@@ -10311,31 +10970,161 @@ static size_t repeated_bytes(void *closure, const void *handler_data,
|
|
10311
10970
|
return len;
|
10312
10971
|
}
|
10313
10972
|
|
10314
|
-
|
10973
|
+
static size_t mapkey_bytes(void *closure, const void *handler_data,
|
10974
|
+
const char *str, size_t len,
|
10975
|
+
const upb_bufhandle *handle) {
|
10976
|
+
upb_json_printer *p = closure;
|
10977
|
+
CHK(putbytes(closure, handler_data, str, len, handle));
|
10978
|
+
print_data(p, ":", 1);
|
10979
|
+
return len;
|
10980
|
+
}
|
10981
|
+
|
10982
|
+
static void set_enum_hd(upb_handlers *h,
|
10983
|
+
const upb_fielddef *f,
|
10984
|
+
upb_handlerattr *attr) {
|
10985
|
+
EnumHandlerData *hd = malloc(sizeof(EnumHandlerData));
|
10986
|
+
hd->enumdef = (const upb_enumdef *)upb_fielddef_subdef(f);
|
10987
|
+
hd->keyname = newstrpc(h, f);
|
10988
|
+
upb_handlers_addcleanup(h, hd, free);
|
10989
|
+
upb_handlerattr_sethandlerdata(attr, hd);
|
10990
|
+
}
|
10991
|
+
|
10992
|
+
// Set up handlers for a mapentry submessage (i.e., an individual key/value pair
|
10993
|
+
// in a map).
|
10994
|
+
//
|
10995
|
+
// TODO: Handle missing key, missing value, out-of-order key/value, or repeated
|
10996
|
+
// key or value cases properly. The right way to do this is to allocate a
|
10997
|
+
// temporary structure at the start of a mapentry submessage, store key and
|
10998
|
+
// value data in it as key and value handlers are called, and then print the
|
10999
|
+
// key/value pair once at the end of the submessage. If we don't do this, we
|
11000
|
+
// should at least detect the case and throw an error. However, so far all of
|
11001
|
+
// our sources that emit mapentry messages do so canonically (with one key
|
11002
|
+
// field, and then one value field), so this is not a pressing concern at the
|
11003
|
+
// moment.
|
11004
|
+
void printer_sethandlers_mapentry(const void *closure, upb_handlers *h) {
|
10315
11005
|
UPB_UNUSED(closure);
|
11006
|
+
const upb_msgdef *md = upb_handlers_msgdef(h);
|
10316
11007
|
|
11008
|
+
// A mapentry message is printed simply as '"key": value'. Rather than
|
11009
|
+
// special-case key and value for every type below, we just handle both
|
11010
|
+
// fields explicitly here.
|
11011
|
+
const upb_fielddef* key_field = upb_msgdef_itof(md, UPB_MAPENTRY_KEY);
|
11012
|
+
const upb_fielddef* value_field = upb_msgdef_itof(md, UPB_MAPENTRY_VALUE);
|
11013
|
+
|
11014
|
+
upb_handlerattr empty_attr = UPB_HANDLERATTR_INITIALIZER;
|
11015
|
+
|
11016
|
+
switch (upb_fielddef_type(key_field)) {
|
11017
|
+
case UPB_TYPE_INT32:
|
11018
|
+
upb_handlers_setint32(h, key_field, putmapkey_int32_t, &empty_attr);
|
11019
|
+
break;
|
11020
|
+
case UPB_TYPE_INT64:
|
11021
|
+
upb_handlers_setint64(h, key_field, putmapkey_int64_t, &empty_attr);
|
11022
|
+
break;
|
11023
|
+
case UPB_TYPE_UINT32:
|
11024
|
+
upb_handlers_setuint32(h, key_field, putmapkey_uint32_t, &empty_attr);
|
11025
|
+
break;
|
11026
|
+
case UPB_TYPE_UINT64:
|
11027
|
+
upb_handlers_setuint64(h, key_field, putmapkey_uint64_t, &empty_attr);
|
11028
|
+
break;
|
11029
|
+
case UPB_TYPE_BOOL:
|
11030
|
+
upb_handlers_setbool(h, key_field, putmapkey_bool, &empty_attr);
|
11031
|
+
break;
|
11032
|
+
case UPB_TYPE_STRING:
|
11033
|
+
upb_handlers_setstartstr(h, key_field, mapkeyval_startstr, &empty_attr);
|
11034
|
+
upb_handlers_setstring(h, key_field, mapkey_str, &empty_attr);
|
11035
|
+
upb_handlers_setendstr(h, key_field, mapkey_endstr, &empty_attr);
|
11036
|
+
break;
|
11037
|
+
case UPB_TYPE_BYTES:
|
11038
|
+
upb_handlers_setstring(h, key_field, mapkey_bytes, &empty_attr);
|
11039
|
+
break;
|
11040
|
+
default:
|
11041
|
+
assert(false);
|
11042
|
+
break;
|
11043
|
+
}
|
11044
|
+
|
11045
|
+
switch (upb_fielddef_type(value_field)) {
|
11046
|
+
case UPB_TYPE_INT32:
|
11047
|
+
upb_handlers_setint32(h, value_field, putint32_t, &empty_attr);
|
11048
|
+
break;
|
11049
|
+
case UPB_TYPE_INT64:
|
11050
|
+
upb_handlers_setint64(h, value_field, putint64_t, &empty_attr);
|
11051
|
+
break;
|
11052
|
+
case UPB_TYPE_UINT32:
|
11053
|
+
upb_handlers_setuint32(h, value_field, putuint32_t, &empty_attr);
|
11054
|
+
break;
|
11055
|
+
case UPB_TYPE_UINT64:
|
11056
|
+
upb_handlers_setuint64(h, value_field, putuint64_t, &empty_attr);
|
11057
|
+
break;
|
11058
|
+
case UPB_TYPE_BOOL:
|
11059
|
+
upb_handlers_setbool(h, value_field, putbool, &empty_attr);
|
11060
|
+
break;
|
11061
|
+
case UPB_TYPE_FLOAT:
|
11062
|
+
upb_handlers_setfloat(h, value_field, putfloat, &empty_attr);
|
11063
|
+
break;
|
11064
|
+
case UPB_TYPE_DOUBLE:
|
11065
|
+
upb_handlers_setdouble(h, value_field, putdouble, &empty_attr);
|
11066
|
+
break;
|
11067
|
+
case UPB_TYPE_STRING:
|
11068
|
+
upb_handlers_setstartstr(h, value_field, mapkeyval_startstr, &empty_attr);
|
11069
|
+
upb_handlers_setstring(h, value_field, putstr, &empty_attr);
|
11070
|
+
upb_handlers_setendstr(h, value_field, mapvalue_endstr, &empty_attr);
|
11071
|
+
break;
|
11072
|
+
case UPB_TYPE_BYTES:
|
11073
|
+
upb_handlers_setstring(h, value_field, putbytes, &empty_attr);
|
11074
|
+
break;
|
11075
|
+
case UPB_TYPE_ENUM: {
|
11076
|
+
upb_handlerattr enum_attr = UPB_HANDLERATTR_INITIALIZER;
|
11077
|
+
set_enum_hd(h, value_field, &enum_attr);
|
11078
|
+
upb_handlers_setint32(h, value_field, mapvalue_enum, &enum_attr);
|
11079
|
+
upb_handlerattr_uninit(&enum_attr);
|
11080
|
+
break;
|
11081
|
+
}
|
11082
|
+
case UPB_TYPE_MESSAGE:
|
11083
|
+
// No handler necessary -- the submsg handlers will print the message
|
11084
|
+
// as appropriate.
|
11085
|
+
break;
|
11086
|
+
}
|
11087
|
+
|
11088
|
+
upb_handlerattr_uninit(&empty_attr);
|
11089
|
+
}
|
11090
|
+
|
11091
|
+
void printer_sethandlers(const void *closure, upb_handlers *h) {
|
11092
|
+
UPB_UNUSED(closure);
|
11093
|
+
const upb_msgdef *md = upb_handlers_msgdef(h);
|
11094
|
+
bool is_mapentry = upb_msgdef_mapentry(md);
|
10317
11095
|
upb_handlerattr empty_attr = UPB_HANDLERATTR_INITIALIZER;
|
10318
|
-
|
10319
|
-
|
10320
|
-
|
10321
|
-
|
10322
|
-
|
10323
|
-
|
10324
|
-
|
10325
|
-
|
10326
|
-
|
10327
|
-
|
11096
|
+
|
11097
|
+
if (is_mapentry) {
|
11098
|
+
// mapentry messages are sufficiently different that we handle them
|
11099
|
+
// separately.
|
11100
|
+
printer_sethandlers_mapentry(closure, h);
|
11101
|
+
return;
|
11102
|
+
}
|
11103
|
+
|
11104
|
+
upb_handlers_setstartmsg(h, printer_startmsg, &empty_attr);
|
11105
|
+
upb_handlers_setendmsg(h, printer_endmsg, &empty_attr);
|
11106
|
+
|
11107
|
+
#define TYPE(type, name, ctype) \
|
11108
|
+
case type: \
|
11109
|
+
if (upb_fielddef_isseq(f)) { \
|
11110
|
+
upb_handlers_set##name(h, f, repeated_##ctype, &empty_attr); \
|
11111
|
+
} else { \
|
11112
|
+
upb_handlers_set##name(h, f, scalar_##ctype, &name_attr); \
|
11113
|
+
} \
|
10328
11114
|
break;
|
10329
11115
|
|
10330
|
-
|
10331
|
-
|
10332
|
-
for(; !
|
11116
|
+
upb_msg_field_iter i;
|
11117
|
+
upb_msg_field_begin(&i, md);
|
11118
|
+
for(; !upb_msg_field_done(&i); upb_msg_field_next(&i)) {
|
10333
11119
|
const upb_fielddef *f = upb_msg_iter_field(&i);
|
10334
11120
|
|
10335
11121
|
upb_handlerattr name_attr = UPB_HANDLERATTR_INITIALIZER;
|
10336
11122
|
upb_handlerattr_sethandlerdata(&name_attr, newstrpc(h, f));
|
10337
11123
|
|
10338
|
-
if (
|
11124
|
+
if (upb_fielddef_ismap(f)) {
|
11125
|
+
upb_handlers_setstartseq(h, f, startmap, &name_attr);
|
11126
|
+
upb_handlers_setendseq(h, f, endmap, &name_attr);
|
11127
|
+
} else if (upb_fielddef_isseq(f)) {
|
10339
11128
|
upb_handlers_setstartseq(h, f, startseq, &name_attr);
|
10340
11129
|
upb_handlers_setendseq(h, f, endseq, &empty_attr);
|
10341
11130
|
}
|
@@ -10352,12 +11141,8 @@ void printer_sethandlers(const void *closure, upb_handlers *h) {
|
|
10352
11141
|
// For now, we always emit symbolic names for enums. We may want an
|
10353
11142
|
// option later to control this behavior, but we will wait for a real
|
10354
11143
|
// need first.
|
10355
|
-
EnumHandlerData *hd = malloc(sizeof(EnumHandlerData));
|
10356
|
-
hd->enumdef = (const upb_enumdef *)upb_fielddef_subdef(f);
|
10357
|
-
hd->keyname = newstrpc(h, f);
|
10358
|
-
upb_handlers_addcleanup(h, hd, free);
|
10359
11144
|
upb_handlerattr enum_attr = UPB_HANDLERATTR_INITIALIZER;
|
10360
|
-
|
11145
|
+
set_enum_hd(h, f, &enum_attr);
|
10361
11146
|
|
10362
11147
|
if (upb_fielddef_isseq(f)) {
|
10363
11148
|
upb_handlers_setint32(h, f, repeated_enum, &enum_attr);
|