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