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