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.

@@ -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
- upb_msg_iter j;
265
+ upb_msg_field_iter j;
251
266
  int i;
252
267
  m->submsg_field_count = 0;
253
- for(i = 0, upb_msg_begin(&j, m); !upb_msg_done(&j); upb_msg_next(&j), i++) {
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(upb_msg_begin(&j, m); !upb_msg_done(&j); upb_msg_next(&j)) {
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
- upb_msg_iter i;
1251
- for(upb_msg_begin(&i, m); !upb_msg_done(&i); upb_msg_next(&i)) {
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 err2;
1271
- if (!upb_strtable_init(&m->ntof, UPB_CTYPE_PTR)) goto err1;
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
- upb_inttable_uninit(&m->itof);
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
- upb_msg_iter i;
1290
- for(upb_msg_begin(&i, m); !upb_msg_done(&i); upb_msg_next(&i)) {
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 (upb_fielddef_containingtype(f) != NULL) {
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 (upb_fielddef_name(f) == NULL || upb_fielddef_number(f) == 0) {
1353
- upb_status_seterrmsg(s, "field name or number were not set");
1354
- return false;
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
- release_containingtype(f);
1363
- f->msg.def = m;
1364
- f->msg_is_symbolic = false;
1365
- upb_inttable_insert(&m->itof, upb_fielddef_number(f), upb_value_ptr(f));
1366
- upb_strtable_insert(&m->ntof, upb_fielddef_name(f), upb_value_ptr(f));
1367
- upb_ref2(f, m);
1368
- upb_ref2(m, f);
1369
- if (ref_donor) upb_fielddef_unref(f, ref_donor);
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 upb_msg_begin(upb_msg_iter *iter, const upb_msgdef *m) {
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 upb_msg_next(upb_msg_iter *iter) { upb_inttable_next(iter); }
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 upb_msg_done(const upb_msg_iter *iter) { return upb_inttable_done(iter); }
1771
+ bool upb_oneof_done(upb_oneof_iter *iter) {
1772
+ return upb_inttable_done(iter);
1773
+ }
1407
1774
 
1408
- upb_fielddef *upb_msg_iter_field(const upb_msg_iter *iter) {
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 upb_msg_iter_setdone(upb_msg_iter *iter) {
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
- upb_msg_iter i;
1456
- for(upb_msg_begin(&i, h->msg); !upb_msg_done(&i); upb_msg_next(&i)) {
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
- upb_msg_iter i;
1486
- for(upb_msg_begin(&i, m); !upb_msg_done(&i); upb_msg_next(&i)) {
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
- upb_msg_iter j;
1844
- for(upb_msg_begin(&j, h->msg); !upb_msg_done(&j); upb_msg_next(&j)) {
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
- upb_msg_iter i;
3118
- for(upb_msg_begin(&i, m); !upb_msg_done(&i); upb_msg_next(&i)) {
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
- upb_msg_iter j;
3272
- for(upb_msg_begin(&j, m); !upb_msg_done(&j); upb_msg_next(&j)) {
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
- upb_msg_iter i;
6466
- for(upb_msg_begin(&i, md); !upb_msg_done(&i); upb_msg_next(&i)) {
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
- upb_msg_iter i;
6895
+ upb_msg_field_iter i;
6517
6896
  const upb_msgdef *md = upb_handlers_msgdef(h);
6518
- for(upb_msg_begin(&i, md); !upb_msg_done(&i); upb_msg_next(&i)) {
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
- upb_msg_iter i;
7984
- for(upb_msg_begin(&i, m); !upb_msg_done(&i); upb_msg_next(&i)) {
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
- upb_msg_iter i;
8447
- for(upb_msg_begin(&i, m); !upb_msg_done(&i); upb_msg_next(&i)) {
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
- static bool end_member(upb_json_parser *p) {
9335
- assert(!p->top->f);
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
- const upb_fielddef *f = upb_msgdef_ntof(p->top->m, buf, len);
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
- if (!f) {
9342
- // TODO(haberman): Ignore unknown fields if requested/configured to do so.
9343
- upb_status_seterrf(p->status, "No such field: %.*s\n", (int)len, buf);
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
- p->top->f = f;
9348
- multipart_end(p);
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 void clear_member(upb_json_parser *p) { p->top->f = NULL; }
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 (!upb_fielddef_issubmsg(p->top->f)) {
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
- upb_selector_t sel = getsel_for_handlertype(p, UPB_HANDLER_ENDSUBMSG);
9381
- upb_sink_endsubmsg(&p->top->sink, sel);
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
- upb_sink_startmsg(&p->top->sink);
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
- upb_status status;
9420
- upb_sink_endmsg(&p->top->sink, &status);
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 904 "upb/json/parser.rl"
10011
+ #line 1085 "upb/json/parser.rl"
9446
10012
 
9447
10013
 
9448
10014
 
9449
- #line 816 "upb/json/parser.c"
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 907 "upb/json/parser.rl"
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 987 "upb/json/parser.c"
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 819 "upb/json/parser.rl"
10261
+ #line 1000 "upb/json/parser.rl"
9696
10262
  { p--; {cs = stack[--top]; goto _again;} }
9697
10263
  break;
9698
10264
  case 1:
9699
- #line 820 "upb/json/parser.rl"
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 824 "upb/json/parser.rl"
10269
+ #line 1005 "upb/json/parser.rl"
9704
10270
  { start_text(parser, p); }
9705
10271
  break;
9706
10272
  case 3:
9707
- #line 825 "upb/json/parser.rl"
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 831 "upb/json/parser.rl"
10277
+ #line 1012 "upb/json/parser.rl"
9712
10278
  { start_hex(parser); }
9713
10279
  break;
9714
10280
  case 5:
9715
- #line 832 "upb/json/parser.rl"
10281
+ #line 1013 "upb/json/parser.rl"
9716
10282
  { hexdigit(parser, p); }
9717
10283
  break;
9718
10284
  case 6:
9719
- #line 833 "upb/json/parser.rl"
10285
+ #line 1014 "upb/json/parser.rl"
9720
10286
  { CHECK_RETURN_TOP(end_hex(parser)); }
9721
10287
  break;
9722
10288
  case 7:
9723
- #line 839 "upb/json/parser.rl"
10289
+ #line 1020 "upb/json/parser.rl"
9724
10290
  { CHECK_RETURN_TOP(escape(parser, p)); }
9725
10291
  break;
9726
10292
  case 8:
9727
- #line 845 "upb/json/parser.rl"
10293
+ #line 1026 "upb/json/parser.rl"
9728
10294
  { p--; {cs = stack[--top]; goto _again;} }
9729
10295
  break;
9730
10296
  case 9:
9731
- #line 848 "upb/json/parser.rl"
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 850 "upb/json/parser.rl"
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 855 "upb/json/parser.rl"
10305
+ #line 1036 "upb/json/parser.rl"
9740
10306
  { start_member(parser); }
9741
10307
  break;
9742
10308
  case 12:
9743
- #line 856 "upb/json/parser.rl"
9744
- { CHECK_RETURN_TOP(end_member(parser)); }
10309
+ #line 1037 "upb/json/parser.rl"
10310
+ { CHECK_RETURN_TOP(end_membername(parser)); }
9745
10311
  break;
9746
10312
  case 13:
9747
- #line 859 "upb/json/parser.rl"
9748
- { clear_member(parser); }
10313
+ #line 1040 "upb/json/parser.rl"
10314
+ { end_member(parser); }
9749
10315
  break;
9750
10316
  case 14:
9751
- #line 865 "upb/json/parser.rl"
10317
+ #line 1046 "upb/json/parser.rl"
9752
10318
  { start_object(parser); }
9753
10319
  break;
9754
10320
  case 15:
9755
- #line 868 "upb/json/parser.rl"
10321
+ #line 1049 "upb/json/parser.rl"
9756
10322
  { end_object(parser); }
9757
10323
  break;
9758
10324
  case 16:
9759
- #line 874 "upb/json/parser.rl"
10325
+ #line 1055 "upb/json/parser.rl"
9760
10326
  { CHECK_RETURN_TOP(start_array(parser)); }
9761
10327
  break;
9762
10328
  case 17:
9763
- #line 878 "upb/json/parser.rl"
10329
+ #line 1059 "upb/json/parser.rl"
9764
10330
  { end_array(parser); }
9765
10331
  break;
9766
10332
  case 18:
9767
- #line 883 "upb/json/parser.rl"
10333
+ #line 1064 "upb/json/parser.rl"
9768
10334
  { start_number(parser, p); }
9769
10335
  break;
9770
10336
  case 19:
9771
- #line 884 "upb/json/parser.rl"
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 886 "upb/json/parser.rl"
10341
+ #line 1067 "upb/json/parser.rl"
9776
10342
  { CHECK_RETURN_TOP(start_stringval(parser)); }
9777
10343
  break;
9778
10344
  case 21:
9779
- #line 887 "upb/json/parser.rl"
10345
+ #line 1068 "upb/json/parser.rl"
9780
10346
  { CHECK_RETURN_TOP(end_stringval(parser)); }
9781
10347
  break;
9782
10348
  case 22:
9783
- #line 889 "upb/json/parser.rl"
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 891 "upb/json/parser.rl"
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 893 "upb/json/parser.rl"
10357
+ #line 1074 "upb/json/parser.rl"
9792
10358
  { /* null value */ }
9793
10359
  break;
9794
10360
  case 25:
9795
- #line 895 "upb/json/parser.rl"
10361
+ #line 1076 "upb/json/parser.rl"
9796
10362
  { CHECK_RETURN_TOP(start_subobject(parser)); }
9797
10363
  break;
9798
10364
  case 26:
9799
- #line 896 "upb/json/parser.rl"
10365
+ #line 1077 "upb/json/parser.rl"
9800
10366
  { end_subobject(parser); }
9801
10367
  break;
9802
10368
  case 27:
9803
- #line 901 "upb/json/parser.rl"
10369
+ #line 1082 "upb/json/parser.rl"
9804
10370
  { p--; {cs = stack[--top]; goto _again;} }
9805
10371
  break;
9806
- #line 1173 "upb/json/parser.c"
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 926 "upb/json/parser.rl"
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 1235 "upb/json/parser.c"
10436
+ #line 1418 "upb/json/parser.c"
9869
10437
  {
9870
10438
  cs = json_start;
9871
10439
  top = 0;
9872
10440
  }
9873
10441
 
9874
- #line 974 "upb/json/parser.rl"
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
- type val) { \
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 bool repeated_enum(void *closure, const void *handler_data,
10116
- int32_t val) {
10117
- const EnumHandlerData *hd = handler_data;
10118
- upb_json_printer *p = closure;
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(closure, NULL, val);
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 bool startmap(void *closure, const void *handler_data) {
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_++ == 0) {
10760
+ if (p->depth_ == 0) {
10148
10761
  upb_bytessink_start(p->output_, 0, &p->subc_);
10149
10762
  }
10150
- p->first_elem_[p->depth_] = true;
10151
- print_data(p, "{", 1);
10763
+ start_frame(p);
10152
10764
  return true;
10153
10765
  }
10154
10766
 
10155
- static bool endmap(void *closure, const void *handler_data, upb_status *s) {
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
- if (--p->depth_ == 0) {
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
- void printer_sethandlers(const void *closure, upb_handlers *h) {
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
- upb_handlers_setstartmsg(h, startmap, &empty_attr);
10319
- upb_handlers_setendmsg(h, endmap, &empty_attr);
10320
-
10321
- #define TYPE(type, name, ctype) \
10322
- case type: \
10323
- if (upb_fielddef_isseq(f)) { \
10324
- upb_handlers_set##name(h, f, repeated_##ctype, &empty_attr); \
10325
- } else { \
10326
- upb_handlers_set##name(h, f, scalar_##ctype, &name_attr); \
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
- upb_msg_iter i;
10331
- upb_msg_begin(&i, upb_handlers_msgdef(h));
10332
- for(; !upb_msg_done(&i); upb_msg_next(&i)) {
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 (upb_fielddef_isseq(f)) {
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
- upb_handlerattr_sethandlerdata(&enum_attr, hd);
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);