Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1)

Side by Side Diff: third_party/protobuf/src/google/protobuf/compiler/parser_unittest.cc

Issue 1842653006: Update //third_party/protobuf to version 3. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: update sync unittest and README.chromium Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Protocol Buffers - Google's data interchange format 1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2008 Google Inc. All rights reserved. 2 // Copyright 2008 Google Inc. All rights reserved.
3 // http://code.google.com/p/protobuf/ 3 // https://developers.google.com/protocol-buffers/
4 // 4 //
5 // Redistribution and use in source and binary forms, with or without 5 // Redistribution and use in source and binary forms, with or without
6 // modification, are permitted provided that the following conditions are 6 // modification, are permitted provided that the following conditions are
7 // met: 7 // met:
8 // 8 //
9 // * Redistributions of source code must retain the above copyright 9 // * Redistributions of source code must retain the above copyright
10 // notice, this list of conditions and the following disclaimer. 10 // notice, this list of conditions and the following disclaimer.
11 // * Redistributions in binary form must reproduce the above 11 // * Redistributions in binary form must reproduce the above
12 // copyright notice, this list of conditions and the following disclaimer 12 // copyright notice, this list of conditions and the following disclaimer
13 // in the documentation and/or other materials provided with the 13 // in the documentation and/or other materials provided with the
(...skipping 11 matching lines...) Expand all
25 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 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. 29 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 30
31 // Author: kenton@google.com (Kenton Varda) 31 // Author: kenton@google.com (Kenton Varda)
32 // Based on original Protocol Buffers design by 32 // Based on original Protocol Buffers design by
33 // Sanjay Ghemawat, Jeff Dean, and others. 33 // Sanjay Ghemawat, Jeff Dean, and others.
34 34
35 #include <memory>
36 #ifndef _SHARED_PTR_H
37 #include <google/protobuf/stubs/shared_ptr.h>
38 #endif
35 #include <vector> 39 #include <vector>
36 #include <algorithm> 40 #include <algorithm>
37 #include <map> 41 #include <map>
38 42
39 #include <google/protobuf/compiler/parser.h> 43 #include <google/protobuf/compiler/parser.h>
40 44
41 #include <google/protobuf/io/tokenizer.h> 45 #include <google/protobuf/io/tokenizer.h>
42 #include <google/protobuf/io/zero_copy_stream_impl.h> 46 #include <google/protobuf/io/zero_copy_stream_impl.h>
43 #include <google/protobuf/descriptor.pb.h> 47 #include <google/protobuf/descriptor.pb.h>
44 #include <google/protobuf/wire_format.h> 48 #include <google/protobuf/wire_format.h>
45 #include <google/protobuf/text_format.h> 49 #include <google/protobuf/text_format.h>
46 #include <google/protobuf/unittest.pb.h> 50 #include <google/protobuf/unittest.pb.h>
47 #include <google/protobuf/unittest_custom_options.pb.h> 51 #include <google/protobuf/unittest_custom_options.pb.h>
48 #include <google/protobuf/stubs/strutil.h> 52 #include <google/protobuf/stubs/strutil.h>
49 #include <google/protobuf/stubs/substitute.h> 53 #include <google/protobuf/stubs/substitute.h>
50 #include <google/protobuf/stubs/map-util.h> 54 #include <google/protobuf/stubs/map_util.h>
51 55
52 #include <google/protobuf/testing/googletest.h> 56 #include <google/protobuf/testing/googletest.h>
53 #include <gtest/gtest.h> 57 #include <gtest/gtest.h>
54 58
55 namespace google { 59 namespace google {
56 namespace protobuf { 60 namespace protobuf {
57 namespace compiler { 61 namespace compiler {
58 62
59 namespace { 63 namespace {
60 64
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
167 MockValidationErrorCollector validation_error_collector( 171 MockValidationErrorCollector validation_error_collector(
168 source_locations, &error_collector_); 172 source_locations, &error_collector_);
169 EXPECT_TRUE(pool_.BuildFileCollectingErrors( 173 EXPECT_TRUE(pool_.BuildFileCollectingErrors(
170 file, &validation_error_collector) == NULL); 174 file, &validation_error_collector) == NULL);
171 EXPECT_EQ(expected_errors, error_collector_.text_); 175 EXPECT_EQ(expected_errors, error_collector_.text_);
172 } 176 }
173 177
174 MockErrorCollector error_collector_; 178 MockErrorCollector error_collector_;
175 DescriptorPool pool_; 179 DescriptorPool pool_;
176 180
177 scoped_ptr<io::ZeroCopyInputStream> raw_input_; 181 google::protobuf::scoped_ptr<io::ZeroCopyInputStream> raw_input_;
178 scoped_ptr<io::Tokenizer> input_; 182 google::protobuf::scoped_ptr<io::Tokenizer> input_;
179 scoped_ptr<Parser> parser_; 183 google::protobuf::scoped_ptr<Parser> parser_;
180 bool require_syntax_identifier_; 184 bool require_syntax_identifier_;
181 }; 185 };
182 186
183 // =================================================================== 187 // ===================================================================
184 188
185 TEST_F(ParserTest, StopAfterSyntaxIdentifier) { 189 TEST_F(ParserTest, StopAfterSyntaxIdentifier) {
186 SetupParser( 190 SetupParser(
187 "// blah\n" 191 "// blah\n"
188 "syntax = \"foobar\";\n" 192 "syntax = \"foobar\";\n"
189 "this line will not be parsed\n"); 193 "this line will not be parsed\n");
(...skipping 15 matching lines...) Expand all
205 209
206 TEST_F(ParserTest, StopAfterSyntaxIdentifierWithErrors) { 210 TEST_F(ParserTest, StopAfterSyntaxIdentifierWithErrors) {
207 SetupParser( 211 SetupParser(
208 "// blah\n" 212 "// blah\n"
209 "syntax = error;\n"); 213 "syntax = error;\n");
210 parser_->SetStopAfterSyntaxIdentifier(true); 214 parser_->SetStopAfterSyntaxIdentifier(true);
211 EXPECT_FALSE(parser_->Parse(input_.get(), NULL)); 215 EXPECT_FALSE(parser_->Parse(input_.get(), NULL));
212 EXPECT_EQ("1:9: Expected syntax identifier.\n", error_collector_.text_); 216 EXPECT_EQ("1:9: Expected syntax identifier.\n", error_collector_.text_);
213 } 217 }
214 218
219 TEST_F(ParserTest, WarnIfSyntaxIdentifierOmmitted) {
220 SetupParser("message A {}");
221 FileDescriptorProto file;
222 CaptureTestStderr();
223 EXPECT_TRUE(parser_->Parse(input_.get(), &file));
224 EXPECT_TRUE(
225 GetCapturedTestStderr().find("No syntax specified") != string::npos);
226 }
227
215 // =================================================================== 228 // ===================================================================
216 229
217 typedef ParserTest ParseMessageTest; 230 typedef ParserTest ParseMessageTest;
218 231
232 TEST_F(ParseMessageTest, IgnoreBOM) {
233 char input[] = " message TestMessage {\n"
234 " required int32 foo = 1;\n"
235 "}\n";
236 // Set UTF-8 BOM.
237 input[0] = (char)0xEF;
238 input[1] = (char)0xBB;
239 input[2] = (char)0xBF;
240 ExpectParsesTo(input,
241 "message_type {"
242 " name: \"TestMessage\""
243 " field { name:\"foo\" label:LABEL_REQUIRED type:TYPE_INT32 number:1 }"
244 "}");
245 }
246
247 TEST_F(ParseMessageTest, BOMError) {
248 char input[] = " message TestMessage {\n"
249 " required int32 foo = 1;\n"
250 "}\n";
251 input[0] = (char)0xEF;
252 ExpectHasErrors(input,
253 "0:1: Proto file starts with 0xEF but not UTF-8 BOM. "
254 "Only UTF-8 is accepted for proto file.\n"
255 "0:0: Expected top-level statement (e.g. \"message\").\n");
256 }
257
219 TEST_F(ParseMessageTest, SimpleMessage) { 258 TEST_F(ParseMessageTest, SimpleMessage) {
220 ExpectParsesTo( 259 ExpectParsesTo(
221 "message TestMessage {\n" 260 "message TestMessage {\n"
222 " required int32 foo = 1;\n" 261 " required int32 foo = 1;\n"
223 "}\n", 262 "}\n",
224 263
225 "message_type {" 264 "message_type {"
226 " name: \"TestMessage\"" 265 " name: \"TestMessage\""
227 " field { name:\"foo\" label:LABEL_REQUIRED type:TYPE_INT32 number:1 }" 266 " field { name:\"foo\" label:LABEL_REQUIRED type:TYPE_INT32 number:1 }"
228 "}"); 267 "}");
(...skipping 13 matching lines...) Expand all
242 EXPECT_EQ("proto2", parser_->GetSyntaxIdentifier()); 281 EXPECT_EQ("proto2", parser_->GetSyntaxIdentifier());
243 } 282 }
244 283
245 TEST_F(ParseMessageTest, ExplicitSyntaxIdentifier) { 284 TEST_F(ParseMessageTest, ExplicitSyntaxIdentifier) {
246 ExpectParsesTo( 285 ExpectParsesTo(
247 "syntax = \"proto2\";\n" 286 "syntax = \"proto2\";\n"
248 "message TestMessage {\n" 287 "message TestMessage {\n"
249 " required int32 foo = 1;\n" 288 " required int32 foo = 1;\n"
250 "}\n", 289 "}\n",
251 290
291 "syntax: 'proto2' "
252 "message_type {" 292 "message_type {"
253 " name: \"TestMessage\"" 293 " name: \"TestMessage\""
254 " field { name:\"foo\" label:LABEL_REQUIRED type:TYPE_INT32 number:1 }" 294 " field { name:\"foo\" label:LABEL_REQUIRED type:TYPE_INT32 number:1 }"
255 "}"); 295 "}");
256 EXPECT_EQ("proto2", parser_->GetSyntaxIdentifier()); 296 EXPECT_EQ("proto2", parser_->GetSyntaxIdentifier());
257 } 297 }
258 298
259 TEST_F(ParseMessageTest, ExplicitRequiredSyntaxIdentifier) { 299 TEST_F(ParseMessageTest, ExplicitRequiredSyntaxIdentifier) {
260 require_syntax_identifier_ = true; 300 require_syntax_identifier_ = true;
261 ExpectParsesTo( 301 ExpectParsesTo(
262 "syntax = \"proto2\";\n" 302 "syntax = \"proto2\";\n"
263 "message TestMessage {\n" 303 "message TestMessage {\n"
264 " required int32 foo = 1;\n" 304 " required int32 foo = 1;\n"
265 "}\n", 305 "}\n",
266 306
307 "syntax: 'proto2' "
267 "message_type {" 308 "message_type {"
268 " name: \"TestMessage\"" 309 " name: \"TestMessage\""
269 " field { name:\"foo\" label:LABEL_REQUIRED type:TYPE_INT32 number:1 }" 310 " field { name:\"foo\" label:LABEL_REQUIRED type:TYPE_INT32 number:1 }"
270 "}"); 311 "}");
271 EXPECT_EQ("proto2", parser_->GetSyntaxIdentifier()); 312 EXPECT_EQ("proto2", parser_->GetSyntaxIdentifier());
272 } 313 }
273 314
274 TEST_F(ParseMessageTest, SimpleFields) { 315 TEST_F(ParseMessageTest, SimpleFields) {
275 ExpectParsesTo( 316 ExpectParsesTo(
276 "message TestMessage {\n" 317 "message TestMessage {\n"
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
357 " required uint32 foo = 1 [default= 0xFFFFFFFF];\n" 398 " required uint32 foo = 1 [default= 0xFFFFFFFF];\n"
358 " required int64 foo = 1 [default= 0x7FFFFFFFFFFFFFFF];\n" 399 " required int64 foo = 1 [default= 0x7FFFFFFFFFFFFFFF];\n"
359 " required int64 foo = 1 [default=-0x8000000000000000];\n" 400 " required int64 foo = 1 [default=-0x8000000000000000];\n"
360 " required uint64 foo = 1 [default= 0xFFFFFFFFFFFFFFFF];\n" 401 " required uint64 foo = 1 [default= 0xFFFFFFFFFFFFFFFF];\n"
361 " required double foo = 1 [default= 0xabcd];\n" 402 " required double foo = 1 [default= 0xabcd];\n"
362 "}\n", 403 "}\n",
363 404
364 #define ETC "name:\"foo\" label:LABEL_REQUIRED number:1" 405 #define ETC "name:\"foo\" label:LABEL_REQUIRED number:1"
365 "message_type {" 406 "message_type {"
366 " name: \"TestMessage\"" 407 " name: \"TestMessage\""
367 " field { type:TYPE_INT32 default_value:\"1\" "ETC" }" 408 " field { type:TYPE_INT32 default_value:\"1\" " ETC " }"
368 " field { type:TYPE_INT32 default_value:\"-2\" "ETC" }" 409 " field { type:TYPE_INT32 default_value:\"-2\" " ETC " }"
369 " field { type:TYPE_INT64 default_value:\"3\" "ETC" }" 410 " field { type:TYPE_INT64 default_value:\"3\" " ETC " }"
370 " field { type:TYPE_INT64 default_value:\"-4\" "ETC" }" 411 " field { type:TYPE_INT64 default_value:\"-4\" " ETC " }"
371 " field { type:TYPE_UINT32 default_value:\"5\" "ETC" }" 412 " field { type:TYPE_UINT32 default_value:\"5\" " ETC " }"
372 " field { type:TYPE_UINT64 default_value:\"6\" "ETC" }" 413 " field { type:TYPE_UINT64 default_value:\"6\" " ETC " }"
373 " field { type:TYPE_FLOAT default_value:\"7.5\" "ETC" }" 414 " field { type:TYPE_FLOAT default_value:\"7.5\" " ETC " }"
374 " field { type:TYPE_FLOAT default_value:\"-8.5\" "ETC" }" 415 " field { type:TYPE_FLOAT default_value:\"-8.5\" " ETC " }"
375 " field { type:TYPE_FLOAT default_value:\"9\" "ETC" }" 416 " field { type:TYPE_FLOAT default_value:\"9\" " ETC " }"
376 " field { type:TYPE_DOUBLE default_value:\"10.5\" "ETC" }" 417 " field { type:TYPE_DOUBLE default_value:\"10.5\" " ETC " }"
377 " field { type:TYPE_DOUBLE default_value:\"-11.5\" "ETC" }" 418 " field { type:TYPE_DOUBLE default_value:\"-11.5\" " ETC " }"
378 " field { type:TYPE_DOUBLE default_value:\"12\" "ETC" }" 419 " field { type:TYPE_DOUBLE default_value:\"12\" " ETC " }"
379 " field { type:TYPE_DOUBLE default_value:\"inf\" "ETC" }" 420 " field { type:TYPE_DOUBLE default_value:\"inf\" " ETC " }"
380 " field { type:TYPE_DOUBLE default_value:\"-inf\" "ETC" }" 421 " field { type:TYPE_DOUBLE default_value:\"-inf\" " ETC " }"
381 " field { type:TYPE_DOUBLE default_value:\"nan\" "ETC" }" 422 " field { type:TYPE_DOUBLE default_value:\"nan\" " ETC " }"
382 " field { type:TYPE_STRING default_value:\"13\\001\" "ETC" }" 423 " field { type:TYPE_STRING default_value:\"13\\001\" " ETC " }"
383 " field { type:TYPE_STRING default_value:\"abc\" "ETC" }" 424 " field { type:TYPE_STRING default_value:\"abc\" " ETC " }"
384 " field { type:TYPE_BYTES default_value:\"14\\\\002\" "ETC" }" 425 " field { type:TYPE_BYTES default_value:\"14\\\\002\" " ETC " }"
385 " field { type:TYPE_BYTES default_value:\"abc\" "ETC" }" 426 " field { type:TYPE_BYTES default_value:\"abc\" " ETC " }"
386 " field { type:TYPE_BOOL default_value:\"true\" "ETC" }" 427 " field { type:TYPE_BOOL default_value:\"true\" " ETC " }"
387 " field { type_name:\"Foo\" default_value:\"FOO\" "ETC" }" 428 " field { type_name:\"Foo\" default_value:\"FOO\" " ETC " }"
388 429
389 " field { type:TYPE_INT32 default_value:\"2147483647\" "ETC" }" 430 " field {"
390 " field { type:TYPE_INT32 default_value:\"-2147483648\" "ETC" }" 431 " type:TYPE_INT32 default_value:\"2147483647\" " ETC
391 " field { type:TYPE_UINT32 default_value:\"4294967295\" "ETC" }" 432 " }"
392 " field { type:TYPE_INT64 default_value:\"9223372036854775807\" "ETC" }" 433 " field {"
393 " field { type:TYPE_INT64 default_value:\"-9223372036854775808\" "ETC" }" 434 " type:TYPE_INT32 default_value:\"-2147483648\" " ETC
394 " field { type:TYPE_UINT64 default_value:\"18446744073709551615\" "ETC" }" 435 " }"
395 " field { type:TYPE_DOUBLE default_value:\"43981\" "ETC" }" 436 " field {"
437 " type:TYPE_UINT32 default_value:\"4294967295\" " ETC
438 " }"
439 " field {"
440 " type:TYPE_INT64 default_value:\"9223372036854775807\" " ETC
441 " }"
442 " field {"
443 " type:TYPE_INT64 default_value:\"-9223372036854775808\" " ETC
444 " }"
445 " field {"
446 " type:TYPE_UINT64 default_value:\"18446744073709551615\" " ETC
447 " }"
448 " field {"
449 " type:TYPE_DOUBLE default_value:\"43981\" " ETC
450 " }"
396 "}"); 451 "}");
397 #undef ETC 452 #undef ETC
398 } 453 }
399 454
455 TEST_F(ParseMessageTest, FieldJsonName) {
456 ExpectParsesTo(
457 "message TestMessage {\n"
458 " optional string foo = 1 [json_name = \"@type\"];\n"
459 "}\n",
460 "message_type {"
461 " name: \"TestMessage\""
462 " field {\n"
463 " name: \"foo\" label: LABEL_OPTIONAL type: TYPE_STRING number: 1"
464 " json_name: \"@type\"\n"
465 " }\n"
466 "}\n");
467 }
468
400 TEST_F(ParseMessageTest, FieldOptions) { 469 TEST_F(ParseMessageTest, FieldOptions) {
401 ExpectParsesTo( 470 ExpectParsesTo(
402 "message TestMessage {\n" 471 "message TestMessage {\n"
403 " optional string foo = 1\n" 472 " optional string foo = 1\n"
404 " [ctype=CORD, (foo)=7, foo.(.bar.baz).qux.quux.(corge)=-33, \n" 473 " [ctype=CORD, (foo)=7, foo.(.bar.baz).qux.quux.(corge)=-33, \n"
405 " (quux)=\"x\040y\", (baz.qux)=hey];\n" 474 " (quux)=\"x\040y\", (baz.qux)=hey];\n"
406 "}\n", 475 "}\n",
407 476
408 "message_type {" 477 "message_type {"
409 " name: \"TestMessage\"" 478 " name: \"TestMessage\""
(...skipping 19 matching lines...) Expand all
429 " is_extension: true } " 498 " is_extension: true } "
430 " string_value: \"x y\" }" 499 " string_value: \"x y\" }"
431 " uninterpreted_option: { name { name_part: \"baz.qux\" " 500 " uninterpreted_option: { name { name_part: \"baz.qux\" "
432 " is_extension: true } " 501 " is_extension: true } "
433 " identifier_value: \"hey\" }" 502 " identifier_value: \"hey\" }"
434 " }" 503 " }"
435 " }" 504 " }"
436 "}"); 505 "}");
437 } 506 }
438 507
508 TEST_F(ParseMessageTest, Oneof) {
509 ExpectParsesTo(
510 "message TestMessage {\n"
511 " oneof foo {\n"
512 " int32 a = 1;\n"
513 " string b = 2;\n"
514 " TestMessage c = 3;\n"
515 " group D = 4 { optional int32 i = 5; }\n"
516 " }\n"
517 "}\n",
518
519 "message_type {"
520 " name: \"TestMessage\""
521 " field { name:\"a\" label:LABEL_OPTIONAL type:TYPE_INT32 number:1 "
522 " oneof_index:0 }"
523 " field { name:\"b\" label:LABEL_OPTIONAL type:TYPE_STRING number:2 "
524 " oneof_index:0 }"
525 " field { name:\"c\" label:LABEL_OPTIONAL type_name:\"TestMessage\" "
526 " number:3 oneof_index:0 }"
527 " field { name:\"d\" label:LABEL_OPTIONAL type:TYPE_GROUP "
528 " type_name:\"D\" number:4 oneof_index:0 }"
529 " oneof_decl {"
530 " name: \"foo\""
531 " }"
532 " nested_type {"
533 " name: \"D\""
534 " field { name:\"i\" label:LABEL_OPTIONAL type:TYPE_INT32 number:5 }"
535 " }"
536 "}");
537 }
538
539 TEST_F(ParseMessageTest, MultipleOneofs) {
540 ExpectParsesTo(
541 "message TestMessage {\n"
542 " oneof foo {\n"
543 " int32 a = 1;\n"
544 " string b = 2;\n"
545 " }\n"
546 " oneof bar {\n"
547 " int32 c = 3;\n"
548 " string d = 4;\n"
549 " }\n"
550 "}\n",
551
552 "message_type {"
553 " name: \"TestMessage\""
554 " field { name:\"a\" label:LABEL_OPTIONAL type:TYPE_INT32 number:1 "
555 " oneof_index:0 }"
556 " field { name:\"b\" label:LABEL_OPTIONAL type:TYPE_STRING number:2 "
557 " oneof_index:0 }"
558 " field { name:\"c\" label:LABEL_OPTIONAL type:TYPE_INT32 number:3 "
559 " oneof_index:1 }"
560 " field { name:\"d\" label:LABEL_OPTIONAL type:TYPE_STRING number:4 "
561 " oneof_index:1 }"
562 " oneof_decl {"
563 " name: \"foo\""
564 " }"
565 " oneof_decl {"
566 " name: \"bar\""
567 " }"
568 "}");
569 }
570
571 TEST_F(ParseMessageTest, Maps) {
572 ExpectParsesTo(
573 "message TestMessage {\n"
574 " map<int32, string> primitive_type_map = 1;\n"
575 " map<KeyType, ValueType> composite_type_map = 2;\n"
576 "}\n",
577
578 "message_type {"
579 " name: \"TestMessage\""
580 " nested_type {"
581 " name: \"PrimitiveTypeMapEntry\""
582 " field { "
583 " name: \"key\" number: 1 label:LABEL_OPTIONAL"
584 " type:TYPE_INT32"
585 " }"
586 " field { "
587 " name: \"value\" number: 2 label:LABEL_OPTIONAL"
588 " type:TYPE_STRING"
589 " }"
590 " options { map_entry: true }"
591 " }"
592 " nested_type {"
593 " name: \"CompositeTypeMapEntry\""
594 " field { "
595 " name: \"key\" number: 1 label:LABEL_OPTIONAL"
596 " type_name: \"KeyType\""
597 " }"
598 " field { "
599 " name: \"value\" number: 2 label:LABEL_OPTIONAL"
600 " type_name: \"ValueType\""
601 " }"
602 " options { map_entry: true }"
603 " }"
604 " field {"
605 " name: \"primitive_type_map\""
606 " label: LABEL_REPEATED"
607 " type_name: \"PrimitiveTypeMapEntry\""
608 " number: 1"
609 " }"
610 " field {"
611 " name: \"composite_type_map\""
612 " label: LABEL_REPEATED"
613 " type_name: \"CompositeTypeMapEntry\""
614 " number: 2"
615 " }"
616 "}");
617 }
618
439 TEST_F(ParseMessageTest, Group) { 619 TEST_F(ParseMessageTest, Group) {
440 ExpectParsesTo( 620 ExpectParsesTo(
441 "message TestMessage {\n" 621 "message TestMessage {\n"
442 " optional group TestGroup = 1 {};\n" 622 " optional group TestGroup = 1 {};\n"
443 "}\n", 623 "}\n",
444 624
445 "message_type {" 625 "message_type {"
446 " name: \"TestMessage\"" 626 " name: \"TestMessage\""
447 " nested_type { name: \"TestGroup\" }" 627 " nested_type { name: \"TestGroup\" }"
448 " field { name:\"testgroup\" label:LABEL_OPTIONAL number:1" 628 " field { name:\"testgroup\" label:LABEL_OPTIONAL number:1"
(...skipping 24 matching lines...) Expand all
473 "}\n", 653 "}\n",
474 654
475 "message_type {" 655 "message_type {"
476 " name: \"TestMessage\"" 656 " name: \"TestMessage\""
477 " enum_type { name: \"NestedEnum\" }" 657 " enum_type { name: \"NestedEnum\" }"
478 " field { name:\"test_enum\" label:LABEL_OPTIONAL number:1" 658 " field { name:\"test_enum\" label:LABEL_OPTIONAL number:1"
479 " type_name: \"NestedEnum\" }" 659 " type_name: \"NestedEnum\" }"
480 "}"); 660 "}");
481 } 661 }
482 662
663 TEST_F(ParseMessageTest, ReservedRange) {
664 ExpectParsesTo(
665 "message TestMessage {\n"
666 " required int32 foo = 1;\n"
667 " reserved 2, 15, 9 to 11, 3;\n"
668 "}\n",
669
670 "message_type {"
671 " name: \"TestMessage\""
672 " field { name:\"foo\" label:LABEL_REQUIRED type:TYPE_INT32 number:1 }"
673 " reserved_range { start:2 end:3 }"
674 " reserved_range { start:15 end:16 }"
675 " reserved_range { start:9 end:12 }"
676 " reserved_range { start:3 end:4 }"
677 "}");
678 }
679
680 TEST_F(ParseMessageTest, ReservedNames) {
681 ExpectParsesTo(
682 "message TestMessage {\n"
683 " reserved \"foo\", \"bar\";\n"
684 "}\n",
685
686 "message_type {"
687 " name: \"TestMessage\""
688 " reserved_name: \"foo\""
689 " reserved_name: \"bar\""
690 "}");
691 }
692
483 TEST_F(ParseMessageTest, ExtensionRange) { 693 TEST_F(ParseMessageTest, ExtensionRange) {
484 ExpectParsesTo( 694 ExpectParsesTo(
485 "message TestMessage {\n" 695 "message TestMessage {\n"
486 " extensions 10 to 19;\n" 696 " extensions 10 to 19;\n"
487 " extensions 30 to max;\n" 697 " extensions 30 to max;\n"
488 "}\n", 698 "}\n",
489 699
490 "message_type {" 700 "message_type {"
491 " name: \"TestMessage\"" 701 " name: \"TestMessage\""
492 " extension_range { start:10 end:20 }" 702 " extension_range { start:10 end:20 }"
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
568 " optional int32 foo = 12;\n" 778 " optional int32 foo = 12;\n"
569 " repeated TestMessage bar = 22;\n" 779 " repeated TestMessage bar = 22;\n"
570 "}\n", 780 "}\n",
571 781
572 "extension { name:\"foo\" label:LABEL_OPTIONAL type:TYPE_INT32 number:12" 782 "extension { name:\"foo\" label:LABEL_OPTIONAL type:TYPE_INT32 number:12"
573 " extendee: \"Extendee1\" } " 783 " extendee: \"Extendee1\" } "
574 "extension { name:\"bar\" label:LABEL_REPEATED number:22" 784 "extension { name:\"bar\" label:LABEL_REPEATED number:22"
575 " type_name:\"TestMessage\" extendee: \"Extendee1\" }"); 785 " type_name:\"TestMessage\" extendee: \"Extendee1\" }");
576 } 786 }
577 787
788 TEST_F(ParseMessageTest, OptionalLabelProto3) {
789 ExpectParsesTo(
790 "syntax = \"proto3\";\n"
791 "message TestMessage {\n"
792 " int32 foo = 1;\n"
793 "}\n",
794
795 "syntax: \"proto3\" "
796 "message_type {"
797 " name: \"TestMessage\""
798 " field { name:\"foo\" label:LABEL_OPTIONAL type:TYPE_INT32 number:1 } }");
799 }
800
578 // =================================================================== 801 // ===================================================================
579 802
580 typedef ParserTest ParseEnumTest; 803 typedef ParserTest ParseEnumTest;
581 804
582 TEST_F(ParseEnumTest, SimpleEnum) { 805 TEST_F(ParseEnumTest, SimpleEnum) {
583 ExpectParsesTo( 806 ExpectParsesTo(
584 "enum TestEnum {\n" 807 "enum TestEnum {\n"
585 " FOO = 0;\n" 808 " FOO = 0;\n"
586 "}\n", 809 "}\n",
587 810
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
674 "}\n", 897 "}\n",
675 898
676 "service {" 899 "service {"
677 " name: \"TestService\"" 900 " name: \"TestService\""
678 " method { name:\"Foo\" input_type:\"In1\" output_type:\"Out1\" }" 901 " method { name:\"Foo\" input_type:\"In1\" output_type:\"Out1\" }"
679 " method { name:\"Bar\" input_type:\"In2\" output_type:\"Out2\" }" 902 " method { name:\"Bar\" input_type:\"In2\" output_type:\"Out2\" }"
680 " method { name:\"Baz\" input_type:\"In3\" output_type:\"Out3\" }" 903 " method { name:\"Baz\" input_type:\"In3\" output_type:\"Out3\" }"
681 "}"); 904 "}");
682 } 905 }
683 906
907
908
684 // =================================================================== 909 // ===================================================================
685 // imports and packages 910 // imports and packages
686 911
687 typedef ParserTest ParseMiscTest; 912 typedef ParserTest ParseMiscTest;
688 913
689 TEST_F(ParseMiscTest, ParseImport) { 914 TEST_F(ParseMiscTest, ParseImport) {
690 ExpectParsesTo( 915 ExpectParsesTo(
691 "import \"foo/bar/baz.proto\";\n", 916 "import \"foo/bar/baz.proto\";\n",
692 "dependency: \"foo/bar/baz.proto\""); 917 "dependency: \"foo/bar/baz.proto\"");
693 } 918 }
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
754 // report, so it's infeasible to test every single one of them. Instead, 979 // report, so it's infeasible to test every single one of them. Instead,
755 // we test each unique call to AddError() in parser.h. This does not mean 980 // we test each unique call to AddError() in parser.h. This does not mean
756 // we are testing every possible error that Parser can generate because 981 // we are testing every possible error that Parser can generate because
757 // each variant of the Consume() helper only counts as one unique call to 982 // each variant of the Consume() helper only counts as one unique call to
758 // AddError(). 983 // AddError().
759 984
760 typedef ParserTest ParseErrorTest; 985 typedef ParserTest ParseErrorTest;
761 986
762 TEST_F(ParseErrorTest, MissingSyntaxIdentifier) { 987 TEST_F(ParseErrorTest, MissingSyntaxIdentifier) {
763 require_syntax_identifier_ = true; 988 require_syntax_identifier_ = true;
764 ExpectHasEarlyExitErrors( 989 ExpectHasEarlyExitErrors("message TestMessage {}",
765 "message TestMessage {}", 990 "0:0: File must begin with a syntax statement, e.g. "
766 "0:0: File must begin with 'syntax = \"proto2\";'.\n"); 991 "'syntax = \"proto2\";'.\n");
767 EXPECT_EQ("", parser_->GetSyntaxIdentifier()); 992 EXPECT_EQ("", parser_->GetSyntaxIdentifier());
768 } 993 }
769 994
770 TEST_F(ParseErrorTest, UnknownSyntaxIdentifier) { 995 TEST_F(ParseErrorTest, UnknownSyntaxIdentifier) {
771 ExpectHasEarlyExitErrors( 996 ExpectHasEarlyExitErrors(
772 "syntax = \"no_such_syntax\";", 997 "syntax = \"no_such_syntax\";",
773 "0:9: Unrecognized syntax identifier \"no_such_syntax\". This parser " 998 "0:9: Unrecognized syntax identifier \"no_such_syntax\". This parser "
774 "only recognizes \"proto2\".\n"); 999 "only recognizes \"proto2\" and \"proto3\".\n");
775 EXPECT_EQ("no_such_syntax", parser_->GetSyntaxIdentifier()); 1000 EXPECT_EQ("no_such_syntax", parser_->GetSyntaxIdentifier());
776 } 1001 }
777 1002
778 TEST_F(ParseErrorTest, SimpleSyntaxError) { 1003 TEST_F(ParseErrorTest, SimpleSyntaxError) {
779 ExpectHasErrors( 1004 ExpectHasErrors(
780 "message TestMessage @#$ { blah }", 1005 "message TestMessage @#$ { blah }",
781 "0:20: Expected \"{\".\n"); 1006 "0:20: Expected \"{\".\n");
782 EXPECT_EQ("proto2", parser_->GetSyntaxIdentifier()); 1007 EXPECT_EQ("proto2", parser_->GetSyntaxIdentifier());
783 } 1008 }
784 1009
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
863 " optional uint32 foo = 1 [.foo=1];\n" 1088 " optional uint32 foo = 1 [.foo=1];\n"
864 "}\n", 1089 "}\n",
865 "1:27: Expected identifier.\n"); 1090 "1:27: Expected identifier.\n");
866 } 1091 }
867 1092
868 TEST_F(ParseErrorTest, DefaultValueTypeMismatch) { 1093 TEST_F(ParseErrorTest, DefaultValueTypeMismatch) {
869 ExpectHasErrors( 1094 ExpectHasErrors(
870 "message TestMessage {\n" 1095 "message TestMessage {\n"
871 " optional uint32 foo = 1 [default=true];\n" 1096 " optional uint32 foo = 1 [default=true];\n"
872 "}\n", 1097 "}\n",
873 "1:35: Expected integer.\n"); 1098 "1:35: Expected integer for field default value.\n");
874 } 1099 }
875 1100
876 TEST_F(ParseErrorTest, DefaultValueNotBoolean) { 1101 TEST_F(ParseErrorTest, DefaultValueNotBoolean) {
877 ExpectHasErrors( 1102 ExpectHasErrors(
878 "message TestMessage {\n" 1103 "message TestMessage {\n"
879 " optional bool foo = 1 [default=blah];\n" 1104 " optional bool foo = 1 [default=blah];\n"
880 "}\n", 1105 "}\n",
881 "1:33: Expected \"true\" or \"false\".\n"); 1106 "1:33: Expected \"true\" or \"false\".\n");
882 } 1107 }
883 1108
884 TEST_F(ParseErrorTest, DefaultValueNotString) { 1109 TEST_F(ParseErrorTest, DefaultValueNotString) {
885 ExpectHasErrors( 1110 ExpectHasErrors(
886 "message TestMessage {\n" 1111 "message TestMessage {\n"
887 " optional string foo = 1 [default=1];\n" 1112 " optional string foo = 1 [default=1];\n"
888 "}\n", 1113 "}\n",
889 "1:35: Expected string.\n"); 1114 "1:35: Expected string for field default value.\n");
890 } 1115 }
891 1116
892 TEST_F(ParseErrorTest, DefaultValueUnsignedNegative) { 1117 TEST_F(ParseErrorTest, DefaultValueUnsignedNegative) {
893 ExpectHasErrors( 1118 ExpectHasErrors(
894 "message TestMessage {\n" 1119 "message TestMessage {\n"
895 " optional uint32 foo = 1 [default=-1];\n" 1120 " optional uint32 foo = 1 [default=-1];\n"
896 "}\n", 1121 "}\n",
897 "1:36: Unsigned field can't have negative default value.\n"); 1122 "1:36: Unsigned field can't have negative default value.\n");
898 } 1123 }
899 1124
900 TEST_F(ParseErrorTest, DefaultValueTooLarge) { 1125 TEST_F(ParseErrorTest, DefaultValueTooLarge) {
901 ExpectHasErrors( 1126 ExpectHasErrors(
902 "message TestMessage {\n" 1127 "message TestMessage {\n"
903 " optional int32 foo = 1 [default= 0x80000000];\n" 1128 " optional int32 foo = 1 [default= 0x80000000];\n"
904 " optional int32 foo = 1 [default=-0x80000001];\n" 1129 " optional int32 foo = 1 [default=-0x80000001];\n"
905 " optional uint32 foo = 1 [default= 0x100000000];\n" 1130 " optional uint32 foo = 1 [default= 0x100000000];\n"
906 " optional int64 foo = 1 [default= 0x80000000000000000];\n" 1131 " optional int64 foo = 1 [default= 0x80000000000000000];\n"
907 " optional int64 foo = 1 [default=-0x80000000000000001];\n" 1132 " optional int64 foo = 1 [default=-0x80000000000000001];\n"
908 " optional uint64 foo = 1 [default= 0x100000000000000000];\n" 1133 " optional uint64 foo = 1 [default= 0x100000000000000000];\n"
909 "}\n", 1134 "}\n",
910 "1:36: Integer out of range.\n" 1135 "1:36: Integer out of range.\n"
911 "2:36: Integer out of range.\n" 1136 "2:36: Integer out of range.\n"
912 "3:36: Integer out of range.\n" 1137 "3:36: Integer out of range.\n"
913 "4:36: Integer out of range.\n" 1138 "4:36: Integer out of range.\n"
914 "5:36: Integer out of range.\n" 1139 "5:36: Integer out of range.\n"
915 "6:36: Integer out of range.\n"); 1140 "6:36: Integer out of range.\n");
916 } 1141 }
917 1142
1143 TEST_F(ParseErrorTest, JsonNameNotString) {
1144 ExpectHasErrors(
1145 "message TestMessage {\n"
1146 " optional string foo = 1 [json_name=1];\n"
1147 "}\n",
1148 "1:37: Expected string for JSON name.\n");
1149 }
1150
1151 TEST_F(ParseErrorTest, DuplicateJsonName) {
1152 ExpectHasErrors(
1153 "message TestMessage {\n"
1154 " optional uint32 foo = 1 [json_name=\"a\",json_name=\"b\"];\n"
1155 "}\n",
1156 "1:41: Already set option \"json_name\".\n");
1157 }
1158
918 TEST_F(ParseErrorTest, EnumValueOutOfRange) { 1159 TEST_F(ParseErrorTest, EnumValueOutOfRange) {
919 ExpectHasErrors( 1160 ExpectHasErrors(
920 "enum TestEnum {\n" 1161 "enum TestEnum {\n"
921 " HEX_TOO_BIG = 0x80000000;\n" 1162 " HEX_TOO_BIG = 0x80000000;\n"
922 " HEX_TOO_SMALL = -0x80000001;\n" 1163 " HEX_TOO_SMALL = -0x80000001;\n"
923 " INT_TOO_BIG = 2147483648;\n" 1164 " INT_TOO_BIG = 2147483648;\n"
924 " INT_TOO_SMALL = -2147483649;\n" 1165 " INT_TOO_SMALL = -2147483649;\n"
925 "}\n", 1166 "}\n",
926 "1:19: Integer out of range.\n" 1167 "1:19: Integer out of range.\n"
927 "2:19: Integer out of range.\n" 1168 "2:19: Integer out of range.\n"
928 "3:19: Integer out of range.\n" 1169 "3:19: Integer out of range.\n"
929 "4:19: Integer out of range.\n"); 1170 "4:19: Integer out of range.\n");
930 } 1171 }
931 1172
1173 TEST_F(ParseErrorTest, EnumAllowAliasFalse) {
1174 ExpectHasErrors(
1175 "enum Foo {\n"
1176 " option allow_alias = false;\n"
1177 " BAR = 1;\n"
1178 " BAZ = 2;\n"
1179 "}\n",
1180 "5:0: \"Foo\" declares 'option allow_alias = false;' which has no effect. "
1181 "Please remove the declaration.\n");
1182 }
1183
1184 TEST_F(ParseErrorTest, UnnecessaryEnumAllowAlias) {
1185 ExpectHasErrors(
1186 "enum Foo {\n"
1187 " option allow_alias = true;\n"
1188 " BAR = 1;\n"
1189 " BAZ = 2;\n"
1190 "}\n",
1191 "5:0: \"Foo\" declares support for enum aliases but no enum values share "
1192 "field numbers. Please remove the unnecessary 'option allow_alias = true;' "
1193 "declaration.\n");
1194 }
1195
932 TEST_F(ParseErrorTest, DefaultValueMissing) { 1196 TEST_F(ParseErrorTest, DefaultValueMissing) {
933 ExpectHasErrors( 1197 ExpectHasErrors(
934 "message TestMessage {\n" 1198 "message TestMessage {\n"
935 " optional uint32 foo = 1 [default=];\n" 1199 " optional uint32 foo = 1 [default=];\n"
936 "}\n", 1200 "}\n",
937 "1:35: Expected integer.\n"); 1201 "1:35: Expected integer for field default value.\n");
938 } 1202 }
939 1203
940 TEST_F(ParseErrorTest, DefaultValueForGroup) { 1204 TEST_F(ParseErrorTest, DefaultValueForGroup) {
941 ExpectHasErrors( 1205 ExpectHasErrors(
942 "message TestMessage {\n" 1206 "message TestMessage {\n"
943 " optional group Foo = 1 [default=blah] {}\n" 1207 " optional group Foo = 1 [default=blah] {}\n"
944 "}\n", 1208 "}\n",
945 "1:34: Messages can't have default values.\n"); 1209 "1:34: Messages can't have default values.\n");
946 } 1210 }
947 1211
948 TEST_F(ParseErrorTest, DuplicateDefaultValue) { 1212 TEST_F(ParseErrorTest, DuplicateDefaultValue) {
949 ExpectHasErrors( 1213 ExpectHasErrors(
950 "message TestMessage {\n" 1214 "message TestMessage {\n"
951 " optional uint32 foo = 1 [default=1,default=2];\n" 1215 " optional uint32 foo = 1 [default=1,default=2];\n"
952 "}\n", 1216 "}\n",
953 "1:37: Already set option \"default\".\n"); 1217 "1:37: Already set option \"default\".\n");
954 } 1218 }
955 1219
1220 TEST_F(ParseErrorTest, MissingOneofName) {
1221 ExpectHasErrors(
1222 "message TestMessage {\n"
1223 " oneof {\n"
1224 " int32 bar = 1;\n"
1225 " }\n"
1226 "}\n",
1227 "1:8: Expected oneof name.\n");
1228 }
1229
1230 TEST_F(ParseErrorTest, LabelInOneof) {
1231 ExpectHasErrors(
1232 "message TestMessage {\n"
1233 " oneof foo {\n"
1234 " optional int32 bar = 1;\n"
1235 " }\n"
1236 "}\n",
1237 "2:4: Fields in oneofs must not have labels (required / optional "
1238 "/ repeated).\n");
1239 }
1240
1241 TEST_F(ParseErrorTest, MapInOneof) {
1242 ExpectHasErrors(
1243 "message TestMessage {\n"
1244 " oneof foo {\n"
1245 " map<int32, int32> foo_map = 1;\n"
1246 " map message_field = 2;\n" // a normal message field is OK
1247 " }\n"
1248 "}\n",
1249 "2:7: Map fields are not allowed in oneofs.\n");
1250 }
1251
1252 TEST_F(ParseErrorTest, LabelForMap) {
1253 ExpectHasErrors(
1254 "message TestMessage {\n"
1255 " optional map<int32, int32> int_map = 1;\n"
1256 " required map<int32, int32> int_map2 = 2;\n"
1257 " repeated map<int32, int32> int_map3 = 3;\n"
1258 " optional map map_message = 4;\n" // a normal message field is OK
1259 "}\n",
1260 "1:14: Field labels (required/optional/repeated) are not allowed on map "
1261 "fields.\n"
1262 "2:14: Field labels (required/optional/repeated) are not allowed on map "
1263 "fields.\n"
1264 "3:14: Field labels (required/optional/repeated) are not allowed on map "
1265 "fields.\n");
1266 }
1267
1268 TEST_F(ParseErrorTest, MalformedMaps) {
1269 ExpectHasErrors(
1270 "message TestMessage {\n"
1271 " map map_message = 1;\n" // a normal message field lacking label
1272 " map<string> str_map = 2;\n"
1273 " map<string,> str_map2 = 3;\n"
1274 " map<,string> str_map3 = 4;\n"
1275 " map<> empty_map = 5;\n"
1276 " map<string,string str_map6 = 6;\n"
1277 "}"
1278 "extend SomeMessage {\n"
1279 " map<int32, int32> int_map = 1;\n"
1280 "}",
1281 "1:6: Expected \"required\", \"optional\", or \"repeated\".\n"
1282 "2:12: Expected \",\".\n"
1283 "3:13: Expected type name.\n"
1284 "4:6: Expected type name.\n"
1285 "5:6: Expected type name.\n"
1286 "6:20: Expected \">\".\n"
1287 "8:5: Map fields are not allowed to be extensions.\n");
1288 }
1289
956 TEST_F(ParseErrorTest, GroupNotCapitalized) { 1290 TEST_F(ParseErrorTest, GroupNotCapitalized) {
957 ExpectHasErrors( 1291 ExpectHasErrors(
958 "message TestMessage {\n" 1292 "message TestMessage {\n"
959 " optional group foo = 1 {}\n" 1293 " optional group foo = 1 {}\n"
960 "}\n", 1294 "}\n",
961 "1:17: Group names must start with a capital letter.\n"); 1295 "1:17: Group names must start with a capital letter.\n");
962 } 1296 }
963 1297
964 TEST_F(ParseErrorTest, GroupMissingBody) { 1298 TEST_F(ParseErrorTest, GroupMissingBody) {
965 ExpectHasErrors( 1299 ExpectHasErrors(
(...skipping 30 matching lines...) Expand all
996 "2:2: Expected type name.\n" 1330 "2:2: Expected type name.\n"
997 "3:25: Expected \";\".\n"); 1331 "3:25: Expected \";\".\n");
998 } 1332 }
999 1333
1000 TEST_F(ParseErrorTest, EofInAggregateValue) { 1334 TEST_F(ParseErrorTest, EofInAggregateValue) {
1001 ExpectHasErrors( 1335 ExpectHasErrors(
1002 "option (fileopt) = { i:100\n", 1336 "option (fileopt) = { i:100\n",
1003 "1:0: Unexpected end of stream while parsing aggregate value.\n"); 1337 "1:0: Unexpected end of stream while parsing aggregate value.\n");
1004 } 1338 }
1005 1339
1340 TEST_F(ParseErrorTest, ExplicitOptionalLabelProto3) {
1341 ExpectHasErrors(
1342 "syntax = 'proto3';\n"
1343 "message TestMessage {\n"
1344 " optional int32 foo = 1;\n"
1345 "}\n",
1346 "2:11: Explicit 'optional' labels are disallowed in the Proto3 syntax. "
1347 "To define 'optional' fields in Proto3, simply remove the 'optional' "
1348 "label, as fields are 'optional' by default.\n");
1349 }
1350
1351
1006 // ------------------------------------------------------------------- 1352 // -------------------------------------------------------------------
1007 // Enum errors 1353 // Enum errors
1008 1354
1009 TEST_F(ParseErrorTest, EofInEnum) { 1355 TEST_F(ParseErrorTest, EofInEnum) {
1010 ExpectHasErrors( 1356 ExpectHasErrors(
1011 "enum TestEnum {", 1357 "enum TestEnum {",
1012 "0:15: Reached end of input in enum definition (missing '}').\n"); 1358 "0:15: Reached end of input in enum definition (missing '}').\n");
1013 } 1359 }
1014 1360
1015 TEST_F(ParseErrorTest, EnumValueMissingNumber) { 1361 TEST_F(ParseErrorTest, EnumValueMissingNumber) {
1016 ExpectHasErrors( 1362 ExpectHasErrors(
1017 "enum TestEnum {\n" 1363 "enum TestEnum {\n"
1018 " FOO;\n" 1364 " FOO;\n"
1019 "}\n", 1365 "}\n",
1020 "1:5: Missing numeric value for enum constant.\n"); 1366 "1:5: Missing numeric value for enum constant.\n");
1021 } 1367 }
1022 1368
1023 // ------------------------------------------------------------------- 1369 // -------------------------------------------------------------------
1370 // Reserved field number errors
1371
1372 TEST_F(ParseErrorTest, ReservedMaxNotAllowed) {
1373 ExpectHasErrors(
1374 "message Foo {\n"
1375 " reserved 10 to max;\n"
1376 "}\n",
1377 "1:17: Expected integer.\n");
1378 }
1379
1380 TEST_F(ParseErrorTest, ReservedMixNameAndNumber) {
1381 ExpectHasErrors(
1382 "message Foo {\n"
1383 " reserved 10, \"foo\";\n"
1384 "}\n",
1385 "1:15: Expected field number range.\n");
1386 }
1387
1388 TEST_F(ParseErrorTest, ReservedMissingQuotes) {
1389 ExpectHasErrors(
1390 "message Foo {\n"
1391 " reserved foo;\n"
1392 "}\n",
1393 "1:11: Expected field name or number range.\n");
1394 }
1395
1396 // -------------------------------------------------------------------
1024 // Service errors 1397 // Service errors
1025 1398
1026 TEST_F(ParseErrorTest, EofInService) { 1399 TEST_F(ParseErrorTest, EofInService) {
1027 ExpectHasErrors( 1400 ExpectHasErrors(
1028 "service TestService {", 1401 "service TestService {",
1029 "0:21: Reached end of input in service definition (missing '}').\n"); 1402 "0:21: Reached end of input in service definition (missing '}').\n");
1030 } 1403 }
1031 1404
1032 TEST_F(ParseErrorTest, ServiceMethodPrimitiveParams) { 1405 TEST_F(ParseErrorTest, ServiceMethodPrimitiveParams) {
1033 ExpectHasErrors( 1406 ExpectHasErrors(
(...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after
1237 TEST_F(ParserValidationErrorTest, MethodOutputTypeError) { 1610 TEST_F(ParserValidationErrorTest, MethodOutputTypeError) {
1238 ExpectHasValidationErrors( 1611 ExpectHasValidationErrors(
1239 "message Baz {}\n" 1612 "message Baz {}\n"
1240 "service Foo {\n" 1613 "service Foo {\n"
1241 " rpc Bar(Baz) returns(Qux);\n" 1614 " rpc Bar(Baz) returns(Qux);\n"
1242 "}\n", 1615 "}\n",
1243 "2:23: \"Qux\" is not defined.\n"); 1616 "2:23: \"Qux\" is not defined.\n");
1244 } 1617 }
1245 1618
1246 1619
1620 TEST_F(ParserValidationErrorTest, ResovledUndefinedError) {
1621 // Create another file which defines symbol ".base.bar".
1622 FileDescriptorProto other_file;
1623 other_file.set_name("base.proto");
1624 other_file.set_package("base");
1625 other_file.add_message_type()->set_name("bar");
1626 EXPECT_TRUE(pool_.BuildFile(other_file) != NULL);
1627
1628 // Define "foo.base" and try "base.bar".
1629 // "base.bar" is resolved to "foo.base.bar" which is not defined.
1630 ExpectHasValidationErrors(
1631 "package foo.base;\n"
1632 "import \"base.proto\";\n"
1633 "message qux {\n"
1634 " optional base.bar baz = 1;\n"
1635 " optional .base.bar quz = 2;\n"
1636 "}\n",
1637 "3:11: \"base.bar\" is resolved to \"foo.base.bar\","
1638 " which is not defined. The innermost scope is searched first "
1639 "in name resolution. Consider using a leading '.'(i.e., \".base.bar\")"
1640 " to start from the outermost scope.\n");
1641 }
1642
1643 TEST_F(ParserValidationErrorTest, ResovledUndefinedOptionError) {
1644 // Build descriptor message in test pool
1645 FileDescriptorProto descriptor_proto;
1646 DescriptorProto::descriptor()->file()->CopyTo(&descriptor_proto);
1647 ASSERT_TRUE(pool_.BuildFile(descriptor_proto) != NULL);
1648
1649 // base2.proto:
1650 // package baz
1651 // import google/protobuf/descriptor.proto
1652 // message Bar { optional int32 foo = 1; }
1653 // extend FileOptions { optional Bar bar = 7672757; }
1654 FileDescriptorProto other_file;
1655 other_file.set_name("base2.proto");
1656 other_file.set_package("baz");
1657 other_file.add_dependency();
1658 other_file.set_dependency(0, descriptor_proto.name());
1659
1660 DescriptorProto* message(other_file.add_message_type());
1661 message->set_name("Bar");
1662 FieldDescriptorProto* field(message->add_field());
1663 field->set_name("foo");
1664 field->set_number(1);
1665 field->set_label(FieldDescriptorProto_Label_LABEL_OPTIONAL);
1666 field->set_type(FieldDescriptorProto_Type_TYPE_INT32);
1667
1668 FieldDescriptorProto* extension(other_file.add_extension());
1669 extension->set_name("bar");
1670 extension->set_number(7672757);
1671 extension->set_label(FieldDescriptorProto_Label_LABEL_OPTIONAL);
1672 extension->set_type(FieldDescriptorProto_Type_TYPE_MESSAGE);
1673 extension->set_type_name("Bar");
1674 extension->set_extendee("google.protobuf.FileOptions");
1675
1676 EXPECT_TRUE(pool_.BuildFile(other_file) != NULL);
1677
1678 // qux.proto:
1679 // package qux.baz
1680 // option (baz.bar).foo = 1;
1681 //
1682 // Although "baz.bar" is already defined, the lookup code will try
1683 // "qux.baz.bar", since it's the match from the innermost scope,
1684 // which will cause a symbol not defined error.
1685 ExpectHasValidationErrors(
1686 "package qux.baz;\n"
1687 "import \"base2.proto\";\n"
1688 "option (baz.bar).foo = 1;\n",
1689 "2:7: Option \"(baz.bar)\" is resolved to \"(qux.baz.bar)\","
1690 " which is not defined. The innermost scope is searched first "
1691 "in name resolution. Consider using a leading '.'(i.e., \"(.baz.bar)\")"
1692 " to start from the outermost scope.\n");
1693 }
1694
1247 // =================================================================== 1695 // ===================================================================
1248 // Test that the output from FileDescriptor::DebugString() (and all other 1696 // Test that the output from FileDescriptor::DebugString() (and all other
1249 // descriptor types) is parseable, and results in the same Descriptor 1697 // descriptor types) is parseable, and results in the same Descriptor
1250 // definitions again afoter parsing (not, however, that the order of messages 1698 // definitions again afoter parsing (note, however, that the order of messages
1251 // cannot be guaranteed to be the same) 1699 // cannot be guaranteed to be the same)
1252 1700
1253 typedef ParserTest ParseDecriptorDebugTest; 1701 typedef ParserTest ParseDescriptorDebugTest;
1254 1702
1255 class CompareDescriptorNames { 1703 class CompareDescriptorNames {
1256 public: 1704 public:
1257 bool operator()(const DescriptorProto* left, const DescriptorProto* right) { 1705 bool operator()(const DescriptorProto* left,
1706 const DescriptorProto* right) const {
1258 return left->name() < right->name(); 1707 return left->name() < right->name();
1259 } 1708 }
1260 }; 1709 };
1261 1710
1262 // Sorts nested DescriptorProtos of a DescriptoProto, by name. 1711 // Sorts nested DescriptorProtos of a DescriptoProto, by name.
1263 void SortMessages(DescriptorProto *descriptor_proto) { 1712 void SortMessages(DescriptorProto *descriptor_proto) {
1264 int size = descriptor_proto->nested_type_size(); 1713 int size = descriptor_proto->nested_type_size();
1265 // recursively sort; we can't guarantee the order of nested messages either 1714 // recursively sort; we can't guarantee the order of nested messages either
1266 for (int i = 0; i < size; ++i) { 1715 for (int i = 0; i < size; ++i) {
1267 SortMessages(descriptor_proto->mutable_nested_type(i)); 1716 SortMessages(descriptor_proto->mutable_nested_type(i));
1268 } 1717 }
1269 DescriptorProto **data = 1718 DescriptorProto **data =
1270 descriptor_proto->mutable_nested_type()->mutable_data(); 1719 descriptor_proto->mutable_nested_type()->mutable_data();
1271 sort(data, data + size, CompareDescriptorNames()); 1720 std::sort(data, data + size, CompareDescriptorNames());
1272 } 1721 }
1273 1722
1274 // Sorts DescriptorProtos belonging to a FileDescriptorProto, by name. 1723 // Sorts DescriptorProtos belonging to a FileDescriptorProto, by name.
1275 void SortMessages(FileDescriptorProto *file_descriptor_proto) { 1724 void SortMessages(FileDescriptorProto *file_descriptor_proto) {
1276 int size = file_descriptor_proto->message_type_size(); 1725 int size = file_descriptor_proto->message_type_size();
1277 // recursively sort; we can't guarantee the order of nested messages either 1726 // recursively sort; we can't guarantee the order of nested messages either
1278 for (int i = 0; i < size; ++i) { 1727 for (int i = 0; i < size; ++i) {
1279 SortMessages(file_descriptor_proto->mutable_message_type(i)); 1728 SortMessages(file_descriptor_proto->mutable_message_type(i));
1280 } 1729 }
1281 DescriptorProto **data = 1730 DescriptorProto **data =
1282 file_descriptor_proto->mutable_message_type()->mutable_data(); 1731 file_descriptor_proto->mutable_message_type()->mutable_data();
1283 sort(data, data + size, CompareDescriptorNames()); 1732 std::sort(data, data + size, CompareDescriptorNames());
1284 } 1733 }
1285 1734
1286 TEST_F(ParseDecriptorDebugTest, TestAllDescriptorTypes) { 1735 // Strips the message and enum field type names for comparison purpose only.
1736 void StripFieldTypeName(DescriptorProto* proto) {
1737 for (int i = 0; i < proto->field_size(); ++i) {
1738 string type_name = proto->field(i).type_name();
1739 string::size_type pos = type_name.find_last_of(".");
1740 if (pos != string::npos) {
1741 proto->mutable_field(i)->mutable_type_name()->assign(
1742 type_name.begin() + pos + 1, type_name.end());
1743 }
1744 }
1745 for (int i = 0; i < proto->nested_type_size(); ++i) {
1746 StripFieldTypeName(proto->mutable_nested_type(i));
1747 }
1748 }
1749
1750 void StripFieldTypeName(FileDescriptorProto* file_proto) {
1751 for (int i = 0; i < file_proto->message_type_size(); ++i) {
1752 StripFieldTypeName(file_proto->mutable_message_type(i));
1753 }
1754 }
1755
1756 TEST_F(ParseDescriptorDebugTest, TestAllDescriptorTypes) {
1287 const FileDescriptor* original_file = 1757 const FileDescriptor* original_file =
1288 protobuf_unittest::TestAllTypes::descriptor()->file(); 1758 protobuf_unittest::TestAllTypes::descriptor()->file();
1289 FileDescriptorProto expected; 1759 FileDescriptorProto expected;
1290 original_file->CopyTo(&expected); 1760 original_file->CopyTo(&expected);
1291 1761
1292 // Get the DebugString of the unittest.proto FileDecriptor, which includes 1762 // Get the DebugString of the unittest.proto FileDecriptor, which includes
1293 // all other descriptor types 1763 // all other descriptor types
1294 string debug_string = original_file->DebugString(); 1764 string debug_string = original_file->DebugString();
1295 1765
1296 // Parse the debug string 1766 // Parse the debug string
1297 SetupParser(debug_string.c_str()); 1767 SetupParser(debug_string.c_str());
1298 FileDescriptorProto parsed; 1768 FileDescriptorProto parsed;
1299 parser_->Parse(input_.get(), &parsed); 1769 parser_->Parse(input_.get(), &parsed);
1300 EXPECT_EQ(io::Tokenizer::TYPE_END, input_->current().type); 1770 EXPECT_EQ(io::Tokenizer::TYPE_END, input_->current().type);
1301 ASSERT_EQ("", error_collector_.text_); 1771 ASSERT_EQ("", error_collector_.text_)
1772 << "Failed to parse:\n" << debug_string;
1302 1773
1303 // We now have a FileDescriptorProto, but to compare with the expected we 1774 // We now have a FileDescriptorProto, but to compare with the expected we
1304 // need to link to a FileDecriptor, then output back to a proto. We'll 1775 // need to link to a FileDecriptor, then output back to a proto. We'll
1305 // also need to give it the same name as the original. 1776 // also need to give it the same name as the original.
1306 parsed.set_name("google/protobuf/unittest.proto"); 1777 parsed.set_name("google/protobuf/unittest.proto");
1307 // We need the imported dependency before we can build our parsed proto 1778 // We need the imported dependency before we can build our parsed proto
1308 const FileDescriptor* public_import = 1779 const FileDescriptor* public_import =
1309 protobuf_unittest_import::PublicImportMessage::descriptor()->file(); 1780 protobuf_unittest_import::PublicImportMessage::descriptor()->file();
1310 FileDescriptorProto public_import_proto; 1781 FileDescriptorProto public_import_proto;
1311 public_import->CopyTo(&public_import_proto); 1782 public_import->CopyTo(&public_import_proto);
1312 ASSERT_TRUE(pool_.BuildFile(public_import_proto) != NULL); 1783 ASSERT_TRUE(pool_.BuildFile(public_import_proto) != NULL);
1313 const FileDescriptor* import = 1784 const FileDescriptor* import =
1314 protobuf_unittest_import::ImportMessage::descriptor()->file(); 1785 protobuf_unittest_import::ImportMessage::descriptor()->file();
1315 FileDescriptorProto import_proto; 1786 FileDescriptorProto import_proto;
1316 import->CopyTo(&import_proto); 1787 import->CopyTo(&import_proto);
1317 ASSERT_TRUE(pool_.BuildFile(import_proto) != NULL); 1788 ASSERT_TRUE(pool_.BuildFile(import_proto) != NULL);
1318 const FileDescriptor* actual = pool_.BuildFile(parsed); 1789 const FileDescriptor* actual = pool_.BuildFile(parsed);
1319 parsed.Clear(); 1790 parsed.Clear();
1791 ASSERT_TRUE(actual != NULL)
1792 << "Failed to validate:\n" << debug_string;
1320 actual->CopyTo(&parsed); 1793 actual->CopyTo(&parsed);
1321 ASSERT_TRUE(actual != NULL); 1794 ASSERT_TRUE(actual != NULL);
1322 1795
1323 // The messages might be in different orders, making them hard to compare. 1796 // The messages might be in different orders, making them hard to compare.
1324 // So, sort the messages in the descriptor protos (including nested messages, 1797 // So, sort the messages in the descriptor protos (including nested messages,
1325 // recursively). 1798 // recursively).
1326 SortMessages(&expected); 1799 SortMessages(&expected);
1327 SortMessages(&parsed); 1800 SortMessages(&parsed);
1328 1801
1329 // I really wanted to use StringDiff here for the debug output on fail, 1802 // I really wanted to use StringDiff here for the debug output on fail,
1330 // but the strings are too long for it, and if I increase its max size, 1803 // but the strings are too long for it, and if I increase its max size,
1331 // we get a memory allocation failure :( 1804 // we get a memory allocation failure :(
1332 EXPECT_EQ(expected.DebugString(), parsed.DebugString()); 1805 EXPECT_EQ(expected.DebugString(), parsed.DebugString());
1333 } 1806 }
1334 1807
1335 TEST_F(ParseDecriptorDebugTest, TestCustomOptions) { 1808 TEST_F(ParseDescriptorDebugTest, TestCustomOptions) {
1336 const FileDescriptor* original_file = 1809 const FileDescriptor* original_file =
1337 protobuf_unittest::AggregateMessage::descriptor()->file(); 1810 protobuf_unittest::AggregateMessage::descriptor()->file();
1338 FileDescriptorProto expected; 1811 FileDescriptorProto expected;
1339 original_file->CopyTo(&expected); 1812 original_file->CopyTo(&expected);
1340 1813
1341 string debug_string = original_file->DebugString(); 1814 string debug_string = original_file->DebugString();
1342 1815
1343 // Parse the debug string 1816 // Parse the debug string
1344 SetupParser(debug_string.c_str()); 1817 SetupParser(debug_string.c_str());
1345 FileDescriptorProto parsed; 1818 FileDescriptorProto parsed;
(...skipping 18 matching lines...) Expand all
1364 1837
1365 // The messages might be in different orders, making them hard to compare. 1838 // The messages might be in different orders, making them hard to compare.
1366 // So, sort the messages in the descriptor protos (including nested messages, 1839 // So, sort the messages in the descriptor protos (including nested messages,
1367 // recursively). 1840 // recursively).
1368 SortMessages(&expected); 1841 SortMessages(&expected);
1369 SortMessages(&parsed); 1842 SortMessages(&parsed);
1370 1843
1371 EXPECT_EQ(expected.DebugString(), parsed.DebugString()); 1844 EXPECT_EQ(expected.DebugString(), parsed.DebugString());
1372 } 1845 }
1373 1846
1847 // Ensure that DebugStringWithOptions(), with |include_comments| set to true,
1848 // includes comments from the original parser input in all of the appropriate
1849 // places.
1850 TEST_F(ParseDescriptorDebugTest, TestCommentsInDebugString) {
1851 SetupParser(
1852 "// Detached comment before syntax.\n"
1853 "\n"
1854 "// Syntax comment.\n"
1855 "syntax = \"proto2\";\n"
1856 "\n"
1857 "// Detached comment before package.\n"
1858 "\n"
1859 "// Package comment.\n"
1860 "package comment_test;\n"
1861 "\n"
1862 "// Detached comment before TestMessage1.\n"
1863 "\n"
1864 "// Message comment.\n"
1865 "//\n"
1866 "// More detail in message comment.\n"
1867 "message TestMessage1 {\n"
1868 "\n"
1869 " // Detached comment before foo.\n"
1870 "\n"
1871 " // Field comment.\n"
1872 " optional int32 foo = 1;\n"
1873 "\n"
1874 " // Detached comment before NestedMessage.\n"
1875 "\n"
1876 " // Nested-message comment.\n"
1877 " message NestedMessage {\n"
1878 " optional int32 bar = 1;\n"
1879 " }\n"
1880 "}\n"
1881 "\n"
1882 "// Detached comment before MyEnumType.\n"
1883 "\n"
1884 "// Enum comment.\n"
1885 "enum MyEnumType {\n"
1886 "\n"
1887 " // Detached comment before ASDF.\n"
1888 "\n"
1889 " // Enum-value comment.\n"
1890 " ASDF = 1;\n"
1891 "}\n"
1892 "\n"
1893 "// Detached comment before MyService.\n"
1894 "\n"
1895 "// Service comment.\n"
1896 "service MyService {\n"
1897 "\n"
1898 " // Detached comment before MyRPCCall.\n"
1899 "\n"
1900 " // RPC comment.\n"
1901 " rpc MyRPCCall(TestMessage1) returns (TestMessage1) { }\n"
1902 "}\n");
1903
1904 FileDescriptorProto parsed_desc;
1905 parsed_desc.set_name("foo.proto");
1906 SourceLocationTable source_locations;
1907 parser_->RecordSourceLocationsTo(&source_locations);
1908 parser_->Parse(input_.get(), &parsed_desc);
1909 EXPECT_EQ(io::Tokenizer::TYPE_END, input_->current().type);
1910 ASSERT_EQ("", error_collector_.text_);
1911
1912 // We need to import the FileDescriptorProto to get a FileDescriptor.
1913 MockValidationErrorCollector collector(source_locations, &error_collector_);
1914 const FileDescriptor* descriptor =
1915 pool_.BuildFileCollectingErrors(parsed_desc, &collector);
1916 ASSERT_TRUE(descriptor != NULL);
1917
1918 // Ensure that each of the comments appears somewhere in the DebugString().
1919 // We don't test the exact comment placement or formatting, because we do not
1920 // want to be too fragile here.
1921 const char* expected_comments[] = {
1922 "Detached comment before syntax.",
1923 "Syntax comment.",
1924 "Detached comment before package.",
1925 "Package comment.",
1926 "Detached comment before TestMessage1.",
1927 "Message comment.",
1928 "More detail in message comment.",
1929 "Detached comment before foo.",
1930 "Field comment",
1931 "Detached comment before NestedMessage.",
1932 "Nested-message comment",
1933 "Detached comment before MyEnumType.",
1934 "Enum comment",
1935 "Detached comment before ASDF.",
1936 "Enum-value comment",
1937 "Detached comment before MyService.",
1938 "Service comment",
1939 "Detached comment before MyRPCCall.",
1940 "RPC comment",
1941 };
1942
1943 DebugStringOptions debug_string_options;
1944 debug_string_options.include_comments = true;
1945
1946 {
1947 const string debug_string =
1948 descriptor->DebugStringWithOptions(debug_string_options);
1949
1950 for (int i = 0; i < GOOGLE_ARRAYSIZE(expected_comments); ++i) {
1951 string::size_type found_pos = debug_string.find(expected_comments[i]);
1952 EXPECT_TRUE(found_pos != string::npos)
1953 << "\"" << expected_comments[i] << "\" not found.";
1954 }
1955
1956 // Result of DebugStringWithOptions should be parseable.
1957 SetupParser(debug_string.c_str());
1958 FileDescriptorProto parsed;
1959 parser_->Parse(input_.get(), &parsed);
1960 EXPECT_EQ(io::Tokenizer::TYPE_END, input_->current().type);
1961 ASSERT_EQ("", error_collector_.text_)
1962 << "Failed to parse:\n" << debug_string;
1963 }
1964
1965 }
1966
1967 TEST_F(ParseDescriptorDebugTest, TestMaps) {
1968 SetupParser(
1969 "syntax = \"proto3\"; "
1970 "message Foo { "
1971 " message Bar { } "
1972 " map<int32, Bar> enum_message_map = 1; "
1973 " map<string, float> primitive_map = 2; "
1974 "} ");
1975 FileDescriptorProto original;
1976 EXPECT_TRUE(parser_->Parse(input_.get(), &original));
1977 original.set_name("foo.proto");
1978 const FileDescriptor* file = pool_.BuildFile(original);
1979 ASSERT_TRUE(file != NULL);
1980
1981 // Make sure the debug string uses map syntax and does not have the auto
1982 // generated entry.
1983 string debug_string = file->DebugString();
1984 EXPECT_TRUE(debug_string.find("map<") != string::npos);
1985 EXPECT_TRUE(debug_string.find("option map_entry") == string::npos);
1986 EXPECT_TRUE(debug_string.find("MapEntry") == string::npos);
1987
1988 // Make sure the descriptor debug string is parsable.
1989 FileDescriptorProto parsed;
1990 SetupParser(debug_string.c_str());
1991 parsed.set_name("foo.proto");
1992 ASSERT_TRUE(parser_->Parse(input_.get(), &parsed));
1993
1994 original.clear_source_code_info();
1995 parsed.clear_source_code_info();
1996 StripFieldTypeName(&original);
1997 StripFieldTypeName(&parsed);
1998 EXPECT_EQ(original.DebugString(), parsed.DebugString());
1999 }
2000
1374 // =================================================================== 2001 // ===================================================================
1375 // SourceCodeInfo tests. 2002 // SourceCodeInfo tests.
1376 2003
1377 // Follows a path -- as defined by SourceCodeInfo.Location.path -- from a 2004 // Follows a path -- as defined by SourceCodeInfo.Location.path -- from a
1378 // message to a particular sub-field. 2005 // message to a particular sub-field.
1379 // * If the target is itself a message, sets *output_message to point at it, 2006 // * If the target is itself a message, sets *output_message to point at it,
1380 // *output_field to NULL, and *output_index to -1. 2007 // *output_field to NULL, and *output_index to -1.
1381 // * Otherwise, if the target is an element of a repeated field, sets 2008 // * Otherwise, if the target is an element of a repeated field, sets
1382 // *output_message to the containing message, *output_field to the descriptor 2009 // *output_message to the containing message, *output_field to the descriptor
1383 // of the field, and *output_index to the index of the element. 2010 // of the field, and *output_index to the index of the element.
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
1496 for (int i = 0; i < source_info.location_size(); i++) { 2123 for (int i = 0; i < source_info.location_size(); i++) {
1497 const SourceCodeInfo::Location& location = source_info.location(i); 2124 const SourceCodeInfo::Location& location = source_info.location(i);
1498 const Message* descriptor_proto = NULL; 2125 const Message* descriptor_proto = NULL;
1499 const FieldDescriptor* field = NULL; 2126 const FieldDescriptor* field = NULL;
1500 int index = 0; 2127 int index = 0;
1501 if (!FollowPath(file_, location.path().begin(), location.path().end(), 2128 if (!FollowPath(file_, location.path().begin(), location.path().end(),
1502 &descriptor_proto, &field, &index)) { 2129 &descriptor_proto, &field, &index)) {
1503 return false; 2130 return false;
1504 } 2131 }
1505 2132
1506 spans_.insert(make_pair(SpanKey(*descriptor_proto, field, index), 2133 spans_.insert(
1507 &location)); 2134 std::make_pair(SpanKey(*descriptor_proto, field, index), &location));
1508 } 2135 }
1509 2136
1510 return true; 2137 return true;
1511 } 2138 }
1512 2139
1513 virtual void TearDown() { 2140 virtual void TearDown() {
1514 EXPECT_TRUE(spans_.empty()) 2141 EXPECT_TRUE(spans_.empty())
1515 << "Forgot to call HasSpan() for:\n" 2142 << "Forgot to call HasSpan() for:\n"
1516 << spans_.begin()->second->DebugString(); 2143 << spans_.begin()->second->DebugString();
1517 } 2144 }
1518 2145
1519 // ----------------------------------------------------------------- 2146 // -----------------------------------------------------------------
1520 // HasSpan() checks that the span of source code delimited by the given 2147 // HasSpan() checks that the span of source code delimited by the given
1521 // tags (comments) correspond via the SourceCodeInfo table to the given 2148 // tags (comments) correspond via the SourceCodeInfo table to the given
1522 // part of the FileDescriptorProto. (If unclear, look at the actual tests; 2149 // part of the FileDescriptorProto. (If unclear, look at the actual tests;
1523 // it should quickly become obvious.) 2150 // it should quickly become obvious.)
1524 2151
1525 bool HasSpan(char start_marker, char end_marker, 2152 bool HasSpan(char start_marker, char end_marker,
1526 const Message& descriptor_proto) { 2153 const Message& descriptor_proto) {
1527 return HasSpanWithComment( 2154 return HasSpanWithComment(
1528 start_marker, end_marker, descriptor_proto, NULL, -1, NULL, NULL); 2155 start_marker, end_marker, descriptor_proto, NULL, -1, NULL, NULL, NULL);
1529 } 2156 }
1530 2157
1531 bool HasSpanWithComment(char start_marker, char end_marker, 2158 bool HasSpanWithComment(char start_marker, char end_marker,
1532 const Message& descriptor_proto, 2159 const Message& descriptor_proto,
1533 const char* expected_leading_comments, 2160 const char* expected_leading_comments,
1534 const char* expected_trailing_comments) { 2161 const char* expected_trailing_comments,
2162 const char* expected_leading_detached_comments) {
1535 return HasSpanWithComment( 2163 return HasSpanWithComment(
1536 start_marker, end_marker, descriptor_proto, NULL, -1, 2164 start_marker, end_marker, descriptor_proto, NULL, -1,
1537 expected_leading_comments, expected_trailing_comments); 2165 expected_leading_comments, expected_trailing_comments,
2166 expected_leading_detached_comments);
1538 } 2167 }
1539 2168
1540 bool HasSpan(char start_marker, char end_marker, 2169 bool HasSpan(char start_marker, char end_marker,
1541 const Message& descriptor_proto, const string& field_name) { 2170 const Message& descriptor_proto, const string& field_name) {
1542 return HasSpan(start_marker, end_marker, descriptor_proto, field_name, -1); 2171 return HasSpan(start_marker, end_marker, descriptor_proto, field_name, -1);
1543 } 2172 }
1544 2173
1545 bool HasSpan(char start_marker, char end_marker, 2174 bool HasSpan(char start_marker, char end_marker,
1546 const Message& descriptor_proto, const string& field_name, 2175 const Message& descriptor_proto, const string& field_name,
1547 int index) { 2176 int index) {
1548 return HasSpan(start_marker, end_marker, descriptor_proto, 2177 return HasSpan(start_marker, end_marker, descriptor_proto,
1549 field_name, index, NULL, NULL); 2178 field_name, index, NULL, NULL, NULL);
1550 } 2179 }
1551 2180
1552 bool HasSpan(char start_marker, char end_marker, 2181 bool HasSpan(char start_marker, char end_marker,
1553 const Message& descriptor_proto, 2182 const Message& descriptor_proto,
1554 const string& field_name, int index, 2183 const string& field_name, int index,
1555 const char* expected_leading_comments, 2184 const char* expected_leading_comments,
1556 const char* expected_trailing_comments) { 2185 const char* expected_trailing_comments,
2186 const char* expected_leading_detached_comments) {
1557 const FieldDescriptor* field = 2187 const FieldDescriptor* field =
1558 descriptor_proto.GetDescriptor()->FindFieldByName(field_name); 2188 descriptor_proto.GetDescriptor()->FindFieldByName(field_name);
1559 if (field == NULL) { 2189 if (field == NULL) {
1560 ADD_FAILURE() << descriptor_proto.GetDescriptor()->name() 2190 ADD_FAILURE() << descriptor_proto.GetDescriptor()->name()
1561 << " has no such field: " << field_name; 2191 << " has no such field: " << field_name;
1562 return false; 2192 return false;
1563 } 2193 }
1564 2194
1565 return HasSpanWithComment( 2195 return HasSpanWithComment(
1566 start_marker, end_marker, descriptor_proto, field, index, 2196 start_marker, end_marker, descriptor_proto, field, index,
1567 expected_leading_comments, expected_trailing_comments); 2197 expected_leading_comments, expected_trailing_comments,
2198 expected_leading_detached_comments);
1568 } 2199 }
1569 2200
1570 bool HasSpan(const Message& descriptor_proto) { 2201 bool HasSpan(const Message& descriptor_proto) {
1571 return HasSpanWithComment( 2202 return HasSpanWithComment(
1572 '\0', '\0', descriptor_proto, NULL, -1, NULL, NULL); 2203 '\0', '\0', descriptor_proto, NULL, -1, NULL, NULL, NULL);
1573 } 2204 }
1574 2205
1575 bool HasSpan(const Message& descriptor_proto, const string& field_name) { 2206 bool HasSpan(const Message& descriptor_proto, const string& field_name) {
1576 return HasSpan('\0', '\0', descriptor_proto, field_name, -1); 2207 return HasSpan('\0', '\0', descriptor_proto, field_name, -1);
1577 } 2208 }
1578 2209
1579 bool HasSpan(const Message& descriptor_proto, const string& field_name, 2210 bool HasSpan(const Message& descriptor_proto, const string& field_name,
1580 int index) { 2211 int index) {
1581 return HasSpan('\0', '\0', descriptor_proto, field_name, index); 2212 return HasSpan('\0', '\0', descriptor_proto, field_name, index);
1582 } 2213 }
1583 2214
1584 bool HasSpanWithComment(char start_marker, char end_marker, 2215 bool HasSpanWithComment(
1585 const Message& descriptor_proto, 2216 char start_marker, char end_marker, const Message& descriptor_proto,
1586 const FieldDescriptor* field, int index, 2217 const FieldDescriptor* field, int index,
1587 const char* expected_leading_comments, 2218 const char* expected_leading_comments,
1588 const char* expected_trailing_comments) { 2219 const char* expected_trailing_comments,
2220 const char* expected_leading_detached_comments) {
1589 pair<SpanMap::iterator, SpanMap::iterator> range = 2221 pair<SpanMap::iterator, SpanMap::iterator> range =
1590 spans_.equal_range(SpanKey(descriptor_proto, field, index)); 2222 spans_.equal_range(SpanKey(descriptor_proto, field, index));
1591 2223
1592 if (start_marker == '\0') { 2224 if (start_marker == '\0') {
1593 if (range.first == range.second) { 2225 if (range.first == range.second) {
1594 return false; 2226 return false;
1595 } else { 2227 } else {
1596 spans_.erase(range.first); 2228 spans_.erase(range.first);
1597 return true; 2229 return true;
1598 } 2230 }
(...skipping 18 matching lines...) Expand all
1617 EXPECT_EQ(expected_leading_comments, 2249 EXPECT_EQ(expected_leading_comments,
1618 iter->second->leading_comments()); 2250 iter->second->leading_comments());
1619 } 2251 }
1620 if (expected_trailing_comments == NULL) { 2252 if (expected_trailing_comments == NULL) {
1621 EXPECT_FALSE(iter->second->has_trailing_comments()); 2253 EXPECT_FALSE(iter->second->has_trailing_comments());
1622 } else { 2254 } else {
1623 EXPECT_TRUE(iter->second->has_trailing_comments()); 2255 EXPECT_TRUE(iter->second->has_trailing_comments());
1624 EXPECT_EQ(expected_trailing_comments, 2256 EXPECT_EQ(expected_trailing_comments,
1625 iter->second->trailing_comments()); 2257 iter->second->trailing_comments());
1626 } 2258 }
2259 if (expected_leading_detached_comments == NULL) {
2260 EXPECT_EQ(0, iter->second->leading_detached_comments_size());
2261 } else {
2262 EXPECT_EQ(
2263 expected_leading_detached_comments,
2264 Join(iter->second->leading_detached_comments(), "\n"));
2265 }
1627 2266
1628 spans_.erase(iter); 2267 spans_.erase(iter);
1629 return true; 2268 return true;
1630 } 2269 }
1631 } 2270 }
1632 2271
1633 return false; 2272 return false;
1634 } 2273 }
1635 } 2274 }
1636 2275
(...skipping 30 matching lines...) Expand all
1667 int line = 0; 2306 int line = 0;
1668 int column = 0; 2307 int column = 0;
1669 while (*text != '\0') { 2308 while (*text != '\0') {
1670 if (*text == '$') { 2309 if (*text == '$') {
1671 ++text; 2310 ++text;
1672 GOOGLE_CHECK_NE('\0', *text); 2311 GOOGLE_CHECK_NE('\0', *text);
1673 if (*text == '$') { 2312 if (*text == '$') {
1674 text_without_markers_ += '$'; 2313 text_without_markers_ += '$';
1675 ++column; 2314 ++column;
1676 } else { 2315 } else {
1677 markers_[*text] = make_pair(line, column); 2316 markers_[*text] = std::make_pair(line, column);
1678 ++text; 2317 ++text;
1679 GOOGLE_CHECK_EQ('$', *text); 2318 GOOGLE_CHECK_EQ('$', *text);
1680 } 2319 }
1681 } else if (*text == '\n') { 2320 } else if (*text == '\n') {
1682 ++line; 2321 ++line;
1683 column = 0; 2322 column = 0;
1684 text_without_markers_ += *text; 2323 text_without_markers_ += *text;
1685 } else { 2324 } else {
1686 text_without_markers_ += *text; 2325 text_without_markers_ += *text;
1687 ++column; 2326 ++column;
1688 } 2327 }
1689 ++text; 2328 ++text;
1690 } 2329 }
1691 } 2330 }
1692 }; 2331 };
1693 2332
1694 TEST_F(SourceInfoTest, BasicFileDecls) { 2333 TEST_F(SourceInfoTest, BasicFileDecls) {
1695 EXPECT_TRUE(Parse( 2334 EXPECT_TRUE(Parse(
1696 "$a$syntax = \"proto2\";\n" 2335 "$a$syntax = \"proto2\";$i$\n"
1697 "package $b$foo.bar$c$;\n" 2336 "package $b$foo.bar$c$;\n"
1698 "import $d$\"baz.proto\"$e$;\n" 2337 "import $d$\"baz.proto\"$e$;\n"
1699 "import $f$\"qux.proto\"$g$;$h$\n" 2338 "import $f$\"qux.proto\"$g$;$h$\n"
1700 "\n" 2339 "\n"
1701 "// comment ignored\n")); 2340 "// comment ignored\n"));
1702 2341
1703 EXPECT_TRUE(HasSpan('a', 'h', file_)); 2342 EXPECT_TRUE(HasSpan('a', 'h', file_));
1704 EXPECT_TRUE(HasSpan('b', 'c', file_, "package")); 2343 EXPECT_TRUE(HasSpan('b', 'c', file_, "package"));
1705 EXPECT_TRUE(HasSpan('d', 'e', file_, "dependency", 0)); 2344 EXPECT_TRUE(HasSpan('d', 'e', file_, "dependency", 0));
1706 EXPECT_TRUE(HasSpan('f', 'g', file_, "dependency", 1)); 2345 EXPECT_TRUE(HasSpan('f', 'g', file_, "dependency", 1));
2346 EXPECT_TRUE(HasSpan('a', 'i', file_, "syntax"));
1707 } 2347 }
1708 2348
1709 TEST_F(SourceInfoTest, Messages) { 2349 TEST_F(SourceInfoTest, Messages) {
1710 EXPECT_TRUE(Parse( 2350 EXPECT_TRUE(Parse(
1711 "$a$message $b$Foo$c$ {}$d$\n" 2351 "$a$message $b$Foo$c$ {}$d$\n"
1712 "$e$message $f$Bar$g$ {}$h$\n")); 2352 "$e$message $f$Bar$g$ {}$h$\n"));
1713 2353
1714 EXPECT_TRUE(HasSpan('a', 'd', file_.message_type(0))); 2354 EXPECT_TRUE(HasSpan('a', 'd', file_.message_type(0)));
1715 EXPECT_TRUE(HasSpan('b', 'c', file_.message_type(0), "name")); 2355 EXPECT_TRUE(HasSpan('b', 'c', file_.message_type(0), "name"));
1716 EXPECT_TRUE(HasSpan('e', 'h', file_.message_type(1))); 2356 EXPECT_TRUE(HasSpan('e', 'h', file_.message_type(1)));
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after
1864 EXPECT_TRUE(HasSpan('j', 'm', range3)); 2504 EXPECT_TRUE(HasSpan('j', 'm', range3));
1865 EXPECT_TRUE(HasSpan('j', 'k', range3, "start")); 2505 EXPECT_TRUE(HasSpan('j', 'k', range3, "start"));
1866 EXPECT_TRUE(HasSpan('l', 'm', range3, "end")); 2506 EXPECT_TRUE(HasSpan('l', 'm', range3, "end"));
1867 2507
1868 // Ignore these. 2508 // Ignore these.
1869 EXPECT_TRUE(HasSpan(file_)); 2509 EXPECT_TRUE(HasSpan(file_));
1870 EXPECT_TRUE(HasSpan(file_.message_type(0))); 2510 EXPECT_TRUE(HasSpan(file_.message_type(0)));
1871 EXPECT_TRUE(HasSpan(file_.message_type(0), "name")); 2511 EXPECT_TRUE(HasSpan(file_.message_type(0), "name"));
1872 } 2512 }
1873 2513
2514 TEST_F(SourceInfoTest, Oneofs) {
2515 EXPECT_TRUE(Parse(
2516 "message Foo {\n"
2517 " $a$oneof $c$foo$d$ {\n"
2518 " $e$int32$f$ $g$a$h$ = $i$1$j$;$k$\n"
2519 " }$r$\n"
2520 "}\n"));
2521
2522 const OneofDescriptorProto& oneof_decl = file_.message_type(0).oneof_decl(0);
2523 const FieldDescriptorProto& field = file_.message_type(0).field(0);
2524
2525 EXPECT_TRUE(HasSpan('a', 'r', oneof_decl));
2526 EXPECT_TRUE(HasSpan('c', 'd', oneof_decl, "name"));
2527
2528 EXPECT_TRUE(HasSpan('e', 'k', field));
2529 EXPECT_TRUE(HasSpan('e', 'f', field, "type"));
2530 EXPECT_TRUE(HasSpan('g', 'h', field, "name"));
2531 EXPECT_TRUE(HasSpan('i', 'j', field, "number"));
2532
2533 // Ignore these.
2534 EXPECT_TRUE(HasSpan(file_));
2535 EXPECT_TRUE(HasSpan(file_.message_type(0)));
2536 EXPECT_TRUE(HasSpan(file_.message_type(0), "name"));
2537 }
2538
1874 TEST_F(SourceInfoTest, NestedMessages) { 2539 TEST_F(SourceInfoTest, NestedMessages) {
1875 EXPECT_TRUE(Parse( 2540 EXPECT_TRUE(Parse(
1876 "message Foo {\n" 2541 "message Foo {\n"
1877 " $a$message $b$Bar$c$ {\n" 2542 " $a$message $b$Bar$c$ {\n"
1878 " $d$message $e$Baz$f$ {}$g$\n" 2543 " $d$message $e$Baz$f$ {}$g$\n"
1879 " }$h$\n" 2544 " }$h$\n"
1880 " $i$message $j$Qux$k$ {}$l$\n" 2545 " $i$message $j$Qux$k$ {}$l$\n"
1881 "}\n")); 2546 "}\n"));
1882 2547
1883 const DescriptorProto& bar = file_.message_type(0).nested_type(0); 2548 const DescriptorProto& bar = file_.message_type(0).nested_type(0);
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after
2022 EXPECT_TRUE(HasSpan('j', 'k', baz, "name")); 2687 EXPECT_TRUE(HasSpan('j', 'k', baz, "name"));
2023 EXPECT_TRUE(HasSpan('l', 'm', baz, "input_type")); 2688 EXPECT_TRUE(HasSpan('l', 'm', baz, "input_type"));
2024 EXPECT_TRUE(HasSpan('n', 'o', baz, "output_type")); 2689 EXPECT_TRUE(HasSpan('n', 'o', baz, "output_type"));
2025 2690
2026 // Ignore these. 2691 // Ignore these.
2027 EXPECT_TRUE(HasSpan(file_)); 2692 EXPECT_TRUE(HasSpan(file_));
2028 EXPECT_TRUE(HasSpan(file_.service(0))); 2693 EXPECT_TRUE(HasSpan(file_.service(0)));
2029 EXPECT_TRUE(HasSpan(file_.service(0), "name")); 2694 EXPECT_TRUE(HasSpan(file_.service(0), "name"));
2030 } 2695 }
2031 2696
2697
2032 TEST_F(SourceInfoTest, Options) { 2698 TEST_F(SourceInfoTest, Options) {
2033 EXPECT_TRUE(Parse( 2699 EXPECT_TRUE(Parse(
2034 "$a$option $b$foo$c$.$d$($e$bar.baz$f$)$g$ = " 2700 "$a$option $b$foo$c$.$d$($e$bar.baz$f$)$g$ = "
2035 "$h$123$i$;$j$\n" 2701 "$h$123$i$;$j$\n"
2036 "$k$option qux = $l$-123$m$;$n$\n" 2702 "$k$option qux = $l$-123$m$;$n$\n"
2037 "$o$option corge = $p$abc$q$;$r$\n" 2703 "$o$option corge = $p$abc$q$;$r$\n"
2038 "$s$option grault = $t$'blah'$u$;$v$\n" 2704 "$s$option grault = $t$'blah'$u$;$v$\n"
2039 "$w$option garply = $x${ yadda yadda }$y$;$z$\n" 2705 "$w$option garply = $x${ yadda yadda }$y$;$z$\n"
2040 "$0$option waldo = $1$123.0$2$;$3$\n" 2706 "$0$option waldo = $1$123.0$2$;$3$\n"
2041 )); 2707 ));
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
2101 " $a$option mopt = 1;$b$\n" 2767 " $a$option mopt = 1;$b$\n"
2102 "}\n" 2768 "}\n"
2103 "enum Bar {\n" 2769 "enum Bar {\n"
2104 " $c$option eopt = 1;$d$\n" 2770 " $c$option eopt = 1;$d$\n"
2105 "}\n" 2771 "}\n"
2106 "service Baz {\n" 2772 "service Baz {\n"
2107 " $e$option sopt = 1;$f$\n" 2773 " $e$option sopt = 1;$f$\n"
2108 " rpc M(X) returns(Y) {\n" 2774 " rpc M(X) returns(Y) {\n"
2109 " $g$option mopt = 1;$h$\n" 2775 " $g$option mopt = 1;$h$\n"
2110 " }\n" 2776 " }\n"
2777 " rpc MS4($1$stream$2$ X) returns($3$stream$4$ Y) {\n"
2778 " $k$option mopt = 1;$l$\n"
2779 " }\n"
2111 "}\n")); 2780 "}\n"));
2112 2781
2113 EXPECT_TRUE(HasSpan('a', 'b', file_.message_type(0).options())); 2782 EXPECT_TRUE(HasSpan('a', 'b', file_.message_type(0).options()));
2114 EXPECT_TRUE(HasSpan('c', 'd', file_.enum_type(0).options())); 2783 EXPECT_TRUE(HasSpan('c', 'd', file_.enum_type(0).options()));
2115 EXPECT_TRUE(HasSpan('e', 'f', file_.service(0).options())); 2784 EXPECT_TRUE(HasSpan('e', 'f', file_.service(0).options()));
2116 EXPECT_TRUE(HasSpan('g', 'h', file_.service(0).method(0).options())); 2785 EXPECT_TRUE(HasSpan('g', 'h', file_.service(0).method(0).options()));
2117 2786
2118 // Ignore these. 2787 // Ignore these.
2119 EXPECT_TRUE(HasSpan(file_)); 2788 EXPECT_TRUE(HasSpan(file_));
2120 EXPECT_TRUE(HasSpan(file_.message_type(0))); 2789 EXPECT_TRUE(HasSpan(file_.message_type(0)));
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
2160 EXPECT_TRUE(HasSpan(file_.service(0).method(0).options() 2829 EXPECT_TRUE(HasSpan(file_.service(0).method(0).options()
2161 .uninterpreted_option(0))); 2830 .uninterpreted_option(0)));
2162 EXPECT_TRUE(HasSpan(file_.service(0).method(0).options() 2831 EXPECT_TRUE(HasSpan(file_.service(0).method(0).options()
2163 .uninterpreted_option(0), "name")); 2832 .uninterpreted_option(0), "name"));
2164 EXPECT_TRUE(HasSpan(file_.service(0).method(0).options() 2833 EXPECT_TRUE(HasSpan(file_.service(0).method(0).options()
2165 .uninterpreted_option(0).name(0))); 2834 .uninterpreted_option(0).name(0)));
2166 EXPECT_TRUE(HasSpan(file_.service(0).method(0).options() 2835 EXPECT_TRUE(HasSpan(file_.service(0).method(0).options()
2167 .uninterpreted_option(0).name(0), "name_part")); 2836 .uninterpreted_option(0).name(0), "name_part"));
2168 EXPECT_TRUE(HasSpan(file_.service(0).method(0).options() 2837 EXPECT_TRUE(HasSpan(file_.service(0).method(0).options()
2169 .uninterpreted_option(0), "positive_int_value")); 2838 .uninterpreted_option(0), "positive_int_value"));
2839
2840 EXPECT_TRUE(HasSpan('k', 'l', file_.service(0).method(1).options()));
2841 EXPECT_TRUE(HasSpan(file_.service(0).method(1)));
2842 EXPECT_TRUE(HasSpan(file_.service(0).method(1), "name"));
2843 EXPECT_TRUE(HasSpan(file_.service(0).method(1), "input_type"));
2844 EXPECT_TRUE(HasSpan(file_.service(0).method(1), "output_type"));
2845 EXPECT_TRUE(HasSpan(file_.service(0).method(1).options()
2846 .uninterpreted_option(0)));
2847 EXPECT_TRUE(HasSpan(file_.service(0).method(1).options()
2848 .uninterpreted_option(0), "name"));
2849 EXPECT_TRUE(HasSpan(file_.service(0).method(1).options()
2850 .uninterpreted_option(0).name(0)));
2851 EXPECT_TRUE(HasSpan(file_.service(0).method(1).options()
2852 .uninterpreted_option(0).name(0), "name_part"));
2853 EXPECT_TRUE(HasSpan(file_.service(0).method(1).options()
2854 .uninterpreted_option(0), "positive_int_value"));
2855 EXPECT_TRUE(HasSpan('1', '2', file_.service(0).method(1),
2856 "client_streaming"));
2857 EXPECT_TRUE(HasSpan('3', '4', file_.service(0).method(1),
2858 "server_streaming"));
2170 } 2859 }
2171 2860
2172 TEST_F(SourceInfoTest, FieldOptions) { 2861 TEST_F(SourceInfoTest, FieldOptions) {
2173 // The actual "name = value" pairs are parsed by the same code as for 2862 // The actual "name = value" pairs are parsed by the same code as for
2174 // top-level options so we won't re-test that -- just make sure that the 2863 // top-level options so we won't re-test that -- just make sure that the
2175 // syntax used for field options is understood. 2864 // syntax used for field options is understood.
2176 EXPECT_TRUE(Parse( 2865 EXPECT_TRUE(Parse(
2177 "message Foo {" 2866 "message Foo {"
2178 " optional int32 bar = 1 " 2867 " optional int32 bar = 1 "
2179 "$a$[default=$b$123$c$,$d$opt1=123$e$," 2868 "$a$[default=$b$123$c$,$d$opt1=123$e$,"
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
2245 } 2934 }
2246 2935
2247 TEST_F(SourceInfoTest, DocComments) { 2936 TEST_F(SourceInfoTest, DocComments) {
2248 EXPECT_TRUE(Parse( 2937 EXPECT_TRUE(Parse(
2249 "// Foo leading\n" 2938 "// Foo leading\n"
2250 "// line 2\n" 2939 "// line 2\n"
2251 "$a$message Foo {\n" 2940 "$a$message Foo {\n"
2252 " // Foo trailing\n" 2941 " // Foo trailing\n"
2253 " // line 2\n" 2942 " // line 2\n"
2254 "\n" 2943 "\n"
2255 " // ignored\n" 2944 " // detached\n"
2256 "\n" 2945 "\n"
2257 " // bar leading\n" 2946 " // bar leading\n"
2258 " $b$optional int32 bar = 1;$c$\n" 2947 " $b$optional int32 bar = 1;$c$\n"
2259 " // bar trailing\n" 2948 " // bar trailing\n"
2260 "}$d$\n" 2949 "}$d$\n"
2261 "// ignored\n" 2950 "// ignored\n"
2262 )); 2951 ));
2263 2952
2264 const DescriptorProto& foo = file_.message_type(0); 2953 const DescriptorProto& foo = file_.message_type(0);
2265 const FieldDescriptorProto& bar = foo.field(0); 2954 const FieldDescriptorProto& bar = foo.field(0);
2266 2955
2267 EXPECT_TRUE(HasSpanWithComment('a', 'd', foo, 2956 EXPECT_TRUE(HasSpanWithComment('a', 'd', foo,
2268 " Foo leading\n line 2\n", 2957 " Foo leading\n line 2\n",
2269 " Foo trailing\n line 2\n")); 2958 " Foo trailing\n line 2\n",
2959 NULL));
2270 EXPECT_TRUE(HasSpanWithComment('b', 'c', bar, 2960 EXPECT_TRUE(HasSpanWithComment('b', 'c', bar,
2271 " bar leading\n", 2961 " bar leading\n",
2272 " bar trailing\n")); 2962 " bar trailing\n",
2963 " detached\n"));
2273 2964
2274 // Ignore these. 2965 // Ignore these.
2275 EXPECT_TRUE(HasSpan(file_)); 2966 EXPECT_TRUE(HasSpan(file_));
2276 EXPECT_TRUE(HasSpan(foo, "name")); 2967 EXPECT_TRUE(HasSpan(foo, "name"));
2277 EXPECT_TRUE(HasSpan(bar, "label")); 2968 EXPECT_TRUE(HasSpan(bar, "label"));
2278 EXPECT_TRUE(HasSpan(bar, "type")); 2969 EXPECT_TRUE(HasSpan(bar, "type"));
2279 EXPECT_TRUE(HasSpan(bar, "name")); 2970 EXPECT_TRUE(HasSpan(bar, "name"));
2280 EXPECT_TRUE(HasSpan(bar, "number")); 2971 EXPECT_TRUE(HasSpan(bar, "number"));
2281 } 2972 }
2282 2973
2283 TEST_F(SourceInfoTest, DocComments2) { 2974 TEST_F(SourceInfoTest, DocComments2) {
2284 EXPECT_TRUE(Parse( 2975 EXPECT_TRUE(Parse(
2285 "// ignored\n" 2976 "// detached before message.\n"
2286 "syntax = \"proto2\";\n" 2977 "\n"
2287 "// Foo leading\n" 2978 "// Foo leading\n"
2288 "// line 2\n" 2979 "// line 2\n"
2289 "$a$message Foo {\n" 2980 "$a$message Foo {\n"
2290 " /* Foo trailing\n" 2981 " /* Foo trailing\n"
2291 " * line 2 */\n" 2982 " * line 2 */\n"
2292 " // ignored\n" 2983 " // detached\n"
2293 " /* bar leading\n" 2984 " /* bar leading\n"
2294 " */" 2985 " */"
2295 " $b$optional int32 bar = 1;$c$ // bar trailing\n" 2986 " $b$optional int32 bar = 1;$c$ // bar trailing\n"
2296 " // ignored\n" 2987 " // ignored detached\n"
2297 "}$d$\n" 2988 "}$d$\n"
2298 "// ignored\n" 2989 "// ignored\n"
2299 "\n" 2990 "\n"
2991 "// detached before option\n"
2992 "\n"
2300 "// option leading\n" 2993 "// option leading\n"
2301 "$e$option baz = 123;$f$\n" 2994 "$e$option baz = 123;$f$\n"
2302 "// option trailing\n" 2995 "// option trailing\n"
2303 )); 2996 ));
2304 2997
2305 const DescriptorProto& foo = file_.message_type(0); 2998 const DescriptorProto& foo = file_.message_type(0);
2306 const FieldDescriptorProto& bar = foo.field(0); 2999 const FieldDescriptorProto& bar = foo.field(0);
2307 const UninterpretedOption& baz = file_.options().uninterpreted_option(0); 3000 const UninterpretedOption& baz = file_.options().uninterpreted_option(0);
2308 3001
2309 EXPECT_TRUE(HasSpanWithComment('a', 'd', foo, 3002 EXPECT_TRUE(HasSpanWithComment('a', 'd', foo,
2310 " Foo leading\n line 2\n", 3003 " Foo leading\n line 2\n",
2311 " Foo trailing\n line 2 ")); 3004 " Foo trailing\n line 2 ",
3005 " detached before message.\n"));
2312 EXPECT_TRUE(HasSpanWithComment('b', 'c', bar, 3006 EXPECT_TRUE(HasSpanWithComment('b', 'c', bar,
2313 " bar leading\n", 3007 " bar leading\n",
2314 " bar trailing\n")); 3008 " bar trailing\n",
3009 " detached\n"));
2315 EXPECT_TRUE(HasSpanWithComment('e', 'f', baz, 3010 EXPECT_TRUE(HasSpanWithComment('e', 'f', baz,
2316 " option leading\n", 3011 " option leading\n",
2317 " option trailing\n")); 3012 " option trailing\n",
3013 " detached before option\n"));
2318 3014
2319 // Ignore these. 3015 // Ignore these.
2320 EXPECT_TRUE(HasSpan(file_)); 3016 EXPECT_TRUE(HasSpan(file_));
2321 EXPECT_TRUE(HasSpan(foo, "name")); 3017 EXPECT_TRUE(HasSpan(foo, "name"));
2322 EXPECT_TRUE(HasSpan(bar, "label")); 3018 EXPECT_TRUE(HasSpan(bar, "label"));
2323 EXPECT_TRUE(HasSpan(bar, "type")); 3019 EXPECT_TRUE(HasSpan(bar, "type"));
2324 EXPECT_TRUE(HasSpan(bar, "name")); 3020 EXPECT_TRUE(HasSpan(bar, "name"));
2325 EXPECT_TRUE(HasSpan(bar, "number")); 3021 EXPECT_TRUE(HasSpan(bar, "number"));
2326 EXPECT_TRUE(HasSpan(file_.options())); 3022 EXPECT_TRUE(HasSpan(file_.options()));
2327 EXPECT_TRUE(HasSpan(baz, "name")); 3023 EXPECT_TRUE(HasSpan(baz, "name"));
(...skipping 10 matching lines...) Expand all
2338 " // bar trailing\n" 3034 " // bar trailing\n"
2339 "}$d$\n" 3035 "}$d$\n"
2340 "// ignored\n" 3036 "// ignored\n"
2341 )); 3037 ));
2342 3038
2343 const DescriptorProto& foo = file_.message_type(0); 3039 const DescriptorProto& foo = file_.message_type(0);
2344 const FieldDescriptorProto& bar = foo.field(0); 3040 const FieldDescriptorProto& bar = foo.field(0);
2345 3041
2346 EXPECT_TRUE(HasSpanWithComment('b', 'c', bar, 3042 EXPECT_TRUE(HasSpanWithComment('b', 'c', bar,
2347 " bar leading\n", 3043 " bar leading\n",
2348 " bar trailing\n")); 3044 " bar trailing\n",
3045 NULL));
2349 3046
2350 // Ignore these. 3047 // Ignore these.
2351 EXPECT_TRUE(HasSpan(file_)); 3048 EXPECT_TRUE(HasSpan(file_));
2352 EXPECT_TRUE(HasSpan(foo)); 3049 EXPECT_TRUE(HasSpan(foo));
2353 EXPECT_TRUE(HasSpan(foo, "name")); 3050 EXPECT_TRUE(HasSpan(foo, "name"));
2354 EXPECT_TRUE(HasSpan(bar, "label")); 3051 EXPECT_TRUE(HasSpan(bar, "label"));
2355 EXPECT_TRUE(HasSpan(bar, "type")); 3052 EXPECT_TRUE(HasSpan(bar, "type"));
2356 EXPECT_TRUE(HasSpan(bar, "name")); 3053 EXPECT_TRUE(HasSpan(bar, "name"));
2357 EXPECT_TRUE(HasSpan(bar, "number")); 3054 EXPECT_TRUE(HasSpan(bar, "number"));
2358 EXPECT_TRUE(HasSpan(bar.options())); 3055 EXPECT_TRUE(HasSpan(bar.options()));
2359 EXPECT_TRUE(HasSpan(bar.options().uninterpreted_option(0))); 3056 EXPECT_TRUE(HasSpan(bar.options().uninterpreted_option(0)));
2360 EXPECT_TRUE(HasSpan(bar.options().uninterpreted_option(0), "name")); 3057 EXPECT_TRUE(HasSpan(bar.options().uninterpreted_option(0), "name"));
2361 EXPECT_TRUE(HasSpan(bar.options().uninterpreted_option(0).name(0))); 3058 EXPECT_TRUE(HasSpan(bar.options().uninterpreted_option(0).name(0)));
2362 EXPECT_TRUE(HasSpan( 3059 EXPECT_TRUE(HasSpan(
2363 bar.options().uninterpreted_option(0).name(0), "name_part")); 3060 bar.options().uninterpreted_option(0).name(0), "name_part"));
2364 EXPECT_TRUE(HasSpan( 3061 EXPECT_TRUE(HasSpan(
2365 bar.options().uninterpreted_option(0), "aggregate_value")); 3062 bar.options().uninterpreted_option(0), "aggregate_value"));
2366 } 3063 }
2367 3064
3065 TEST_F(SourceInfoTest, DocCommentsTopLevel) {
3066 EXPECT_TRUE(Parse(
3067 "// detached before syntax paragraph 1\n"
3068 "\n"
3069 "// detached before syntax paragraph 2\n"
3070 "\n"
3071 "// syntax leading\n"
3072 "$a$syntax = \"proto2\";$b$\n"
3073 "// syntax trailing\n"
3074 "\n"
3075 "// syntax-package detached comments\n"
3076 "\n"
3077 ";\n"
3078 "\n"
3079 "// detached after empty before package\n"
3080 "\n"
3081 "// package leading\n"
3082 "package $c$foo$d$;\n"
3083 "// package trailing\n"
3084 "\n"
3085 "// ignored detach\n"
3086 "\n"));
3087
3088 EXPECT_TRUE(HasSpan('a', 'b', file_, "syntax", -1,
3089 " syntax leading\n",
3090 " syntax trailing\n",
3091 " detached before syntax paragraph 1\n"
3092 "\n"
3093 " detached before syntax paragraph 2\n"));
3094 EXPECT_TRUE(HasSpan('c', 'd', file_, "package", -1,
3095 " package leading\n",
3096 " package trailing\n",
3097 " syntax-package detached comments\n"
3098 "\n"
3099 " detached after empty before package\n"));
3100
3101 // ignore these.
3102 EXPECT_TRUE(HasSpan(file_));
3103 }
3104
3105 TEST_F(SourceInfoTest, DocCommentsOneof) {
3106 EXPECT_TRUE(Parse(
3107 "// Foo leading\n"
3108 "$a$message Foo {\n"
3109 " /* Foo trailing\n"
3110 " */\n"
3111 " // detached before oneof\n"
3112 " /* bar leading\n"
3113 " * line 2 */\n"
3114 " $b$oneof bar {\n"
3115 " /* bar trailing\n"
3116 " * line 2 */\n"
3117 " // detached before bar_int\n"
3118 " /* bar_int leading\n"
3119 " */\n"
3120 " $c$int32 bar_int = 1;$d$ // bar_int trailing\n"
3121 " // detach comment ignored\n"
3122 " }$e$\n"
3123 "}$f$\n"));
3124
3125 const DescriptorProto& foo = file_.message_type(0);
3126 const OneofDescriptorProto& bar = foo.oneof_decl(0);
3127 const FieldDescriptorProto& bar_int = foo.field(0);
3128
3129 EXPECT_TRUE(HasSpanWithComment('a', 'f', foo,
3130 " Foo leading\n",
3131 " Foo trailing\n",
3132 NULL));
3133 EXPECT_TRUE(HasSpanWithComment('b', 'e', bar,
3134 " bar leading\n line 2 ",
3135 " bar trailing\n line 2 ",
3136 " detached before oneof\n"));
3137 EXPECT_TRUE(HasSpanWithComment('c', 'd', bar_int,
3138 " bar_int leading\n",
3139 " bar_int trailing\n",
3140 " detached before bar_int\n"));
3141
3142 // Ignore these.
3143 EXPECT_TRUE(HasSpan(file_));
3144 EXPECT_TRUE(HasSpan(foo, "name"));
3145 EXPECT_TRUE(HasSpan(bar, "name"));
3146 EXPECT_TRUE(HasSpan(bar_int, "type"));
3147 EXPECT_TRUE(HasSpan(bar_int, "name"));
3148 EXPECT_TRUE(HasSpan(bar_int, "number"));
3149 }
3150
2368 // =================================================================== 3151 // ===================================================================
2369 3152
2370 } // anonymous namespace 3153 } // anonymous namespace
2371 3154
2372 } // namespace compiler 3155 } // namespace compiler
2373 } // namespace protobuf 3156 } // namespace protobuf
2374 } // namespace google 3157 } // namespace google
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698