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

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

Issue 1842653006: Update //third_party/protobuf to version 3. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: merge 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 23 matching lines...) Expand all
37 #include <float.h> 37 #include <float.h>
38 #include <google/protobuf/stubs/hash.h> 38 #include <google/protobuf/stubs/hash.h>
39 #include <limits> 39 #include <limits>
40 40
41 41
42 #include <google/protobuf/compiler/parser.h> 42 #include <google/protobuf/compiler/parser.h>
43 #include <google/protobuf/descriptor.h> 43 #include <google/protobuf/descriptor.h>
44 #include <google/protobuf/descriptor.pb.h> 44 #include <google/protobuf/descriptor.pb.h>
45 #include <google/protobuf/wire_format.h> 45 #include <google/protobuf/wire_format.h>
46 #include <google/protobuf/io/tokenizer.h> 46 #include <google/protobuf/io/tokenizer.h>
47 #include <google/protobuf/stubs/logging.h>
47 #include <google/protobuf/stubs/common.h> 48 #include <google/protobuf/stubs/common.h>
48 #include <google/protobuf/stubs/strutil.h> 49 #include <google/protobuf/stubs/strutil.h>
49 #include <google/protobuf/stubs/map-util.h> 50 #include <google/protobuf/stubs/map_util.h>
50 51
51 namespace google { 52 namespace google {
52 namespace protobuf { 53 namespace protobuf {
53 namespace compiler { 54 namespace compiler {
54 55
55 using internal::WireFormat; 56 using internal::WireFormat;
56 57
57 namespace { 58 namespace {
58 59
59 typedef hash_map<string, FieldDescriptorProto::Type> TypeNameMap; 60 typedef hash_map<string, FieldDescriptorProto::Type> TypeNameMap;
(...skipping 17 matching lines...) Expand all
77 result["int32" ] = FieldDescriptorProto::TYPE_INT32; 78 result["int32" ] = FieldDescriptorProto::TYPE_INT32;
78 result["int64" ] = FieldDescriptorProto::TYPE_INT64; 79 result["int64" ] = FieldDescriptorProto::TYPE_INT64;
79 result["sint32" ] = FieldDescriptorProto::TYPE_SINT32; 80 result["sint32" ] = FieldDescriptorProto::TYPE_SINT32;
80 result["sint64" ] = FieldDescriptorProto::TYPE_SINT64; 81 result["sint64" ] = FieldDescriptorProto::TYPE_SINT64;
81 82
82 return result; 83 return result;
83 } 84 }
84 85
85 const TypeNameMap kTypeNames = MakeTypeNameTable(); 86 const TypeNameMap kTypeNames = MakeTypeNameTable();
86 87
88 // Camel-case the field name and append "Entry" for generated map entry name.
89 // e.g. map<KeyType, ValueType> foo_map => FooMapEntry
90 string MapEntryName(const string& field_name) {
91 string result;
92 static const char kSuffix[] = "Entry";
93 result.reserve(field_name.size() + sizeof(kSuffix));
94 bool cap_next = true;
95 for (int i = 0; i < field_name.size(); ++i) {
96 if (field_name[i] == '_') {
97 cap_next = true;
98 } else if (cap_next) {
99 // Note: Do not use ctype.h due to locales.
100 if ('a' <= field_name[i] && field_name[i] <= 'z') {
101 result.push_back(field_name[i] - 'a' + 'A');
102 } else {
103 result.push_back(field_name[i]);
104 }
105 cap_next = false;
106 } else {
107 result.push_back(field_name[i]);
108 }
109 }
110 result.append(kSuffix);
111 return result;
112 }
113
87 } // anonymous namespace 114 } // anonymous namespace
88 115
89 // Makes code slightly more readable. The meaning of "DO(foo)" is 116 // Makes code slightly more readable. The meaning of "DO(foo)" is
90 // "Execute foo and fail if it fails.", where failure is indicated by 117 // "Execute foo and fail if it fails.", where failure is indicated by
91 // returning false. 118 // returning false.
92 #define DO(STATEMENT) if (STATEMENT) {} else return false 119 #define DO(STATEMENT) if (STATEMENT) {} else return false
93 120
94 // =================================================================== 121 // ===================================================================
95 122
96 Parser::Parser() 123 Parser::Parser()
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after
244 io::Tokenizer::ParseStringAppend(input_->current().text, output); 271 io::Tokenizer::ParseStringAppend(input_->current().text, output);
245 input_->Next(); 272 input_->Next();
246 } 273 }
247 return true; 274 return true;
248 } else { 275 } else {
249 AddError(error); 276 AddError(error);
250 return false; 277 return false;
251 } 278 }
252 } 279 }
253 280
254 bool Parser::TryConsumeEndOfDeclaration(const char* text, 281 bool Parser::TryConsumeEndOfDeclaration(
255 const LocationRecorder* location) { 282 const char* text, const LocationRecorder* location) {
256 if (LookingAt(text)) { 283 if (LookingAt(text)) {
257 string leading, trailing; 284 string leading, trailing;
258 input_->NextWithComments(&trailing, NULL, &leading); 285 vector<string> detached;
286 input_->NextWithComments(&trailing, &detached, &leading);
259 287
260 // Save the leading comments for next time, and recall the leading comments 288 // Save the leading comments for next time, and recall the leading comments
261 // from last time. 289 // from last time.
262 leading.swap(upcoming_doc_comments_); 290 leading.swap(upcoming_doc_comments_);
263 291
264 if (location != NULL) { 292 if (location != NULL) {
265 location->AttachComments(&leading, &trailing); 293 upcoming_detached_comments_.swap(detached);
294 location->AttachComments(&leading, &trailing, &detached);
295 } else if (strcmp(text, "}") == 0) {
296 // If the current location is null and we are finishing the current scope,
297 // drop pending upcoming detached comments.
298 upcoming_detached_comments_.swap(detached);
299 } else {
300 // Otherwise, append the new detached comments to the existing upcoming
301 // detached comments.
302 upcoming_detached_comments_.insert(upcoming_detached_comments_.end(),
303 detached.begin(), detached.end());
266 } 304 }
305
267 return true; 306 return true;
268 } else { 307 } else {
269 return false; 308 return false;
270 } 309 }
271 } 310 }
272 311
273 bool Parser::ConsumeEndOfDeclaration(const char* text, 312 bool Parser::ConsumeEndOfDeclaration(
274 const LocationRecorder* location) { 313 const char* text, const LocationRecorder* location) {
275 if (TryConsumeEndOfDeclaration(text, location)) { 314 if (TryConsumeEndOfDeclaration(text, location)) {
276 return true; 315 return true;
277 } else { 316 } else {
278 AddError("Expected \"" + string(text) + "\"."); 317 AddError("Expected \"" + string(text) + "\".");
279 return false; 318 return false;
280 } 319 }
281 } 320 }
282 321
283 // ------------------------------------------------------------------- 322 // -------------------------------------------------------------------
284 323
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
336 375
337 void Parser::LocationRecorder::AddPath(int path_component) { 376 void Parser::LocationRecorder::AddPath(int path_component) {
338 location_->add_path(path_component); 377 location_->add_path(path_component);
339 } 378 }
340 379
341 void Parser::LocationRecorder::StartAt(const io::Tokenizer::Token& token) { 380 void Parser::LocationRecorder::StartAt(const io::Tokenizer::Token& token) {
342 location_->set_span(0, token.line); 381 location_->set_span(0, token.line);
343 location_->set_span(1, token.column); 382 location_->set_span(1, token.column);
344 } 383 }
345 384
385 void Parser::LocationRecorder::StartAt(const LocationRecorder& other) {
386 location_->set_span(0, other.location_->span(0));
387 location_->set_span(1, other.location_->span(1));
388 }
389
346 void Parser::LocationRecorder::EndAt(const io::Tokenizer::Token& token) { 390 void Parser::LocationRecorder::EndAt(const io::Tokenizer::Token& token) {
347 if (token.line != location_->span(0)) { 391 if (token.line != location_->span(0)) {
348 location_->add_span(token.line); 392 location_->add_span(token.line);
349 } 393 }
350 location_->add_span(token.end_column); 394 location_->add_span(token.end_column);
351 } 395 }
352 396
353 void Parser::LocationRecorder::RecordLegacyLocation(const Message* descriptor, 397 void Parser::LocationRecorder::RecordLegacyLocation(const Message* descriptor,
354 DescriptorPool::ErrorCollector::ErrorLocation location) { 398 DescriptorPool::ErrorCollector::ErrorLocation location) {
355 if (parser_->source_location_table_ != NULL) { 399 if (parser_->source_location_table_ != NULL) {
356 parser_->source_location_table_->Add( 400 parser_->source_location_table_->Add(
357 descriptor, location, location_->span(0), location_->span(1)); 401 descriptor, location, location_->span(0), location_->span(1));
358 } 402 }
359 } 403 }
360 404
361 void Parser::LocationRecorder::AttachComments( 405 void Parser::LocationRecorder::AttachComments(
362 string* leading, string* trailing) const { 406 string* leading, string* trailing,
407 vector<string>* detached_comments) const {
363 GOOGLE_CHECK(!location_->has_leading_comments()); 408 GOOGLE_CHECK(!location_->has_leading_comments());
364 GOOGLE_CHECK(!location_->has_trailing_comments()); 409 GOOGLE_CHECK(!location_->has_trailing_comments());
365 410
366 if (!leading->empty()) { 411 if (!leading->empty()) {
367 location_->mutable_leading_comments()->swap(*leading); 412 location_->mutable_leading_comments()->swap(*leading);
368 } 413 }
369 if (!trailing->empty()) { 414 if (!trailing->empty()) {
370 location_->mutable_trailing_comments()->swap(*trailing); 415 location_->mutable_trailing_comments()->swap(*trailing);
371 } 416 }
417 for (int i = 0; i < detached_comments->size(); ++i) {
418 location_->add_leading_detached_comments()->swap(
419 (*detached_comments)[i]);
420 }
421 detached_comments->clear();
372 } 422 }
373 423
374 // ------------------------------------------------------------------- 424 // -------------------------------------------------------------------
375 425
376 void Parser::SkipStatement() { 426 void Parser::SkipStatement() {
377 while (true) { 427 while (true) {
378 if (AtEnd()) { 428 if (AtEnd()) {
379 return; 429 return;
380 } else if (LookingAtType(io::Tokenizer::TYPE_SYMBOL)) { 430 } else if (LookingAtType(io::Tokenizer::TYPE_SYMBOL)) {
381 if (TryConsumeEndOfDeclaration(";", NULL)) { 431 if (TryConsumeEndOfDeclaration(";", NULL)) {
(...skipping 19 matching lines...) Expand all
401 } else if (TryConsume("{")) { 451 } else if (TryConsume("{")) {
402 SkipRestOfBlock(); 452 SkipRestOfBlock();
403 } 453 }
404 } 454 }
405 input_->Next(); 455 input_->Next();
406 } 456 }
407 } 457 }
408 458
409 // =================================================================== 459 // ===================================================================
410 460
461 bool Parser::ValidateEnum(const EnumDescriptorProto* proto) {
462 bool has_allow_alias = false;
463 bool allow_alias = false;
464
465 for (int i = 0; i < proto->options().uninterpreted_option_size(); i++) {
466 const UninterpretedOption option = proto->options().uninterpreted_option(i);
467 if (option.name_size() > 1) {
468 continue;
469 }
470 if (!option.name(0).is_extension() &&
471 option.name(0).name_part() == "allow_alias") {
472 has_allow_alias = true;
473 if (option.identifier_value() == "true") {
474 allow_alias = true;
475 }
476 break;
477 }
478 }
479
480 if (has_allow_alias && !allow_alias) {
481 string error =
482 "\"" + proto->name() +
483 "\" declares 'option allow_alias = false;' which has no effect. "
484 "Please remove the declaration.";
485 // This needlessly clutters declarations with nops.
486 AddError(error);
487 return false;
488 }
489
490 set<int> used_values;
491 bool has_duplicates = false;
492 for (int i = 0; i < proto->value_size(); ++i) {
493 const EnumValueDescriptorProto enum_value = proto->value(i);
494 if (used_values.find(enum_value.number()) != used_values.end()) {
495 has_duplicates = true;
496 break;
497 } else {
498 used_values.insert(enum_value.number());
499 }
500 }
501 if (allow_alias && !has_duplicates) {
502 string error =
503 "\"" + proto->name() +
504 "\" declares support for enum aliases but no enum values share field "
505 "numbers. Please remove the unnecessary 'option allow_alias = true;' "
506 "declaration.";
507 // Generate an error if an enum declares support for duplicate enum values
508 // and does not use it protect future authors.
509 AddError(error);
510 return false;
511 }
512
513 return true;
514 }
515
411 bool Parser::Parse(io::Tokenizer* input, FileDescriptorProto* file) { 516 bool Parser::Parse(io::Tokenizer* input, FileDescriptorProto* file) {
412 input_ = input; 517 input_ = input;
413 had_errors_ = false; 518 had_errors_ = false;
414 syntax_identifier_.clear(); 519 syntax_identifier_.clear();
415 520
416 // Note that |file| could be NULL at this point if 521 // Note that |file| could be NULL at this point if
417 // stop_after_syntax_identifier_ is true. So, we conservatively allocate 522 // stop_after_syntax_identifier_ is true. So, we conservatively allocate
418 // SourceCodeInfo on the stack, then swap it into the FileDescriptorProto 523 // SourceCodeInfo on the stack, then swap it into the FileDescriptorProto
419 // later on. 524 // later on.
420 SourceCodeInfo source_code_info; 525 SourceCodeInfo source_code_info;
421 source_code_info_ = &source_code_info; 526 source_code_info_ = &source_code_info;
422 527
528 vector<string> top_doc_comments;
423 if (LookingAtType(io::Tokenizer::TYPE_START)) { 529 if (LookingAtType(io::Tokenizer::TYPE_START)) {
424 // Advance to first token. 530 // Advance to first token.
425 input_->NextWithComments(NULL, NULL, &upcoming_doc_comments_); 531 input_->NextWithComments(NULL, &upcoming_detached_comments_,
532 &upcoming_doc_comments_);
426 } 533 }
427 534
428 { 535 {
429 LocationRecorder root_location(this); 536 LocationRecorder root_location(this);
430 537
431 if (require_syntax_identifier_ || LookingAt("syntax")) { 538 if (require_syntax_identifier_ || LookingAt("syntax")) {
432 if (!ParseSyntaxIdentifier()) { 539 if (!ParseSyntaxIdentifier(root_location)) {
433 // Don't attempt to parse the file if we didn't recognize the syntax 540 // Don't attempt to parse the file if we didn't recognize the syntax
434 // identifier. 541 // identifier.
435 return false; 542 return false;
436 } 543 }
544 // Store the syntax into the file.
545 if (file != NULL) file->set_syntax(syntax_identifier_);
437 } else if (!stop_after_syntax_identifier_) { 546 } else if (!stop_after_syntax_identifier_) {
547 GOOGLE_LOG(WARNING) << "No syntax specified for the proto file. "
548 << "Please use 'syntax = \"proto2\";' or "
549 << "'syntax = \"proto3\";' to specify a syntax "
550 << "version. (Defaulted to proto2 syntax.)";
438 syntax_identifier_ = "proto2"; 551 syntax_identifier_ = "proto2";
439 } 552 }
440 553
441 if (stop_after_syntax_identifier_) return !had_errors_; 554 if (stop_after_syntax_identifier_) return !had_errors_;
442 555
443 // Repeatedly parse statements until we reach the end of the file. 556 // Repeatedly parse statements until we reach the end of the file.
444 while (!AtEnd()) { 557 while (!AtEnd()) {
445 if (!ParseTopLevelStatement(file, root_location)) { 558 if (!ParseTopLevelStatement(file, root_location)) {
446 // This statement failed to parse. Skip it, but keep looping to parse 559 // This statement failed to parse. Skip it, but keep looping to parse
447 // other statements. 560 // other statements.
448 SkipStatement(); 561 SkipStatement();
449 562
450 if (LookingAt("}")) { 563 if (LookingAt("}")) {
451 AddError("Unmatched \"}\"."); 564 AddError("Unmatched \"}\".");
452 input_->NextWithComments(NULL, NULL, &upcoming_doc_comments_); 565 input_->NextWithComments(NULL, &upcoming_detached_comments_,
566 &upcoming_doc_comments_);
453 } 567 }
454 } 568 }
455 } 569 }
456 } 570 }
457 571
458 input_ = NULL; 572 input_ = NULL;
459 source_code_info_ = NULL; 573 source_code_info_ = NULL;
460 source_code_info.Swap(file->mutable_source_code_info()); 574 source_code_info.Swap(file->mutable_source_code_info());
461 return !had_errors_; 575 return !had_errors_;
462 } 576 }
463 577
464 bool Parser::ParseSyntaxIdentifier() { 578 bool Parser::ParseSyntaxIdentifier(const LocationRecorder& parent) {
465 DO(Consume("syntax", "File must begin with 'syntax = \"proto2\";'.")); 579 LocationRecorder syntax_location(parent,
580 FileDescriptorProto::kSyntaxFieldNumber);
581 DO(Consume(
582 "syntax",
583 "File must begin with a syntax statement, e.g. 'syntax = \"proto2\";'."));
466 DO(Consume("=")); 584 DO(Consume("="));
467 io::Tokenizer::Token syntax_token = input_->current(); 585 io::Tokenizer::Token syntax_token = input_->current();
468 string syntax; 586 string syntax;
469 DO(ConsumeString(&syntax, "Expected syntax identifier.")); 587 DO(ConsumeString(&syntax, "Expected syntax identifier."));
470 DO(ConsumeEndOfDeclaration(";", NULL)); 588 DO(ConsumeEndOfDeclaration(";", &syntax_location));
471 589
472 syntax_identifier_ = syntax; 590 syntax_identifier_ = syntax;
473 591
474 if (syntax != "proto2" && !stop_after_syntax_identifier_) { 592 if (syntax != "proto2" && syntax != "proto3" &&
593 !stop_after_syntax_identifier_) {
475 AddError(syntax_token.line, syntax_token.column, 594 AddError(syntax_token.line, syntax_token.column,
476 "Unrecognized syntax identifier \"" + syntax + "\". This parser " 595 "Unrecognized syntax identifier \"" + syntax + "\". This parser "
477 "only recognizes \"proto2\"."); 596 "only recognizes \"proto2\" and \"proto3\".");
478 return false; 597 return false;
479 } 598 }
480 599
481 return true; 600 return true;
482 } 601 }
483 602
484 bool Parser::ParseTopLevelStatement(FileDescriptorProto* file, 603 bool Parser::ParseTopLevelStatement(FileDescriptorProto* file,
485 const LocationRecorder& root_location) { 604 const LocationRecorder& root_location) {
486 if (TryConsumeEndOfDeclaration(";", NULL)) { 605 if (TryConsumeEndOfDeclaration(";", NULL)) {
487 // empty statement; ignore 606 // empty statement; ignore
488 return true; 607 return true;
489 } else if (LookingAt("message")) { 608 } else if (LookingAt("message")) {
490 LocationRecorder location(root_location, 609 LocationRecorder location(root_location,
491 FileDescriptorProto::kMessageTypeFieldNumber, file->message_type_size()); 610 FileDescriptorProto::kMessageTypeFieldNumber, file->message_type_size());
492 return ParseMessageDefinition(file->add_message_type(), location); 611 return ParseMessageDefinition(file->add_message_type(), location, file);
493 } else if (LookingAt("enum")) { 612 } else if (LookingAt("enum")) {
494 LocationRecorder location(root_location, 613 LocationRecorder location(root_location,
495 FileDescriptorProto::kEnumTypeFieldNumber, file->enum_type_size()); 614 FileDescriptorProto::kEnumTypeFieldNumber, file->enum_type_size());
496 return ParseEnumDefinition(file->add_enum_type(), location); 615 return ParseEnumDefinition(file->add_enum_type(), location, file);
497 } else if (LookingAt("service")) { 616 } else if (LookingAt("service")) {
498 LocationRecorder location(root_location, 617 LocationRecorder location(root_location,
499 FileDescriptorProto::kServiceFieldNumber, file->service_size()); 618 FileDescriptorProto::kServiceFieldNumber, file->service_size());
500 return ParseServiceDefinition(file->add_service(), location); 619 return ParseServiceDefinition(file->add_service(), location, file);
501 } else if (LookingAt("extend")) { 620 } else if (LookingAt("extend")) {
502 LocationRecorder location(root_location, 621 LocationRecorder location(root_location,
503 FileDescriptorProto::kExtensionFieldNumber); 622 FileDescriptorProto::kExtensionFieldNumber);
504 return ParseExtend(file->mutable_extension(), 623 return ParseExtend(file->mutable_extension(),
505 file->mutable_message_type(), 624 file->mutable_message_type(),
506 root_location, 625 root_location,
507 FileDescriptorProto::kMessageTypeFieldNumber, 626 FileDescriptorProto::kMessageTypeFieldNumber,
508 location); 627 location, file);
509 } else if (LookingAt("import")) { 628 } else if (LookingAt("import")) {
510 return ParseImport(file->mutable_dependency(), 629 return ParseImport(file->mutable_dependency(),
511 file->mutable_public_dependency(), 630 file->mutable_public_dependency(),
512 file->mutable_weak_dependency(), 631 file->mutable_weak_dependency(),
513 root_location); 632 root_location, file);
514 } else if (LookingAt("package")) { 633 } else if (LookingAt("package")) {
515 return ParsePackage(file, root_location); 634 return ParsePackage(file, root_location, file);
516 } else if (LookingAt("option")) { 635 } else if (LookingAt("option")) {
517 LocationRecorder location(root_location, 636 LocationRecorder location(root_location,
518 FileDescriptorProto::kOptionsFieldNumber); 637 FileDescriptorProto::kOptionsFieldNumber);
519 return ParseOption(file->mutable_options(), location, OPTION_STATEMENT); 638 return ParseOption(file->mutable_options(), location, file,
639 OPTION_STATEMENT);
520 } else { 640 } else {
521 AddError("Expected top-level statement (e.g. \"message\")."); 641 AddError("Expected top-level statement (e.g. \"message\").");
522 return false; 642 return false;
523 } 643 }
524 } 644 }
525 645
526 // ------------------------------------------------------------------- 646 // -------------------------------------------------------------------
527 // Messages 647 // Messages
528 648
529 bool Parser::ParseMessageDefinition(DescriptorProto* message, 649 bool Parser::ParseMessageDefinition(
530 const LocationRecorder& message_location) { 650 DescriptorProto* message,
651 const LocationRecorder& message_location,
652 const FileDescriptorProto* containing_file) {
531 DO(Consume("message")); 653 DO(Consume("message"));
532 { 654 {
533 LocationRecorder location(message_location, 655 LocationRecorder location(message_location,
534 DescriptorProto::kNameFieldNumber); 656 DescriptorProto::kNameFieldNumber);
535 location.RecordLegacyLocation( 657 location.RecordLegacyLocation(
536 message, DescriptorPool::ErrorCollector::NAME); 658 message, DescriptorPool::ErrorCollector::NAME);
537 DO(ConsumeIdentifier(message->mutable_name(), "Expected message name.")); 659 DO(ConsumeIdentifier(message->mutable_name(), "Expected message name."));
538 } 660 }
539 DO(ParseMessageBlock(message, message_location)); 661 DO(ParseMessageBlock(message, message_location, containing_file));
540 return true; 662 return true;
541 } 663 }
542 664
543 namespace { 665 namespace {
544 666
545 const int kMaxExtensionRangeSentinel = -1; 667 const int kMaxExtensionRangeSentinel = -1;
546 668
547 bool IsMessageSetWireFormatMessage(const DescriptorProto& message) { 669 bool IsMessageSetWireFormatMessage(const DescriptorProto& message) {
548 const MessageOptions& options = message.options(); 670 const MessageOptions& options = message.options();
549 for (int i = 0; i < options.uninterpreted_option_size(); ++i) { 671 for (int i = 0; i < options.uninterpreted_option_size(); ++i) {
(...skipping 18 matching lines...) Expand all
568 for (int i = 0; i < message->extension_range_size(); ++i) { 690 for (int i = 0; i < message->extension_range_size(); ++i) {
569 if (message->extension_range(i).end() == kMaxExtensionRangeSentinel) { 691 if (message->extension_range(i).end() == kMaxExtensionRangeSentinel) {
570 message->mutable_extension_range(i)->set_end(max_extension_number); 692 message->mutable_extension_range(i)->set_end(max_extension_number);
571 } 693 }
572 } 694 }
573 } 695 }
574 696
575 } // namespace 697 } // namespace
576 698
577 bool Parser::ParseMessageBlock(DescriptorProto* message, 699 bool Parser::ParseMessageBlock(DescriptorProto* message,
578 const LocationRecorder& message_location) { 700 const LocationRecorder& message_location,
701 const FileDescriptorProto* containing_file) {
579 DO(ConsumeEndOfDeclaration("{", &message_location)); 702 DO(ConsumeEndOfDeclaration("{", &message_location));
580 703
581 while (!TryConsumeEndOfDeclaration("}", NULL)) { 704 while (!TryConsumeEndOfDeclaration("}", NULL)) {
582 if (AtEnd()) { 705 if (AtEnd()) {
583 AddError("Reached end of input in message definition (missing '}')."); 706 AddError("Reached end of input in message definition (missing '}').");
584 return false; 707 return false;
585 } 708 }
586 709
587 if (!ParseMessageStatement(message, message_location)) { 710 if (!ParseMessageStatement(message, message_location, containing_file)) {
588 // This statement failed to parse. Skip it, but keep looping to parse 711 // This statement failed to parse. Skip it, but keep looping to parse
589 // other statements. 712 // other statements.
590 SkipStatement(); 713 SkipStatement();
591 } 714 }
592 } 715 }
593 716
594 if (message->extension_range_size() > 0) { 717 if (message->extension_range_size() > 0) {
595 AdjustExtensionRangesWithMaxEndNumber(message); 718 AdjustExtensionRangesWithMaxEndNumber(message);
596 } 719 }
597 return true; 720 return true;
598 } 721 }
599 722
600 bool Parser::ParseMessageStatement(DescriptorProto* message, 723 bool Parser::ParseMessageStatement(DescriptorProto* message,
601 const LocationRecorder& message_location) { 724 const LocationRecorder& message_location,
725 const FileDescriptorProto* containing_file) {
602 if (TryConsumeEndOfDeclaration(";", NULL)) { 726 if (TryConsumeEndOfDeclaration(";", NULL)) {
603 // empty statement; ignore 727 // empty statement; ignore
604 return true; 728 return true;
605 } else if (LookingAt("message")) { 729 } else if (LookingAt("message")) {
606 LocationRecorder location(message_location, 730 LocationRecorder location(message_location,
607 DescriptorProto::kNestedTypeFieldNumber, 731 DescriptorProto::kNestedTypeFieldNumber,
608 message->nested_type_size()); 732 message->nested_type_size());
609 return ParseMessageDefinition(message->add_nested_type(), location); 733 return ParseMessageDefinition(message->add_nested_type(), location,
734 containing_file);
610 } else if (LookingAt("enum")) { 735 } else if (LookingAt("enum")) {
611 LocationRecorder location(message_location, 736 LocationRecorder location(message_location,
612 DescriptorProto::kEnumTypeFieldNumber, 737 DescriptorProto::kEnumTypeFieldNumber,
613 message->enum_type_size()); 738 message->enum_type_size());
614 return ParseEnumDefinition(message->add_enum_type(), location); 739 return ParseEnumDefinition(message->add_enum_type(), location,
740 containing_file);
615 } else if (LookingAt("extensions")) { 741 } else if (LookingAt("extensions")) {
616 LocationRecorder location(message_location, 742 LocationRecorder location(message_location,
617 DescriptorProto::kExtensionRangeFieldNumber); 743 DescriptorProto::kExtensionRangeFieldNumber);
618 return ParseExtensions(message, location); 744 return ParseExtensions(message, location, containing_file);
745 } else if (LookingAt("reserved")) {
746 return ParseReserved(message, message_location);
619 } else if (LookingAt("extend")) { 747 } else if (LookingAt("extend")) {
620 LocationRecorder location(message_location, 748 LocationRecorder location(message_location,
621 DescriptorProto::kExtensionFieldNumber); 749 DescriptorProto::kExtensionFieldNumber);
622 return ParseExtend(message->mutable_extension(), 750 return ParseExtend(message->mutable_extension(),
623 message->mutable_nested_type(), 751 message->mutable_nested_type(),
624 message_location, 752 message_location,
625 DescriptorProto::kNestedTypeFieldNumber, 753 DescriptorProto::kNestedTypeFieldNumber,
626 location); 754 location, containing_file);
627 } else if (LookingAt("option")) { 755 } else if (LookingAt("option")) {
628 LocationRecorder location(message_location, 756 LocationRecorder location(message_location,
629 DescriptorProto::kOptionsFieldNumber); 757 DescriptorProto::kOptionsFieldNumber);
630 return ParseOption(message->mutable_options(), location, OPTION_STATEMENT); 758 return ParseOption(message->mutable_options(), location,
759 containing_file, OPTION_STATEMENT);
760 } else if (LookingAt("oneof")) {
761 int oneof_index = message->oneof_decl_size();
762 LocationRecorder oneof_location(message_location,
763 DescriptorProto::kOneofDeclFieldNumber,
764 oneof_index);
765
766 return ParseOneof(message->add_oneof_decl(), message,
767 oneof_index, oneof_location, message_location,
768 containing_file);
631 } else { 769 } else {
632 LocationRecorder location(message_location, 770 LocationRecorder location(message_location,
633 DescriptorProto::kFieldFieldNumber, 771 DescriptorProto::kFieldFieldNumber,
634 message->field_size()); 772 message->field_size());
635 return ParseMessageField(message->add_field(), 773 return ParseMessageField(message->add_field(),
636 message->mutable_nested_type(), 774 message->mutable_nested_type(),
637 message_location, 775 message_location,
638 DescriptorProto::kNestedTypeFieldNumber, 776 DescriptorProto::kNestedTypeFieldNumber,
639 location); 777 location,
778 containing_file);
640 } 779 }
641 } 780 }
642 781
643 bool Parser::ParseMessageField(FieldDescriptorProto* field, 782 bool Parser::ParseMessageField(FieldDescriptorProto* field,
644 RepeatedPtrField<DescriptorProto>* messages, 783 RepeatedPtrField<DescriptorProto>* messages,
645 const LocationRecorder& parent_location, 784 const LocationRecorder& parent_location,
646 int location_field_number_for_nested_type, 785 int location_field_number_for_nested_type,
647 const LocationRecorder& field_location) { 786 const LocationRecorder& field_location,
648 // Parse label and type. 787 const FileDescriptorProto* containing_file) {
649 io::Tokenizer::Token label_token = input_->current();
650 { 788 {
651 LocationRecorder location(field_location, 789 LocationRecorder location(field_location,
652 FieldDescriptorProto::kLabelFieldNumber); 790 FieldDescriptorProto::kLabelFieldNumber);
653 FieldDescriptorProto::Label label; 791 FieldDescriptorProto::Label label;
654 DO(ParseLabel(&label)); 792 if (ParseLabel(&label, containing_file)) {
655 field->set_label(label); 793 field->set_label(label);
794 if (label == FieldDescriptorProto::LABEL_OPTIONAL &&
795 syntax_identifier_ == "proto3") {
796 AddError(
797 "Explicit 'optional' labels are disallowed in the Proto3 syntax. "
798 "To define 'optional' fields in Proto3, simply remove the "
799 "'optional' label, as fields are 'optional' by default.");
800 }
801 }
656 } 802 }
657 803
804 return ParseMessageFieldNoLabel(field, messages, parent_location,
805 location_field_number_for_nested_type,
806 field_location,
807 containing_file);
808 }
809
810 bool Parser::ParseMessageFieldNoLabel(
811 FieldDescriptorProto* field,
812 RepeatedPtrField<DescriptorProto>* messages,
813 const LocationRecorder& parent_location,
814 int location_field_number_for_nested_type,
815 const LocationRecorder& field_location,
816 const FileDescriptorProto* containing_file) {
817 MapField map_field;
818 // Parse type.
658 { 819 {
659 LocationRecorder location(field_location); // add path later 820 LocationRecorder location(field_location); // add path later
660 location.RecordLegacyLocation(field, DescriptorPool::ErrorCollector::TYPE); 821 location.RecordLegacyLocation(field, DescriptorPool::ErrorCollector::TYPE);
661 822
823 bool type_parsed = false;
662 FieldDescriptorProto::Type type = FieldDescriptorProto::TYPE_INT32; 824 FieldDescriptorProto::Type type = FieldDescriptorProto::TYPE_INT32;
663 string type_name; 825 string type_name;
664 DO(ParseType(&type, &type_name)); 826
665 if (type_name.empty()) { 827 // Special case map field. We only treat the field as a map field if the
666 location.AddPath(FieldDescriptorProto::kTypeFieldNumber); 828 // field type name starts with the word "map" with a following "<".
667 field->set_type(type); 829 if (TryConsume("map")) {
830 if (LookingAt("<")) {
831 map_field.is_map_field = true;
832 } else {
833 // False positive
834 type_parsed = true;
835 type_name = "map";
836 }
837 }
838 if (map_field.is_map_field) {
839 if (field->has_oneof_index()) {
840 AddError("Map fields are not allowed in oneofs.");
841 return false;
842 }
843 if (field->has_label()) {
844 AddError(
845 "Field labels (required/optional/repeated) are not allowed on "
846 "map fields.");
847 return false;
848 }
849 if (field->has_extendee()) {
850 AddError("Map fields are not allowed to be extensions.");
851 return false;
852 }
853 field->set_label(FieldDescriptorProto::LABEL_REPEATED);
854 DO(Consume("<"));
855 DO(ParseType(&map_field.key_type, &map_field.key_type_name));
856 DO(Consume(","));
857 DO(ParseType(&map_field.value_type, &map_field.value_type_name));
858 DO(Consume(">"));
859 // Defer setting of the type name of the map field until the
860 // field name is parsed. Add the source location though.
861 location.AddPath(FieldDescriptorProto::kTypeNameFieldNumber);
668 } else { 862 } else {
669 location.AddPath(FieldDescriptorProto::kTypeNameFieldNumber); 863 // Handle the case where no explicit label is given for a non-map field.
670 field->set_type_name(type_name); 864 if (!field->has_label() && DefaultToOptionalFields()) {
865 field->set_label(FieldDescriptorProto::LABEL_OPTIONAL);
866 }
867 if (!field->has_label()) {
868 AddError("Expected \"required\", \"optional\", or \"repeated\".");
869 // We can actually reasonably recover here by just assuming the user
870 // forgot the label altogether.
871 field->set_label(FieldDescriptorProto::LABEL_OPTIONAL);
872 }
873
874 // Handle the case where the actual type is a message or enum named "map",
875 // which we already consumed in the code above.
876 if (!type_parsed) {
877 DO(ParseType(&type, &type_name));
878 }
879 if (type_name.empty()) {
880 location.AddPath(FieldDescriptorProto::kTypeFieldNumber);
881 field->set_type(type);
882 } else {
883 location.AddPath(FieldDescriptorProto::kTypeNameFieldNumber);
884 field->set_type_name(type_name);
885 }
671 } 886 }
672 } 887 }
673 888
674 // Parse name and '='. 889 // Parse name and '='.
675 io::Tokenizer::Token name_token = input_->current(); 890 io::Tokenizer::Token name_token = input_->current();
676 { 891 {
677 LocationRecorder location(field_location, 892 LocationRecorder location(field_location,
678 FieldDescriptorProto::kNameFieldNumber); 893 FieldDescriptorProto::kNameFieldNumber);
679 location.RecordLegacyLocation(field, DescriptorPool::ErrorCollector::NAME); 894 location.RecordLegacyLocation(field, DescriptorPool::ErrorCollector::NAME);
680 DO(ConsumeIdentifier(field->mutable_name(), "Expected field name.")); 895 DO(ConsumeIdentifier(field->mutable_name(), "Expected field name."));
681 } 896 }
682 DO(Consume("=", "Missing field number.")); 897 DO(Consume("=", "Missing field number."));
683 898
684 // Parse field number. 899 // Parse field number.
685 { 900 {
686 LocationRecorder location(field_location, 901 LocationRecorder location(field_location,
687 FieldDescriptorProto::kNumberFieldNumber); 902 FieldDescriptorProto::kNumberFieldNumber);
688 location.RecordLegacyLocation( 903 location.RecordLegacyLocation(
689 field, DescriptorPool::ErrorCollector::NUMBER); 904 field, DescriptorPool::ErrorCollector::NUMBER);
690 int number; 905 int number;
691 DO(ConsumeInteger(&number, "Expected field number.")); 906 DO(ConsumeInteger(&number, "Expected field number."));
692 field->set_number(number); 907 field->set_number(number);
693 } 908 }
694 909
695 // Parse options. 910 // Parse options.
696 DO(ParseFieldOptions(field, field_location)); 911 DO(ParseFieldOptions(field, field_location, containing_file));
697 912
698 // Deal with groups. 913 // Deal with groups.
699 if (field->has_type() && field->type() == FieldDescriptorProto::TYPE_GROUP) { 914 if (field->has_type() && field->type() == FieldDescriptorProto::TYPE_GROUP) {
700 // Awkward: Since a group declares both a message type and a field, we 915 // Awkward: Since a group declares both a message type and a field, we
701 // have to create overlapping locations. 916 // have to create overlapping locations.
702 LocationRecorder group_location(parent_location); 917 LocationRecorder group_location(parent_location);
703 group_location.StartAt(label_token); 918 group_location.StartAt(field_location);
704 group_location.AddPath(location_field_number_for_nested_type); 919 group_location.AddPath(location_field_number_for_nested_type);
705 group_location.AddPath(messages->size()); 920 group_location.AddPath(messages->size());
706 921
707 DescriptorProto* group = messages->Add(); 922 DescriptorProto* group = messages->Add();
708 group->set_name(field->name()); 923 group->set_name(field->name());
709 924
710 // Record name location to match the field name's location. 925 // Record name location to match the field name's location.
711 { 926 {
712 LocationRecorder location(group_location, 927 LocationRecorder location(group_location,
713 DescriptorProto::kNameFieldNumber); 928 DescriptorProto::kNameFieldNumber);
(...skipping 15 matching lines...) Expand all
729 // with a capital letter and lower-case the field name. New code should 944 // with a capital letter and lower-case the field name. New code should
730 // not use groups; it should use nested messages. 945 // not use groups; it should use nested messages.
731 if (group->name()[0] < 'A' || 'Z' < group->name()[0]) { 946 if (group->name()[0] < 'A' || 'Z' < group->name()[0]) {
732 AddError(name_token.line, name_token.column, 947 AddError(name_token.line, name_token.column,
733 "Group names must start with a capital letter."); 948 "Group names must start with a capital letter.");
734 } 949 }
735 LowerString(field->mutable_name()); 950 LowerString(field->mutable_name());
736 951
737 field->set_type_name(group->name()); 952 field->set_type_name(group->name());
738 if (LookingAt("{")) { 953 if (LookingAt("{")) {
739 DO(ParseMessageBlock(group, group_location)); 954 DO(ParseMessageBlock(group, group_location, containing_file));
740 } else { 955 } else {
741 AddError("Missing group body."); 956 AddError("Missing group body.");
742 return false; 957 return false;
743 } 958 }
744 } else { 959 } else {
745 DO(ConsumeEndOfDeclaration(";", &field_location)); 960 DO(ConsumeEndOfDeclaration(";", &field_location));
746 } 961 }
747 962
963 // Create a map entry type if this is a map field.
964 if (map_field.is_map_field) {
965 GenerateMapEntry(map_field, field, messages);
966 }
967
748 return true; 968 return true;
749 } 969 }
750 970
971 void Parser::GenerateMapEntry(const MapField& map_field,
972 FieldDescriptorProto* field,
973 RepeatedPtrField<DescriptorProto>* messages) {
974 DescriptorProto* entry = messages->Add();
975 string entry_name = MapEntryName(field->name());
976 field->set_type_name(entry_name);
977 entry->set_name(entry_name);
978 entry->mutable_options()->set_map_entry(true);
979 FieldDescriptorProto* key_field = entry->add_field();
980 key_field->set_name("key");
981 key_field->set_label(FieldDescriptorProto::LABEL_OPTIONAL);
982 key_field->set_number(1);
983 if (map_field.key_type_name.empty()) {
984 key_field->set_type(map_field.key_type);
985 } else {
986 key_field->set_type_name(map_field.key_type_name);
987 }
988 FieldDescriptorProto* value_field = entry->add_field();
989 value_field->set_name("value");
990 value_field->set_label(FieldDescriptorProto::LABEL_OPTIONAL);
991 value_field->set_number(2);
992 if (map_field.value_type_name.empty()) {
993 value_field->set_type(map_field.value_type);
994 } else {
995 value_field->set_type_name(map_field.value_type_name);
996 }
997 // Propagate the "enforce_utf8" option to key and value fields if they
998 // are strings. This helps simplify the implementation of code generators
999 // and also reflection-based parsing code.
1000 //
1001 // The following definition:
1002 // message Foo {
1003 // map<string, string> value = 1 [enforce_utf8 = false];
1004 // }
1005 // will be interpreted as:
1006 // message Foo {
1007 // message ValueEntry {
1008 // option map_entry = true;
1009 // string key = 1 [enforce_utf8 = false];
1010 // string value = 2 [enforce_utf8 = false];
1011 // }
1012 // repeated ValueEntry value = 1 [enforce_utf8 = false];
1013 // }
1014 //
1015 // TODO(xiaofeng): Remove this when the "enforce_utf8" option is removed
1016 // from protocol compiler.
1017 for (int i = 0; i < field->options().uninterpreted_option_size(); ++i) {
1018 const UninterpretedOption& option =
1019 field->options().uninterpreted_option(i);
1020 if (option.name_size() == 1 &&
1021 option.name(0).name_part() == "enforce_utf8" &&
1022 !option.name(0).is_extension()) {
1023 if (key_field->type() == FieldDescriptorProto::TYPE_STRING) {
1024 key_field->mutable_options()->add_uninterpreted_option()
1025 ->CopyFrom(option);
1026 }
1027 if (value_field->type() == FieldDescriptorProto::TYPE_STRING) {
1028 value_field->mutable_options()->add_uninterpreted_option()
1029 ->CopyFrom(option);
1030 }
1031 }
1032 }
1033 }
1034
751 bool Parser::ParseFieldOptions(FieldDescriptorProto* field, 1035 bool Parser::ParseFieldOptions(FieldDescriptorProto* field,
752 const LocationRecorder& field_location) { 1036 const LocationRecorder& field_location,
1037 const FileDescriptorProto* containing_file) {
753 if (!LookingAt("[")) return true; 1038 if (!LookingAt("[")) return true;
754 1039
755 LocationRecorder location(field_location, 1040 LocationRecorder location(field_location,
756 FieldDescriptorProto::kOptionsFieldNumber); 1041 FieldDescriptorProto::kOptionsFieldNumber);
757 1042
758 DO(Consume("[")); 1043 DO(Consume("["));
759 1044
760 // Parse field options. 1045 // Parse field options.
761 do { 1046 do {
762 if (LookingAt("default")) { 1047 if (LookingAt("default")) {
763 // We intentionally pass field_location rather than location here, since 1048 // We intentionally pass field_location rather than location here, since
764 // the default value is not actually an option. 1049 // the default value is not actually an option.
765 DO(ParseDefaultAssignment(field, field_location)); 1050 DO(ParseDefaultAssignment(field, field_location, containing_file));
1051 } else if (LookingAt("json_name")) {
1052 // Like default value, this "json_name" is not an actual option.
1053 DO(ParseJsonName(field, field_location, containing_file));
766 } else { 1054 } else {
767 DO(ParseOption(field->mutable_options(), location, OPTION_ASSIGNMENT)); 1055 DO(ParseOption(field->mutable_options(), location,
1056 containing_file, OPTION_ASSIGNMENT));
768 } 1057 }
769 } while (TryConsume(",")); 1058 } while (TryConsume(","));
770 1059
771 DO(Consume("]")); 1060 DO(Consume("]"));
772 return true; 1061 return true;
773 } 1062 }
774 1063
775 bool Parser::ParseDefaultAssignment(FieldDescriptorProto* field, 1064 bool Parser::ParseDefaultAssignment(
776 const LocationRecorder& field_location) { 1065 FieldDescriptorProto* field,
1066 const LocationRecorder& field_location,
1067 const FileDescriptorProto* containing_file) {
777 if (field->has_default_value()) { 1068 if (field->has_default_value()) {
778 AddError("Already set option \"default\"."); 1069 AddError("Already set option \"default\".");
779 field->clear_default_value(); 1070 field->clear_default_value();
780 } 1071 }
781 1072
782 DO(Consume("default")); 1073 DO(Consume("default"));
783 DO(Consume("=")); 1074 DO(Consume("="));
784 1075
785 LocationRecorder location(field_location, 1076 LocationRecorder location(field_location,
786 FieldDescriptorProto::kDefaultValueFieldNumber); 1077 FieldDescriptorProto::kDefaultValueFieldNumber);
787 location.RecordLegacyLocation( 1078 location.RecordLegacyLocation(
788 field, DescriptorPool::ErrorCollector::DEFAULT_VALUE); 1079 field, DescriptorPool::ErrorCollector::DEFAULT_VALUE);
789 string* default_value = field->mutable_default_value(); 1080 string* default_value = field->mutable_default_value();
790 1081
791 if (!field->has_type()) { 1082 if (!field->has_type()) {
792 // The field has a type name, but we don't know if it is a message or an 1083 // The field has a type name, but we don't know if it is a message or an
793 // enum yet. Assume an enum for now. 1084 // enum yet. (If it were a primitive type, |field| would have a type set
794 DO(ConsumeIdentifier(default_value, "Expected identifier.")); 1085 // already.) In this case, simply take the current string as the default
1086 // value; we will catch the error later if it is not a valid enum value.
1087 // (N.B. that we do not check whether the current token is an identifier:
1088 // doing so throws strange errors when the user mistypes a primitive
1089 // typename and we assume it's an enum. E.g.: "optional int foo = 1 [default
1090 // = 42]". In such a case the fundamental error is really that "int" is not
1091 // a type, not that "42" is not an identifier. See b/12533582.)
1092 *default_value = input_->current().text;
1093 input_->Next();
795 return true; 1094 return true;
796 } 1095 }
797 1096
798 switch (field->type()) { 1097 switch (field->type()) {
799 case FieldDescriptorProto::TYPE_INT32: 1098 case FieldDescriptorProto::TYPE_INT32:
800 case FieldDescriptorProto::TYPE_INT64: 1099 case FieldDescriptorProto::TYPE_INT64:
801 case FieldDescriptorProto::TYPE_SINT32: 1100 case FieldDescriptorProto::TYPE_SINT32:
802 case FieldDescriptorProto::TYPE_SINT64: 1101 case FieldDescriptorProto::TYPE_SINT64:
803 case FieldDescriptorProto::TYPE_SFIXED32: 1102 case FieldDescriptorProto::TYPE_SFIXED32:
804 case FieldDescriptorProto::TYPE_SFIXED64: { 1103 case FieldDescriptorProto::TYPE_SFIXED64: {
805 uint64 max_value = kint64max; 1104 uint64 max_value = kint64max;
806 if (field->type() == FieldDescriptorProto::TYPE_INT32 || 1105 if (field->type() == FieldDescriptorProto::TYPE_INT32 ||
807 field->type() == FieldDescriptorProto::TYPE_SINT32 || 1106 field->type() == FieldDescriptorProto::TYPE_SINT32 ||
808 field->type() == FieldDescriptorProto::TYPE_SFIXED32) { 1107 field->type() == FieldDescriptorProto::TYPE_SFIXED32) {
809 max_value = kint32max; 1108 max_value = kint32max;
810 } 1109 }
811 1110
812 // These types can be negative. 1111 // These types can be negative.
813 if (TryConsume("-")) { 1112 if (TryConsume("-")) {
814 default_value->append("-"); 1113 default_value->append("-");
815 // Two's complement always has one more negative value than positive. 1114 // Two's complement always has one more negative value than positive.
816 ++max_value; 1115 ++max_value;
817 } 1116 }
818 // Parse the integer to verify that it is not out-of-range. 1117 // Parse the integer to verify that it is not out-of-range.
819 uint64 value; 1118 uint64 value;
820 DO(ConsumeInteger64(max_value, &value, "Expected integer.")); 1119 DO(ConsumeInteger64(max_value, &value,
1120 "Expected integer for field default value."));
821 // And stringify it again. 1121 // And stringify it again.
822 default_value->append(SimpleItoa(value)); 1122 default_value->append(SimpleItoa(value));
823 break; 1123 break;
824 } 1124 }
825 1125
826 case FieldDescriptorProto::TYPE_UINT32: 1126 case FieldDescriptorProto::TYPE_UINT32:
827 case FieldDescriptorProto::TYPE_UINT64: 1127 case FieldDescriptorProto::TYPE_UINT64:
828 case FieldDescriptorProto::TYPE_FIXED32: 1128 case FieldDescriptorProto::TYPE_FIXED32:
829 case FieldDescriptorProto::TYPE_FIXED64: { 1129 case FieldDescriptorProto::TYPE_FIXED64: {
830 uint64 max_value = kuint64max; 1130 uint64 max_value = kuint64max;
831 if (field->type() == FieldDescriptorProto::TYPE_UINT32 || 1131 if (field->type() == FieldDescriptorProto::TYPE_UINT32 ||
832 field->type() == FieldDescriptorProto::TYPE_FIXED32) { 1132 field->type() == FieldDescriptorProto::TYPE_FIXED32) {
833 max_value = kuint32max; 1133 max_value = kuint32max;
834 } 1134 }
835 1135
836 // Numeric, not negative. 1136 // Numeric, not negative.
837 if (TryConsume("-")) { 1137 if (TryConsume("-")) {
838 AddError("Unsigned field can't have negative default value."); 1138 AddError("Unsigned field can't have negative default value.");
839 } 1139 }
840 // Parse the integer to verify that it is not out-of-range. 1140 // Parse the integer to verify that it is not out-of-range.
841 uint64 value; 1141 uint64 value;
842 DO(ConsumeInteger64(max_value, &value, "Expected integer.")); 1142 DO(ConsumeInteger64(max_value, &value,
1143 "Expected integer for field default value."));
843 // And stringify it again. 1144 // And stringify it again.
844 default_value->append(SimpleItoa(value)); 1145 default_value->append(SimpleItoa(value));
845 break; 1146 break;
846 } 1147 }
847 1148
848 case FieldDescriptorProto::TYPE_FLOAT: 1149 case FieldDescriptorProto::TYPE_FLOAT:
849 case FieldDescriptorProto::TYPE_DOUBLE: 1150 case FieldDescriptorProto::TYPE_DOUBLE:
850 // These types can be negative. 1151 // These types can be negative.
851 if (TryConsume("-")) { 1152 if (TryConsume("-")) {
852 default_value->append("-"); 1153 default_value->append("-");
(...skipping 11 matching lines...) Expand all
864 default_value->assign("true"); 1165 default_value->assign("true");
865 } else if (TryConsume("false")) { 1166 } else if (TryConsume("false")) {
866 default_value->assign("false"); 1167 default_value->assign("false");
867 } else { 1168 } else {
868 AddError("Expected \"true\" or \"false\"."); 1169 AddError("Expected \"true\" or \"false\".");
869 return false; 1170 return false;
870 } 1171 }
871 break; 1172 break;
872 1173
873 case FieldDescriptorProto::TYPE_STRING: 1174 case FieldDescriptorProto::TYPE_STRING:
874 DO(ConsumeString(default_value, "Expected string.")); 1175 // Note: When file opton java_string_check_utf8 is true, if a
1176 // non-string representation (eg byte[]) is later supported, it must
1177 // be checked for UTF-8-ness.
1178 DO(ConsumeString(default_value, "Expected string for field default "
1179 "value."));
875 break; 1180 break;
876 1181
877 case FieldDescriptorProto::TYPE_BYTES: 1182 case FieldDescriptorProto::TYPE_BYTES:
878 DO(ConsumeString(default_value, "Expected string.")); 1183 DO(ConsumeString(default_value, "Expected string."));
879 *default_value = CEscape(*default_value); 1184 *default_value = CEscape(*default_value);
880 break; 1185 break;
881 1186
882 case FieldDescriptorProto::TYPE_ENUM: 1187 case FieldDescriptorProto::TYPE_ENUM:
883 DO(ConsumeIdentifier(default_value, "Expected identifier.")); 1188 DO(ConsumeIdentifier(default_value, "Expected enum identifier for field "
1189 "default value."));
884 break; 1190 break;
885 1191
886 case FieldDescriptorProto::TYPE_MESSAGE: 1192 case FieldDescriptorProto::TYPE_MESSAGE:
887 case FieldDescriptorProto::TYPE_GROUP: 1193 case FieldDescriptorProto::TYPE_GROUP:
888 AddError("Messages can't have default values."); 1194 AddError("Messages can't have default values.");
889 return false; 1195 return false;
890 } 1196 }
891 1197
892 return true; 1198 return true;
893 } 1199 }
894 1200
1201 bool Parser::ParseJsonName(
1202 FieldDescriptorProto* field,
1203 const LocationRecorder& field_location,
1204 const FileDescriptorProto* containing_file) {
1205 if (field->has_json_name()) {
1206 AddError("Already set option \"json_name\".");
1207 field->clear_json_name();
1208 }
1209
1210 DO(Consume("json_name"));
1211 DO(Consume("="));
1212
1213 LocationRecorder location(field_location,
1214 FieldDescriptorProto::kJsonNameFieldNumber);
1215 location.RecordLegacyLocation(
1216 field, DescriptorPool::ErrorCollector::OPTION_VALUE);
1217 DO(ConsumeString(field->mutable_json_name(),
1218 "Expected string for JSON name."));
1219 return true;
1220 }
1221
1222
895 bool Parser::ParseOptionNamePart(UninterpretedOption* uninterpreted_option, 1223 bool Parser::ParseOptionNamePart(UninterpretedOption* uninterpreted_option,
896 const LocationRecorder& part_location) { 1224 const LocationRecorder& part_location,
1225 const FileDescriptorProto* containing_file) {
897 UninterpretedOption::NamePart* name = uninterpreted_option->add_name(); 1226 UninterpretedOption::NamePart* name = uninterpreted_option->add_name();
898 string identifier; // We parse identifiers into this string. 1227 string identifier; // We parse identifiers into this string.
899 if (LookingAt("(")) { // This is an extension. 1228 if (LookingAt("(")) { // This is an extension.
900 DO(Consume("(")); 1229 DO(Consume("("));
901 1230
902 { 1231 {
903 LocationRecorder location( 1232 LocationRecorder location(
904 part_location, UninterpretedOption::NamePart::kNamePartFieldNumber); 1233 part_location, UninterpretedOption::NamePart::kNamePartFieldNumber);
905 // An extension name consists of dot-separated identifiers, and may begin 1234 // An extension name consists of dot-separated identifiers, and may begin
906 // with a dot. 1235 // with a dot.
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
950 input_->Next(); 1279 input_->Next();
951 } 1280 }
952 AddError("Unexpected end of stream while parsing aggregate value."); 1281 AddError("Unexpected end of stream while parsing aggregate value.");
953 return false; 1282 return false;
954 } 1283 }
955 1284
956 // We don't interpret the option here. Instead we store it in an 1285 // We don't interpret the option here. Instead we store it in an
957 // UninterpretedOption, to be interpreted later. 1286 // UninterpretedOption, to be interpreted later.
958 bool Parser::ParseOption(Message* options, 1287 bool Parser::ParseOption(Message* options,
959 const LocationRecorder& options_location, 1288 const LocationRecorder& options_location,
1289 const FileDescriptorProto* containing_file,
960 OptionStyle style) { 1290 OptionStyle style) {
961 // Create an entry in the uninterpreted_option field. 1291 // Create an entry in the uninterpreted_option field.
962 const FieldDescriptor* uninterpreted_option_field = options->GetDescriptor()-> 1292 const FieldDescriptor* uninterpreted_option_field = options->GetDescriptor()->
963 FindFieldByName("uninterpreted_option"); 1293 FindFieldByName("uninterpreted_option");
964 GOOGLE_CHECK(uninterpreted_option_field != NULL) 1294 GOOGLE_CHECK(uninterpreted_option_field != NULL)
965 << "No field named \"uninterpreted_option\" in the Options proto."; 1295 << "No field named \"uninterpreted_option\" in the Options proto.";
966 1296
967 const Reflection* reflection = options->GetReflection(); 1297 const Reflection* reflection = options->GetReflection();
968 1298
969 LocationRecorder location( 1299 LocationRecorder location(
(...skipping 11 matching lines...) Expand all
981 // Parse dot-separated name. 1311 // Parse dot-separated name.
982 { 1312 {
983 LocationRecorder name_location(location, 1313 LocationRecorder name_location(location,
984 UninterpretedOption::kNameFieldNumber); 1314 UninterpretedOption::kNameFieldNumber);
985 name_location.RecordLegacyLocation( 1315 name_location.RecordLegacyLocation(
986 uninterpreted_option, DescriptorPool::ErrorCollector::OPTION_NAME); 1316 uninterpreted_option, DescriptorPool::ErrorCollector::OPTION_NAME);
987 1317
988 { 1318 {
989 LocationRecorder part_location(name_location, 1319 LocationRecorder part_location(name_location,
990 uninterpreted_option->name_size()); 1320 uninterpreted_option->name_size());
991 DO(ParseOptionNamePart(uninterpreted_option, part_location)); 1321 DO(ParseOptionNamePart(uninterpreted_option, part_location,
1322 containing_file));
992 } 1323 }
993 1324
994 while (LookingAt(".")) { 1325 while (LookingAt(".")) {
995 DO(Consume(".")); 1326 DO(Consume("."));
996 LocationRecorder part_location(name_location, 1327 LocationRecorder part_location(name_location,
997 uninterpreted_option->name_size()); 1328 uninterpreted_option->name_size());
998 DO(ParseOptionNamePart(uninterpreted_option, part_location)); 1329 DO(ParseOptionNamePart(uninterpreted_option, part_location,
1330 containing_file));
999 } 1331 }
1000 } 1332 }
1001 1333
1002 DO(Consume("=")); 1334 DO(Consume("="));
1003 1335
1004 { 1336 {
1005 LocationRecorder value_location(location); 1337 LocationRecorder value_location(location);
1006 value_location.RecordLegacyLocation( 1338 value_location.RecordLegacyLocation(
1007 uninterpreted_option, DescriptorPool::ErrorCollector::OPTION_VALUE); 1339 uninterpreted_option, DescriptorPool::ErrorCollector::OPTION_VALUE);
1008 1340
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
1085 } 1417 }
1086 1418
1087 if (style == OPTION_STATEMENT) { 1419 if (style == OPTION_STATEMENT) {
1088 DO(ConsumeEndOfDeclaration(";", &location)); 1420 DO(ConsumeEndOfDeclaration(";", &location));
1089 } 1421 }
1090 1422
1091 return true; 1423 return true;
1092 } 1424 }
1093 1425
1094 bool Parser::ParseExtensions(DescriptorProto* message, 1426 bool Parser::ParseExtensions(DescriptorProto* message,
1095 const LocationRecorder& extensions_location) { 1427 const LocationRecorder& extensions_location,
1428 const FileDescriptorProto* containing_file) {
1096 // Parse the declaration. 1429 // Parse the declaration.
1097 DO(Consume("extensions")); 1430 DO(Consume("extensions"));
1098 1431
1099 do { 1432 do {
1100 // Note that kExtensionRangeFieldNumber was already pushed by the parent. 1433 // Note that kExtensionRangeFieldNumber was already pushed by the parent.
1101 LocationRecorder location(extensions_location, 1434 LocationRecorder location(extensions_location,
1102 message->extension_range_size()); 1435 message->extension_range_size());
1103 1436
1104 DescriptorProto::ExtensionRange* range = message->add_extension_range(); 1437 DescriptorProto::ExtensionRange* range = message->add_extension_range();
1105 location.RecordLegacyLocation( 1438 location.RecordLegacyLocation(
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
1139 ++end; 1472 ++end;
1140 1473
1141 range->set_start(start); 1474 range->set_start(start);
1142 range->set_end(end); 1475 range->set_end(end);
1143 } while (TryConsume(",")); 1476 } while (TryConsume(","));
1144 1477
1145 DO(ConsumeEndOfDeclaration(";", &extensions_location)); 1478 DO(ConsumeEndOfDeclaration(";", &extensions_location));
1146 return true; 1479 return true;
1147 } 1480 }
1148 1481
1482 // This is similar to extension range parsing, except that "max" is not
1483 // supported, and accepts field name literals.
1484 bool Parser::ParseReserved(DescriptorProto* message,
1485 const LocationRecorder& message_location) {
1486 // Parse the declaration.
1487 DO(Consume("reserved"));
1488 if (LookingAtType(io::Tokenizer::TYPE_STRING)) {
1489 LocationRecorder location(message_location,
1490 DescriptorProto::kReservedNameFieldNumber);
1491 return ParseReservedNames(message, location);
1492 } else {
1493 LocationRecorder location(message_location,
1494 DescriptorProto::kReservedRangeFieldNumber);
1495 return ParseReservedNumbers(message, location);
1496 }
1497 }
1498
1499
1500 bool Parser::ParseReservedNames(DescriptorProto* message,
1501 const LocationRecorder& parent_location) {
1502 do {
1503 LocationRecorder location(parent_location, message->reserved_name_size());
1504 DO(ConsumeString(message->add_reserved_name(), "Expected field name."));
1505 } while (TryConsume(","));
1506 DO(ConsumeEndOfDeclaration(";", &parent_location));
1507 return true;
1508 }
1509
1510 bool Parser::ParseReservedNumbers(DescriptorProto* message,
1511 const LocationRecorder& parent_location) {
1512 bool first = true;
1513 do {
1514 LocationRecorder location(parent_location, message->reserved_range_size());
1515
1516 DescriptorProto::ReservedRange* range = message->add_reserved_range();
1517 int start, end;
1518 io::Tokenizer::Token start_token;
1519 {
1520 LocationRecorder start_location(
1521 location, DescriptorProto::ReservedRange::kStartFieldNumber);
1522 start_token = input_->current();
1523 DO(ConsumeInteger(&start, (first ?
1524 "Expected field name or number range." :
1525 "Expected field number range.")));
1526 }
1527
1528 if (TryConsume("to")) {
1529 LocationRecorder end_location(
1530 location, DescriptorProto::ReservedRange::kEndFieldNumber);
1531 DO(ConsumeInteger(&end, "Expected integer."));
1532 } else {
1533 LocationRecorder end_location(
1534 location, DescriptorProto::ReservedRange::kEndFieldNumber);
1535 end_location.StartAt(start_token);
1536 end_location.EndAt(start_token);
1537 end = start;
1538 }
1539
1540 // Users like to specify inclusive ranges, but in code we like the end
1541 // number to be exclusive.
1542 ++end;
1543
1544 range->set_start(start);
1545 range->set_end(end);
1546 first = false;
1547 } while (TryConsume(","));
1548
1549 DO(ConsumeEndOfDeclaration(";", &parent_location));
1550 return true;
1551 }
1552
1149 bool Parser::ParseExtend(RepeatedPtrField<FieldDescriptorProto>* extensions, 1553 bool Parser::ParseExtend(RepeatedPtrField<FieldDescriptorProto>* extensions,
1150 RepeatedPtrField<DescriptorProto>* messages, 1554 RepeatedPtrField<DescriptorProto>* messages,
1151 const LocationRecorder& parent_location, 1555 const LocationRecorder& parent_location,
1152 int location_field_number_for_nested_type, 1556 int location_field_number_for_nested_type,
1153 const LocationRecorder& extend_location) { 1557 const LocationRecorder& extend_location,
1558 const FileDescriptorProto* containing_file) {
1154 DO(Consume("extend")); 1559 DO(Consume("extend"));
1155 1560
1156 // Parse the extendee type. 1561 // Parse the extendee type.
1157 io::Tokenizer::Token extendee_start = input_->current(); 1562 io::Tokenizer::Token extendee_start = input_->current();
1158 string extendee; 1563 string extendee;
1159 DO(ParseUserDefinedType(&extendee)); 1564 DO(ParseUserDefinedType(&extendee));
1160 io::Tokenizer::Token extendee_end = input_->previous(); 1565 io::Tokenizer::Token extendee_end = input_->previous();
1161 1566
1162 // Parse the block. 1567 // Parse the block.
1163 DO(ConsumeEndOfDeclaration("{", &extend_location)); 1568 DO(ConsumeEndOfDeclaration("{", &extend_location));
(...skipping 21 matching lines...) Expand all
1185 extendee_location.RecordLegacyLocation( 1590 extendee_location.RecordLegacyLocation(
1186 field, DescriptorPool::ErrorCollector::EXTENDEE); 1591 field, DescriptorPool::ErrorCollector::EXTENDEE);
1187 is_first = false; 1592 is_first = false;
1188 } 1593 }
1189 } 1594 }
1190 1595
1191 field->set_extendee(extendee); 1596 field->set_extendee(extendee);
1192 1597
1193 if (!ParseMessageField(field, messages, parent_location, 1598 if (!ParseMessageField(field, messages, parent_location,
1194 location_field_number_for_nested_type, 1599 location_field_number_for_nested_type,
1195 location)) { 1600 location,
1601 containing_file)) {
1196 // This statement failed to parse. Skip it, but keep looping to parse 1602 // This statement failed to parse. Skip it, but keep looping to parse
1197 // other statements. 1603 // other statements.
1198 SkipStatement(); 1604 SkipStatement();
1605 }
1606 } while (!TryConsumeEndOfDeclaration("}", NULL));
1607
1608 return true;
1609 }
1610
1611 bool Parser::ParseOneof(OneofDescriptorProto* oneof_decl,
1612 DescriptorProto* containing_type,
1613 int oneof_index,
1614 const LocationRecorder& oneof_location,
1615 const LocationRecorder& containing_type_location,
1616 const FileDescriptorProto* containing_file) {
1617 DO(Consume("oneof"));
1618
1619 {
1620 LocationRecorder name_location(oneof_location,
1621 OneofDescriptorProto::kNameFieldNumber);
1622 DO(ConsumeIdentifier(oneof_decl->mutable_name(), "Expected oneof name."));
1623 }
1624
1625 DO(ConsumeEndOfDeclaration("{", &oneof_location));
1626
1627 do {
1628 if (AtEnd()) {
1629 AddError("Reached end of input in oneof definition (missing '}').");
1630 return false;
1631 }
1632
1633 // Print a nice error if the user accidentally tries to place a label
1634 // on an individual member of a oneof.
1635 if (LookingAt("required") ||
1636 LookingAt("optional") ||
1637 LookingAt("repeated")) {
1638 AddError("Fields in oneofs must not have labels (required / optional "
1639 "/ repeated).");
1640 // We can continue parsing here because we understand what the user
1641 // meant. The error report will still make parsing fail overall.
1642 input_->Next();
1643 }
1644
1645 LocationRecorder field_location(containing_type_location,
1646 DescriptorProto::kFieldFieldNumber,
1647 containing_type->field_size());
1648
1649 FieldDescriptorProto* field = containing_type->add_field();
1650 field->set_label(FieldDescriptorProto::LABEL_OPTIONAL);
1651 field->set_oneof_index(oneof_index);
1652
1653 if (!ParseMessageFieldNoLabel(field,
1654 containing_type->mutable_nested_type(),
1655 containing_type_location,
1656 DescriptorProto::kNestedTypeFieldNumber,
1657 field_location,
1658 containing_file)) {
1659 // This statement failed to parse. Skip it, but keep looping to parse
1660 // other statements.
1661 SkipStatement();
1199 } 1662 }
1200 } while (!TryConsumeEndOfDeclaration("}", NULL)); 1663 } while (!TryConsumeEndOfDeclaration("}", NULL));
1201 1664
1202 return true; 1665 return true;
1203 } 1666 }
1204 1667
1205 // ------------------------------------------------------------------- 1668 // -------------------------------------------------------------------
1206 // Enums 1669 // Enums
1207 1670
1208 bool Parser::ParseEnumDefinition(EnumDescriptorProto* enum_type, 1671 bool Parser::ParseEnumDefinition(EnumDescriptorProto* enum_type,
1209 const LocationRecorder& enum_location) { 1672 const LocationRecorder& enum_location,
1673 const FileDescriptorProto* containing_file) {
1210 DO(Consume("enum")); 1674 DO(Consume("enum"));
1211 1675
1212 { 1676 {
1213 LocationRecorder location(enum_location, 1677 LocationRecorder location(enum_location,
1214 EnumDescriptorProto::kNameFieldNumber); 1678 EnumDescriptorProto::kNameFieldNumber);
1215 location.RecordLegacyLocation( 1679 location.RecordLegacyLocation(
1216 enum_type, DescriptorPool::ErrorCollector::NAME); 1680 enum_type, DescriptorPool::ErrorCollector::NAME);
1217 DO(ConsumeIdentifier(enum_type->mutable_name(), "Expected enum name.")); 1681 DO(ConsumeIdentifier(enum_type->mutable_name(), "Expected enum name."));
1218 } 1682 }
1219 1683
1220 DO(ParseEnumBlock(enum_type, enum_location)); 1684 DO(ParseEnumBlock(enum_type, enum_location, containing_file));
1685
1686 DO(ValidateEnum(enum_type));
1687
1221 return true; 1688 return true;
1222 } 1689 }
1223 1690
1224 bool Parser::ParseEnumBlock(EnumDescriptorProto* enum_type, 1691 bool Parser::ParseEnumBlock(EnumDescriptorProto* enum_type,
1225 const LocationRecorder& enum_location) { 1692 const LocationRecorder& enum_location,
1693 const FileDescriptorProto* containing_file) {
1226 DO(ConsumeEndOfDeclaration("{", &enum_location)); 1694 DO(ConsumeEndOfDeclaration("{", &enum_location));
1227 1695
1228 while (!TryConsumeEndOfDeclaration("}", NULL)) { 1696 while (!TryConsumeEndOfDeclaration("}", NULL)) {
1229 if (AtEnd()) { 1697 if (AtEnd()) {
1230 AddError("Reached end of input in enum definition (missing '}')."); 1698 AddError("Reached end of input in enum definition (missing '}').");
1231 return false; 1699 return false;
1232 } 1700 }
1233 1701
1234 if (!ParseEnumStatement(enum_type, enum_location)) { 1702 if (!ParseEnumStatement(enum_type, enum_location, containing_file)) {
1235 // This statement failed to parse. Skip it, but keep looping to parse 1703 // This statement failed to parse. Skip it, but keep looping to parse
1236 // other statements. 1704 // other statements.
1237 SkipStatement(); 1705 SkipStatement();
1238 } 1706 }
1239 } 1707 }
1240 1708
1241 return true; 1709 return true;
1242 } 1710 }
1243 1711
1244 bool Parser::ParseEnumStatement(EnumDescriptorProto* enum_type, 1712 bool Parser::ParseEnumStatement(EnumDescriptorProto* enum_type,
1245 const LocationRecorder& enum_location) { 1713 const LocationRecorder& enum_location,
1714 const FileDescriptorProto* containing_file) {
1246 if (TryConsumeEndOfDeclaration(";", NULL)) { 1715 if (TryConsumeEndOfDeclaration(";", NULL)) {
1247 // empty statement; ignore 1716 // empty statement; ignore
1248 return true; 1717 return true;
1249 } else if (LookingAt("option")) { 1718 } else if (LookingAt("option")) {
1250 LocationRecorder location(enum_location, 1719 LocationRecorder location(enum_location,
1251 EnumDescriptorProto::kOptionsFieldNumber); 1720 EnumDescriptorProto::kOptionsFieldNumber);
1252 return ParseOption(enum_type->mutable_options(), location, 1721 return ParseOption(enum_type->mutable_options(), location,
1253 OPTION_STATEMENT); 1722 containing_file, OPTION_STATEMENT);
1254 } else { 1723 } else {
1255 LocationRecorder location(enum_location, 1724 LocationRecorder location(enum_location,
1256 EnumDescriptorProto::kValueFieldNumber, enum_type->value_size()); 1725 EnumDescriptorProto::kValueFieldNumber, enum_type->value_size());
1257 return ParseEnumConstant(enum_type->add_value(), location); 1726 return ParseEnumConstant(enum_type->add_value(), location, containing_file);
1258 } 1727 }
1259 } 1728 }
1260 1729
1261 bool Parser::ParseEnumConstant(EnumValueDescriptorProto* enum_value, 1730 bool Parser::ParseEnumConstant(EnumValueDescriptorProto* enum_value,
1262 const LocationRecorder& enum_value_location) { 1731 const LocationRecorder& enum_value_location,
1732 const FileDescriptorProto* containing_file) {
1263 // Parse name. 1733 // Parse name.
1264 { 1734 {
1265 LocationRecorder location(enum_value_location, 1735 LocationRecorder location(enum_value_location,
1266 EnumValueDescriptorProto::kNameFieldNumber); 1736 EnumValueDescriptorProto::kNameFieldNumber);
1267 location.RecordLegacyLocation( 1737 location.RecordLegacyLocation(
1268 enum_value, DescriptorPool::ErrorCollector::NAME); 1738 enum_value, DescriptorPool::ErrorCollector::NAME);
1269 DO(ConsumeIdentifier(enum_value->mutable_name(), 1739 DO(ConsumeIdentifier(enum_value->mutable_name(),
1270 "Expected enum constant name.")); 1740 "Expected enum constant name."));
1271 } 1741 }
1272 1742
1273 DO(Consume("=", "Missing numeric value for enum constant.")); 1743 DO(Consume("=", "Missing numeric value for enum constant."));
1274 1744
1275 // Parse value. 1745 // Parse value.
1276 { 1746 {
1277 LocationRecorder location( 1747 LocationRecorder location(
1278 enum_value_location, EnumValueDescriptorProto::kNumberFieldNumber); 1748 enum_value_location, EnumValueDescriptorProto::kNumberFieldNumber);
1279 location.RecordLegacyLocation( 1749 location.RecordLegacyLocation(
1280 enum_value, DescriptorPool::ErrorCollector::NUMBER); 1750 enum_value, DescriptorPool::ErrorCollector::NUMBER);
1281 1751
1282 int number; 1752 int number;
1283 DO(ConsumeSignedInteger(&number, "Expected integer.")); 1753 DO(ConsumeSignedInteger(&number, "Expected integer."));
1284 enum_value->set_number(number); 1754 enum_value->set_number(number);
1285 } 1755 }
1286 1756
1287 DO(ParseEnumConstantOptions(enum_value, enum_value_location)); 1757 DO(ParseEnumConstantOptions(enum_value, enum_value_location,
1758 containing_file));
1288 1759
1289 DO(ConsumeEndOfDeclaration(";", &enum_value_location)); 1760 DO(ConsumeEndOfDeclaration(";", &enum_value_location));
1290 1761
1291 return true; 1762 return true;
1292 } 1763 }
1293 1764
1294 bool Parser::ParseEnumConstantOptions( 1765 bool Parser::ParseEnumConstantOptions(
1295 EnumValueDescriptorProto* value, 1766 EnumValueDescriptorProto* value,
1296 const LocationRecorder& enum_value_location) { 1767 const LocationRecorder& enum_value_location,
1768 const FileDescriptorProto* containing_file) {
1297 if (!LookingAt("[")) return true; 1769 if (!LookingAt("[")) return true;
1298 1770
1299 LocationRecorder location( 1771 LocationRecorder location(
1300 enum_value_location, EnumValueDescriptorProto::kOptionsFieldNumber); 1772 enum_value_location, EnumValueDescriptorProto::kOptionsFieldNumber);
1301 1773
1302 DO(Consume("[")); 1774 DO(Consume("["));
1303 1775
1304 do { 1776 do {
1305 DO(ParseOption(value->mutable_options(), location, OPTION_ASSIGNMENT)); 1777 DO(ParseOption(value->mutable_options(), location,
1778 containing_file, OPTION_ASSIGNMENT));
1306 } while (TryConsume(",")); 1779 } while (TryConsume(","));
1307 1780
1308 DO(Consume("]")); 1781 DO(Consume("]"));
1309 return true; 1782 return true;
1310 } 1783 }
1311 1784
1312 // ------------------------------------------------------------------- 1785 // -------------------------------------------------------------------
1313 // Services 1786 // Services
1314 1787
1315 bool Parser::ParseServiceDefinition(ServiceDescriptorProto* service, 1788 bool Parser::ParseServiceDefinition(
1316 const LocationRecorder& service_location) { 1789 ServiceDescriptorProto* service,
1790 const LocationRecorder& service_location,
1791 const FileDescriptorProto* containing_file) {
1317 DO(Consume("service")); 1792 DO(Consume("service"));
1318 1793
1319 { 1794 {
1320 LocationRecorder location(service_location, 1795 LocationRecorder location(service_location,
1321 ServiceDescriptorProto::kNameFieldNumber); 1796 ServiceDescriptorProto::kNameFieldNumber);
1322 location.RecordLegacyLocation( 1797 location.RecordLegacyLocation(
1323 service, DescriptorPool::ErrorCollector::NAME); 1798 service, DescriptorPool::ErrorCollector::NAME);
1324 DO(ConsumeIdentifier(service->mutable_name(), "Expected service name.")); 1799 DO(ConsumeIdentifier(service->mutable_name(), "Expected service name."));
1325 } 1800 }
1326 1801
1327 DO(ParseServiceBlock(service, service_location)); 1802 DO(ParseServiceBlock(service, service_location, containing_file));
1328 return true; 1803 return true;
1329 } 1804 }
1330 1805
1331 bool Parser::ParseServiceBlock(ServiceDescriptorProto* service, 1806 bool Parser::ParseServiceBlock(ServiceDescriptorProto* service,
1332 const LocationRecorder& service_location) { 1807 const LocationRecorder& service_location,
1808 const FileDescriptorProto* containing_file) {
1333 DO(ConsumeEndOfDeclaration("{", &service_location)); 1809 DO(ConsumeEndOfDeclaration("{", &service_location));
1334 1810
1335 while (!TryConsumeEndOfDeclaration("}", NULL)) { 1811 while (!TryConsumeEndOfDeclaration("}", NULL)) {
1336 if (AtEnd()) { 1812 if (AtEnd()) {
1337 AddError("Reached end of input in service definition (missing '}')."); 1813 AddError("Reached end of input in service definition (missing '}').");
1338 return false; 1814 return false;
1339 } 1815 }
1340 1816
1341 if (!ParseServiceStatement(service, service_location)) { 1817 if (!ParseServiceStatement(service, service_location, containing_file)) {
1342 // This statement failed to parse. Skip it, but keep looping to parse 1818 // This statement failed to parse. Skip it, but keep looping to parse
1343 // other statements. 1819 // other statements.
1344 SkipStatement(); 1820 SkipStatement();
1345 } 1821 }
1346 } 1822 }
1347 1823
1348 return true; 1824 return true;
1349 } 1825 }
1350 1826
1351 bool Parser::ParseServiceStatement(ServiceDescriptorProto* service, 1827 bool Parser::ParseServiceStatement(ServiceDescriptorProto* service,
1352 const LocationRecorder& service_location) { 1828 const LocationRecorder& service_location,
1829 const FileDescriptorProto* containing_file) {
1353 if (TryConsumeEndOfDeclaration(";", NULL)) { 1830 if (TryConsumeEndOfDeclaration(";", NULL)) {
1354 // empty statement; ignore 1831 // empty statement; ignore
1355 return true; 1832 return true;
1356 } else if (LookingAt("option")) { 1833 } else if (LookingAt("option")) {
1357 LocationRecorder location( 1834 LocationRecorder location(
1358 service_location, ServiceDescriptorProto::kOptionsFieldNumber); 1835 service_location, ServiceDescriptorProto::kOptionsFieldNumber);
1359 return ParseOption(service->mutable_options(), location, OPTION_STATEMENT); 1836 return ParseOption(service->mutable_options(), location,
1837 containing_file, OPTION_STATEMENT);
1360 } else { 1838 } else {
1361 LocationRecorder location(service_location, 1839 LocationRecorder location(service_location,
1362 ServiceDescriptorProto::kMethodFieldNumber, service->method_size()); 1840 ServiceDescriptorProto::kMethodFieldNumber, service->method_size());
1363 return ParseServiceMethod(service->add_method(), location); 1841 return ParseServiceMethod(service->add_method(), location, containing_file);
1364 } 1842 }
1365 } 1843 }
1366 1844
1367 bool Parser::ParseServiceMethod(MethodDescriptorProto* method, 1845 bool Parser::ParseServiceMethod(MethodDescriptorProto* method,
1368 const LocationRecorder& method_location) { 1846 const LocationRecorder& method_location,
1847 const FileDescriptorProto* containing_file) {
1369 DO(Consume("rpc")); 1848 DO(Consume("rpc"));
1370 1849
1371 { 1850 {
1372 LocationRecorder location(method_location, 1851 LocationRecorder location(method_location,
1373 MethodDescriptorProto::kNameFieldNumber); 1852 MethodDescriptorProto::kNameFieldNumber);
1374 location.RecordLegacyLocation( 1853 location.RecordLegacyLocation(
1375 method, DescriptorPool::ErrorCollector::NAME); 1854 method, DescriptorPool::ErrorCollector::NAME);
1376 DO(ConsumeIdentifier(method->mutable_name(), "Expected method name.")); 1855 DO(ConsumeIdentifier(method->mutable_name(), "Expected method name."));
1377 } 1856 }
1378 1857
1379 // Parse input type. 1858 // Parse input type.
1380 DO(Consume("(")); 1859 DO(Consume("("));
1381 { 1860 {
1861 if (LookingAt("stream")) {
1862 LocationRecorder location(
1863 method_location, MethodDescriptorProto::kClientStreamingFieldNumber);
1864 location.RecordLegacyLocation(
1865 method, DescriptorPool::ErrorCollector::OTHER);
1866 method->set_client_streaming(true);
1867 DO(Consume("stream"));
1868
1869 }
1382 LocationRecorder location(method_location, 1870 LocationRecorder location(method_location,
1383 MethodDescriptorProto::kInputTypeFieldNumber); 1871 MethodDescriptorProto::kInputTypeFieldNumber);
1384 location.RecordLegacyLocation( 1872 location.RecordLegacyLocation(
1385 method, DescriptorPool::ErrorCollector::INPUT_TYPE); 1873 method, DescriptorPool::ErrorCollector::INPUT_TYPE);
1386 DO(ParseUserDefinedType(method->mutable_input_type())); 1874 DO(ParseUserDefinedType(method->mutable_input_type()));
1387 } 1875 }
1388 DO(Consume(")")); 1876 DO(Consume(")"));
1389 1877
1390 // Parse output type. 1878 // Parse output type.
1391 DO(Consume("returns")); 1879 DO(Consume("returns"));
1392 DO(Consume("(")); 1880 DO(Consume("("));
1393 { 1881 {
1882 if (LookingAt("stream")) {
1883 LocationRecorder location(
1884 method_location, MethodDescriptorProto::kServerStreamingFieldNumber);
1885 location.RecordLegacyLocation(
1886 method, DescriptorPool::ErrorCollector::OTHER);
1887 DO(Consume("stream"));
1888 method->set_server_streaming(true);
1889
1890 }
1394 LocationRecorder location(method_location, 1891 LocationRecorder location(method_location,
1395 MethodDescriptorProto::kOutputTypeFieldNumber); 1892 MethodDescriptorProto::kOutputTypeFieldNumber);
1396 location.RecordLegacyLocation( 1893 location.RecordLegacyLocation(
1397 method, DescriptorPool::ErrorCollector::OUTPUT_TYPE); 1894 method, DescriptorPool::ErrorCollector::OUTPUT_TYPE);
1398 DO(ParseUserDefinedType(method->mutable_output_type())); 1895 DO(ParseUserDefinedType(method->mutable_output_type()));
1399 } 1896 }
1400 DO(Consume(")")); 1897 DO(Consume(")"));
1401 1898
1402 if (LookingAt("{")) { 1899 if (LookingAt("{")) {
1403 // Options! 1900 // Options!
1404 DO(ParseOptions(method_location, 1901 DO(ParseMethodOptions(method_location, containing_file,
1405 MethodDescriptorProto::kOptionsFieldNumber, 1902 MethodDescriptorProto::kOptionsFieldNumber,
1406 method->mutable_options())); 1903 method->mutable_options()));
1407 } else { 1904 } else {
1408 DO(ConsumeEndOfDeclaration(";", &method_location)); 1905 DO(ConsumeEndOfDeclaration(";", &method_location));
1409 } 1906 }
1410 1907
1411 return true; 1908 return true;
1412 } 1909 }
1413 1910
1414 1911
1415 bool Parser::ParseOptions(const LocationRecorder& parent_location, 1912 bool Parser::ParseMethodOptions(const LocationRecorder& parent_location,
1416 const int optionsFieldNumber, 1913 const FileDescriptorProto* containing_file,
1417 Message* mutable_options) { 1914 const int optionsFieldNumber,
1915 Message* mutable_options) {
1418 // Options! 1916 // Options!
1419 ConsumeEndOfDeclaration("{", &parent_location); 1917 ConsumeEndOfDeclaration("{", &parent_location);
1420 while (!TryConsumeEndOfDeclaration("}", NULL)) { 1918 while (!TryConsumeEndOfDeclaration("}", NULL)) {
1421 if (AtEnd()) { 1919 if (AtEnd()) {
1422 AddError("Reached end of input in method options (missing '}')."); 1920 AddError("Reached end of input in method options (missing '}').");
1423 return false; 1921 return false;
1424 } 1922 }
1425 1923
1426 if (TryConsumeEndOfDeclaration(";", NULL)) { 1924 if (TryConsumeEndOfDeclaration(";", NULL)) {
1427 // empty statement; ignore 1925 // empty statement; ignore
1428 } else { 1926 } else {
1429 LocationRecorder location(parent_location, 1927 LocationRecorder location(parent_location,
1430 optionsFieldNumber); 1928 optionsFieldNumber);
1431 if (!ParseOption(mutable_options, location, OPTION_STATEMENT)) { 1929 if (!ParseOption(mutable_options, location,
1930 containing_file, OPTION_STATEMENT)) {
1432 // This statement failed to parse. Skip it, but keep looping to 1931 // This statement failed to parse. Skip it, but keep looping to
1433 // parse other statements. 1932 // parse other statements.
1434 SkipStatement(); 1933 SkipStatement();
1435 } 1934 }
1436 } 1935 }
1437 } 1936 }
1438 1937
1439 return true; 1938 return true;
1440 } 1939 }
1441 1940
1442 // ------------------------------------------------------------------- 1941 // -------------------------------------------------------------------
1443 1942
1444 bool Parser::ParseLabel(FieldDescriptorProto::Label* label) { 1943 bool Parser::ParseLabel(FieldDescriptorProto::Label* label,
1944 const FileDescriptorProto* containing_file) {
1445 if (TryConsume("optional")) { 1945 if (TryConsume("optional")) {
1446 *label = FieldDescriptorProto::LABEL_OPTIONAL; 1946 *label = FieldDescriptorProto::LABEL_OPTIONAL;
1447 return true; 1947 return true;
1448 } else if (TryConsume("repeated")) { 1948 } else if (TryConsume("repeated")) {
1449 *label = FieldDescriptorProto::LABEL_REPEATED; 1949 *label = FieldDescriptorProto::LABEL_REPEATED;
1450 return true; 1950 return true;
1451 } else if (TryConsume("required")) { 1951 } else if (TryConsume("required")) {
1452 *label = FieldDescriptorProto::LABEL_REQUIRED; 1952 *label = FieldDescriptorProto::LABEL_REQUIRED;
1453 return true; 1953 return true;
1454 } else {
1455 AddError("Expected \"required\", \"optional\", or \"repeated\".");
1456 // We can actually reasonably recover here by just assuming the user
1457 // forgot the label altogether.
1458 *label = FieldDescriptorProto::LABEL_OPTIONAL;
1459 return true;
1460 } 1954 }
1955 return false;
1461 } 1956 }
1462 1957
1463 bool Parser::ParseType(FieldDescriptorProto::Type* type, 1958 bool Parser::ParseType(FieldDescriptorProto::Type* type,
1464 string* type_name) { 1959 string* type_name) {
1465 TypeNameMap::const_iterator iter = kTypeNames.find(input_->current().text); 1960 TypeNameMap::const_iterator iter = kTypeNames.find(input_->current().text);
1466 if (iter != kTypeNames.end()) { 1961 if (iter != kTypeNames.end()) {
1467 *type = iter->second; 1962 *type = iter->second;
1468 input_->Next(); 1963 input_->Next();
1469 } else { 1964 } else {
1470 DO(ParseUserDefinedType(type_name)); 1965 DO(ParseUserDefinedType(type_name));
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
1503 DO(ConsumeIdentifier(&identifier, "Expected identifier.")); 1998 DO(ConsumeIdentifier(&identifier, "Expected identifier."));
1504 type_name->append(identifier); 1999 type_name->append(identifier);
1505 } 2000 }
1506 2001
1507 return true; 2002 return true;
1508 } 2003 }
1509 2004
1510 // =================================================================== 2005 // ===================================================================
1511 2006
1512 bool Parser::ParsePackage(FileDescriptorProto* file, 2007 bool Parser::ParsePackage(FileDescriptorProto* file,
1513 const LocationRecorder& root_location) { 2008 const LocationRecorder& root_location,
2009 const FileDescriptorProto* containing_file) {
1514 if (file->has_package()) { 2010 if (file->has_package()) {
1515 AddError("Multiple package definitions."); 2011 AddError("Multiple package definitions.");
1516 // Don't append the new package to the old one. Just replace it. Not 2012 // Don't append the new package to the old one. Just replace it. Not
1517 // that it really matters since this is an error anyway. 2013 // that it really matters since this is an error anyway.
1518 file->clear_package(); 2014 file->clear_package();
1519 } 2015 }
1520 2016
1521 DO(Consume("package")); 2017 DO(Consume("package"));
1522 2018
1523 { 2019 {
(...skipping 13 matching lines...) Expand all
1537 2033
1538 DO(ConsumeEndOfDeclaration(";", &location)); 2034 DO(ConsumeEndOfDeclaration(";", &location));
1539 } 2035 }
1540 2036
1541 return true; 2037 return true;
1542 } 2038 }
1543 2039
1544 bool Parser::ParseImport(RepeatedPtrField<string>* dependency, 2040 bool Parser::ParseImport(RepeatedPtrField<string>* dependency,
1545 RepeatedField<int32>* public_dependency, 2041 RepeatedField<int32>* public_dependency,
1546 RepeatedField<int32>* weak_dependency, 2042 RepeatedField<int32>* weak_dependency,
1547 const LocationRecorder& root_location) { 2043 const LocationRecorder& root_location,
2044 const FileDescriptorProto* containing_file) {
1548 DO(Consume("import")); 2045 DO(Consume("import"));
1549 if (LookingAt("public")) { 2046 if (LookingAt("public")) {
1550 LocationRecorder location( 2047 LocationRecorder location(
1551 root_location, FileDescriptorProto::kPublicDependencyFieldNumber, 2048 root_location, FileDescriptorProto::kPublicDependencyFieldNumber,
1552 public_dependency->size()); 2049 public_dependency->size());
1553 DO(Consume("public")); 2050 DO(Consume("public"));
1554 *public_dependency->Add() = dependency->size(); 2051 *public_dependency->Add() = dependency->size();
1555 } else if (LookingAt("weak")) { 2052 } else if (LookingAt("weak")) {
1556 LocationRecorder location( 2053 LocationRecorder location(
1557 root_location, FileDescriptorProto::kWeakDependencyFieldNumber, 2054 root_location, FileDescriptorProto::kWeakDependencyFieldNumber,
(...skipping 18 matching lines...) Expand all
1576 // =================================================================== 2073 // ===================================================================
1577 2074
1578 SourceLocationTable::SourceLocationTable() {} 2075 SourceLocationTable::SourceLocationTable() {}
1579 SourceLocationTable::~SourceLocationTable() {} 2076 SourceLocationTable::~SourceLocationTable() {}
1580 2077
1581 bool SourceLocationTable::Find( 2078 bool SourceLocationTable::Find(
1582 const Message* descriptor, 2079 const Message* descriptor,
1583 DescriptorPool::ErrorCollector::ErrorLocation location, 2080 DescriptorPool::ErrorCollector::ErrorLocation location,
1584 int* line, int* column) const { 2081 int* line, int* column) const {
1585 const pair<int, int>* result = 2082 const pair<int, int>* result =
1586 FindOrNull(location_map_, make_pair(descriptor, location)); 2083 FindOrNull(location_map_, std::make_pair(descriptor, location));
1587 if (result == NULL) { 2084 if (result == NULL) {
1588 *line = -1; 2085 *line = -1;
1589 *column = 0; 2086 *column = 0;
1590 return false; 2087 return false;
1591 } else { 2088 } else {
1592 *line = result->first; 2089 *line = result->first;
1593 *column = result->second; 2090 *column = result->second;
1594 return true; 2091 return true;
1595 } 2092 }
1596 } 2093 }
1597 2094
1598 void SourceLocationTable::Add( 2095 void SourceLocationTable::Add(
1599 const Message* descriptor, 2096 const Message* descriptor,
1600 DescriptorPool::ErrorCollector::ErrorLocation location, 2097 DescriptorPool::ErrorCollector::ErrorLocation location,
1601 int line, int column) { 2098 int line, int column) {
1602 location_map_[make_pair(descriptor, location)] = make_pair(line, column); 2099 location_map_[std::make_pair(descriptor, location)] =
2100 std::make_pair(line, column);
1603 } 2101 }
1604 2102
1605 void SourceLocationTable::Clear() { 2103 void SourceLocationTable::Clear() {
1606 location_map_.clear(); 2104 location_map_.clear();
1607 } 2105 }
1608 2106
1609 } // namespace compiler 2107 } // namespace compiler
1610 } // namespace protobuf 2108 } // namespace protobuf
1611 } // namespace google 2109 } // namespace google
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698