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