google-protobuf 3.0.0.alpha.1.1 → 3.0.0.alpha.2.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of google-protobuf might be problematic. Click here for more details.

@@ -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);