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