google-protobuf 3.0.0.alpha.1.1 → 3.0.0.alpha.2.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 +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);
|