1// Protocol Buffers - Google's data interchange format
2// Copyright 2008 Google Inc.  All rights reserved.
3// https://developers.google.com/protocol-buffers/
4//
5// Redistribution and use in source and binary forms, with or without
6// modification, are permitted provided that the following conditions are
7// met:
8//
9//     * Redistributions of source code must retain the above copyright
10// notice, this list of conditions and the following disclaimer.
11//     * Redistributions in binary form must reproduce the above
12// copyright notice, this list of conditions and the following disclaimer
13// in the documentation and/or other materials provided with the
14// distribution.
15//     * Neither the name of Google Inc. nor the names of its
16// contributors may be used to endorse or promote products derived from
17// this software without specific prior written permission.
18//
19// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
31// Author: kenton@google.com (Kenton Varda)
32//  Based on original Protocol Buffers design by
33//  Sanjay Ghemawat, Jeff Dean, and others.
34
35#include <memory>
36#include <vector>
37#include <algorithm>
38#include <map>
39
40#include <google/protobuf/compiler/parser.h>
41
42#include <google/protobuf/io/tokenizer.h>
43#include <google/protobuf/io/zero_copy_stream_impl.h>
44#include <google/protobuf/descriptor.pb.h>
45#include <google/protobuf/wire_format.h>
46#include <google/protobuf/text_format.h>
47#include <google/protobuf/unittest.pb.h>
48#include <google/protobuf/unittest_custom_options.pb.h>
49#include <google/protobuf/stubs/strutil.h>
50#include <google/protobuf/stubs/substitute.h>
51#include <google/protobuf/stubs/map_util.h>
52
53#include <google/protobuf/testing/googletest.h>
54#include <gtest/gtest.h>
55
56namespace google {
57namespace protobuf {
58namespace compiler {
59
60namespace {
61
62class MockErrorCollector : public io::ErrorCollector {
63 public:
64  MockErrorCollector() {}
65  ~MockErrorCollector() {}
66
67  string text_;
68
69  // implements ErrorCollector ---------------------------------------
70  void AddError(int line, int column, const string& message) {
71    strings::SubstituteAndAppend(&text_, "$0:$1: $2\n",
72                                 line, column, message);
73  }
74};
75
76class MockValidationErrorCollector : public DescriptorPool::ErrorCollector {
77 public:
78  MockValidationErrorCollector(const SourceLocationTable& source_locations,
79                               io::ErrorCollector* wrapped_collector)
80    : source_locations_(source_locations),
81      wrapped_collector_(wrapped_collector) {}
82  ~MockValidationErrorCollector() {}
83
84  // implements ErrorCollector ---------------------------------------
85  void AddError(const string& filename,
86                const string& element_name,
87                const Message* descriptor,
88                ErrorLocation location,
89                const string& message) {
90    int line, column;
91    source_locations_.Find(descriptor, location, &line, &column);
92    wrapped_collector_->AddError(line, column, message);
93  }
94
95 private:
96  const SourceLocationTable& source_locations_;
97  io::ErrorCollector* wrapped_collector_;
98};
99
100class ParserTest : public testing::Test {
101 protected:
102  ParserTest()
103    : require_syntax_identifier_(false) {}
104
105  // Set up the parser to parse the given text.
106  void SetupParser(const char* text) {
107    raw_input_.reset(new io::ArrayInputStream(text, strlen(text)));
108    input_.reset(new io::Tokenizer(raw_input_.get(), &error_collector_));
109    parser_.reset(new Parser());
110    parser_->RecordErrorsTo(&error_collector_);
111    parser_->SetRequireSyntaxIdentifier(require_syntax_identifier_);
112  }
113
114  // Parse the input and expect that the resulting FileDescriptorProto matches
115  // the given output.  The output is a FileDescriptorProto in protocol buffer
116  // text format.
117  void ExpectParsesTo(const char* input, const char* output) {
118    SetupParser(input);
119    FileDescriptorProto actual, expected;
120
121    parser_->Parse(input_.get(), &actual);
122    EXPECT_EQ(io::Tokenizer::TYPE_END, input_->current().type);
123    ASSERT_EQ("", error_collector_.text_);
124
125    // We don't cover SourceCodeInfo in these tests.
126    actual.clear_source_code_info();
127
128    // Parse the ASCII representation in order to canonicalize it.  We could
129    // just compare directly to actual.DebugString(), but that would require
130    // that the caller precisely match the formatting that DebugString()
131    // produces.
132    ASSERT_TRUE(TextFormat::ParseFromString(output, &expected));
133
134    // Compare by comparing debug strings.
135    // TODO(kenton):  Use differencer, once it is available.
136    EXPECT_EQ(expected.DebugString(), actual.DebugString());
137  }
138
139  // Parse the text and expect that the given errors are reported.
140  void ExpectHasErrors(const char* text, const char* expected_errors) {
141    ExpectHasEarlyExitErrors(text, expected_errors);
142    EXPECT_EQ(io::Tokenizer::TYPE_END, input_->current().type);
143  }
144
145  // Same as above but does not expect that the parser parses the complete
146  // input.
147  void ExpectHasEarlyExitErrors(const char* text, const char* expected_errors) {
148    SetupParser(text);
149    FileDescriptorProto file;
150    parser_->Parse(input_.get(), &file);
151    EXPECT_EQ(expected_errors, error_collector_.text_);
152  }
153
154  // Parse the text as a file and validate it (with a DescriptorPool), and
155  // expect that the validation step reports the given errors.
156  void ExpectHasValidationErrors(const char* text,
157                                 const char* expected_errors) {
158    SetupParser(text);
159    SourceLocationTable source_locations;
160    parser_->RecordSourceLocationsTo(&source_locations);
161
162    FileDescriptorProto file;
163    file.set_name("foo.proto");
164    parser_->Parse(input_.get(), &file);
165    EXPECT_EQ(io::Tokenizer::TYPE_END, input_->current().type);
166    ASSERT_EQ("", error_collector_.text_);
167
168    MockValidationErrorCollector validation_error_collector(
169      source_locations, &error_collector_);
170    EXPECT_TRUE(pool_.BuildFileCollectingErrors(
171      file, &validation_error_collector) == NULL);
172    EXPECT_EQ(expected_errors, error_collector_.text_);
173  }
174
175  MockErrorCollector error_collector_;
176  DescriptorPool pool_;
177
178  scoped_ptr<io::ZeroCopyInputStream> raw_input_;
179  scoped_ptr<io::Tokenizer> input_;
180  scoped_ptr<Parser> parser_;
181  bool require_syntax_identifier_;
182};
183
184// ===================================================================
185
186TEST_F(ParserTest, StopAfterSyntaxIdentifier) {
187  SetupParser(
188    "// blah\n"
189    "syntax = \"foobar\";\n"
190    "this line will not be parsed\n");
191  parser_->SetStopAfterSyntaxIdentifier(true);
192  EXPECT_TRUE(parser_->Parse(input_.get(), NULL));
193  EXPECT_EQ("", error_collector_.text_);
194  EXPECT_EQ("foobar", parser_->GetSyntaxIdentifier());
195}
196
197TEST_F(ParserTest, StopAfterOmittedSyntaxIdentifier) {
198  SetupParser(
199    "// blah\n"
200    "this line will not be parsed\n");
201  parser_->SetStopAfterSyntaxIdentifier(true);
202  EXPECT_TRUE(parser_->Parse(input_.get(), NULL));
203  EXPECT_EQ("", error_collector_.text_);
204  EXPECT_EQ("", parser_->GetSyntaxIdentifier());
205}
206
207TEST_F(ParserTest, StopAfterSyntaxIdentifierWithErrors) {
208  SetupParser(
209    "// blah\n"
210    "syntax = error;\n");
211  parser_->SetStopAfterSyntaxIdentifier(true);
212  EXPECT_FALSE(parser_->Parse(input_.get(), NULL));
213  EXPECT_EQ("1:9: Expected syntax identifier.\n", error_collector_.text_);
214}
215
216// ===================================================================
217
218typedef ParserTest ParseMessageTest;
219
220TEST_F(ParseMessageTest, SimpleMessage) {
221  ExpectParsesTo(
222    "message TestMessage {\n"
223    "  required int32 foo = 1;\n"
224    "}\n",
225
226    "message_type {"
227    "  name: \"TestMessage\""
228    "  field { name:\"foo\" label:LABEL_REQUIRED type:TYPE_INT32 number:1 }"
229    "}");
230}
231
232TEST_F(ParseMessageTest, ImplicitSyntaxIdentifier) {
233  require_syntax_identifier_ = false;
234  ExpectParsesTo(
235    "message TestMessage {\n"
236    "  required int32 foo = 1;\n"
237    "}\n",
238
239    "message_type {"
240    "  name: \"TestMessage\""
241    "  field { name:\"foo\" label:LABEL_REQUIRED type:TYPE_INT32 number:1 }"
242    "}");
243  EXPECT_EQ("proto2", parser_->GetSyntaxIdentifier());
244}
245
246TEST_F(ParseMessageTest, ExplicitSyntaxIdentifier) {
247  ExpectParsesTo(
248    "syntax = \"proto2\";\n"
249    "message TestMessage {\n"
250    "  required int32 foo = 1;\n"
251    "}\n",
252
253    "message_type {"
254    "  name: \"TestMessage\""
255    "  field { name:\"foo\" label:LABEL_REQUIRED type:TYPE_INT32 number:1 }"
256    "}");
257  EXPECT_EQ("proto2", parser_->GetSyntaxIdentifier());
258}
259
260TEST_F(ParseMessageTest, ExplicitRequiredSyntaxIdentifier) {
261  require_syntax_identifier_ = true;
262  ExpectParsesTo(
263    "syntax = \"proto2\";\n"
264    "message TestMessage {\n"
265    "  required int32 foo = 1;\n"
266    "}\n",
267
268    "message_type {"
269    "  name: \"TestMessage\""
270    "  field { name:\"foo\" label:LABEL_REQUIRED type:TYPE_INT32 number:1 }"
271    "}");
272  EXPECT_EQ("proto2", parser_->GetSyntaxIdentifier());
273}
274
275TEST_F(ParseMessageTest, SimpleFields) {
276  ExpectParsesTo(
277    "message TestMessage {\n"
278    "  required int32 foo = 15;\n"
279    "  optional int32 bar = 34;\n"
280    "  repeated int32 baz = 3;\n"
281    "}\n",
282
283    "message_type {"
284    "  name: \"TestMessage\""
285    "  field { name:\"foo\" label:LABEL_REQUIRED type:TYPE_INT32 number:15 }"
286    "  field { name:\"bar\" label:LABEL_OPTIONAL type:TYPE_INT32 number:34 }"
287    "  field { name:\"baz\" label:LABEL_REPEATED type:TYPE_INT32 number:3  }"
288    "}");
289}
290
291TEST_F(ParseMessageTest, PrimitiveFieldTypes) {
292  ExpectParsesTo(
293    "message TestMessage {\n"
294    "  required int32    foo = 1;\n"
295    "  required int64    foo = 1;\n"
296    "  required uint32   foo = 1;\n"
297    "  required uint64   foo = 1;\n"
298    "  required sint32   foo = 1;\n"
299    "  required sint64   foo = 1;\n"
300    "  required fixed32  foo = 1;\n"
301    "  required fixed64  foo = 1;\n"
302    "  required sfixed32 foo = 1;\n"
303    "  required sfixed64 foo = 1;\n"
304    "  required float    foo = 1;\n"
305    "  required double   foo = 1;\n"
306    "  required string   foo = 1;\n"
307    "  required bytes    foo = 1;\n"
308    "  required bool     foo = 1;\n"
309    "}\n",
310
311    "message_type {"
312    "  name: \"TestMessage\""
313    "  field { name:\"foo\" label:LABEL_REQUIRED type:TYPE_INT32    number:1 }"
314    "  field { name:\"foo\" label:LABEL_REQUIRED type:TYPE_INT64    number:1 }"
315    "  field { name:\"foo\" label:LABEL_REQUIRED type:TYPE_UINT32   number:1 }"
316    "  field { name:\"foo\" label:LABEL_REQUIRED type:TYPE_UINT64   number:1 }"
317    "  field { name:\"foo\" label:LABEL_REQUIRED type:TYPE_SINT32   number:1 }"
318    "  field { name:\"foo\" label:LABEL_REQUIRED type:TYPE_SINT64   number:1 }"
319    "  field { name:\"foo\" label:LABEL_REQUIRED type:TYPE_FIXED32  number:1 }"
320    "  field { name:\"foo\" label:LABEL_REQUIRED type:TYPE_FIXED64  number:1 }"
321    "  field { name:\"foo\" label:LABEL_REQUIRED type:TYPE_SFIXED32 number:1 }"
322    "  field { name:\"foo\" label:LABEL_REQUIRED type:TYPE_SFIXED64 number:1 }"
323    "  field { name:\"foo\" label:LABEL_REQUIRED type:TYPE_FLOAT    number:1 }"
324    "  field { name:\"foo\" label:LABEL_REQUIRED type:TYPE_DOUBLE   number:1 }"
325    "  field { name:\"foo\" label:LABEL_REQUIRED type:TYPE_STRING   number:1 }"
326    "  field { name:\"foo\" label:LABEL_REQUIRED type:TYPE_BYTES    number:1 }"
327    "  field { name:\"foo\" label:LABEL_REQUIRED type:TYPE_BOOL     number:1 }"
328    "}");
329}
330
331TEST_F(ParseMessageTest, FieldDefaults) {
332  ExpectParsesTo(
333    "message TestMessage {\n"
334    "  required int32  foo = 1 [default=  1  ];\n"
335    "  required int32  foo = 1 [default= -2  ];\n"
336    "  required int64  foo = 1 [default=  3  ];\n"
337    "  required int64  foo = 1 [default= -4  ];\n"
338    "  required uint32 foo = 1 [default=  5  ];\n"
339    "  required uint64 foo = 1 [default=  6  ];\n"
340    "  required float  foo = 1 [default=  7.5];\n"
341    "  required float  foo = 1 [default= -8.5];\n"
342    "  required float  foo = 1 [default=  9  ];\n"
343    "  required double foo = 1 [default= 10.5];\n"
344    "  required double foo = 1 [default=-11.5];\n"
345    "  required double foo = 1 [default= 12  ];\n"
346    "  required double foo = 1 [default= inf ];\n"
347    "  required double foo = 1 [default=-inf ];\n"
348    "  required double foo = 1 [default= nan ];\n"
349    "  required string foo = 1 [default='13\\001'];\n"
350    "  required string foo = 1 [default='a' \"b\" \n \"c\"];\n"
351    "  required bytes  foo = 1 [default='14\\002'];\n"
352    "  required bytes  foo = 1 [default='a' \"b\" \n 'c'];\n"
353    "  required bool   foo = 1 [default=true ];\n"
354    "  required Foo    foo = 1 [default=FOO  ];\n"
355
356    "  required int32  foo = 1 [default= 0x7FFFFFFF];\n"
357    "  required int32  foo = 1 [default=-0x80000000];\n"
358    "  required uint32 foo = 1 [default= 0xFFFFFFFF];\n"
359    "  required int64  foo = 1 [default= 0x7FFFFFFFFFFFFFFF];\n"
360    "  required int64  foo = 1 [default=-0x8000000000000000];\n"
361    "  required uint64 foo = 1 [default= 0xFFFFFFFFFFFFFFFF];\n"
362    "  required double foo = 1 [default= 0xabcd];\n"
363    "}\n",
364
365#define ETC "name:\"foo\" label:LABEL_REQUIRED number:1"
366    "message_type {"
367    "  name: \"TestMessage\""
368    "  field { type:TYPE_INT32   default_value:\"1\"         "ETC" }"
369    "  field { type:TYPE_INT32   default_value:\"-2\"        "ETC" }"
370    "  field { type:TYPE_INT64   default_value:\"3\"         "ETC" }"
371    "  field { type:TYPE_INT64   default_value:\"-4\"        "ETC" }"
372    "  field { type:TYPE_UINT32  default_value:\"5\"         "ETC" }"
373    "  field { type:TYPE_UINT64  default_value:\"6\"         "ETC" }"
374    "  field { type:TYPE_FLOAT   default_value:\"7.5\"       "ETC" }"
375    "  field { type:TYPE_FLOAT   default_value:\"-8.5\"      "ETC" }"
376    "  field { type:TYPE_FLOAT   default_value:\"9\"         "ETC" }"
377    "  field { type:TYPE_DOUBLE  default_value:\"10.5\"      "ETC" }"
378    "  field { type:TYPE_DOUBLE  default_value:\"-11.5\"     "ETC" }"
379    "  field { type:TYPE_DOUBLE  default_value:\"12\"        "ETC" }"
380    "  field { type:TYPE_DOUBLE  default_value:\"inf\"       "ETC" }"
381    "  field { type:TYPE_DOUBLE  default_value:\"-inf\"      "ETC" }"
382    "  field { type:TYPE_DOUBLE  default_value:\"nan\"       "ETC" }"
383    "  field { type:TYPE_STRING  default_value:\"13\\001\"   "ETC" }"
384    "  field { type:TYPE_STRING  default_value:\"abc\"       "ETC" }"
385    "  field { type:TYPE_BYTES   default_value:\"14\\\\002\" "ETC" }"
386    "  field { type:TYPE_BYTES   default_value:\"abc\"       "ETC" }"
387    "  field { type:TYPE_BOOL    default_value:\"true\"      "ETC" }"
388    "  field { type_name:\"Foo\" default_value:\"FOO\"       "ETC" }"
389
390    "  field { type:TYPE_INT32   default_value:\"2147483647\"           "ETC" }"
391    "  field { type:TYPE_INT32   default_value:\"-2147483648\"          "ETC" }"
392    "  field { type:TYPE_UINT32  default_value:\"4294967295\"           "ETC" }"
393    "  field { type:TYPE_INT64   default_value:\"9223372036854775807\"  "ETC" }"
394    "  field { type:TYPE_INT64   default_value:\"-9223372036854775808\" "ETC" }"
395    "  field { type:TYPE_UINT64  default_value:\"18446744073709551615\" "ETC" }"
396    "  field { type:TYPE_DOUBLE  default_value:\"43981\"                "ETC" }"
397    "}");
398#undef ETC
399}
400
401TEST_F(ParseMessageTest, FieldOptions) {
402  ExpectParsesTo(
403    "message TestMessage {\n"
404    "  optional string foo = 1\n"
405    "      [ctype=CORD, (foo)=7, foo.(.bar.baz).qux.quux.(corge)=-33, \n"
406    "       (quux)=\"x\040y\", (baz.qux)=hey];\n"
407    "}\n",
408
409    "message_type {"
410    "  name: \"TestMessage\""
411    "  field { name: \"foo\" label: LABEL_OPTIONAL type: TYPE_STRING number: 1"
412    "          options { uninterpreted_option: { name { name_part: \"ctype\" "
413    "                                                   is_extension: false } "
414    "                                            identifier_value: \"CORD\"  }"
415    "                    uninterpreted_option: { name { name_part: \"foo\" "
416    "                                                   is_extension: true } "
417    "                                            positive_int_value: 7  }"
418    "                    uninterpreted_option: { name { name_part: \"foo\" "
419    "                                                   is_extension: false } "
420    "                                            name { name_part: \".bar.baz\""
421    "                                                   is_extension: true } "
422    "                                            name { name_part: \"qux\" "
423    "                                                   is_extension: false } "
424    "                                            name { name_part: \"quux\" "
425    "                                                   is_extension: false } "
426    "                                            name { name_part: \"corge\" "
427    "                                                   is_extension: true } "
428    "                                            negative_int_value: -33 }"
429    "                    uninterpreted_option: { name { name_part: \"quux\" "
430    "                                                   is_extension: true } "
431    "                                            string_value: \"x y\" }"
432    "                    uninterpreted_option: { name { name_part: \"baz.qux\" "
433    "                                                   is_extension: true } "
434    "                                            identifier_value: \"hey\" }"
435    "          }"
436    "  }"
437    "}");
438}
439
440TEST_F(ParseMessageTest, Oneof) {
441  ExpectParsesTo(
442    "message TestMessage {\n"
443    "  oneof foo {\n"
444    "    int32 a = 1;\n"
445    "    string b = 2;\n"
446    "    TestMessage c = 3;\n"
447    "    group D = 4 { optional int32 i = 5; }\n"
448    "  }\n"
449    "}\n",
450
451    "message_type {"
452    "  name: \"TestMessage\""
453    "  field { name:\"a\" label:LABEL_OPTIONAL type:TYPE_INT32 number:1 "
454    "          oneof_index:0 }"
455    "  field { name:\"b\" label:LABEL_OPTIONAL type:TYPE_STRING number:2 "
456    "          oneof_index:0 }"
457    "  field { name:\"c\" label:LABEL_OPTIONAL type_name:\"TestMessage\" "
458    "          number:3 oneof_index:0 }"
459    "  field { name:\"d\" label:LABEL_OPTIONAL type:TYPE_GROUP "
460    "          type_name:\"D\" number:4 oneof_index:0 }"
461    "  oneof_decl {"
462    "    name: \"foo\""
463    "  }"
464    "  nested_type {"
465    "    name: \"D\""
466    "    field { name:\"i\" label:LABEL_OPTIONAL type:TYPE_INT32 number:5 }"
467    "  }"
468    "}");
469}
470
471TEST_F(ParseMessageTest, MultipleOneofs) {
472  ExpectParsesTo(
473    "message TestMessage {\n"
474    "  oneof foo {\n"
475    "    int32 a = 1;\n"
476    "    string b = 2;\n"
477    "  }\n"
478    "  oneof bar {\n"
479    "    int32 c = 3;\n"
480    "    string d = 4;\n"
481    "  }\n"
482    "}\n",
483
484    "message_type {"
485    "  name: \"TestMessage\""
486    "  field { name:\"a\" label:LABEL_OPTIONAL type:TYPE_INT32 number:1 "
487    "          oneof_index:0 }"
488    "  field { name:\"b\" label:LABEL_OPTIONAL type:TYPE_STRING number:2 "
489    "          oneof_index:0 }"
490    "  field { name:\"c\" label:LABEL_OPTIONAL type:TYPE_INT32 number:3 "
491    "          oneof_index:1 }"
492    "  field { name:\"d\" label:LABEL_OPTIONAL type:TYPE_STRING number:4 "
493    "          oneof_index:1 }"
494    "  oneof_decl {"
495    "    name: \"foo\""
496    "  }"
497    "  oneof_decl {"
498    "    name: \"bar\""
499    "  }"
500    "}");
501}
502
503TEST_F(ParseMessageTest, Group) {
504  ExpectParsesTo(
505    "message TestMessage {\n"
506    "  optional group TestGroup = 1 {};\n"
507    "}\n",
508
509    "message_type {"
510    "  name: \"TestMessage\""
511    "  nested_type { name: \"TestGroup\" }"
512    "  field { name:\"testgroup\" label:LABEL_OPTIONAL number:1"
513    "          type:TYPE_GROUP type_name: \"TestGroup\" }"
514    "}");
515}
516
517TEST_F(ParseMessageTest, NestedMessage) {
518  ExpectParsesTo(
519    "message TestMessage {\n"
520    "  message Nested {}\n"
521    "  optional Nested test_nested = 1;\n"
522    "}\n",
523
524    "message_type {"
525    "  name: \"TestMessage\""
526    "  nested_type { name: \"Nested\" }"
527    "  field { name:\"test_nested\" label:LABEL_OPTIONAL number:1"
528    "          type_name: \"Nested\" }"
529    "}");
530}
531
532TEST_F(ParseMessageTest, NestedEnum) {
533  ExpectParsesTo(
534    "message TestMessage {\n"
535    "  enum NestedEnum {}\n"
536    "  optional NestedEnum test_enum = 1;\n"
537    "}\n",
538
539    "message_type {"
540    "  name: \"TestMessage\""
541    "  enum_type { name: \"NestedEnum\" }"
542    "  field { name:\"test_enum\" label:LABEL_OPTIONAL number:1"
543    "          type_name: \"NestedEnum\" }"
544    "}");
545}
546
547TEST_F(ParseMessageTest, ExtensionRange) {
548  ExpectParsesTo(
549    "message TestMessage {\n"
550    "  extensions 10 to 19;\n"
551    "  extensions 30 to max;\n"
552    "}\n",
553
554    "message_type {"
555    "  name: \"TestMessage\""
556    "  extension_range { start:10 end:20        }"
557    "  extension_range { start:30 end:536870912 }"
558    "}");
559}
560
561TEST_F(ParseMessageTest, CompoundExtensionRange) {
562  ExpectParsesTo(
563    "message TestMessage {\n"
564    "  extensions 2, 15, 9 to 11, 100 to max, 3;\n"
565    "}\n",
566
567    "message_type {"
568    "  name: \"TestMessage\""
569    "  extension_range { start:2   end:3         }"
570    "  extension_range { start:15  end:16        }"
571    "  extension_range { start:9   end:12        }"
572    "  extension_range { start:100 end:536870912 }"
573    "  extension_range { start:3   end:4         }"
574    "}");
575}
576
577TEST_F(ParseMessageTest, LargerMaxForMessageSetWireFormatMessages) {
578  // Messages using the message_set_wire_format option can accept larger
579  // extension numbers, as the numbers are not encoded as int32 field values
580  // rather than tags.
581  ExpectParsesTo(
582    "message TestMessage {\n"
583    "  extensions 4 to max;\n"
584    "  option message_set_wire_format = true;\n"
585    "}\n",
586
587    "message_type {"
588    "  name: \"TestMessage\""
589    "    extension_range { start:4 end: 0x7fffffff }"
590    "  options {\n"
591    "    uninterpreted_option { \n"
592    "      name {\n"
593    "        name_part: \"message_set_wire_format\"\n"
594    "        is_extension: false\n"
595    "      }\n"
596    "      identifier_value: \"true\"\n"
597    "    }\n"
598    "  }\n"
599    "}");
600}
601
602TEST_F(ParseMessageTest, Extensions) {
603  ExpectParsesTo(
604    "extend Extendee1 { optional int32 foo = 12; }\n"
605    "extend Extendee2 { repeated TestMessage bar = 22; }\n",
606
607    "extension { name:\"foo\" label:LABEL_OPTIONAL type:TYPE_INT32 number:12"
608    "            extendee: \"Extendee1\" } "
609    "extension { name:\"bar\" label:LABEL_REPEATED number:22"
610    "            type_name:\"TestMessage\" extendee: \"Extendee2\" }");
611}
612
613TEST_F(ParseMessageTest, ExtensionsInMessageScope) {
614  ExpectParsesTo(
615    "message TestMessage {\n"
616    "  extend Extendee1 { optional int32 foo = 12; }\n"
617    "  extend Extendee2 { repeated TestMessage bar = 22; }\n"
618    "}\n",
619
620    "message_type {"
621    "  name: \"TestMessage\""
622    "  extension { name:\"foo\" label:LABEL_OPTIONAL type:TYPE_INT32 number:12"
623    "              extendee: \"Extendee1\" }"
624    "  extension { name:\"bar\" label:LABEL_REPEATED number:22"
625    "              type_name:\"TestMessage\" extendee: \"Extendee2\" }"
626    "}");
627}
628
629TEST_F(ParseMessageTest, MultipleExtensionsOneExtendee) {
630  ExpectParsesTo(
631    "extend Extendee1 {\n"
632    "  optional int32 foo = 12;\n"
633    "  repeated TestMessage bar = 22;\n"
634    "}\n",
635
636    "extension { name:\"foo\" label:LABEL_OPTIONAL type:TYPE_INT32 number:12"
637    "            extendee: \"Extendee1\" } "
638    "extension { name:\"bar\" label:LABEL_REPEATED number:22"
639    "            type_name:\"TestMessage\" extendee: \"Extendee1\" }");
640}
641
642
643// ===================================================================
644
645typedef ParserTest ParseEnumTest;
646
647TEST_F(ParseEnumTest, SimpleEnum) {
648  ExpectParsesTo(
649    "enum TestEnum {\n"
650    "  FOO = 0;\n"
651    "}\n",
652
653    "enum_type {"
654    "  name: \"TestEnum\""
655    "  value { name:\"FOO\" number:0 }"
656    "}");
657}
658
659TEST_F(ParseEnumTest, Values) {
660  ExpectParsesTo(
661    "enum TestEnum {\n"
662    "  FOO = 13;\n"
663    "  BAR = -10;\n"
664    "  BAZ = 500;\n"
665    "  HEX_MAX = 0x7FFFFFFF;\n"
666    "  HEX_MIN = -0x80000000;\n"
667    "  INT_MAX = 2147483647;\n"
668    "  INT_MIN = -2147483648;\n"
669    "}\n",
670
671    "enum_type {"
672    "  name: \"TestEnum\""
673    "  value { name:\"FOO\" number:13 }"
674    "  value { name:\"BAR\" number:-10 }"
675    "  value { name:\"BAZ\" number:500 }"
676    "  value { name:\"HEX_MAX\" number:2147483647 }"
677    "  value { name:\"HEX_MIN\" number:-2147483648 }"
678    "  value { name:\"INT_MAX\" number:2147483647 }"
679    "  value { name:\"INT_MIN\" number:-2147483648 }"
680    "}");
681}
682
683TEST_F(ParseEnumTest, ValueOptions) {
684  ExpectParsesTo(
685    "enum TestEnum {\n"
686    "  FOO = 13;\n"
687    "  BAR = -10 [ (something.text) = 'abc' ];\n"
688    "  BAZ = 500 [ (something.text) = 'def', other = 1 ];\n"
689    "}\n",
690
691    "enum_type {"
692    "  name: \"TestEnum\""
693    "  value { name: \"FOO\" number: 13 }"
694    "  value { name: \"BAR\" number: -10 "
695    "    options { "
696    "      uninterpreted_option { "
697    "        name { name_part: \"something.text\" is_extension: true } "
698    "        string_value: \"abc\" "
699    "      } "
700    "    } "
701    "  } "
702    "  value { name: \"BAZ\" number: 500 "
703    "    options { "
704    "      uninterpreted_option { "
705    "        name { name_part: \"something.text\" is_extension: true } "
706    "        string_value: \"def\" "
707    "      } "
708    "      uninterpreted_option { "
709    "        name { name_part: \"other\" is_extension: false } "
710    "        positive_int_value: 1 "
711    "      } "
712    "    } "
713    "  } "
714    "}");
715}
716
717// ===================================================================
718
719typedef ParserTest ParseServiceTest;
720
721TEST_F(ParseServiceTest, SimpleService) {
722  ExpectParsesTo(
723    "service TestService {\n"
724    "  rpc Foo(In) returns (Out);\n"
725    "}\n",
726
727    "service {"
728    "  name: \"TestService\""
729    "  method { name:\"Foo\" input_type:\"In\" output_type:\"Out\" }"
730    "}");
731}
732
733TEST_F(ParseServiceTest, MethodsAndStreams) {
734  ExpectParsesTo(
735    "service TestService {\n"
736    "  rpc Foo(In1) returns (Out1);\n"
737    "  rpc Bar(In2) returns (Out2);\n"
738    "  rpc Baz(In3) returns (Out3);\n"
739    "}\n",
740
741    "service {"
742    "  name: \"TestService\""
743    "  method { name:\"Foo\" input_type:\"In1\" output_type:\"Out1\" }"
744    "  method { name:\"Bar\" input_type:\"In2\" output_type:\"Out2\" }"
745    "  method { name:\"Baz\" input_type:\"In3\" output_type:\"Out3\" }"
746    "}");
747}
748
749
750
751// ===================================================================
752// imports and packages
753
754typedef ParserTest ParseMiscTest;
755
756TEST_F(ParseMiscTest, ParseImport) {
757  ExpectParsesTo(
758    "import \"foo/bar/baz.proto\";\n",
759    "dependency: \"foo/bar/baz.proto\"");
760}
761
762TEST_F(ParseMiscTest, ParseMultipleImports) {
763  ExpectParsesTo(
764    "import \"foo.proto\";\n"
765    "import \"bar.proto\";\n"
766    "import \"baz.proto\";\n",
767    "dependency: \"foo.proto\""
768    "dependency: \"bar.proto\""
769    "dependency: \"baz.proto\"");
770}
771
772TEST_F(ParseMiscTest, ParsePublicImports) {
773  ExpectParsesTo(
774    "import \"foo.proto\";\n"
775    "import public \"bar.proto\";\n"
776    "import \"baz.proto\";\n"
777    "import public \"qux.proto\";\n",
778    "dependency: \"foo.proto\""
779    "dependency: \"bar.proto\""
780    "dependency: \"baz.proto\""
781    "dependency: \"qux.proto\""
782    "public_dependency: 1 "
783    "public_dependency: 3 ");
784}
785
786TEST_F(ParseMiscTest, ParsePackage) {
787  ExpectParsesTo(
788    "package foo.bar.baz;\n",
789    "package: \"foo.bar.baz\"");
790}
791
792TEST_F(ParseMiscTest, ParsePackageWithSpaces) {
793  ExpectParsesTo(
794    "package foo   .   bar.  \n"
795    "  baz;\n",
796    "package: \"foo.bar.baz\"");
797}
798
799// ===================================================================
800// options
801
802TEST_F(ParseMiscTest, ParseFileOptions) {
803  ExpectParsesTo(
804    "option java_package = \"com.google.foo\";\n"
805    "option optimize_for = CODE_SIZE;",
806
807    "options {"
808    "uninterpreted_option { name { name_part: \"java_package\" "
809    "                              is_extension: false }"
810    "                       string_value: \"com.google.foo\"} "
811    "uninterpreted_option { name { name_part: \"optimize_for\" "
812    "                              is_extension: false }"
813    "                       identifier_value: \"CODE_SIZE\" } "
814    "}");
815}
816
817// ===================================================================
818// Error tests
819//
820// There are a very large number of possible errors that the parser could
821// report, so it's infeasible to test every single one of them.  Instead,
822// we test each unique call to AddError() in parser.h.  This does not mean
823// we are testing every possible error that Parser can generate because
824// each variant of the Consume() helper only counts as one unique call to
825// AddError().
826
827typedef ParserTest ParseErrorTest;
828
829TEST_F(ParseErrorTest, MissingSyntaxIdentifier) {
830  require_syntax_identifier_ = true;
831  ExpectHasEarlyExitErrors(
832    "message TestMessage {}",
833    "0:0: File must begin with 'syntax = \"proto2\";'.\n");
834  EXPECT_EQ("", parser_->GetSyntaxIdentifier());
835}
836
837TEST_F(ParseErrorTest, UnknownSyntaxIdentifier) {
838  ExpectHasEarlyExitErrors(
839    "syntax = \"no_such_syntax\";",
840    "0:9: Unrecognized syntax identifier \"no_such_syntax\".  This parser "
841      "only recognizes \"proto2\".\n");
842  EXPECT_EQ("no_such_syntax", parser_->GetSyntaxIdentifier());
843}
844
845TEST_F(ParseErrorTest, SimpleSyntaxError) {
846  ExpectHasErrors(
847    "message TestMessage @#$ { blah }",
848    "0:20: Expected \"{\".\n");
849  EXPECT_EQ("proto2", parser_->GetSyntaxIdentifier());
850}
851
852TEST_F(ParseErrorTest, ExpectedTopLevel) {
853  ExpectHasErrors(
854    "blah;",
855    "0:0: Expected top-level statement (e.g. \"message\").\n");
856}
857
858TEST_F(ParseErrorTest, UnmatchedCloseBrace) {
859  // This used to cause an infinite loop.  Doh.
860  ExpectHasErrors(
861    "}",
862    "0:0: Expected top-level statement (e.g. \"message\").\n"
863    "0:0: Unmatched \"}\".\n");
864}
865
866// -------------------------------------------------------------------
867// Message errors
868
869TEST_F(ParseErrorTest, MessageMissingName) {
870  ExpectHasErrors(
871    "message {}",
872    "0:8: Expected message name.\n");
873}
874
875TEST_F(ParseErrorTest, MessageMissingBody) {
876  ExpectHasErrors(
877    "message TestMessage;",
878    "0:19: Expected \"{\".\n");
879}
880
881TEST_F(ParseErrorTest, EofInMessage) {
882  ExpectHasErrors(
883    "message TestMessage {",
884    "0:21: Reached end of input in message definition (missing '}').\n");
885}
886
887TEST_F(ParseErrorTest, MissingFieldNumber) {
888  ExpectHasErrors(
889    "message TestMessage {\n"
890    "  optional int32 foo;\n"
891    "}\n",
892    "1:20: Missing field number.\n");
893}
894
895TEST_F(ParseErrorTest, ExpectedFieldNumber) {
896  ExpectHasErrors(
897    "message TestMessage {\n"
898    "  optional int32 foo = ;\n"
899    "}\n",
900    "1:23: Expected field number.\n");
901}
902
903TEST_F(ParseErrorTest, FieldNumberOutOfRange) {
904  ExpectHasErrors(
905    "message TestMessage {\n"
906    "  optional int32 foo = 0x100000000;\n"
907    "}\n",
908    "1:23: Integer out of range.\n");
909}
910
911TEST_F(ParseErrorTest, MissingLabel) {
912  ExpectHasErrors(
913    "message TestMessage {\n"
914    "  int32 foo = 1;\n"
915    "}\n",
916    "1:2: Expected \"required\", \"optional\", or \"repeated\".\n");
917}
918
919TEST_F(ParseErrorTest, ExpectedOptionName) {
920  ExpectHasErrors(
921    "message TestMessage {\n"
922    "  optional uint32 foo = 1 [];\n"
923    "}\n",
924    "1:27: Expected identifier.\n");
925}
926
927TEST_F(ParseErrorTest, NonExtensionOptionNameBeginningWithDot) {
928  ExpectHasErrors(
929    "message TestMessage {\n"
930    "  optional uint32 foo = 1 [.foo=1];\n"
931    "}\n",
932    "1:27: Expected identifier.\n");
933}
934
935TEST_F(ParseErrorTest, DefaultValueTypeMismatch) {
936  ExpectHasErrors(
937    "message TestMessage {\n"
938    "  optional uint32 foo = 1 [default=true];\n"
939    "}\n",
940    "1:35: Expected integer for field default value.\n");
941}
942
943TEST_F(ParseErrorTest, DefaultValueNotBoolean) {
944  ExpectHasErrors(
945    "message TestMessage {\n"
946    "  optional bool foo = 1 [default=blah];\n"
947    "}\n",
948    "1:33: Expected \"true\" or \"false\".\n");
949}
950
951TEST_F(ParseErrorTest, DefaultValueNotString) {
952  ExpectHasErrors(
953    "message TestMessage {\n"
954    "  optional string foo = 1 [default=1];\n"
955    "}\n",
956    "1:35: Expected string for field default value.\n");
957}
958
959TEST_F(ParseErrorTest, DefaultValueUnsignedNegative) {
960  ExpectHasErrors(
961    "message TestMessage {\n"
962    "  optional uint32 foo = 1 [default=-1];\n"
963    "}\n",
964    "1:36: Unsigned field can't have negative default value.\n");
965}
966
967TEST_F(ParseErrorTest, DefaultValueTooLarge) {
968  ExpectHasErrors(
969    "message TestMessage {\n"
970    "  optional int32  foo = 1 [default= 0x80000000];\n"
971    "  optional int32  foo = 1 [default=-0x80000001];\n"
972    "  optional uint32 foo = 1 [default= 0x100000000];\n"
973    "  optional int64  foo = 1 [default= 0x80000000000000000];\n"
974    "  optional int64  foo = 1 [default=-0x80000000000000001];\n"
975    "  optional uint64 foo = 1 [default= 0x100000000000000000];\n"
976    "}\n",
977    "1:36: Integer out of range.\n"
978    "2:36: Integer out of range.\n"
979    "3:36: Integer out of range.\n"
980    "4:36: Integer out of range.\n"
981    "5:36: Integer out of range.\n"
982    "6:36: Integer out of range.\n");
983}
984
985TEST_F(ParseErrorTest, EnumValueOutOfRange) {
986  ExpectHasErrors(
987    "enum TestEnum {\n"
988    "  HEX_TOO_BIG   =  0x80000000;\n"
989    "  HEX_TOO_SMALL = -0x80000001;\n"
990    "  INT_TOO_BIG   =  2147483648;\n"
991    "  INT_TOO_SMALL = -2147483649;\n"
992    "}\n",
993    "1:19: Integer out of range.\n"
994    "2:19: Integer out of range.\n"
995    "3:19: Integer out of range.\n"
996    "4:19: Integer out of range.\n");
997}
998
999TEST_F(ParseErrorTest, DefaultValueMissing) {
1000  ExpectHasErrors(
1001    "message TestMessage {\n"
1002    "  optional uint32 foo = 1 [default=];\n"
1003    "}\n",
1004    "1:35: Expected integer for field default value.\n");
1005}
1006
1007TEST_F(ParseErrorTest, DefaultValueForGroup) {
1008  ExpectHasErrors(
1009    "message TestMessage {\n"
1010    "  optional group Foo = 1 [default=blah] {}\n"
1011    "}\n",
1012    "1:34: Messages can't have default values.\n");
1013}
1014
1015TEST_F(ParseErrorTest, DuplicateDefaultValue) {
1016  ExpectHasErrors(
1017    "message TestMessage {\n"
1018    "  optional uint32 foo = 1 [default=1,default=2];\n"
1019    "}\n",
1020    "1:37: Already set option \"default\".\n");
1021}
1022
1023TEST_F(ParseErrorTest, MissingOneofName) {
1024  ExpectHasErrors(
1025    "message TestMessage {\n"
1026    "  oneof {\n"
1027    "    int32 bar = 1;\n"
1028    "  }\n"
1029    "}\n",
1030    "1:8: Expected oneof name.\n");
1031}
1032
1033TEST_F(ParseErrorTest, LabelInOneof) {
1034  ExpectHasErrors(
1035    "message TestMessage {\n"
1036    "  oneof foo {\n"
1037    "    optional int32 bar = 1;\n"
1038    "  }\n"
1039    "}\n",
1040    "2:4: Fields in oneofs must not have labels (required / optional "
1041      "/ repeated).\n");
1042}
1043
1044TEST_F(ParseErrorTest, GroupNotCapitalized) {
1045  ExpectHasErrors(
1046    "message TestMessage {\n"
1047    "  optional group foo = 1 {}\n"
1048    "}\n",
1049    "1:17: Group names must start with a capital letter.\n");
1050}
1051
1052TEST_F(ParseErrorTest, GroupMissingBody) {
1053  ExpectHasErrors(
1054    "message TestMessage {\n"
1055    "  optional group Foo = 1;\n"
1056    "}\n",
1057    "1:24: Missing group body.\n");
1058}
1059
1060TEST_F(ParseErrorTest, ExtendingPrimitive) {
1061  ExpectHasErrors(
1062    "extend int32 { optional string foo = 4; }\n",
1063    "0:7: Expected message type.\n");
1064}
1065
1066TEST_F(ParseErrorTest, ErrorInExtension) {
1067  ExpectHasErrors(
1068    "message Foo { extensions 100 to 199; }\n"
1069    "extend Foo { optional string foo; }\n",
1070    "1:32: Missing field number.\n");
1071}
1072
1073TEST_F(ParseErrorTest, MultipleParseErrors) {
1074  // When a statement has a parse error, the parser should be able to continue
1075  // parsing at the next statement.
1076  ExpectHasErrors(
1077    "message TestMessage {\n"
1078    "  optional int32 foo;\n"
1079    "  !invalid statement ending in a block { blah blah { blah } blah }\n"
1080    "  optional int32 bar = 3 {}\n"
1081    "}\n",
1082    "1:20: Missing field number.\n"
1083    "2:2: Expected \"required\", \"optional\", or \"repeated\".\n"
1084    "2:2: Expected type name.\n"
1085    "3:25: Expected \";\".\n");
1086}
1087
1088TEST_F(ParseErrorTest, EofInAggregateValue) {
1089  ExpectHasErrors(
1090      "option (fileopt) = { i:100\n",
1091      "1:0: Unexpected end of stream while parsing aggregate value.\n");
1092}
1093
1094// -------------------------------------------------------------------
1095// Enum errors
1096
1097TEST_F(ParseErrorTest, EofInEnum) {
1098  ExpectHasErrors(
1099    "enum TestEnum {",
1100    "0:15: Reached end of input in enum definition (missing '}').\n");
1101}
1102
1103TEST_F(ParseErrorTest, EnumValueMissingNumber) {
1104  ExpectHasErrors(
1105    "enum TestEnum {\n"
1106    "  FOO;\n"
1107    "}\n",
1108    "1:5: Missing numeric value for enum constant.\n");
1109}
1110
1111// -------------------------------------------------------------------
1112// Service errors
1113
1114TEST_F(ParseErrorTest, EofInService) {
1115  ExpectHasErrors(
1116    "service TestService {",
1117    "0:21: Reached end of input in service definition (missing '}').\n");
1118}
1119
1120TEST_F(ParseErrorTest, ServiceMethodPrimitiveParams) {
1121  ExpectHasErrors(
1122    "service TestService {\n"
1123    "  rpc Foo(int32) returns (string);\n"
1124    "}\n",
1125    "1:10: Expected message type.\n"
1126    "1:26: Expected message type.\n");
1127}
1128
1129
1130TEST_F(ParseErrorTest, EofInMethodOptions) {
1131  ExpectHasErrors(
1132    "service TestService {\n"
1133    "  rpc Foo(Bar) returns(Bar) {",
1134    "1:29: Reached end of input in method options (missing '}').\n"
1135    "1:29: Reached end of input in service definition (missing '}').\n");
1136}
1137
1138
1139TEST_F(ParseErrorTest, PrimitiveMethodInput) {
1140  ExpectHasErrors(
1141    "service TestService {\n"
1142    "  rpc Foo(int32) returns(Bar);\n"
1143    "}\n",
1144    "1:10: Expected message type.\n");
1145}
1146
1147
1148TEST_F(ParseErrorTest, MethodOptionTypeError) {
1149  // This used to cause an infinite loop.
1150  ExpectHasErrors(
1151    "message Baz {}\n"
1152    "service Foo {\n"
1153    "  rpc Bar(Baz) returns(Baz) { option invalid syntax; }\n"
1154    "}\n",
1155    "2:45: Expected \"=\".\n");
1156}
1157
1158
1159// -------------------------------------------------------------------
1160// Import and package errors
1161
1162TEST_F(ParseErrorTest, ImportNotQuoted) {
1163  ExpectHasErrors(
1164    "import foo;\n",
1165    "0:7: Expected a string naming the file to import.\n");
1166}
1167
1168TEST_F(ParseErrorTest, MultiplePackagesInFile) {
1169  ExpectHasErrors(
1170    "package foo;\n"
1171    "package bar;\n",
1172    "1:0: Multiple package definitions.\n");
1173}
1174
1175// ===================================================================
1176// Test that errors detected by DescriptorPool correctly report line and
1177// column numbers.  We have one test for every call to RecordLocation() in
1178// parser.cc.
1179
1180typedef ParserTest ParserValidationErrorTest;
1181
1182TEST_F(ParserValidationErrorTest, PackageNameError) {
1183  // Create another file which defines symbol "foo".
1184  FileDescriptorProto other_file;
1185  other_file.set_name("bar.proto");
1186  other_file.add_message_type()->set_name("foo");
1187  EXPECT_TRUE(pool_.BuildFile(other_file) != NULL);
1188
1189  // Now try to define it as a package.
1190  ExpectHasValidationErrors(
1191    "package foo.bar;",
1192    "0:8: \"foo\" is already defined (as something other than a package) "
1193      "in file \"bar.proto\".\n");
1194}
1195
1196TEST_F(ParserValidationErrorTest, MessageNameError) {
1197  ExpectHasValidationErrors(
1198    "message Foo {}\n"
1199    "message Foo {}\n",
1200    "1:8: \"Foo\" is already defined.\n");
1201}
1202
1203TEST_F(ParserValidationErrorTest, FieldNameError) {
1204  ExpectHasValidationErrors(
1205    "message Foo {\n"
1206    "  optional int32 bar = 1;\n"
1207    "  optional int32 bar = 2;\n"
1208    "}\n",
1209    "2:17: \"bar\" is already defined in \"Foo\".\n");
1210}
1211
1212TEST_F(ParserValidationErrorTest, FieldTypeError) {
1213  ExpectHasValidationErrors(
1214    "message Foo {\n"
1215    "  optional Baz bar = 1;\n"
1216    "}\n",
1217    "1:11: \"Baz\" is not defined.\n");
1218}
1219
1220TEST_F(ParserValidationErrorTest, FieldNumberError) {
1221  ExpectHasValidationErrors(
1222    "message Foo {\n"
1223    "  optional int32 bar = 0;\n"
1224    "}\n",
1225    "1:23: Field numbers must be positive integers.\n");
1226}
1227
1228TEST_F(ParserValidationErrorTest, FieldExtendeeError) {
1229  ExpectHasValidationErrors(
1230    "extend Baz { optional int32 bar = 1; }\n",
1231    "0:7: \"Baz\" is not defined.\n");
1232}
1233
1234TEST_F(ParserValidationErrorTest, FieldDefaultValueError) {
1235  ExpectHasValidationErrors(
1236    "enum Baz { QUX = 1; }\n"
1237    "message Foo {\n"
1238    "  optional Baz bar = 1 [default=NO_SUCH_VALUE];\n"
1239    "}\n",
1240    "2:32: Enum type \"Baz\" has no value named \"NO_SUCH_VALUE\".\n");
1241}
1242
1243TEST_F(ParserValidationErrorTest, FileOptionNameError) {
1244  ExpectHasValidationErrors(
1245    "option foo = 5;",
1246    "0:7: Option \"foo\" unknown.\n");
1247}
1248
1249TEST_F(ParserValidationErrorTest, FileOptionValueError) {
1250  ExpectHasValidationErrors(
1251    "option java_outer_classname = 5;",
1252    "0:30: Value must be quoted string for string option "
1253    "\"google.protobuf.FileOptions.java_outer_classname\".\n");
1254}
1255
1256TEST_F(ParserValidationErrorTest, FieldOptionNameError) {
1257  ExpectHasValidationErrors(
1258    "message Foo {\n"
1259    "  optional bool bar = 1 [foo=1];\n"
1260    "}\n",
1261    "1:25: Option \"foo\" unknown.\n");
1262}
1263
1264TEST_F(ParserValidationErrorTest, FieldOptionValueError) {
1265  ExpectHasValidationErrors(
1266    "message Foo {\n"
1267    "  optional int32 bar = 1 [ctype=1];\n"
1268    "}\n",
1269    "1:32: Value must be identifier for enum-valued option "
1270    "\"google.protobuf.FieldOptions.ctype\".\n");
1271}
1272
1273TEST_F(ParserValidationErrorTest, ExtensionRangeNumberError) {
1274  ExpectHasValidationErrors(
1275    "message Foo {\n"
1276    "  extensions 0;\n"
1277    "}\n",
1278    "1:13: Extension numbers must be positive integers.\n");
1279}
1280
1281TEST_F(ParserValidationErrorTest, EnumNameError) {
1282  ExpectHasValidationErrors(
1283    "enum Foo {A = 1;}\n"
1284    "enum Foo {B = 1;}\n",
1285    "1:5: \"Foo\" is already defined.\n");
1286}
1287
1288TEST_F(ParserValidationErrorTest, EnumValueNameError) {
1289  ExpectHasValidationErrors(
1290    "enum Foo {\n"
1291    "  BAR = 1;\n"
1292    "  BAR = 1;\n"
1293    "}\n",
1294    "2:2: \"BAR\" is already defined.\n");
1295}
1296
1297TEST_F(ParserValidationErrorTest, ServiceNameError) {
1298  ExpectHasValidationErrors(
1299    "service Foo {}\n"
1300    "service Foo {}\n",
1301    "1:8: \"Foo\" is already defined.\n");
1302}
1303
1304TEST_F(ParserValidationErrorTest, MethodNameError) {
1305  ExpectHasValidationErrors(
1306    "message Baz {}\n"
1307    "service Foo {\n"
1308    "  rpc Bar(Baz) returns(Baz);\n"
1309    "  rpc Bar(Baz) returns(Baz);\n"
1310    "}\n",
1311    "3:6: \"Bar\" is already defined in \"Foo\".\n");
1312}
1313
1314
1315TEST_F(ParserValidationErrorTest, MethodInputTypeError) {
1316  ExpectHasValidationErrors(
1317    "message Baz {}\n"
1318    "service Foo {\n"
1319    "  rpc Bar(Qux) returns(Baz);\n"
1320    "}\n",
1321    "2:10: \"Qux\" is not defined.\n");
1322}
1323
1324
1325TEST_F(ParserValidationErrorTest, MethodOutputTypeError) {
1326  ExpectHasValidationErrors(
1327    "message Baz {}\n"
1328    "service Foo {\n"
1329    "  rpc Bar(Baz) returns(Qux);\n"
1330    "}\n",
1331    "2:23: \"Qux\" is not defined.\n");
1332}
1333
1334
1335TEST_F(ParserValidationErrorTest, ResovledUndefinedError) {
1336  // Create another file which defines symbol ".base.bar".
1337  FileDescriptorProto other_file;
1338  other_file.set_name("base.proto");
1339  other_file.set_package("base");
1340  other_file.add_message_type()->set_name("bar");
1341  EXPECT_TRUE(pool_.BuildFile(other_file) != NULL);
1342
1343  // Define "foo.base" and try "base.bar".
1344  // "base.bar" is resolved to "foo.base.bar" which is not defined.
1345  ExpectHasValidationErrors(
1346    "package foo.base;\n"
1347    "import \"base.proto\";\n"
1348    "message qux {\n"
1349    "  optional base.bar baz = 1;\n"
1350    "  optional .base.bar quz = 2;\n"
1351    "}\n",
1352    "3:11: \"base.bar\" is resolved to \"foo.base.bar\","
1353    " which is not defined. The innermost scope is searched first "
1354    "in name resolution. Consider using a leading '.'(i.e., \".base.bar\")"
1355    " to start from the outermost scope.\n");
1356}
1357
1358TEST_F(ParserValidationErrorTest, ResovledUndefinedOptionError) {
1359  // Build descriptor message in test pool
1360  FileDescriptorProto descriptor_proto;
1361  DescriptorProto::descriptor()->file()->CopyTo(&descriptor_proto);
1362  ASSERT_TRUE(pool_.BuildFile(descriptor_proto) != NULL);
1363
1364  // base2.proto:
1365  //   package baz
1366  //   import google/protobuf/descriptor.proto
1367  //   message Bar { optional int32 foo = 1; }
1368  //   extend FileOptions { optional Bar bar = 7672757; }
1369  FileDescriptorProto other_file;
1370  other_file.set_name("base2.proto");
1371  other_file.set_package("baz");
1372  other_file.add_dependency();
1373  other_file.set_dependency(0, descriptor_proto.name());
1374
1375  DescriptorProto* message(other_file.add_message_type());
1376  message->set_name("Bar");
1377  FieldDescriptorProto* field(message->add_field());
1378  field->set_name("foo");
1379  field->set_number(1);
1380  field->set_label(FieldDescriptorProto_Label_LABEL_OPTIONAL);
1381  field->set_type(FieldDescriptorProto_Type_TYPE_INT32);
1382
1383  FieldDescriptorProto* extension(other_file.add_extension());
1384  extension->set_name("bar");
1385  extension->set_number(7672757);
1386  extension->set_label(FieldDescriptorProto_Label_LABEL_OPTIONAL);
1387  extension->set_type(FieldDescriptorProto_Type_TYPE_MESSAGE);
1388  extension->set_type_name("Bar");
1389  extension->set_extendee("google.protobuf.FileOptions");
1390
1391  EXPECT_TRUE(pool_.BuildFile(other_file) != NULL);
1392
1393  // qux.proto:
1394  //   package qux.baz
1395  //   option (baz.bar).foo = 1;
1396  //
1397  // Although "baz.bar" is already defined, the lookup code will try
1398  // "qux.baz.bar", since it's the match from the innermost scope,
1399  // which will cause a symbol not defined error.
1400  ExpectHasValidationErrors(
1401      "package qux.baz;\n"
1402      "import \"base2.proto\";\n"
1403      "option (baz.bar).foo = 1;\n",
1404      "2:7: Option \"(baz.bar)\" is resolved to \"(qux.baz.bar)\","
1405      " which is not defined. The innermost scope is searched first "
1406      "in name resolution. Consider using a leading '.'(i.e., \"(.baz.bar)\")"
1407      " to start from the outermost scope.\n");
1408}
1409
1410// ===================================================================
1411// Test that the output from FileDescriptor::DebugString() (and all other
1412// descriptor types) is parseable, and results in the same Descriptor
1413// definitions again afoter parsing (note, however, that the order of messages
1414// cannot be guaranteed to be the same)
1415
1416typedef ParserTest ParseDecriptorDebugTest;
1417
1418class CompareDescriptorNames {
1419 public:
1420  bool operator()(const DescriptorProto* left,
1421                  const DescriptorProto* right) const {
1422    return left->name() < right->name();
1423  }
1424};
1425
1426// Sorts nested DescriptorProtos of a DescriptoProto, by name.
1427void SortMessages(DescriptorProto *descriptor_proto) {
1428  int size = descriptor_proto->nested_type_size();
1429  // recursively sort; we can't guarantee the order of nested messages either
1430  for (int i = 0; i < size; ++i) {
1431    SortMessages(descriptor_proto->mutable_nested_type(i));
1432  }
1433  DescriptorProto **data =
1434    descriptor_proto->mutable_nested_type()->mutable_data();
1435  sort(data, data + size, CompareDescriptorNames());
1436}
1437
1438// Sorts DescriptorProtos belonging to a FileDescriptorProto, by name.
1439void SortMessages(FileDescriptorProto *file_descriptor_proto) {
1440  int size = file_descriptor_proto->message_type_size();
1441  // recursively sort; we can't guarantee the order of nested messages either
1442  for (int i = 0; i < size; ++i) {
1443    SortMessages(file_descriptor_proto->mutable_message_type(i));
1444  }
1445  DescriptorProto **data =
1446    file_descriptor_proto->mutable_message_type()->mutable_data();
1447  sort(data, data + size, CompareDescriptorNames());
1448}
1449
1450TEST_F(ParseDecriptorDebugTest, TestAllDescriptorTypes) {
1451  const FileDescriptor* original_file =
1452     protobuf_unittest::TestAllTypes::descriptor()->file();
1453  FileDescriptorProto expected;
1454  original_file->CopyTo(&expected);
1455
1456  // Get the DebugString of the unittest.proto FileDecriptor, which includes
1457  // all other descriptor types
1458  string debug_string = original_file->DebugString();
1459
1460  // Parse the debug string
1461  SetupParser(debug_string.c_str());
1462  FileDescriptorProto parsed;
1463  parser_->Parse(input_.get(), &parsed);
1464  EXPECT_EQ(io::Tokenizer::TYPE_END, input_->current().type);
1465  ASSERT_EQ("", error_collector_.text_)
1466      << "Failed to parse:\n" << debug_string;
1467
1468  // We now have a FileDescriptorProto, but to compare with the expected we
1469  // need to link to a FileDecriptor, then output back to a proto. We'll
1470  // also need to give it the same name as the original.
1471  parsed.set_name("google/protobuf/unittest.proto");
1472  // We need the imported dependency before we can build our parsed proto
1473  const FileDescriptor* public_import =
1474      protobuf_unittest_import::PublicImportMessage::descriptor()->file();
1475  FileDescriptorProto public_import_proto;
1476  public_import->CopyTo(&public_import_proto);
1477  ASSERT_TRUE(pool_.BuildFile(public_import_proto) != NULL);
1478  const FileDescriptor* import =
1479       protobuf_unittest_import::ImportMessage::descriptor()->file();
1480  FileDescriptorProto import_proto;
1481  import->CopyTo(&import_proto);
1482  ASSERT_TRUE(pool_.BuildFile(import_proto) != NULL);
1483  const FileDescriptor* actual = pool_.BuildFile(parsed);
1484  parsed.Clear();
1485  ASSERT_TRUE(actual != NULL)
1486      << "Failed to validate:\n" << debug_string;
1487  actual->CopyTo(&parsed);
1488  ASSERT_TRUE(actual != NULL);
1489
1490  // The messages might be in different orders, making them hard to compare.
1491  // So, sort the messages in the descriptor protos (including nested messages,
1492  // recursively).
1493  SortMessages(&expected);
1494  SortMessages(&parsed);
1495
1496  // I really wanted to use StringDiff here for the debug output on fail,
1497  // but the strings are too long for it, and if I increase its max size,
1498  // we get a memory allocation failure :(
1499  EXPECT_EQ(expected.DebugString(), parsed.DebugString());
1500}
1501
1502TEST_F(ParseDecriptorDebugTest, TestCustomOptions) {
1503  const FileDescriptor* original_file =
1504     protobuf_unittest::AggregateMessage::descriptor()->file();
1505  FileDescriptorProto expected;
1506  original_file->CopyTo(&expected);
1507
1508  string debug_string = original_file->DebugString();
1509
1510  // Parse the debug string
1511  SetupParser(debug_string.c_str());
1512  FileDescriptorProto parsed;
1513  parser_->Parse(input_.get(), &parsed);
1514  EXPECT_EQ(io::Tokenizer::TYPE_END, input_->current().type);
1515  ASSERT_EQ("", error_collector_.text_);
1516
1517  // We now have a FileDescriptorProto, but to compare with the expected we
1518  // need to link to a FileDecriptor, then output back to a proto. We'll
1519  // also need to give it the same name as the original.
1520  parsed.set_name(original_file->name());
1521
1522  // unittest_custom_options.proto depends on descriptor.proto.
1523  const FileDescriptor* import = FileDescriptorProto::descriptor()->file();
1524  FileDescriptorProto import_proto;
1525  import->CopyTo(&import_proto);
1526  ASSERT_TRUE(pool_.BuildFile(import_proto) != NULL);
1527  const FileDescriptor* actual = pool_.BuildFile(parsed);
1528  ASSERT_TRUE(actual != NULL);
1529  parsed.Clear();
1530  actual->CopyTo(&parsed);
1531
1532  // The messages might be in different orders, making them hard to compare.
1533  // So, sort the messages in the descriptor protos (including nested messages,
1534  // recursively).
1535  SortMessages(&expected);
1536  SortMessages(&parsed);
1537
1538  EXPECT_EQ(expected.DebugString(), parsed.DebugString());
1539}
1540
1541// ===================================================================
1542// SourceCodeInfo tests.
1543
1544// Follows a path -- as defined by SourceCodeInfo.Location.path -- from a
1545// message to a particular sub-field.
1546// * If the target is itself a message, sets *output_message to point at it,
1547//   *output_field to NULL, and *output_index to -1.
1548// * Otherwise, if the target is an element of a repeated field, sets
1549//   *output_message to the containing message, *output_field to the descriptor
1550//   of the field, and *output_index to the index of the element.
1551// * Otherwise, the target is a field (possibly a repeated field, but not any
1552//   one element).  Sets *output_message to the containing message,
1553//   *output_field to the descriptor of the field, and *output_index to -1.
1554// Returns true if the path was valid, false otherwise.  A gTest failure is
1555// recorded before returning false.
1556bool FollowPath(const Message& root,
1557                const int* path_begin, const int* path_end,
1558                const Message** output_message,
1559                const FieldDescriptor** output_field,
1560                int* output_index) {
1561  if (path_begin == path_end) {
1562    // Path refers to this whole message.
1563    *output_message = &root;
1564    *output_field = NULL;
1565    *output_index = -1;
1566    return true;
1567  }
1568
1569  const Descriptor* descriptor = root.GetDescriptor();
1570  const Reflection* reflection = root.GetReflection();
1571
1572  const FieldDescriptor* field = descriptor->FindFieldByNumber(*path_begin);
1573
1574  if (field == NULL) {
1575    ADD_FAILURE() << descriptor->name() << " has no field number: "
1576                  << *path_begin;
1577    return false;
1578  }
1579
1580  ++path_begin;
1581
1582  if (field->is_repeated()) {
1583    if (path_begin == path_end) {
1584      // Path refers to the whole repeated field.
1585      *output_message = &root;
1586      *output_field = field;
1587      *output_index = -1;
1588      return true;
1589    }
1590
1591    int index = *path_begin++;
1592    int size = reflection->FieldSize(root, field);
1593
1594    if (index >= size) {
1595      ADD_FAILURE() << descriptor->name() << "." << field->name()
1596                    << " has size " << size << ", but path contained index: "
1597                    << index;
1598      return false;
1599    }
1600
1601    if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
1602      // Descend into child message.
1603      const Message& child = reflection->GetRepeatedMessage(root, field, index);
1604      return FollowPath(child, path_begin, path_end,
1605                        output_message, output_field, output_index);
1606    } else if (path_begin == path_end) {
1607      // Path refers to this element.
1608      *output_message = &root;
1609      *output_field = field;
1610      *output_index = index;
1611      return true;
1612    } else {
1613      ADD_FAILURE() << descriptor->name() << "." << field->name()
1614                    << " is not a message; cannot descend into it.";
1615      return false;
1616    }
1617  } else {
1618    if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
1619      const Message& child = reflection->GetMessage(root, field);
1620      return FollowPath(child, path_begin, path_end,
1621                        output_message, output_field, output_index);
1622    } else if (path_begin == path_end) {
1623      // Path refers to this field.
1624      *output_message = &root;
1625      *output_field = field;
1626      *output_index = -1;
1627      return true;
1628    } else {
1629      ADD_FAILURE() << descriptor->name() << "." << field->name()
1630                    << " is not a message; cannot descend into it.";
1631      return false;
1632    }
1633  }
1634}
1635
1636// Check if two spans are equal.
1637bool CompareSpans(const RepeatedField<int>& span1,
1638                  const RepeatedField<int>& span2) {
1639  if (span1.size() != span2.size()) return false;
1640  for (int i = 0; i < span1.size(); i++) {
1641    if (span1.Get(i) != span2.Get(i)) return false;
1642  }
1643  return true;
1644}
1645
1646// Test fixture for source info tests, which check that source locations are
1647// recorded correctly in FileDescriptorProto.source_code_info.location.
1648class SourceInfoTest : public ParserTest {
1649 protected:
1650  // The parsed file (initialized by Parse()).
1651  FileDescriptorProto file_;
1652
1653  // Parse the given text as a .proto file and populate the spans_ map with
1654  // all the source location spans in its SourceCodeInfo table.
1655  bool Parse(const char* text) {
1656    ExtractMarkers(text);
1657    SetupParser(text_without_markers_.c_str());
1658    if (!parser_->Parse(input_.get(), &file_)) {
1659      return false;
1660    }
1661
1662    const SourceCodeInfo& source_info = file_.source_code_info();
1663    for (int i = 0; i < source_info.location_size(); i++) {
1664      const SourceCodeInfo::Location& location = source_info.location(i);
1665      const Message* descriptor_proto = NULL;
1666      const FieldDescriptor* field = NULL;
1667      int index = 0;
1668      if (!FollowPath(file_, location.path().begin(), location.path().end(),
1669                      &descriptor_proto, &field, &index)) {
1670        return false;
1671      }
1672
1673      spans_.insert(make_pair(SpanKey(*descriptor_proto, field, index),
1674                              &location));
1675    }
1676
1677    return true;
1678  }
1679
1680  virtual void TearDown() {
1681    EXPECT_TRUE(spans_.empty())
1682        << "Forgot to call HasSpan() for:\n"
1683        << spans_.begin()->second->DebugString();
1684  }
1685
1686  // -----------------------------------------------------------------
1687  // HasSpan() checks that the span of source code delimited by the given
1688  // tags (comments) correspond via the SourceCodeInfo table to the given
1689  // part of the FileDescriptorProto.  (If unclear, look at the actual tests;
1690  // it should quickly become obvious.)
1691
1692  bool HasSpan(char start_marker, char end_marker,
1693               const Message& descriptor_proto) {
1694    return HasSpanWithComment(
1695        start_marker, end_marker, descriptor_proto, NULL, -1, NULL, NULL);
1696  }
1697
1698  bool HasSpanWithComment(char start_marker, char end_marker,
1699                          const Message& descriptor_proto,
1700                          const char* expected_leading_comments,
1701                          const char* expected_trailing_comments) {
1702    return HasSpanWithComment(
1703        start_marker, end_marker, descriptor_proto, NULL, -1,
1704        expected_leading_comments, expected_trailing_comments);
1705  }
1706
1707  bool HasSpan(char start_marker, char end_marker,
1708               const Message& descriptor_proto, const string& field_name) {
1709    return HasSpan(start_marker, end_marker, descriptor_proto, field_name, -1);
1710  }
1711
1712  bool HasSpan(char start_marker, char end_marker,
1713               const Message& descriptor_proto, const string& field_name,
1714               int index) {
1715    return HasSpan(start_marker, end_marker, descriptor_proto,
1716                   field_name, index, NULL, NULL);
1717  }
1718
1719  bool HasSpan(char start_marker, char end_marker,
1720               const Message& descriptor_proto,
1721               const string& field_name, int index,
1722               const char* expected_leading_comments,
1723               const char* expected_trailing_comments) {
1724    const FieldDescriptor* field =
1725        descriptor_proto.GetDescriptor()->FindFieldByName(field_name);
1726    if (field == NULL) {
1727      ADD_FAILURE() << descriptor_proto.GetDescriptor()->name()
1728                    << " has no such field: " << field_name;
1729      return false;
1730    }
1731
1732    return HasSpanWithComment(
1733        start_marker, end_marker, descriptor_proto, field, index,
1734        expected_leading_comments, expected_trailing_comments);
1735  }
1736
1737  bool HasSpan(const Message& descriptor_proto) {
1738    return HasSpanWithComment(
1739        '\0', '\0', descriptor_proto, NULL, -1, NULL, NULL);
1740  }
1741
1742  bool HasSpan(const Message& descriptor_proto, const string& field_name) {
1743    return HasSpan('\0', '\0', descriptor_proto, field_name, -1);
1744  }
1745
1746  bool HasSpan(const Message& descriptor_proto, const string& field_name,
1747               int index) {
1748    return HasSpan('\0', '\0', descriptor_proto, field_name, index);
1749  }
1750
1751  bool HasSpanWithComment(char start_marker, char end_marker,
1752                          const Message& descriptor_proto,
1753                          const FieldDescriptor* field, int index,
1754                          const char* expected_leading_comments,
1755                          const char* expected_trailing_comments) {
1756    pair<SpanMap::iterator, SpanMap::iterator> range =
1757        spans_.equal_range(SpanKey(descriptor_proto, field, index));
1758
1759    if (start_marker == '\0') {
1760      if (range.first == range.second) {
1761        return false;
1762      } else {
1763        spans_.erase(range.first);
1764        return true;
1765      }
1766    } else {
1767      pair<int, int> start_pos = FindOrDie(markers_, start_marker);
1768      pair<int, int> end_pos = FindOrDie(markers_, end_marker);
1769
1770      RepeatedField<int> expected_span;
1771      expected_span.Add(start_pos.first);
1772      expected_span.Add(start_pos.second);
1773      if (end_pos.first != start_pos.first) {
1774        expected_span.Add(end_pos.first);
1775      }
1776      expected_span.Add(end_pos.second);
1777
1778      for (SpanMap::iterator iter = range.first; iter != range.second; ++iter) {
1779        if (CompareSpans(expected_span, iter->second->span())) {
1780          if (expected_leading_comments == NULL) {
1781            EXPECT_FALSE(iter->second->has_leading_comments());
1782          } else {
1783            EXPECT_TRUE(iter->second->has_leading_comments());
1784            EXPECT_EQ(expected_leading_comments,
1785                      iter->second->leading_comments());
1786          }
1787          if (expected_trailing_comments == NULL) {
1788            EXPECT_FALSE(iter->second->has_trailing_comments());
1789          } else {
1790            EXPECT_TRUE(iter->second->has_trailing_comments());
1791            EXPECT_EQ(expected_trailing_comments,
1792                      iter->second->trailing_comments());
1793          }
1794
1795          spans_.erase(iter);
1796          return true;
1797        }
1798      }
1799
1800      return false;
1801    }
1802  }
1803
1804 private:
1805  struct SpanKey {
1806    const Message* descriptor_proto;
1807    const FieldDescriptor* field;
1808    int index;
1809
1810    inline SpanKey() {}
1811    inline SpanKey(const Message& descriptor_proto_param,
1812                   const FieldDescriptor* field_param,
1813                   int index_param)
1814        : descriptor_proto(&descriptor_proto_param), field(field_param),
1815          index(index_param) {}
1816
1817    inline bool operator<(const SpanKey& other) const {
1818      if (descriptor_proto < other.descriptor_proto) return true;
1819      if (descriptor_proto > other.descriptor_proto) return false;
1820      if (field < other.field) return true;
1821      if (field > other.field) return false;
1822      return index < other.index;
1823    }
1824  };
1825
1826  typedef multimap<SpanKey, const SourceCodeInfo::Location*> SpanMap;
1827  SpanMap spans_;
1828  map<char, pair<int, int> > markers_;
1829  string text_without_markers_;
1830
1831  void ExtractMarkers(const char* text) {
1832    markers_.clear();
1833    text_without_markers_.clear();
1834    int line = 0;
1835    int column = 0;
1836    while (*text != '\0') {
1837      if (*text == '$') {
1838        ++text;
1839        GOOGLE_CHECK_NE('\0', *text);
1840        if (*text == '$') {
1841          text_without_markers_ += '$';
1842          ++column;
1843        } else {
1844          markers_[*text] = make_pair(line, column);
1845          ++text;
1846          GOOGLE_CHECK_EQ('$', *text);
1847        }
1848      } else if (*text == '\n') {
1849        ++line;
1850        column = 0;
1851        text_without_markers_ += *text;
1852      } else {
1853        text_without_markers_ += *text;
1854        ++column;
1855      }
1856      ++text;
1857    }
1858  }
1859};
1860
1861TEST_F(SourceInfoTest, BasicFileDecls) {
1862  EXPECT_TRUE(Parse(
1863      "$a$syntax = \"proto2\";\n"
1864      "package $b$foo.bar$c$;\n"
1865      "import $d$\"baz.proto\"$e$;\n"
1866      "import $f$\"qux.proto\"$g$;$h$\n"
1867      "\n"
1868      "// comment ignored\n"));
1869
1870  EXPECT_TRUE(HasSpan('a', 'h', file_));
1871  EXPECT_TRUE(HasSpan('b', 'c', file_, "package"));
1872  EXPECT_TRUE(HasSpan('d', 'e', file_, "dependency", 0));
1873  EXPECT_TRUE(HasSpan('f', 'g', file_, "dependency", 1));
1874}
1875
1876TEST_F(SourceInfoTest, Messages) {
1877  EXPECT_TRUE(Parse(
1878      "$a$message $b$Foo$c$ {}$d$\n"
1879      "$e$message $f$Bar$g$ {}$h$\n"));
1880
1881  EXPECT_TRUE(HasSpan('a', 'd', file_.message_type(0)));
1882  EXPECT_TRUE(HasSpan('b', 'c', file_.message_type(0), "name"));
1883  EXPECT_TRUE(HasSpan('e', 'h', file_.message_type(1)));
1884  EXPECT_TRUE(HasSpan('f', 'g', file_.message_type(1), "name"));
1885
1886  // Ignore these.
1887  EXPECT_TRUE(HasSpan(file_));
1888}
1889
1890TEST_F(SourceInfoTest, Fields) {
1891  EXPECT_TRUE(Parse(
1892      "message Foo {\n"
1893      "  $a$optional$b$ $c$int32$d$ $e$bar$f$ = $g$1$h$;$i$\n"
1894      "  $j$repeated$k$ $l$X.Y$m$ $n$baz$o$ = $p$2$q$;$r$\n"
1895      "}\n"));
1896
1897  const FieldDescriptorProto& field1 = file_.message_type(0).field(0);
1898  const FieldDescriptorProto& field2 = file_.message_type(0).field(1);
1899
1900  EXPECT_TRUE(HasSpan('a', 'i', field1));
1901  EXPECT_TRUE(HasSpan('a', 'b', field1, "label"));
1902  EXPECT_TRUE(HasSpan('c', 'd', field1, "type"));
1903  EXPECT_TRUE(HasSpan('e', 'f', field1, "name"));
1904  EXPECT_TRUE(HasSpan('g', 'h', field1, "number"));
1905
1906  EXPECT_TRUE(HasSpan('j', 'r', field2));
1907  EXPECT_TRUE(HasSpan('j', 'k', field2, "label"));
1908  EXPECT_TRUE(HasSpan('l', 'm', field2, "type_name"));
1909  EXPECT_TRUE(HasSpan('n', 'o', field2, "name"));
1910  EXPECT_TRUE(HasSpan('p', 'q', field2, "number"));
1911
1912  // Ignore these.
1913  EXPECT_TRUE(HasSpan(file_));
1914  EXPECT_TRUE(HasSpan(file_.message_type(0)));
1915  EXPECT_TRUE(HasSpan(file_.message_type(0), "name"));
1916}
1917
1918TEST_F(SourceInfoTest, Extensions) {
1919  EXPECT_TRUE(Parse(
1920      "$a$extend $b$Foo$c$ {\n"
1921      "  $d$optional$e$ int32 bar = 1;$f$\n"
1922      "  $g$repeated$h$ X.Y baz = 2;$i$\n"
1923      "}$j$\n"
1924      "$k$extend $l$Bar$m$ {\n"
1925      "  $n$optional int32 qux = 1;$o$\n"
1926      "}$p$\n"));
1927
1928  const FieldDescriptorProto& field1 = file_.extension(0);
1929  const FieldDescriptorProto& field2 = file_.extension(1);
1930  const FieldDescriptorProto& field3 = file_.extension(2);
1931
1932  EXPECT_TRUE(HasSpan('a', 'j', file_, "extension"));
1933  EXPECT_TRUE(HasSpan('k', 'p', file_, "extension"));
1934
1935  EXPECT_TRUE(HasSpan('d', 'f', field1));
1936  EXPECT_TRUE(HasSpan('d', 'e', field1, "label"));
1937  EXPECT_TRUE(HasSpan('b', 'c', field1, "extendee"));
1938
1939  EXPECT_TRUE(HasSpan('g', 'i', field2));
1940  EXPECT_TRUE(HasSpan('g', 'h', field2, "label"));
1941  EXPECT_TRUE(HasSpan('b', 'c', field2, "extendee"));
1942
1943  EXPECT_TRUE(HasSpan('n', 'o', field3));
1944  EXPECT_TRUE(HasSpan('l', 'm', field3, "extendee"));
1945
1946  // Ignore these.
1947  EXPECT_TRUE(HasSpan(file_));
1948  EXPECT_TRUE(HasSpan(field1, "type"));
1949  EXPECT_TRUE(HasSpan(field1, "name"));
1950  EXPECT_TRUE(HasSpan(field1, "number"));
1951  EXPECT_TRUE(HasSpan(field2, "type_name"));
1952  EXPECT_TRUE(HasSpan(field2, "name"));
1953  EXPECT_TRUE(HasSpan(field2, "number"));
1954  EXPECT_TRUE(HasSpan(field3, "label"));
1955  EXPECT_TRUE(HasSpan(field3, "type"));
1956  EXPECT_TRUE(HasSpan(field3, "name"));
1957  EXPECT_TRUE(HasSpan(field3, "number"));
1958}
1959
1960TEST_F(SourceInfoTest, NestedExtensions) {
1961  EXPECT_TRUE(Parse(
1962      "message Message {\n"
1963      "  $a$extend $b$Foo$c$ {\n"
1964      "    $d$optional$e$ int32 bar = 1;$f$\n"
1965      "    $g$repeated$h$ X.Y baz = 2;$i$\n"
1966      "  }$j$\n"
1967      "  $k$extend $l$Bar$m$ {\n"
1968      "    $n$optional int32 qux = 1;$o$\n"
1969      "  }$p$\n"
1970      "}\n"));
1971
1972  const FieldDescriptorProto& field1 = file_.message_type(0).extension(0);
1973  const FieldDescriptorProto& field2 = file_.message_type(0).extension(1);
1974  const FieldDescriptorProto& field3 = file_.message_type(0).extension(2);
1975
1976  EXPECT_TRUE(HasSpan('a', 'j', file_.message_type(0), "extension"));
1977  EXPECT_TRUE(HasSpan('k', 'p', file_.message_type(0), "extension"));
1978
1979  EXPECT_TRUE(HasSpan('d', 'f', field1));
1980  EXPECT_TRUE(HasSpan('d', 'e', field1, "label"));
1981  EXPECT_TRUE(HasSpan('b', 'c', field1, "extendee"));
1982
1983  EXPECT_TRUE(HasSpan('g', 'i', field2));
1984  EXPECT_TRUE(HasSpan('g', 'h', field2, "label"));
1985  EXPECT_TRUE(HasSpan('b', 'c', field2, "extendee"));
1986
1987  EXPECT_TRUE(HasSpan('n', 'o', field3));
1988  EXPECT_TRUE(HasSpan('l', 'm', field3, "extendee"));
1989
1990  // Ignore these.
1991  EXPECT_TRUE(HasSpan(file_));
1992  EXPECT_TRUE(HasSpan(file_.message_type(0)));
1993  EXPECT_TRUE(HasSpan(file_.message_type(0), "name"));
1994  EXPECT_TRUE(HasSpan(field1, "type"));
1995  EXPECT_TRUE(HasSpan(field1, "name"));
1996  EXPECT_TRUE(HasSpan(field1, "number"));
1997  EXPECT_TRUE(HasSpan(field2, "type_name"));
1998  EXPECT_TRUE(HasSpan(field2, "name"));
1999  EXPECT_TRUE(HasSpan(field2, "number"));
2000  EXPECT_TRUE(HasSpan(field3, "label"));
2001  EXPECT_TRUE(HasSpan(field3, "type"));
2002  EXPECT_TRUE(HasSpan(field3, "name"));
2003  EXPECT_TRUE(HasSpan(field3, "number"));
2004}
2005
2006TEST_F(SourceInfoTest, ExtensionRanges) {
2007  EXPECT_TRUE(Parse(
2008      "message Message {\n"
2009      "  $a$extensions $b$1$c$ to $d$4$e$, $f$6$g$;$h$\n"
2010      "  $i$extensions $j$8$k$ to $l$max$m$;$n$\n"
2011      "}\n"));
2012
2013  const DescriptorProto::ExtensionRange& range1 =
2014      file_.message_type(0).extension_range(0);
2015  const DescriptorProto::ExtensionRange& range2 =
2016      file_.message_type(0).extension_range(1);
2017  const DescriptorProto::ExtensionRange& range3 =
2018      file_.message_type(0).extension_range(2);
2019
2020  EXPECT_TRUE(HasSpan('a', 'h', file_.message_type(0), "extension_range"));
2021  EXPECT_TRUE(HasSpan('i', 'n', file_.message_type(0), "extension_range"));
2022
2023  EXPECT_TRUE(HasSpan('b', 'e', range1));
2024  EXPECT_TRUE(HasSpan('b', 'c', range1, "start"));
2025  EXPECT_TRUE(HasSpan('d', 'e', range1, "end"));
2026
2027  EXPECT_TRUE(HasSpan('f', 'g', range2));
2028  EXPECT_TRUE(HasSpan('f', 'g', range2, "start"));
2029  EXPECT_TRUE(HasSpan('f', 'g', range2, "end"));
2030
2031  EXPECT_TRUE(HasSpan('j', 'm', range3));
2032  EXPECT_TRUE(HasSpan('j', 'k', range3, "start"));
2033  EXPECT_TRUE(HasSpan('l', 'm', range3, "end"));
2034
2035  // Ignore these.
2036  EXPECT_TRUE(HasSpan(file_));
2037  EXPECT_TRUE(HasSpan(file_.message_type(0)));
2038  EXPECT_TRUE(HasSpan(file_.message_type(0), "name"));
2039}
2040
2041TEST_F(SourceInfoTest, Oneofs) {
2042  EXPECT_TRUE(Parse(
2043      "message Foo {\n"
2044      "  $a$oneof $c$foo$d$ {\n"
2045      "    $e$int32$f$ $g$a$h$ = $i$1$j$;$k$\n"
2046      "  }$r$\n"
2047      "}\n"));
2048
2049  const OneofDescriptorProto& oneof_decl = file_.message_type(0).oneof_decl(0);
2050  const FieldDescriptorProto& field = file_.message_type(0).field(0);
2051
2052  EXPECT_TRUE(HasSpan('a', 'r', oneof_decl));
2053  EXPECT_TRUE(HasSpan('c', 'd', oneof_decl, "name"));
2054
2055  EXPECT_TRUE(HasSpan('e', 'k', field));
2056  EXPECT_TRUE(HasSpan('e', 'f', field, "type"));
2057  EXPECT_TRUE(HasSpan('g', 'h', field, "name"));
2058  EXPECT_TRUE(HasSpan('i', 'j', field, "number"));
2059
2060  // Ignore these.
2061  EXPECT_TRUE(HasSpan(file_));
2062  EXPECT_TRUE(HasSpan(file_.message_type(0)));
2063  EXPECT_TRUE(HasSpan(file_.message_type(0), "name"));
2064}
2065
2066TEST_F(SourceInfoTest, NestedMessages) {
2067  EXPECT_TRUE(Parse(
2068      "message Foo {\n"
2069      "  $a$message $b$Bar$c$ {\n"
2070      "    $d$message $e$Baz$f$ {}$g$\n"
2071      "  }$h$\n"
2072      "  $i$message $j$Qux$k$ {}$l$\n"
2073      "}\n"));
2074
2075  const DescriptorProto& bar = file_.message_type(0).nested_type(0);
2076  const DescriptorProto& baz = bar.nested_type(0);
2077  const DescriptorProto& qux = file_.message_type(0).nested_type(1);
2078
2079  EXPECT_TRUE(HasSpan('a', 'h', bar));
2080  EXPECT_TRUE(HasSpan('b', 'c', bar, "name"));
2081  EXPECT_TRUE(HasSpan('d', 'g', baz));
2082  EXPECT_TRUE(HasSpan('e', 'f', baz, "name"));
2083  EXPECT_TRUE(HasSpan('i', 'l', qux));
2084  EXPECT_TRUE(HasSpan('j', 'k', qux, "name"));
2085
2086  // Ignore these.
2087  EXPECT_TRUE(HasSpan(file_));
2088  EXPECT_TRUE(HasSpan(file_.message_type(0)));
2089  EXPECT_TRUE(HasSpan(file_.message_type(0), "name"));
2090}
2091
2092TEST_F(SourceInfoTest, Groups) {
2093  EXPECT_TRUE(Parse(
2094      "message Foo {\n"
2095      "  message Bar {}\n"
2096      "  $a$optional$b$ $c$group$d$ $e$Baz$f$ = $g$1$h$ {\n"
2097      "    $i$message Qux {}$j$\n"
2098      "  }$k$\n"
2099      "}\n"));
2100
2101  const DescriptorProto& bar = file_.message_type(0).nested_type(0);
2102  const DescriptorProto& baz = file_.message_type(0).nested_type(1);
2103  const DescriptorProto& qux = baz.nested_type(0);
2104  const FieldDescriptorProto& field = file_.message_type(0).field(0);
2105
2106  EXPECT_TRUE(HasSpan('a', 'k', field));
2107  EXPECT_TRUE(HasSpan('a', 'b', field, "label"));
2108  EXPECT_TRUE(HasSpan('c', 'd', field, "type"));
2109  EXPECT_TRUE(HasSpan('e', 'f', field, "name"));
2110  EXPECT_TRUE(HasSpan('e', 'f', field, "type_name"));
2111  EXPECT_TRUE(HasSpan('g', 'h', field, "number"));
2112
2113  EXPECT_TRUE(HasSpan('a', 'k', baz));
2114  EXPECT_TRUE(HasSpan('e', 'f', baz, "name"));
2115  EXPECT_TRUE(HasSpan('i', 'j', qux));
2116
2117  // Ignore these.
2118  EXPECT_TRUE(HasSpan(file_));
2119  EXPECT_TRUE(HasSpan(file_.message_type(0)));
2120  EXPECT_TRUE(HasSpan(file_.message_type(0), "name"));
2121  EXPECT_TRUE(HasSpan(bar));
2122  EXPECT_TRUE(HasSpan(bar, "name"));
2123  EXPECT_TRUE(HasSpan(qux, "name"));
2124}
2125
2126TEST_F(SourceInfoTest, Enums) {
2127  EXPECT_TRUE(Parse(
2128      "$a$enum $b$Foo$c$ {}$d$\n"
2129      "$e$enum $f$Bar$g$ {}$h$\n"));
2130
2131  EXPECT_TRUE(HasSpan('a', 'd', file_.enum_type(0)));
2132  EXPECT_TRUE(HasSpan('b', 'c', file_.enum_type(0), "name"));
2133  EXPECT_TRUE(HasSpan('e', 'h', file_.enum_type(1)));
2134  EXPECT_TRUE(HasSpan('f', 'g', file_.enum_type(1), "name"));
2135
2136  // Ignore these.
2137  EXPECT_TRUE(HasSpan(file_));
2138}
2139
2140TEST_F(SourceInfoTest, EnumValues) {
2141  EXPECT_TRUE(Parse(
2142      "enum Foo {\n"
2143      "  $a$BAR$b$ = $c$1$d$;$e$\n"
2144      "  $f$BAZ$g$ = $h$2$i$;$j$\n"
2145      "}"));
2146
2147  const EnumValueDescriptorProto& bar = file_.enum_type(0).value(0);
2148  const EnumValueDescriptorProto& baz = file_.enum_type(0).value(1);
2149
2150  EXPECT_TRUE(HasSpan('a', 'e', bar));
2151  EXPECT_TRUE(HasSpan('a', 'b', bar, "name"));
2152  EXPECT_TRUE(HasSpan('c', 'd', bar, "number"));
2153  EXPECT_TRUE(HasSpan('f', 'j', baz));
2154  EXPECT_TRUE(HasSpan('f', 'g', baz, "name"));
2155  EXPECT_TRUE(HasSpan('h', 'i', baz, "number"));
2156
2157  // Ignore these.
2158  EXPECT_TRUE(HasSpan(file_));
2159  EXPECT_TRUE(HasSpan(file_.enum_type(0)));
2160  EXPECT_TRUE(HasSpan(file_.enum_type(0), "name"));
2161}
2162
2163TEST_F(SourceInfoTest, NestedEnums) {
2164  EXPECT_TRUE(Parse(
2165      "message Foo {\n"
2166      "  $a$enum $b$Bar$c$ {}$d$\n"
2167      "  $e$enum $f$Baz$g$ {}$h$\n"
2168      "}\n"));
2169
2170  const EnumDescriptorProto& bar = file_.message_type(0).enum_type(0);
2171  const EnumDescriptorProto& baz = file_.message_type(0).enum_type(1);
2172
2173  EXPECT_TRUE(HasSpan('a', 'd', bar));
2174  EXPECT_TRUE(HasSpan('b', 'c', bar, "name"));
2175  EXPECT_TRUE(HasSpan('e', 'h', baz));
2176  EXPECT_TRUE(HasSpan('f', 'g', baz, "name"));
2177
2178  // Ignore these.
2179  EXPECT_TRUE(HasSpan(file_));
2180  EXPECT_TRUE(HasSpan(file_.message_type(0)));
2181  EXPECT_TRUE(HasSpan(file_.message_type(0), "name"));
2182}
2183
2184TEST_F(SourceInfoTest, Services) {
2185  EXPECT_TRUE(Parse(
2186      "$a$service $b$Foo$c$ {}$d$\n"
2187      "$e$service $f$Bar$g$ {}$h$\n"));
2188
2189  EXPECT_TRUE(HasSpan('a', 'd', file_.service(0)));
2190  EXPECT_TRUE(HasSpan('b', 'c', file_.service(0), "name"));
2191  EXPECT_TRUE(HasSpan('e', 'h', file_.service(1)));
2192  EXPECT_TRUE(HasSpan('f', 'g', file_.service(1), "name"));
2193
2194  // Ignore these.
2195  EXPECT_TRUE(HasSpan(file_));
2196}
2197
2198TEST_F(SourceInfoTest, MethodsAndStreams) {
2199  EXPECT_TRUE(Parse(
2200      "service Foo {\n"
2201      "  $a$rpc $b$Bar$c$($d$X$e$) returns($f$Y$g$);$h$"
2202      "  $i$rpc $j$Baz$k$($l$Z$m$) returns($n$W$o$);$p$"
2203      "}"));
2204
2205  const MethodDescriptorProto& bar = file_.service(0).method(0);
2206  const MethodDescriptorProto& baz = file_.service(0).method(1);
2207
2208  EXPECT_TRUE(HasSpan('a', 'h', bar));
2209  EXPECT_TRUE(HasSpan('b', 'c', bar, "name"));
2210  EXPECT_TRUE(HasSpan('d', 'e', bar, "input_type"));
2211  EXPECT_TRUE(HasSpan('f', 'g', bar, "output_type"));
2212
2213  EXPECT_TRUE(HasSpan('i', 'p', baz));
2214  EXPECT_TRUE(HasSpan('j', 'k', baz, "name"));
2215  EXPECT_TRUE(HasSpan('l', 'm', baz, "input_type"));
2216  EXPECT_TRUE(HasSpan('n', 'o', baz, "output_type"));
2217
2218  // Ignore these.
2219  EXPECT_TRUE(HasSpan(file_));
2220  EXPECT_TRUE(HasSpan(file_.service(0)));
2221  EXPECT_TRUE(HasSpan(file_.service(0), "name"));
2222}
2223
2224
2225TEST_F(SourceInfoTest, Options) {
2226  EXPECT_TRUE(Parse(
2227      "$a$option $b$foo$c$.$d$($e$bar.baz$f$)$g$ = "
2228          "$h$123$i$;$j$\n"
2229      "$k$option qux = $l$-123$m$;$n$\n"
2230      "$o$option corge = $p$abc$q$;$r$\n"
2231      "$s$option grault = $t$'blah'$u$;$v$\n"
2232      "$w$option garply = $x${ yadda yadda }$y$;$z$\n"
2233      "$0$option waldo = $1$123.0$2$;$3$\n"
2234  ));
2235
2236  const UninterpretedOption& option1 = file_.options().uninterpreted_option(0);
2237  const UninterpretedOption& option2 = file_.options().uninterpreted_option(1);
2238  const UninterpretedOption& option3 = file_.options().uninterpreted_option(2);
2239  const UninterpretedOption& option4 = file_.options().uninterpreted_option(3);
2240  const UninterpretedOption& option5 = file_.options().uninterpreted_option(4);
2241  const UninterpretedOption& option6 = file_.options().uninterpreted_option(5);
2242
2243  EXPECT_TRUE(HasSpan('a', 'j', file_.options()));
2244  EXPECT_TRUE(HasSpan('a', 'j', option1));
2245  EXPECT_TRUE(HasSpan('b', 'g', option1, "name"));
2246  EXPECT_TRUE(HasSpan('b', 'c', option1.name(0)));
2247  EXPECT_TRUE(HasSpan('b', 'c', option1.name(0), "name_part"));
2248  EXPECT_TRUE(HasSpan('d', 'g', option1.name(1)));
2249  EXPECT_TRUE(HasSpan('e', 'f', option1.name(1), "name_part"));
2250  EXPECT_TRUE(HasSpan('h', 'i', option1, "positive_int_value"));
2251
2252  EXPECT_TRUE(HasSpan('k', 'n', file_.options()));
2253  EXPECT_TRUE(HasSpan('l', 'm', option2, "negative_int_value"));
2254
2255  EXPECT_TRUE(HasSpan('o', 'r', file_.options()));
2256  EXPECT_TRUE(HasSpan('p', 'q', option3, "identifier_value"));
2257
2258  EXPECT_TRUE(HasSpan('s', 'v', file_.options()));
2259  EXPECT_TRUE(HasSpan('t', 'u', option4, "string_value"));
2260
2261  EXPECT_TRUE(HasSpan('w', 'z', file_.options()));
2262  EXPECT_TRUE(HasSpan('x', 'y', option5, "aggregate_value"));
2263
2264  EXPECT_TRUE(HasSpan('0', '3', file_.options()));
2265  EXPECT_TRUE(HasSpan('1', '2', option6, "double_value"));
2266
2267  // Ignore these.
2268  EXPECT_TRUE(HasSpan(file_));
2269  EXPECT_TRUE(HasSpan(option2));
2270  EXPECT_TRUE(HasSpan(option3));
2271  EXPECT_TRUE(HasSpan(option4));
2272  EXPECT_TRUE(HasSpan(option5));
2273  EXPECT_TRUE(HasSpan(option6));
2274  EXPECT_TRUE(HasSpan(option2, "name"));
2275  EXPECT_TRUE(HasSpan(option3, "name"));
2276  EXPECT_TRUE(HasSpan(option4, "name"));
2277  EXPECT_TRUE(HasSpan(option5, "name"));
2278  EXPECT_TRUE(HasSpan(option6, "name"));
2279  EXPECT_TRUE(HasSpan(option2.name(0)));
2280  EXPECT_TRUE(HasSpan(option3.name(0)));
2281  EXPECT_TRUE(HasSpan(option4.name(0)));
2282  EXPECT_TRUE(HasSpan(option5.name(0)));
2283  EXPECT_TRUE(HasSpan(option6.name(0)));
2284  EXPECT_TRUE(HasSpan(option2.name(0), "name_part"));
2285  EXPECT_TRUE(HasSpan(option3.name(0), "name_part"));
2286  EXPECT_TRUE(HasSpan(option4.name(0), "name_part"));
2287  EXPECT_TRUE(HasSpan(option5.name(0), "name_part"));
2288  EXPECT_TRUE(HasSpan(option6.name(0), "name_part"));
2289}
2290
2291TEST_F(SourceInfoTest, ScopedOptions) {
2292  EXPECT_TRUE(Parse(
2293    "message Foo {\n"
2294    "  $a$option mopt = 1;$b$\n"
2295    "}\n"
2296    "enum Bar {\n"
2297    "  $c$option eopt = 1;$d$\n"
2298    "}\n"
2299    "service Baz {\n"
2300    "  $e$option sopt = 1;$f$\n"
2301    "  rpc M(X) returns(Y) {\n"
2302    "    $g$option mopt = 1;$h$\n"
2303    "  }\n"
2304    "}\n"));
2305
2306  EXPECT_TRUE(HasSpan('a', 'b', file_.message_type(0).options()));
2307  EXPECT_TRUE(HasSpan('c', 'd', file_.enum_type(0).options()));
2308  EXPECT_TRUE(HasSpan('e', 'f', file_.service(0).options()));
2309  EXPECT_TRUE(HasSpan('g', 'h', file_.service(0).method(0).options()));
2310
2311  // Ignore these.
2312  EXPECT_TRUE(HasSpan(file_));
2313  EXPECT_TRUE(HasSpan(file_.message_type(0)));
2314  EXPECT_TRUE(HasSpan(file_.message_type(0), "name"));
2315  EXPECT_TRUE(HasSpan(file_.message_type(0).options()
2316                      .uninterpreted_option(0)));
2317  EXPECT_TRUE(HasSpan(file_.message_type(0).options()
2318                      .uninterpreted_option(0), "name"));
2319  EXPECT_TRUE(HasSpan(file_.message_type(0).options()
2320                      .uninterpreted_option(0).name(0)));
2321  EXPECT_TRUE(HasSpan(file_.message_type(0).options()
2322                      .uninterpreted_option(0).name(0), "name_part"));
2323  EXPECT_TRUE(HasSpan(file_.message_type(0).options()
2324                      .uninterpreted_option(0), "positive_int_value"));
2325  EXPECT_TRUE(HasSpan(file_.enum_type(0)));
2326  EXPECT_TRUE(HasSpan(file_.enum_type(0), "name"));
2327  EXPECT_TRUE(HasSpan(file_.enum_type(0).options()
2328                      .uninterpreted_option(0)));
2329  EXPECT_TRUE(HasSpan(file_.enum_type(0).options()
2330                      .uninterpreted_option(0), "name"));
2331  EXPECT_TRUE(HasSpan(file_.enum_type(0).options()
2332                      .uninterpreted_option(0).name(0)));
2333  EXPECT_TRUE(HasSpan(file_.enum_type(0).options()
2334                      .uninterpreted_option(0).name(0), "name_part"));
2335  EXPECT_TRUE(HasSpan(file_.enum_type(0).options()
2336                      .uninterpreted_option(0), "positive_int_value"));
2337  EXPECT_TRUE(HasSpan(file_.service(0)));
2338  EXPECT_TRUE(HasSpan(file_.service(0), "name"));
2339  EXPECT_TRUE(HasSpan(file_.service(0).method(0)));
2340  EXPECT_TRUE(HasSpan(file_.service(0).options()
2341                      .uninterpreted_option(0)));
2342  EXPECT_TRUE(HasSpan(file_.service(0).options()
2343                      .uninterpreted_option(0), "name"));
2344  EXPECT_TRUE(HasSpan(file_.service(0).options()
2345                      .uninterpreted_option(0).name(0)));
2346  EXPECT_TRUE(HasSpan(file_.service(0).options()
2347                      .uninterpreted_option(0).name(0), "name_part"));
2348  EXPECT_TRUE(HasSpan(file_.service(0).options()
2349                      .uninterpreted_option(0), "positive_int_value"));
2350  EXPECT_TRUE(HasSpan(file_.service(0).method(0), "name"));
2351  EXPECT_TRUE(HasSpan(file_.service(0).method(0), "input_type"));
2352  EXPECT_TRUE(HasSpan(file_.service(0).method(0), "output_type"));
2353  EXPECT_TRUE(HasSpan(file_.service(0).method(0).options()
2354                      .uninterpreted_option(0)));
2355  EXPECT_TRUE(HasSpan(file_.service(0).method(0).options()
2356                      .uninterpreted_option(0), "name"));
2357  EXPECT_TRUE(HasSpan(file_.service(0).method(0).options()
2358                      .uninterpreted_option(0).name(0)));
2359  EXPECT_TRUE(HasSpan(file_.service(0).method(0).options()
2360                      .uninterpreted_option(0).name(0), "name_part"));
2361  EXPECT_TRUE(HasSpan(file_.service(0).method(0).options()
2362                      .uninterpreted_option(0), "positive_int_value"));
2363}
2364
2365TEST_F(SourceInfoTest, FieldOptions) {
2366  // The actual "name = value" pairs are parsed by the same code as for
2367  // top-level options so we won't re-test that -- just make sure that the
2368  // syntax used for field options is understood.
2369  EXPECT_TRUE(Parse(
2370      "message Foo {"
2371      "  optional int32 bar = 1 "
2372          "$a$[default=$b$123$c$,$d$opt1=123$e$,"
2373          "$f$opt2='hi'$g$]$h$;"
2374      "}\n"
2375  ));
2376
2377  const FieldDescriptorProto& field = file_.message_type(0).field(0);
2378  const UninterpretedOption& option1 = field.options().uninterpreted_option(0);
2379  const UninterpretedOption& option2 = field.options().uninterpreted_option(1);
2380
2381  EXPECT_TRUE(HasSpan('a', 'h', field.options()));
2382  EXPECT_TRUE(HasSpan('b', 'c', field, "default_value"));
2383  EXPECT_TRUE(HasSpan('d', 'e', option1));
2384  EXPECT_TRUE(HasSpan('f', 'g', option2));
2385
2386  // Ignore these.
2387  EXPECT_TRUE(HasSpan(file_));
2388  EXPECT_TRUE(HasSpan(file_.message_type(0)));
2389  EXPECT_TRUE(HasSpan(file_.message_type(0), "name"));
2390  EXPECT_TRUE(HasSpan(field));
2391  EXPECT_TRUE(HasSpan(field, "label"));
2392  EXPECT_TRUE(HasSpan(field, "type"));
2393  EXPECT_TRUE(HasSpan(field, "name"));
2394  EXPECT_TRUE(HasSpan(field, "number"));
2395  EXPECT_TRUE(HasSpan(option1, "name"));
2396  EXPECT_TRUE(HasSpan(option2, "name"));
2397  EXPECT_TRUE(HasSpan(option1.name(0)));
2398  EXPECT_TRUE(HasSpan(option2.name(0)));
2399  EXPECT_TRUE(HasSpan(option1.name(0), "name_part"));
2400  EXPECT_TRUE(HasSpan(option2.name(0), "name_part"));
2401  EXPECT_TRUE(HasSpan(option1, "positive_int_value"));
2402  EXPECT_TRUE(HasSpan(option2, "string_value"));
2403}
2404
2405TEST_F(SourceInfoTest, EnumValueOptions) {
2406  // The actual "name = value" pairs are parsed by the same code as for
2407  // top-level options so we won't re-test that -- just make sure that the
2408  // syntax used for enum options is understood.
2409  EXPECT_TRUE(Parse(
2410      "enum Foo {"
2411      "  BAR = 1 $a$[$b$opt1=123$c$,$d$opt2='hi'$e$]$f$;"
2412      "}\n"
2413  ));
2414
2415  const EnumValueDescriptorProto& value = file_.enum_type(0).value(0);
2416  const UninterpretedOption& option1 = value.options().uninterpreted_option(0);
2417  const UninterpretedOption& option2 = value.options().uninterpreted_option(1);
2418
2419  EXPECT_TRUE(HasSpan('a', 'f', value.options()));
2420  EXPECT_TRUE(HasSpan('b', 'c', option1));
2421  EXPECT_TRUE(HasSpan('d', 'e', option2));
2422
2423  // Ignore these.
2424  EXPECT_TRUE(HasSpan(file_));
2425  EXPECT_TRUE(HasSpan(file_.enum_type(0)));
2426  EXPECT_TRUE(HasSpan(file_.enum_type(0), "name"));
2427  EXPECT_TRUE(HasSpan(value));
2428  EXPECT_TRUE(HasSpan(value, "name"));
2429  EXPECT_TRUE(HasSpan(value, "number"));
2430  EXPECT_TRUE(HasSpan(option1, "name"));
2431  EXPECT_TRUE(HasSpan(option2, "name"));
2432  EXPECT_TRUE(HasSpan(option1.name(0)));
2433  EXPECT_TRUE(HasSpan(option2.name(0)));
2434  EXPECT_TRUE(HasSpan(option1.name(0), "name_part"));
2435  EXPECT_TRUE(HasSpan(option2.name(0), "name_part"));
2436  EXPECT_TRUE(HasSpan(option1, "positive_int_value"));
2437  EXPECT_TRUE(HasSpan(option2, "string_value"));
2438}
2439
2440TEST_F(SourceInfoTest, DocComments) {
2441  EXPECT_TRUE(Parse(
2442      "// Foo leading\n"
2443      "// line 2\n"
2444      "$a$message Foo {\n"
2445      "  // Foo trailing\n"
2446      "  // line 2\n"
2447      "\n"
2448      "  // ignored\n"
2449      "\n"
2450      "  // bar leading\n"
2451      "  $b$optional int32 bar = 1;$c$\n"
2452      "  // bar trailing\n"
2453      "}$d$\n"
2454      "// ignored\n"
2455  ));
2456
2457  const DescriptorProto& foo = file_.message_type(0);
2458  const FieldDescriptorProto& bar = foo.field(0);
2459
2460  EXPECT_TRUE(HasSpanWithComment('a', 'd', foo,
2461      " Foo leading\n line 2\n",
2462      " Foo trailing\n line 2\n"));
2463  EXPECT_TRUE(HasSpanWithComment('b', 'c', bar,
2464      " bar leading\n",
2465      " bar trailing\n"));
2466
2467  // Ignore these.
2468  EXPECT_TRUE(HasSpan(file_));
2469  EXPECT_TRUE(HasSpan(foo, "name"));
2470  EXPECT_TRUE(HasSpan(bar, "label"));
2471  EXPECT_TRUE(HasSpan(bar, "type"));
2472  EXPECT_TRUE(HasSpan(bar, "name"));
2473  EXPECT_TRUE(HasSpan(bar, "number"));
2474}
2475
2476TEST_F(SourceInfoTest, DocComments2) {
2477  EXPECT_TRUE(Parse(
2478      "// ignored\n"
2479      "syntax = \"proto2\";\n"
2480      "// Foo leading\n"
2481      "// line 2\n"
2482      "$a$message Foo {\n"
2483      "  /* Foo trailing\n"
2484      "   * line 2 */\n"
2485      "  // ignored\n"
2486      "  /* bar leading\n"
2487      "   */"
2488      "  $b$optional int32 bar = 1;$c$  // bar trailing\n"
2489      "  // ignored\n"
2490      "}$d$\n"
2491      "// ignored\n"
2492      "\n"
2493      "// option leading\n"
2494      "$e$option baz = 123;$f$\n"
2495      "// option trailing\n"
2496  ));
2497
2498  const DescriptorProto& foo = file_.message_type(0);
2499  const FieldDescriptorProto& bar = foo.field(0);
2500  const UninterpretedOption& baz = file_.options().uninterpreted_option(0);
2501
2502  EXPECT_TRUE(HasSpanWithComment('a', 'd', foo,
2503      " Foo leading\n line 2\n",
2504      " Foo trailing\n line 2 "));
2505  EXPECT_TRUE(HasSpanWithComment('b', 'c', bar,
2506      " bar leading\n",
2507      " bar trailing\n"));
2508  EXPECT_TRUE(HasSpanWithComment('e', 'f', baz,
2509      " option leading\n",
2510      " option trailing\n"));
2511
2512  // Ignore these.
2513  EXPECT_TRUE(HasSpan(file_));
2514  EXPECT_TRUE(HasSpan(foo, "name"));
2515  EXPECT_TRUE(HasSpan(bar, "label"));
2516  EXPECT_TRUE(HasSpan(bar, "type"));
2517  EXPECT_TRUE(HasSpan(bar, "name"));
2518  EXPECT_TRUE(HasSpan(bar, "number"));
2519  EXPECT_TRUE(HasSpan(file_.options()));
2520  EXPECT_TRUE(HasSpan(baz, "name"));
2521  EXPECT_TRUE(HasSpan(baz.name(0)));
2522  EXPECT_TRUE(HasSpan(baz.name(0), "name_part"));
2523  EXPECT_TRUE(HasSpan(baz, "positive_int_value"));
2524}
2525
2526TEST_F(SourceInfoTest, DocComments3) {
2527  EXPECT_TRUE(Parse(
2528      "$a$message Foo {\n"
2529      "  // bar leading\n"
2530      "  $b$optional int32 bar = 1 [(baz.qux) = {}];$c$\n"
2531      "  // bar trailing\n"
2532      "}$d$\n"
2533      "// ignored\n"
2534  ));
2535
2536  const DescriptorProto& foo = file_.message_type(0);
2537  const FieldDescriptorProto& bar = foo.field(0);
2538
2539  EXPECT_TRUE(HasSpanWithComment('b', 'c', bar,
2540      " bar leading\n",
2541      " bar trailing\n"));
2542
2543  // Ignore these.
2544  EXPECT_TRUE(HasSpan(file_));
2545  EXPECT_TRUE(HasSpan(foo));
2546  EXPECT_TRUE(HasSpan(foo, "name"));
2547  EXPECT_TRUE(HasSpan(bar, "label"));
2548  EXPECT_TRUE(HasSpan(bar, "type"));
2549  EXPECT_TRUE(HasSpan(bar, "name"));
2550  EXPECT_TRUE(HasSpan(bar, "number"));
2551  EXPECT_TRUE(HasSpan(bar.options()));
2552  EXPECT_TRUE(HasSpan(bar.options().uninterpreted_option(0)));
2553  EXPECT_TRUE(HasSpan(bar.options().uninterpreted_option(0), "name"));
2554  EXPECT_TRUE(HasSpan(bar.options().uninterpreted_option(0).name(0)));
2555  EXPECT_TRUE(HasSpan(
2556      bar.options().uninterpreted_option(0).name(0), "name_part"));
2557  EXPECT_TRUE(HasSpan(
2558      bar.options().uninterpreted_option(0), "aggregate_value"));
2559}
2560
2561TEST_F(SourceInfoTest, DocCommentsOneof) {
2562  EXPECT_TRUE(Parse(
2563      "// ignored\n"
2564      "syntax = \"proto2\";\n"
2565      "// Foo leading\n"
2566      "$a$message Foo {\n"
2567      "  /* Foo trailing\n"
2568      "   */\n"
2569      "  // ignored\n"
2570      "  /* bar leading\n"
2571      "   * line 2 */\n"
2572      "  $b$oneof bar {\n"
2573      "  /* bar trailing\n"
2574      "   * line 2 */\n"
2575      "  // ignored\n"
2576      "  /* bar_int leading\n"
2577      "   */\n"
2578      "  $c$int32 bar_int = 1;$d$  // bar_int trailing\n"
2579      "  // ignored\n"
2580      "  }$e$\n"
2581      "}$f$\n"));
2582
2583  const DescriptorProto& foo = file_.message_type(0);
2584  const OneofDescriptorProto& bar = foo.oneof_decl(0);
2585  const FieldDescriptorProto& bar_int = foo.field(0);
2586
2587  EXPECT_TRUE(HasSpanWithComment('a', 'f', foo,
2588      " Foo leading\n",
2589      " Foo trailing\n"));
2590  EXPECT_TRUE(HasSpanWithComment('b', 'e', bar,
2591      " bar leading\n line 2 ",
2592      " bar trailing\n line 2 "));
2593  EXPECT_TRUE(HasSpanWithComment('c', 'd', bar_int,
2594      " bar_int leading\n",
2595      " bar_int trailing\n"));
2596
2597  // Ignore these.
2598  EXPECT_TRUE(HasSpan(file_));
2599  EXPECT_TRUE(HasSpan(foo, "name"));
2600  EXPECT_TRUE(HasSpan(bar, "name"));
2601  EXPECT_TRUE(HasSpan(bar_int, "type"));
2602  EXPECT_TRUE(HasSpan(bar_int, "name"));
2603  EXPECT_TRUE(HasSpan(bar_int, "number"));
2604}
2605
2606// ===================================================================
2607
2608}  // anonymous namespace
2609
2610}  // namespace compiler
2611}  // namespace protobuf
2612}  // namespace google
2613