@@ -871,6 +871,22 @@ TEST_F(ParseMessageTest, ReservedNames) {
871
871
" }" );
872
872
}
873
873
874
+ TEST_F (ParseMessageTest, ReservedIdentifiers) {
875
+ ExpectParsesTo (
876
+ " edition = \" 2023\" ;\n "
877
+ " message TestMessage {\n "
878
+ " reserved foo, bar;\n "
879
+ " }\n " ,
880
+
881
+ " syntax: \" editions\" "
882
+ " edition: \" 2023\" "
883
+ " message_type {"
884
+ " name: \" TestMessage\" "
885
+ " reserved_name: \" foo\" "
886
+ " reserved_name: \" bar\" "
887
+ " }" );
888
+ }
889
+
874
890
TEST_F (ParseMessageTest, ExtensionRange) {
875
891
ExpectParsesTo (
876
892
" message TestMessage {\n "
@@ -1229,6 +1245,24 @@ TEST_F(ParseEnumTest, ReservedNames) {
1229
1245
" }" );
1230
1246
}
1231
1247
1248
+ TEST_F (ParseEnumTest, ReservedIdentifiers) {
1249
+ ExpectParsesTo (
1250
+ " edition = \" 2023\" ;\n "
1251
+ " enum TestEnum {\n "
1252
+ " FOO = 0;\n "
1253
+ " reserved foo, bar;\n "
1254
+ " }\n " ,
1255
+
1256
+ " syntax: \" editions\" "
1257
+ " edition: \" 2023\" "
1258
+ " enum_type {"
1259
+ " name: \" TestEnum\" "
1260
+ " value { name:\" FOO\" number:0 }"
1261
+ " reserved_name: \" foo\" "
1262
+ " reserved_name: \" bar\" "
1263
+ " }" );
1264
+ }
1265
+
1232
1266
// ===================================================================
1233
1267
1234
1268
typedef ParserTest ParseServiceTest;
@@ -1502,6 +1536,44 @@ TEST_F(ParseErrorTest, DuplicateJsonName) {
1502
1536
" 1:41: Already set option \" json_name\" .\n " );
1503
1537
}
1504
1538
1539
+ TEST_F (ParseErrorTest, MsgReservedIdentifierOnlyInEditions) {
1540
+ ExpectHasErrors (
1541
+ " message TestMessage {\n "
1542
+ " reserved foo, bar;\n "
1543
+ " }\n " ,
1544
+ " 1:11: Reserved names must be string literals. (Only editions supports "
1545
+ " identifiers.)\n " );
1546
+ }
1547
+ TEST_F (ParseErrorTest, MsgReservedNameStringNotInEditions) {
1548
+ ExpectHasErrors (
1549
+ " edition = \" 2023\" ;\n "
1550
+ " message TestMessage {\n "
1551
+ " reserved \" foo\" , \" bar\" ;\n "
1552
+ " }\n " ,
1553
+ " 2:11: Reserved names must be identifiers in editions, not string "
1554
+ " literals.\n " );
1555
+ }
1556
+
1557
+ TEST_F (ParseErrorTest, EnumReservedIdentifierOnlyInEditions) {
1558
+ ExpectHasErrors (
1559
+ " enum TestEnum {\n "
1560
+ " FOO = 0;\n "
1561
+ " reserved foo, bar;\n "
1562
+ " }\n " ,
1563
+ " 2:11: Reserved names must be string literals. (Only editions supports "
1564
+ " identifiers.)\n " );
1565
+ }
1566
+ TEST_F (ParseErrorTest, EnumReservedNameStringNotInEditions) {
1567
+ ExpectHasErrors (
1568
+ " edition = \" 2023\" ;\n "
1569
+ " enum TestEnum {\n "
1570
+ " FOO = 0;\n "
1571
+ " reserved \" foo\" , \" bar\" ;\n "
1572
+ " }\n " ,
1573
+ " 3:11: Reserved names must be identifiers in editions, not string "
1574
+ " literals.\n " );
1575
+ }
1576
+
1505
1577
TEST_F (ParseErrorTest, EnumValueOutOfRange) {
1506
1578
ExpectHasErrors (
1507
1579
" enum TestEnum {\n "
@@ -1701,13 +1773,16 @@ TEST_F(ParseErrorTest, EnumValueMissingNumber) {
1701
1773
" 1:5: Missing numeric value for enum constant.\n " );
1702
1774
}
1703
1775
1776
+ // NB: with editions, this would be accepted and would reserve a value name of
1777
+ // "max"
1704
1778
TEST_F (ParseErrorTest, EnumReservedStandaloneMaxNotAllowed) {
1705
1779
ExpectHasErrors (
1706
1780
" enum TestEnum {\n "
1707
1781
" FOO = 1;\n "
1708
1782
" reserved max;\n "
1709
1783
" }\n " ,
1710
- " 2:11: Expected enum value or number range.\n " );
1784
+ " 2:11: Reserved names must be string literals. (Only editions supports "
1785
+ " identifiers.)\n " );
1711
1786
}
1712
1787
1713
1788
TEST_F (ParseErrorTest, EnumReservedMixNameAndNumber) {
@@ -1718,6 +1793,15 @@ TEST_F(ParseErrorTest, EnumReservedMixNameAndNumber) {
1718
1793
" }\n " ,
1719
1794
" 2:15: Expected enum number range.\n " );
1720
1795
}
1796
+ TEST_F (ParseErrorTest, EnumReservedMixNameAndNumberEditions) {
1797
+ ExpectHasErrors (
1798
+ " edition = \" 2023\" ;\n "
1799
+ " enum TestEnum {\n "
1800
+ " FOO = 1;\n "
1801
+ " reserved 10, foo;\n "
1802
+ " }\n " ,
1803
+ " 3:15: Expected enum number range.\n " );
1804
+ }
1721
1805
1722
1806
TEST_F (ParseErrorTest, EnumReservedPositiveNumberOutOfRange) {
1723
1807
ExpectHasErrors (
@@ -1743,29 +1827,33 @@ TEST_F(ParseErrorTest, EnumReservedMissingQuotes) {
1743
1827
" FOO = 1;\n "
1744
1828
" reserved foo;\n "
1745
1829
" }\n " ,
1746
- " 2:11: Expected enum value or number range.\n " );
1830
+ " 2:11: Reserved names must be string literals. (Only editions supports "
1831
+ " identifiers.)\n " );
1747
1832
}
1748
1833
1749
1834
TEST_F (ParseErrorTest, EnumReservedInvalidIdentifier) {
1750
1835
ExpectHasWarnings (
1751
- R"(
1752
- enum TestEnum {
1753
- FOO = 1;
1754
- reserved "foo bar";
1755
- }
1756
- )" ,
1757
- " 3:17 : Reserved name \" foo bar\" is not a valid identifier.\n " );
1836
+ R"schema (
1837
+ enum TestEnum {
1838
+ FOO = 1;
1839
+ reserved "foo bar";
1840
+ }
1841
+ )schema " ,
1842
+ " 3:19 : Reserved name \" foo bar\" is not a valid identifier.\n " );
1758
1843
}
1759
1844
1760
1845
// -------------------------------------------------------------------
1761
1846
// Reserved field number errors
1762
1847
1848
+ // NB: with editions, this would be accepted and would reserve a field name of
1849
+ // "max"
1763
1850
TEST_F (ParseErrorTest, ReservedStandaloneMaxNotAllowed) {
1764
1851
ExpectHasErrors (
1765
1852
" message Foo {\n "
1766
1853
" reserved max;\n "
1767
1854
" }\n " ,
1768
- " 1:11: Expected field name or number range.\n " );
1855
+ " 1:11: Reserved names must be string literals. (Only editions supports "
1856
+ " identifiers.)\n " );
1769
1857
}
1770
1858
1771
1859
TEST_F (ParseErrorTest, ReservedMixNameAndNumber) {
@@ -1775,23 +1863,32 @@ TEST_F(ParseErrorTest, ReservedMixNameAndNumber) {
1775
1863
" }\n " ,
1776
1864
" 1:15: Expected field number range.\n " );
1777
1865
}
1866
+ TEST_F (ParseErrorTest, ReservedMixNameAndNumberEditions) {
1867
+ ExpectHasErrors (
1868
+ " edition = \" 2023\" ;\n "
1869
+ " message Foo {\n "
1870
+ " reserved 10, foo;\n "
1871
+ " }\n " ,
1872
+ " 2:15: Expected field number range.\n " );
1873
+ }
1778
1874
1779
1875
TEST_F (ParseErrorTest, ReservedMissingQuotes) {
1780
1876
ExpectHasErrors (
1781
1877
" message Foo {\n "
1782
1878
" reserved foo;\n "
1783
1879
" }\n " ,
1784
- " 1:11: Expected field name or number range.\n " );
1880
+ " 1:11: Reserved names must be string literals. (Only editions supports "
1881
+ " identifiers.)\n " );
1785
1882
}
1786
1883
1787
1884
TEST_F (ParseErrorTest, ReservedInvalidIdentifier) {
1788
1885
ExpectHasWarnings (
1789
- R"(
1790
- message Foo {
1791
- reserved "foo bar";
1792
- }
1793
- )" ,
1794
- " 2:17 : Reserved name \" foo bar\" is not a valid identifier.\n " );
1886
+ R"schema (
1887
+ message Foo {
1888
+ reserved "foo bar";
1889
+ }
1890
+ )schema " ,
1891
+ " 2:19 : Reserved name \" foo bar\" is not a valid identifier.\n " );
1795
1892
}
1796
1893
1797
1894
TEST_F (ParseErrorTest, ReservedNegativeNumber) {
0 commit comments