1250
1261
// ===================================================================
1262
// SourceCodeInfo tests.
1264
// Follows a path -- as defined by SourceCodeInfo.Location.path -- from a
1265
// message to a particular sub-field.
1266
// * If the target is itself a message, sets *output_message to point at it,
1267
// *output_field to NULL, and *output_index to -1.
1268
// * Otherwise, if the target is an element of a repeated field, sets
1269
// *output_message to the containing message, *output_field to the descriptor
1270
// of the field, and *output_index to the index of the element.
1271
// * Otherwise, the target is a field (possibly a repeated field, but not any
1272
// one element). Sets *output_message to the containing message,
1273
// *output_field to the descriptor of the field, and *output_index to -1.
1274
// Returns true if the path was valid, false otherwise. A gTest failure is
1275
// recorded before returning false.
1276
bool FollowPath(const Message& root,
1277
const int* path_begin, const int* path_end,
1278
const Message** output_message,
1279
const FieldDescriptor** output_field,
1280
int* output_index) {
1281
if (path_begin == path_end) {
1282
// Path refers to this whole message.
1283
*output_message = &root;
1284
*output_field = NULL;
1289
const Descriptor* descriptor = root.GetDescriptor();
1290
const Reflection* reflection = root.GetReflection();
1292
const FieldDescriptor* field = descriptor->FindFieldByNumber(*path_begin);
1294
if (field == NULL) {
1295
ADD_FAILURE() << descriptor->name() << " has no field number: "
1302
if (field->is_repeated()) {
1303
if (path_begin == path_end) {
1304
// Path refers to the whole repeated field.
1305
*output_message = &root;
1306
*output_field = field;
1311
int index = *path_begin++;
1312
int size = reflection->FieldSize(root, field);
1314
if (index >= size) {
1315
ADD_FAILURE() << descriptor->name() << "." << field->name()
1316
<< " has size " << size << ", but path contained index: "
1321
if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
1322
// Descend into child message.
1323
const Message& child = reflection->GetRepeatedMessage(root, field, index);
1324
return FollowPath(child, path_begin, path_end,
1325
output_message, output_field, output_index);
1326
} else if (path_begin == path_end) {
1327
// Path refers to this element.
1328
*output_message = &root;
1329
*output_field = field;
1330
*output_index = index;
1333
ADD_FAILURE() << descriptor->name() << "." << field->name()
1334
<< " is not a message; cannot descend into it.";
1338
if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
1339
const Message& child = reflection->GetMessage(root, field);
1340
return FollowPath(child, path_begin, path_end,
1341
output_message, output_field, output_index);
1342
} else if (path_begin == path_end) {
1343
// Path refers to this field.
1344
*output_message = &root;
1345
*output_field = field;
1349
ADD_FAILURE() << descriptor->name() << "." << field->name()
1350
<< " is not a message; cannot descend into it.";
1356
// Split some text on line breaks. The line breaks are retained in the output,
1357
// so each line (except the last) ends with a '\n', and the lines can be
1358
// concatenated to produce the original text.
1360
// I couldn't find the proper string utility function for this. Our
1361
// split-on-delimiter functions don't include the delimiter in the output.
1362
void SplitLines(const string& text, vector<string>* lines) {
1363
string::size_type pos = 0;
1365
while (pos != string::npos) {
1366
string::size_type last_pos = pos;
1367
pos = text.find_first_of('\n', pos);
1368
if (pos != string::npos) ++pos;
1369
lines->push_back(text.substr(last_pos, pos - last_pos));
1373
// Look for the given tags in the given text and construct a span (as defined
1374
// by SourceCodeInfo.Location.span) from them. E.g. for text like:
1375
// /*a*/message /*b*/Foo/*c*/ {}/*d*/
1376
// There are four tags: "a", "b", "c", and "d". The constructed span starts
1377
// immediately after the start tag's trailing '/' and ends immediately before
1378
// the end tags leading '/'.
1379
void MakeExpectedSpan(const vector<string>& lines,
1380
const string& start_tag, const string& end_tag,
1381
RepeatedField<int>* output) {
1382
string start_comment = "/*" + start_tag + "*/";
1383
string end_comment = "/*" + end_tag + "*/";
1385
int start_line = -1;
1386
int start_column = -1;
1387
for (int i = 0; i < lines.size(); i++) {
1388
string::size_type pos = lines[i].find(start_comment);
1389
if (pos != string::npos) {
1391
start_column = pos + start_comment.size();
1395
ASSERT_NE(start_line, -1)
1396
<< "Tag \"" << start_comment << "\" not found in text.";
1399
int end_column = -1;
1400
for (int i = start_line; i < lines.size(); i++) {
1401
string::size_type pos = lines[i].find(end_comment);
1402
if (pos != string::npos) {
1408
ASSERT_NE(end_line, -1)
1409
<< "Tag \"" << end_comment << "\" not found in text.";
1411
output->Add(start_line);
1412
output->Add(start_column);
1413
if (end_line != start_line) output->Add(end_line);
1414
output->Add(end_column);
1417
// Check if two spans are equal.
1418
bool CompareSpans(const RepeatedField<int>& span1,
1419
const RepeatedField<int>& span2) {
1420
if (span1.size() != span2.size()) return false;
1421
for (int i = 0; i < span1.size(); i++) {
1422
if (span1.Get(i) != span2.Get(i)) return false;
1427
// Test fixture for source info tests, which check that source locations are
1428
// recorded correctly in FileDescriptorProto.source_code_info.location.
1429
class SourceInfoTest : public ParserTest {
1431
// The parsed file (initialized by Parse()).
1432
FileDescriptorProto file_;
1434
// Parse the given text as a .proto file and populate the spans_ map with
1435
// all the source location spans in its SourceCodeInfo table.
1436
bool Parse(const char* text) {
1438
SplitLines(text, &lines_);
1439
if (!parser_->Parse(input_.get(), &file_)) {
1443
const SourceCodeInfo& source_info = file_.source_code_info();
1444
for (int i = 0; i < source_info.location_size(); i++) {
1445
const SourceCodeInfo::Location& location = source_info.location(i);
1446
const Message* descriptor_proto = NULL;
1447
const FieldDescriptor* field = NULL;
1449
if (!FollowPath(file_, location.path().begin(), location.path().end(),
1450
&descriptor_proto, &field, &index)) {
1454
spans_.insert(make_pair(SpanKey(*descriptor_proto, field, index),
1461
virtual void TearDown() {
1462
EXPECT_TRUE(spans_.empty())
1463
<< "Forgot to call HasSpan() for:\n"
1464
<< spans_.begin()->second->DebugString();
1467
// -----------------------------------------------------------------
1468
// HasSpan() checks that the span of source code delimited by the given
1469
// tags (comments) correspond via the SourceCodeInfo table to the given
1470
// part of the FileDescriptorProto. (If unclear, look at the actual tests;
1471
// it should quickly become obvious.)
1473
bool HasSpan(const char* start_tag, const char* end_tag,
1474
const Message& descriptor_proto) {
1475
return HasSpan(start_tag, end_tag, descriptor_proto, NULL, -1);
1478
bool HasSpan(const char* start_tag, const char* end_tag,
1479
const Message& descriptor_proto, const string& field_name) {
1480
return HasSpan(start_tag, end_tag, descriptor_proto, field_name, -1);
1483
bool HasSpan(const char* start_tag, const char* end_tag,
1484
const Message& descriptor_proto, const string& field_name,
1486
const FieldDescriptor* field =
1487
descriptor_proto.GetDescriptor()->FindFieldByName(field_name);
1488
if (field == NULL) {
1489
ADD_FAILURE() << descriptor_proto.GetDescriptor()->name()
1490
<< " has no such field: " << field_name;
1494
return HasSpan(start_tag, end_tag, descriptor_proto, field, index);
1497
bool HasSpan(const Message& descriptor_proto) {
1498
return HasSpan(NULL, NULL, descriptor_proto, NULL, -1);
1501
bool HasSpan(const Message& descriptor_proto, const string& field_name) {
1502
return HasSpan(NULL, NULL, descriptor_proto, field_name, -1);
1505
bool HasSpan(const Message& descriptor_proto, const string& field_name,
1507
return HasSpan(NULL, NULL, descriptor_proto, field_name, index);
1510
bool HasSpan(const char* start_tag, const char* end_tag,
1511
const Message& descriptor_proto, const FieldDescriptor* field,
1513
pair<SpanMap::iterator, SpanMap::iterator> range =
1514
spans_.equal_range(SpanKey(descriptor_proto, field, index));
1516
if (start_tag == NULL) {
1517
if (range.first == range.second) {
1520
spans_.erase(range.first);
1524
RepeatedField<int> expected_span;
1525
MakeExpectedSpan(lines_, start_tag, end_tag, &expected_span);
1527
for (SpanMap::iterator iter = range.first; iter != range.second; ++iter) {
1528
if (CompareSpans(expected_span, iter->second->span())) {
1540
const Message* descriptor_proto;
1541
const FieldDescriptor* field;
1545
inline SpanKey(const Message& descriptor_proto,
1546
const FieldDescriptor* field,
1548
: descriptor_proto(&descriptor_proto), field(field), index(index) {}
1550
inline bool operator<(const SpanKey& other) const {
1551
if (descriptor_proto < other.descriptor_proto) return true;
1552
if (descriptor_proto > other.descriptor_proto) return false;
1553
if (field < other.field) return true;
1554
if (field > other.field) return false;
1555
return index < other.index;
1559
typedef multimap<SpanKey, const SourceCodeInfo::Location*> SpanMap;
1561
vector<string> lines_;
1564
TEST_F(SourceInfoTest, BasicFileDecls) {
1566
"/*a*/syntax = \"proto2\";\n"
1567
"package /*b*/foo.bar/*c*/;\n"
1568
"import /*d*/\"baz.proto\"/*e*/;\n"
1569
"import /*f*/\"qux.proto\"/*g*/;/*h*/\n"
1570
"// comment ignored\n"));
1572
EXPECT_TRUE(HasSpan("a", "h", file_));
1573
EXPECT_TRUE(HasSpan("b", "c", file_, "package"));
1574
EXPECT_TRUE(HasSpan("d", "e", file_, "dependency", 0));
1575
EXPECT_TRUE(HasSpan("f", "g", file_, "dependency", 1));
1578
TEST_F(SourceInfoTest, Messages) {
1580
"/*a*/message /*b*/Foo/*c*/ {}/*d*/\n"
1581
"/*e*/message /*f*/Bar/*g*/ {}/*h*/\n"));
1583
EXPECT_TRUE(HasSpan("a", "d", file_.message_type(0)));
1584
EXPECT_TRUE(HasSpan("b", "c", file_.message_type(0), "name"));
1585
EXPECT_TRUE(HasSpan("e", "h", file_.message_type(1)));
1586
EXPECT_TRUE(HasSpan("f", "g", file_.message_type(1), "name"));
1589
EXPECT_TRUE(HasSpan(file_));
1592
TEST_F(SourceInfoTest, Fields) {
1595
" /*a*/optional/*b*/ /*c*/int32/*d*/ /*e*/bar/*f*/ = /*g*/1/*h*/;/*i*/\n"
1596
" /*j*/repeated/*k*/ /*l*/X.Y/*m*/ /*n*/baz/*o*/ = /*p*/2/*q*/;/*r*/\n"
1599
const FieldDescriptorProto& field1 = file_.message_type(0).field(0);
1600
const FieldDescriptorProto& field2 = file_.message_type(0).field(1);
1602
EXPECT_TRUE(HasSpan("a", "i", field1));
1603
EXPECT_TRUE(HasSpan("a", "b", field1, "label"));
1604
EXPECT_TRUE(HasSpan("c", "d", field1, "type"));
1605
EXPECT_TRUE(HasSpan("e", "f", field1, "name"));
1606
EXPECT_TRUE(HasSpan("g", "h", field1, "number"));
1608
EXPECT_TRUE(HasSpan("j", "r", field2));
1609
EXPECT_TRUE(HasSpan("j", "k", field2, "label"));
1610
EXPECT_TRUE(HasSpan("l", "m", field2, "type_name"));
1611
EXPECT_TRUE(HasSpan("n", "o", field2, "name"));
1612
EXPECT_TRUE(HasSpan("p", "q", field2, "number"));
1615
EXPECT_TRUE(HasSpan(file_));
1616
EXPECT_TRUE(HasSpan(file_.message_type(0)));
1617
EXPECT_TRUE(HasSpan(file_.message_type(0), "name"));
1620
TEST_F(SourceInfoTest, Extensions) {
1622
"/*a*/extend /*b*/Foo/*c*/ {\n"
1623
" /*d*/optional/*e*/ int32 bar = 1;/*f*/\n"
1624
" /*g*/repeated/*h*/ X.Y baz = 2;/*i*/\n"
1626
"/*k*/extend /*l*/Bar/*m*/ {\n"
1627
" /*n*/optional int32 qux = 1;/*o*/\n"
1630
const FieldDescriptorProto& field1 = file_.extension(0);
1631
const FieldDescriptorProto& field2 = file_.extension(1);
1632
const FieldDescriptorProto& field3 = file_.extension(2);
1634
EXPECT_TRUE(HasSpan("a", "j", file_, "extension"));
1635
EXPECT_TRUE(HasSpan("k", "p", file_, "extension"));
1637
EXPECT_TRUE(HasSpan("d", "f", field1));
1638
EXPECT_TRUE(HasSpan("d", "e", field1, "label"));
1639
EXPECT_TRUE(HasSpan("b", "c", field1, "extendee"));
1641
EXPECT_TRUE(HasSpan("g", "i", field2));
1642
EXPECT_TRUE(HasSpan("g", "h", field2, "label"));
1643
EXPECT_TRUE(HasSpan("b", "c", field2, "extendee"));
1645
EXPECT_TRUE(HasSpan("n", "o", field3));
1646
EXPECT_TRUE(HasSpan("l", "m", field3, "extendee"));
1649
EXPECT_TRUE(HasSpan(file_));
1650
EXPECT_TRUE(HasSpan(field1, "type"));
1651
EXPECT_TRUE(HasSpan(field1, "name"));
1652
EXPECT_TRUE(HasSpan(field1, "number"));
1653
EXPECT_TRUE(HasSpan(field2, "type_name"));
1654
EXPECT_TRUE(HasSpan(field2, "name"));
1655
EXPECT_TRUE(HasSpan(field2, "number"));
1656
EXPECT_TRUE(HasSpan(field3, "label"));
1657
EXPECT_TRUE(HasSpan(field3, "type"));
1658
EXPECT_TRUE(HasSpan(field3, "name"));
1659
EXPECT_TRUE(HasSpan(field3, "number"));
1662
TEST_F(SourceInfoTest, NestedExtensions) {
1664
"message Message {\n"
1665
" /*a*/extend /*b*/Foo/*c*/ {\n"
1666
" /*d*/optional/*e*/ int32 bar = 1;/*f*/\n"
1667
" /*g*/repeated/*h*/ X.Y baz = 2;/*i*/\n"
1669
" /*k*/extend /*l*/Bar/*m*/ {\n"
1670
" /*n*/optional int32 qux = 1;/*o*/\n"
1674
const FieldDescriptorProto& field1 = file_.message_type(0).extension(0);
1675
const FieldDescriptorProto& field2 = file_.message_type(0).extension(1);
1676
const FieldDescriptorProto& field3 = file_.message_type(0).extension(2);
1678
EXPECT_TRUE(HasSpan("a", "j", file_.message_type(0), "extension"));
1679
EXPECT_TRUE(HasSpan("k", "p", file_.message_type(0), "extension"));
1681
EXPECT_TRUE(HasSpan("d", "f", field1));
1682
EXPECT_TRUE(HasSpan("d", "e", field1, "label"));
1683
EXPECT_TRUE(HasSpan("b", "c", field1, "extendee"));
1685
EXPECT_TRUE(HasSpan("g", "i", field2));
1686
EXPECT_TRUE(HasSpan("g", "h", field2, "label"));
1687
EXPECT_TRUE(HasSpan("b", "c", field2, "extendee"));
1689
EXPECT_TRUE(HasSpan("n", "o", field3));
1690
EXPECT_TRUE(HasSpan("l", "m", field3, "extendee"));
1693
EXPECT_TRUE(HasSpan(file_));
1694
EXPECT_TRUE(HasSpan(file_.message_type(0)));
1695
EXPECT_TRUE(HasSpan(file_.message_type(0), "name"));
1696
EXPECT_TRUE(HasSpan(field1, "type"));
1697
EXPECT_TRUE(HasSpan(field1, "name"));
1698
EXPECT_TRUE(HasSpan(field1, "number"));
1699
EXPECT_TRUE(HasSpan(field2, "type_name"));
1700
EXPECT_TRUE(HasSpan(field2, "name"));
1701
EXPECT_TRUE(HasSpan(field2, "number"));
1702
EXPECT_TRUE(HasSpan(field3, "label"));
1703
EXPECT_TRUE(HasSpan(field3, "type"));
1704
EXPECT_TRUE(HasSpan(field3, "name"));
1705
EXPECT_TRUE(HasSpan(field3, "number"));
1708
TEST_F(SourceInfoTest, ExtensionRanges) {
1710
"message Message {\n"
1711
" /*a*/extensions /*b*/1/*c*/ to /*d*/4/*e*/, /*f*/6/*g*/;/*h*/\n"
1712
" /*i*/extensions /*j*/8/*k*/ to /*l*/max/*m*/;/*n*/\n"
1715
const DescriptorProto::ExtensionRange& range1 =
1716
file_.message_type(0).extension_range(0);
1717
const DescriptorProto::ExtensionRange& range2 =
1718
file_.message_type(0).extension_range(1);
1719
const DescriptorProto::ExtensionRange& range3 =
1720
file_.message_type(0).extension_range(2);
1722
EXPECT_TRUE(HasSpan("a", "h", file_.message_type(0), "extension_range"));
1723
EXPECT_TRUE(HasSpan("i", "n", file_.message_type(0), "extension_range"));
1725
EXPECT_TRUE(HasSpan("b", "e", range1));
1726
EXPECT_TRUE(HasSpan("b", "c", range1, "start"));
1727
EXPECT_TRUE(HasSpan("d", "e", range1, "end"));
1729
EXPECT_TRUE(HasSpan("f", "g", range2));
1730
EXPECT_TRUE(HasSpan("f", "g", range2, "start"));
1731
EXPECT_TRUE(HasSpan("f", "g", range2, "end"));
1733
EXPECT_TRUE(HasSpan("j", "m", range3));
1734
EXPECT_TRUE(HasSpan("j", "k", range3, "start"));
1735
EXPECT_TRUE(HasSpan("l", "m", range3, "end"));
1738
EXPECT_TRUE(HasSpan(file_));
1739
EXPECT_TRUE(HasSpan(file_.message_type(0)));
1740
EXPECT_TRUE(HasSpan(file_.message_type(0), "name"));
1743
TEST_F(SourceInfoTest, NestedMessages) {
1746
" /*a*/message /*b*/Bar/*c*/ {\n"
1747
" /*d*/message /*e*/Baz/*f*/ {}/*g*/\n"
1749
" /*i*/message /*j*/Qux/*k*/ {}/*l*/\n"
1752
const DescriptorProto& bar = file_.message_type(0).nested_type(0);
1753
const DescriptorProto& baz = bar.nested_type(0);
1754
const DescriptorProto& qux = file_.message_type(0).nested_type(1);
1756
EXPECT_TRUE(HasSpan("a", "h", bar));
1757
EXPECT_TRUE(HasSpan("b", "c", bar, "name"));
1758
EXPECT_TRUE(HasSpan("d", "g", baz));
1759
EXPECT_TRUE(HasSpan("e", "f", baz, "name"));
1760
EXPECT_TRUE(HasSpan("i", "l", qux));
1761
EXPECT_TRUE(HasSpan("j", "k", qux, "name"));
1764
EXPECT_TRUE(HasSpan(file_));
1765
EXPECT_TRUE(HasSpan(file_.message_type(0)));
1766
EXPECT_TRUE(HasSpan(file_.message_type(0), "name"));
1769
TEST_F(SourceInfoTest, Groups) {
1773
" /*a*/optional/*b*/ /*c*/group/*d*/ /*e*/Baz/*f*/ = /*g*/1/*h*/ {\n"
1774
" /*i*/message Qux {}/*j*/\n"
1778
const DescriptorProto& bar = file_.message_type(0).nested_type(0);
1779
const DescriptorProto& baz = file_.message_type(0).nested_type(1);
1780
const DescriptorProto& qux = baz.nested_type(0);
1781
const FieldDescriptorProto& field = file_.message_type(0).field(0);
1783
EXPECT_TRUE(HasSpan("a", "k", field));
1784
EXPECT_TRUE(HasSpan("a", "b", field, "label"));
1785
EXPECT_TRUE(HasSpan("c", "d", field, "type"));
1786
EXPECT_TRUE(HasSpan("e", "f", field, "name"));
1787
EXPECT_TRUE(HasSpan("e", "f", field, "type_name"));
1788
EXPECT_TRUE(HasSpan("g", "h", field, "number"));
1790
EXPECT_TRUE(HasSpan("a", "k", baz));
1791
EXPECT_TRUE(HasSpan("e", "f", baz, "name"));
1792
EXPECT_TRUE(HasSpan("i", "j", qux));
1795
EXPECT_TRUE(HasSpan(file_));
1796
EXPECT_TRUE(HasSpan(file_.message_type(0)));
1797
EXPECT_TRUE(HasSpan(file_.message_type(0), "name"));
1798
EXPECT_TRUE(HasSpan(bar));
1799
EXPECT_TRUE(HasSpan(bar, "name"));
1800
EXPECT_TRUE(HasSpan(qux, "name"));
1803
TEST_F(SourceInfoTest, Enums) {
1805
"/*a*/enum /*b*/Foo/*c*/ {}/*d*/\n"
1806
"/*e*/enum /*f*/Bar/*g*/ {}/*h*/\n"));
1808
EXPECT_TRUE(HasSpan("a", "d", file_.enum_type(0)));
1809
EXPECT_TRUE(HasSpan("b", "c", file_.enum_type(0), "name"));
1810
EXPECT_TRUE(HasSpan("e", "h", file_.enum_type(1)));
1811
EXPECT_TRUE(HasSpan("f", "g", file_.enum_type(1), "name"));
1814
EXPECT_TRUE(HasSpan(file_));
1817
TEST_F(SourceInfoTest, EnumValues) {
1820
" /*a*/BAR/*b*/ = /*c*/1/*d*/;/*e*/\n"
1821
" /*f*/BAZ/*g*/ = /*h*/2/*i*/;/*j*/\n"
1824
const EnumValueDescriptorProto& bar = file_.enum_type(0).value(0);
1825
const EnumValueDescriptorProto& baz = file_.enum_type(0).value(1);
1827
EXPECT_TRUE(HasSpan("a", "e", bar));
1828
EXPECT_TRUE(HasSpan("a", "b", bar, "name"));
1829
EXPECT_TRUE(HasSpan("c", "d", bar, "number"));
1830
EXPECT_TRUE(HasSpan("f", "j", baz));
1831
EXPECT_TRUE(HasSpan("f", "g", baz, "name"));
1832
EXPECT_TRUE(HasSpan("h", "i", baz, "number"));
1835
EXPECT_TRUE(HasSpan(file_));
1836
EXPECT_TRUE(HasSpan(file_.enum_type(0)));
1837
EXPECT_TRUE(HasSpan(file_.enum_type(0), "name"));
1840
TEST_F(SourceInfoTest, NestedEnums) {
1843
" /*a*/enum /*b*/Bar/*c*/ {}/*d*/\n"
1844
" /*e*/enum /*f*/Baz/*g*/ {}/*h*/\n"
1847
const EnumDescriptorProto& bar = file_.message_type(0).enum_type(0);
1848
const EnumDescriptorProto& baz = file_.message_type(0).enum_type(1);
1850
EXPECT_TRUE(HasSpan("a", "d", bar));
1851
EXPECT_TRUE(HasSpan("b", "c", bar, "name"));
1852
EXPECT_TRUE(HasSpan("e", "h", baz));
1853
EXPECT_TRUE(HasSpan("f", "g", baz, "name"));
1856
EXPECT_TRUE(HasSpan(file_));
1857
EXPECT_TRUE(HasSpan(file_.message_type(0)));
1858
EXPECT_TRUE(HasSpan(file_.message_type(0), "name"));
1861
TEST_F(SourceInfoTest, Services) {
1863
"/*a*/service /*b*/Foo/*c*/ {}/*d*/\n"
1864
"/*e*/service /*f*/Bar/*g*/ {}/*h*/\n"));
1866
EXPECT_TRUE(HasSpan("a", "d", file_.service(0)));
1867
EXPECT_TRUE(HasSpan("b", "c", file_.service(0), "name"));
1868
EXPECT_TRUE(HasSpan("e", "h", file_.service(1)));
1869
EXPECT_TRUE(HasSpan("f", "g", file_.service(1), "name"));
1872
EXPECT_TRUE(HasSpan(file_));
1875
TEST_F(SourceInfoTest, Methods) {
1878
" /*a*/rpc /*b*/Bar/*c*/(/*d*/X/*e*/) returns(/*f*/Y/*g*/);/*h*/"
1879
" /*i*/rpc /*j*/Baz/*k*/(/*l*/Z/*m*/) returns(/*n*/W/*o*/);/*p*/"
1882
const MethodDescriptorProto& bar = file_.service(0).method(0);
1883
const MethodDescriptorProto& baz = file_.service(0).method(1);
1885
EXPECT_TRUE(HasSpan("a", "h", bar));
1886
EXPECT_TRUE(HasSpan("b", "c", bar, "name"));
1887
EXPECT_TRUE(HasSpan("d", "e", bar, "input_type"));
1888
EXPECT_TRUE(HasSpan("f", "g", bar, "output_type"));
1890
EXPECT_TRUE(HasSpan("i", "p", baz));
1891
EXPECT_TRUE(HasSpan("j", "k", baz, "name"));
1892
EXPECT_TRUE(HasSpan("l", "m", baz, "input_type"));
1893
EXPECT_TRUE(HasSpan("n", "o", baz, "output_type"));
1896
EXPECT_TRUE(HasSpan(file_));
1897
EXPECT_TRUE(HasSpan(file_.service(0)));
1898
EXPECT_TRUE(HasSpan(file_.service(0), "name"));
1901
TEST_F(SourceInfoTest, Options) {
1903
"/*a*/option /*b*/foo/*c*/./*d*/(/*e*/bar.baz/*f*/)/*g*/ = "
1904
"/*h*/123/*i*/;/*j*/\n"
1905
"/*k*/option qux = /*l*/-123/*m*/;/*n*/\n"
1906
"/*o*/option corge = /*p*/abc/*q*/;/*r*/\n"
1907
"/*s*/option grault = /*t*/'blah'/*u*/;/*v*/\n"
1908
"/*w*/option garply = /*x*/{ yadda yadda }/*y*/;/*z*/\n"
1909
"/*0*/option waldo = /*1*/123.0/*2*/;/*3*/\n"
1912
const UninterpretedOption& option1 = file_.options().uninterpreted_option(0);
1913
const UninterpretedOption& option2 = file_.options().uninterpreted_option(1);
1914
const UninterpretedOption& option3 = file_.options().uninterpreted_option(2);
1915
const UninterpretedOption& option4 = file_.options().uninterpreted_option(3);
1916
const UninterpretedOption& option5 = file_.options().uninterpreted_option(4);
1917
const UninterpretedOption& option6 = file_.options().uninterpreted_option(5);
1919
EXPECT_TRUE(HasSpan("a", "j", file_.options()));
1920
EXPECT_TRUE(HasSpan("b", "i", option1));
1921
EXPECT_TRUE(HasSpan("b", "g", option1, "name"));
1922
EXPECT_TRUE(HasSpan("b", "c", option1.name(0)));
1923
EXPECT_TRUE(HasSpan("b", "c", option1.name(0), "name_part"));
1924
EXPECT_TRUE(HasSpan("d", "g", option1.name(1)));
1925
EXPECT_TRUE(HasSpan("e", "f", option1.name(1), "name_part"));
1926
EXPECT_TRUE(HasSpan("h", "i", option1, "positive_int_value"));
1928
EXPECT_TRUE(HasSpan("k", "n", file_.options()));
1929
EXPECT_TRUE(HasSpan("l", "m", option2, "negative_int_value"));
1931
EXPECT_TRUE(HasSpan("o", "r", file_.options()));
1932
EXPECT_TRUE(HasSpan("p", "q", option3, "identifier_value"));
1934
EXPECT_TRUE(HasSpan("s", "v", file_.options()));
1935
EXPECT_TRUE(HasSpan("t", "u", option4, "string_value"));
1937
EXPECT_TRUE(HasSpan("w", "z", file_.options()));
1938
EXPECT_TRUE(HasSpan("x", "y", option5, "aggregate_value"));
1940
EXPECT_TRUE(HasSpan("0", "3", file_.options()));
1941
EXPECT_TRUE(HasSpan("1", "2", option6, "double_value"));
1944
EXPECT_TRUE(HasSpan(file_));
1945
EXPECT_TRUE(HasSpan(option2));
1946
EXPECT_TRUE(HasSpan(option3));
1947
EXPECT_TRUE(HasSpan(option4));
1948
EXPECT_TRUE(HasSpan(option5));
1949
EXPECT_TRUE(HasSpan(option6));
1950
EXPECT_TRUE(HasSpan(option2, "name"));
1951
EXPECT_TRUE(HasSpan(option3, "name"));
1952
EXPECT_TRUE(HasSpan(option4, "name"));
1953
EXPECT_TRUE(HasSpan(option5, "name"));
1954
EXPECT_TRUE(HasSpan(option6, "name"));
1955
EXPECT_TRUE(HasSpan(option2.name(0)));
1956
EXPECT_TRUE(HasSpan(option3.name(0)));
1957
EXPECT_TRUE(HasSpan(option4.name(0)));
1958
EXPECT_TRUE(HasSpan(option5.name(0)));
1959
EXPECT_TRUE(HasSpan(option6.name(0)));
1960
EXPECT_TRUE(HasSpan(option2.name(0), "name_part"));
1961
EXPECT_TRUE(HasSpan(option3.name(0), "name_part"));
1962
EXPECT_TRUE(HasSpan(option4.name(0), "name_part"));
1963
EXPECT_TRUE(HasSpan(option5.name(0), "name_part"));
1964
EXPECT_TRUE(HasSpan(option6.name(0), "name_part"));
1967
TEST_F(SourceInfoTest, ScopedOptions) {
1970
" /*a*/option mopt = 1;/*b*/\n"
1973
" /*c*/option eopt = 1;/*d*/\n"
1976
" /*e*/option sopt = 1;/*f*/\n"
1977
" rpc M(X) returns(Y) {\n"
1978
" /*g*/option mopt = 1;/*h*/\n"
1982
EXPECT_TRUE(HasSpan("a", "b", file_.message_type(0).options()));
1983
EXPECT_TRUE(HasSpan("c", "d", file_.enum_type(0).options()));
1984
EXPECT_TRUE(HasSpan("e", "f", file_.service(0).options()));
1985
EXPECT_TRUE(HasSpan("g", "h", file_.service(0).method(0).options()));
1988
EXPECT_TRUE(HasSpan(file_));
1989
EXPECT_TRUE(HasSpan(file_.message_type(0)));
1990
EXPECT_TRUE(HasSpan(file_.message_type(0), "name"));
1991
EXPECT_TRUE(HasSpan(file_.message_type(0).options()
1992
.uninterpreted_option(0)));
1993
EXPECT_TRUE(HasSpan(file_.message_type(0).options()
1994
.uninterpreted_option(0), "name"));
1995
EXPECT_TRUE(HasSpan(file_.message_type(0).options()
1996
.uninterpreted_option(0).name(0)));
1997
EXPECT_TRUE(HasSpan(file_.message_type(0).options()
1998
.uninterpreted_option(0).name(0), "name_part"));
1999
EXPECT_TRUE(HasSpan(file_.message_type(0).options()
2000
.uninterpreted_option(0), "positive_int_value"));
2001
EXPECT_TRUE(HasSpan(file_.enum_type(0)));
2002
EXPECT_TRUE(HasSpan(file_.enum_type(0), "name"));
2003
EXPECT_TRUE(HasSpan(file_.enum_type(0).options()
2004
.uninterpreted_option(0)));
2005
EXPECT_TRUE(HasSpan(file_.enum_type(0).options()
2006
.uninterpreted_option(0), "name"));
2007
EXPECT_TRUE(HasSpan(file_.enum_type(0).options()
2008
.uninterpreted_option(0).name(0)));
2009
EXPECT_TRUE(HasSpan(file_.enum_type(0).options()
2010
.uninterpreted_option(0).name(0), "name_part"));
2011
EXPECT_TRUE(HasSpan(file_.enum_type(0).options()
2012
.uninterpreted_option(0), "positive_int_value"));
2013
EXPECT_TRUE(HasSpan(file_.service(0)));
2014
EXPECT_TRUE(HasSpan(file_.service(0), "name"));
2015
EXPECT_TRUE(HasSpan(file_.service(0).method(0)));
2016
EXPECT_TRUE(HasSpan(file_.service(0).options()
2017
.uninterpreted_option(0)));
2018
EXPECT_TRUE(HasSpan(file_.service(0).options()
2019
.uninterpreted_option(0), "name"));
2020
EXPECT_TRUE(HasSpan(file_.service(0).options()
2021
.uninterpreted_option(0).name(0)));
2022
EXPECT_TRUE(HasSpan(file_.service(0).options()
2023
.uninterpreted_option(0).name(0), "name_part"));
2024
EXPECT_TRUE(HasSpan(file_.service(0).options()
2025
.uninterpreted_option(0), "positive_int_value"));
2026
EXPECT_TRUE(HasSpan(file_.service(0).method(0), "name"));
2027
EXPECT_TRUE(HasSpan(file_.service(0).method(0), "input_type"));
2028
EXPECT_TRUE(HasSpan(file_.service(0).method(0), "output_type"));
2029
EXPECT_TRUE(HasSpan(file_.service(0).method(0).options()
2030
.uninterpreted_option(0)));
2031
EXPECT_TRUE(HasSpan(file_.service(0).method(0).options()
2032
.uninterpreted_option(0), "name"));
2033
EXPECT_TRUE(HasSpan(file_.service(0).method(0).options()
2034
.uninterpreted_option(0).name(0)));
2035
EXPECT_TRUE(HasSpan(file_.service(0).method(0).options()
2036
.uninterpreted_option(0).name(0), "name_part"));
2037
EXPECT_TRUE(HasSpan(file_.service(0).method(0).options()
2038
.uninterpreted_option(0), "positive_int_value"));
2041
TEST_F(SourceInfoTest, FieldOptions) {
2042
// The actual "name = value" pairs are parsed by the same code as for
2043
// top-level options so we won't re-test that -- just make sure that the
2044
// syntax used for field options is understood.
2047
" optional int32 bar = 1 "
2048
"/*a*/[default=/*b*/123/*c*/,/*d*/opt1=123/*e*/,"
2049
"/*f*/opt2='hi'/*g*/]/*h*/;"
2053
const FieldDescriptorProto& field = file_.message_type(0).field(0);
2054
const UninterpretedOption& option1 = field.options().uninterpreted_option(0);
2055
const UninterpretedOption& option2 = field.options().uninterpreted_option(1);
2057
EXPECT_TRUE(HasSpan("a", "h", field.options()));
2058
EXPECT_TRUE(HasSpan("b", "c", field, "default_value"));
2059
EXPECT_TRUE(HasSpan("d", "e", option1));
2060
EXPECT_TRUE(HasSpan("f", "g", option2));
2063
EXPECT_TRUE(HasSpan(file_));
2064
EXPECT_TRUE(HasSpan(file_.message_type(0)));
2065
EXPECT_TRUE(HasSpan(file_.message_type(0), "name"));
2066
EXPECT_TRUE(HasSpan(field));
2067
EXPECT_TRUE(HasSpan(field, "label"));
2068
EXPECT_TRUE(HasSpan(field, "type"));
2069
EXPECT_TRUE(HasSpan(field, "name"));
2070
EXPECT_TRUE(HasSpan(field, "number"));
2071
EXPECT_TRUE(HasSpan(option1, "name"));
2072
EXPECT_TRUE(HasSpan(option2, "name"));
2073
EXPECT_TRUE(HasSpan(option1.name(0)));
2074
EXPECT_TRUE(HasSpan(option2.name(0)));
2075
EXPECT_TRUE(HasSpan(option1.name(0), "name_part"));
2076
EXPECT_TRUE(HasSpan(option2.name(0), "name_part"));
2077
EXPECT_TRUE(HasSpan(option1, "positive_int_value"));
2078
EXPECT_TRUE(HasSpan(option2, "string_value"));
2081
TEST_F(SourceInfoTest, EnumValueOptions) {
2082
// The actual "name = value" pairs are parsed by the same code as for
2083
// top-level options so we won't re-test that -- just make sure that the
2084
// syntax used for enum options is understood.
2087
" BAR = 1 /*a*/[/*b*/opt1=123/*c*/,/*d*/opt2='hi'/*e*/]/*f*/;"
2091
const EnumValueDescriptorProto& value = file_.enum_type(0).value(0);
2092
const UninterpretedOption& option1 = value.options().uninterpreted_option(0);
2093
const UninterpretedOption& option2 = value.options().uninterpreted_option(1);
2095
EXPECT_TRUE(HasSpan("a", "f", value.options()));
2096
EXPECT_TRUE(HasSpan("b", "c", option1));
2097
EXPECT_TRUE(HasSpan("d", "e", option2));
2100
EXPECT_TRUE(HasSpan(file_));
2101
EXPECT_TRUE(HasSpan(file_.enum_type(0)));
2102
EXPECT_TRUE(HasSpan(file_.enum_type(0), "name"));
2103
EXPECT_TRUE(HasSpan(value));
2104
EXPECT_TRUE(HasSpan(value, "name"));
2105
EXPECT_TRUE(HasSpan(value, "number"));
2106
EXPECT_TRUE(HasSpan(option1, "name"));
2107
EXPECT_TRUE(HasSpan(option2, "name"));
2108
EXPECT_TRUE(HasSpan(option1.name(0)));
2109
EXPECT_TRUE(HasSpan(option2.name(0)));
2110
EXPECT_TRUE(HasSpan(option1.name(0), "name_part"));
2111
EXPECT_TRUE(HasSpan(option2.name(0), "name_part"));
2112
EXPECT_TRUE(HasSpan(option1, "positive_int_value"));
2113
EXPECT_TRUE(HasSpan(option2, "string_value"));
2116
// ===================================================================
1252
2118
} // anonymous namespace