* @brief Parses a `map name = tag;` declaration as a single MessageRef-like field. */
| 486 | * @brief Parses a `map<K,V> name = tag;` declaration as a single MessageRef-like field. |
| 487 | */ |
| 488 | bool Parser::parseMap(DataModel::ProtoMessage& msg, ParseError& err) |
| 489 | { |
| 490 | if (!expect(Tok::LAngle, QStringLiteral("'<'"), err)) |
| 491 | return false; |
| 492 | |
| 493 | if (m_cur.type != Tok::Ident) { |
| 494 | err = {m_cur.line, QObject::tr("Expected key type in map<>")}; |
| 495 | return false; |
| 496 | } |
| 497 | advance(); |
| 498 | if (!expect(Tok::Comma, QStringLiteral("','"), err)) |
| 499 | return false; |
| 500 | |
| 501 | if (m_cur.type != Tok::Ident) { |
| 502 | err = {m_cur.line, QObject::tr("Expected value type in map<>")}; |
| 503 | return false; |
| 504 | } |
| 505 | advance(); |
| 506 | if (!expect(Tok::RAngle, QStringLiteral("'>'"), err)) |
| 507 | return false; |
| 508 | |
| 509 | if (m_cur.type != Tok::Ident) { |
| 510 | err = {m_cur.line, QObject::tr("Expected map field name")}; |
| 511 | return false; |
| 512 | } |
| 513 | DataModel::ProtoField f; |
| 514 | f.name = m_cur.text; |
| 515 | f.repeated = true; |
| 516 | f.scalar = DataModel::ProtoScalar::Bytes; |
| 517 | advance(); |
| 518 | if (!expect(Tok::Eq, QStringLiteral("'='"), err)) |
| 519 | return false; |
| 520 | |
| 521 | if (m_cur.type != Tok::IntLit) { |
| 522 | err = {m_cur.line, QObject::tr("Expected map field tag")}; |
| 523 | return false; |
| 524 | } |
| 525 | if (!parseFieldTag(f.tag, err)) |
| 526 | return false; |
| 527 | |
| 528 | advance(); |
| 529 | if (m_cur.type == Tok::LBracket) |
| 530 | skipBlock(); |
| 531 | |
| 532 | if (!expect(Tok::Semi, QStringLiteral("';'"), err)) |
| 533 | return false; |
| 534 | |
| 535 | msg.fields.append(f); |
| 536 | return true; |
| 537 | } |
| 538 | |
| 539 | /** |
| 540 | * @brief Parses a single field declaration inside a message body. |