1 // Protocol Buffers - Google's data interchange format 2 // Copyright 2008 Google Inc. All rights reserved. 3 // https://developers.google.com/protocol-buffers/ 4 // 5 // Redistribution and use in source and binary forms, with or without 6 // modification, are permitted provided that the following conditions are 7 // met: 8 // 9 // * Redistributions of source code must retain the above copyright 10 // notice, this list of conditions and the following disclaimer. 11 // * Redistributions in binary form must reproduce the above 12 // copyright notice, this list of conditions and the following disclaimer 13 // in the documentation and/or other materials provided with the 14 // distribution. 15 // * Neither the name of Google Inc. nor the names of its 16 // contributors may be used to endorse or promote products derived from 17 // this software without specific prior written permission. 18 // 19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 31 // Author: kenton (at) google.com (Kenton Varda) 32 // Based on original Protocol Buffers design by 33 // Sanjay Ghemawat, Jeff Dean, and others. 34 // 35 // Recursive descent FTW. 36 37 #include <float.h> 38 #include <google/protobuf/stubs/hash.h> 39 #include <limits> 40 41 42 #include <google/protobuf/compiler/parser.h> 43 #include <google/protobuf/descriptor.h> 44 #include <google/protobuf/descriptor.pb.h> 45 #include <google/protobuf/wire_format.h> 46 #include <google/protobuf/io/tokenizer.h> 47 #include <google/protobuf/stubs/logging.h> 48 #include <google/protobuf/stubs/common.h> 49 #include <google/protobuf/stubs/strutil.h> 50 #include <google/protobuf/stubs/map_util.h> 51 52 namespace google { 53 namespace protobuf { 54 namespace compiler { 55 56 using internal::WireFormat; 57 58 namespace { 59 60 typedef hash_map<string, FieldDescriptorProto::Type> TypeNameMap; 61 62 TypeNameMap MakeTypeNameTable() { 63 TypeNameMap result; 64 65 result["double" ] = FieldDescriptorProto::TYPE_DOUBLE; 66 result["float" ] = FieldDescriptorProto::TYPE_FLOAT; 67 result["uint64" ] = FieldDescriptorProto::TYPE_UINT64; 68 result["fixed64" ] = FieldDescriptorProto::TYPE_FIXED64; 69 result["fixed32" ] = FieldDescriptorProto::TYPE_FIXED32; 70 result["bool" ] = FieldDescriptorProto::TYPE_BOOL; 71 result["string" ] = FieldDescriptorProto::TYPE_STRING; 72 result["group" ] = FieldDescriptorProto::TYPE_GROUP; 73 74 result["bytes" ] = FieldDescriptorProto::TYPE_BYTES; 75 result["uint32" ] = FieldDescriptorProto::TYPE_UINT32; 76 result["sfixed32"] = FieldDescriptorProto::TYPE_SFIXED32; 77 result["sfixed64"] = FieldDescriptorProto::TYPE_SFIXED64; 78 result["int32" ] = FieldDescriptorProto::TYPE_INT32; 79 result["int64" ] = FieldDescriptorProto::TYPE_INT64; 80 result["sint32" ] = FieldDescriptorProto::TYPE_SINT32; 81 result["sint64" ] = FieldDescriptorProto::TYPE_SINT64; 82 83 return result; 84 } 85 86 const TypeNameMap kTypeNames = MakeTypeNameTable(); 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 114 } // anonymous namespace 115 116 // Makes code slightly more readable. The meaning of "DO(foo)" is 117 // "Execute foo and fail if it fails.", where failure is indicated by 118 // returning false. 119 #define DO(STATEMENT) if (STATEMENT) {} else return false 120 121 // =================================================================== 122 123 Parser::Parser() 124 : input_(NULL), 125 error_collector_(NULL), 126 source_location_table_(NULL), 127 had_errors_(false), 128 require_syntax_identifier_(false), 129 stop_after_syntax_identifier_(false) { 130 } 131 132 Parser::~Parser() { 133 } 134 135 // =================================================================== 136 137 inline bool Parser::LookingAt(const char* text) { 138 return input_->current().text == text; 139 } 140 141 inline bool Parser::LookingAtType(io::Tokenizer::TokenType token_type) { 142 return input_->current().type == token_type; 143 } 144 145 inline bool Parser::AtEnd() { 146 return LookingAtType(io::Tokenizer::TYPE_END); 147 } 148 149 bool Parser::TryConsume(const char* text) { 150 if (LookingAt(text)) { 151 input_->Next(); 152 return true; 153 } else { 154 return false; 155 } 156 } 157 158 bool Parser::Consume(const char* text, const char* error) { 159 if (TryConsume(text)) { 160 return true; 161 } else { 162 AddError(error); 163 return false; 164 } 165 } 166 167 bool Parser::Consume(const char* text) { 168 if (TryConsume(text)) { 169 return true; 170 } else { 171 AddError("Expected \"" + string(text) + "\"."); 172 return false; 173 } 174 } 175 176 bool Parser::ConsumeIdentifier(string* output, const char* error) { 177 if (LookingAtType(io::Tokenizer::TYPE_IDENTIFIER)) { 178 *output = input_->current().text; 179 input_->Next(); 180 return true; 181 } else { 182 AddError(error); 183 return false; 184 } 185 } 186 187 bool Parser::ConsumeInteger(int* output, const char* error) { 188 if (LookingAtType(io::Tokenizer::TYPE_INTEGER)) { 189 uint64 value = 0; 190 if (!io::Tokenizer::ParseInteger(input_->current().text, 191 kint32max, &value)) { 192 AddError("Integer out of range."); 193 // We still return true because we did, in fact, parse an integer. 194 } 195 *output = value; 196 input_->Next(); 197 return true; 198 } else { 199 AddError(error); 200 return false; 201 } 202 } 203 204 bool Parser::ConsumeSignedInteger(int* output, const char* error) { 205 bool is_negative = false; 206 uint64 max_value = kint32max; 207 if (TryConsume("-")) { 208 is_negative = true; 209 max_value += 1; 210 } 211 uint64 value = 0; 212 DO(ConsumeInteger64(max_value, &value, error)); 213 if (is_negative) value *= -1; 214 *output = value; 215 return true; 216 } 217 218 bool Parser::ConsumeInteger64(uint64 max_value, uint64* output, 219 const char* error) { 220 if (LookingAtType(io::Tokenizer::TYPE_INTEGER)) { 221 if (!io::Tokenizer::ParseInteger(input_->current().text, max_value, 222 output)) { 223 AddError("Integer out of range."); 224 // We still return true because we did, in fact, parse an integer. 225 *output = 0; 226 } 227 input_->Next(); 228 return true; 229 } else { 230 AddError(error); 231 return false; 232 } 233 } 234 235 bool Parser::ConsumeNumber(double* output, const char* error) { 236 if (LookingAtType(io::Tokenizer::TYPE_FLOAT)) { 237 *output = io::Tokenizer::ParseFloat(input_->current().text); 238 input_->Next(); 239 return true; 240 } else if (LookingAtType(io::Tokenizer::TYPE_INTEGER)) { 241 // Also accept integers. 242 uint64 value = 0; 243 if (!io::Tokenizer::ParseInteger(input_->current().text, 244 kuint64max, &value)) { 245 AddError("Integer out of range."); 246 // We still return true because we did, in fact, parse a number. 247 } 248 *output = value; 249 input_->Next(); 250 return true; 251 } else if (LookingAt("inf")) { 252 *output = numeric_limits<double>::infinity(); 253 input_->Next(); 254 return true; 255 } else if (LookingAt("nan")) { 256 *output = numeric_limits<double>::quiet_NaN(); 257 input_->Next(); 258 return true; 259 } else { 260 AddError(error); 261 return false; 262 } 263 } 264 265 bool Parser::ConsumeString(string* output, const char* error) { 266 if (LookingAtType(io::Tokenizer::TYPE_STRING)) { 267 io::Tokenizer::ParseString(input_->current().text, output); 268 input_->Next(); 269 // Allow C++ like concatenation of adjacent string tokens. 270 while (LookingAtType(io::Tokenizer::TYPE_STRING)) { 271 io::Tokenizer::ParseStringAppend(input_->current().text, output); 272 input_->Next(); 273 } 274 return true; 275 } else { 276 AddError(error); 277 return false; 278 } 279 } 280 281 bool Parser::TryConsumeEndOfDeclaration( 282 const char* text, const LocationRecorder* location) { 283 if (LookingAt(text)) { 284 string leading, trailing; 285 vector<string> detached; 286 input_->NextWithComments(&trailing, &detached, &leading); 287 288 // Save the leading comments for next time, and recall the leading comments 289 // from last time. 290 leading.swap(upcoming_doc_comments_); 291 292 if (location != NULL) { 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()); 304 } 305 306 return true; 307 } else { 308 return false; 309 } 310 } 311 312 bool Parser::ConsumeEndOfDeclaration( 313 const char* text, const LocationRecorder* location) { 314 if (TryConsumeEndOfDeclaration(text, location)) { 315 return true; 316 } else { 317 AddError("Expected \"" + string(text) + "\"."); 318 return false; 319 } 320 } 321 322 // ------------------------------------------------------------------- 323 324 void Parser::AddError(int line, int column, const string& error) { 325 if (error_collector_ != NULL) { 326 error_collector_->AddError(line, column, error); 327 } 328 had_errors_ = true; 329 } 330 331 void Parser::AddError(const string& error) { 332 AddError(input_->current().line, input_->current().column, error); 333 } 334 335 // ------------------------------------------------------------------- 336 337 Parser::LocationRecorder::LocationRecorder(Parser* parser) 338 : parser_(parser), 339 location_(parser_->source_code_info_->add_location()) { 340 location_->add_span(parser_->input_->current().line); 341 location_->add_span(parser_->input_->current().column); 342 } 343 344 Parser::LocationRecorder::LocationRecorder(const LocationRecorder& parent) { 345 Init(parent); 346 } 347 348 Parser::LocationRecorder::LocationRecorder(const LocationRecorder& parent, 349 int path1) { 350 Init(parent); 351 AddPath(path1); 352 } 353 354 Parser::LocationRecorder::LocationRecorder(const LocationRecorder& parent, 355 int path1, int path2) { 356 Init(parent); 357 AddPath(path1); 358 AddPath(path2); 359 } 360 361 void Parser::LocationRecorder::Init(const LocationRecorder& parent) { 362 parser_ = parent.parser_; 363 location_ = parser_->source_code_info_->add_location(); 364 location_->mutable_path()->CopyFrom(parent.location_->path()); 365 366 location_->add_span(parser_->input_->current().line); 367 location_->add_span(parser_->input_->current().column); 368 } 369 370 Parser::LocationRecorder::~LocationRecorder() { 371 if (location_->span_size() <= 2) { 372 EndAt(parser_->input_->previous()); 373 } 374 } 375 376 void Parser::LocationRecorder::AddPath(int path_component) { 377 location_->add_path(path_component); 378 } 379 380 void Parser::LocationRecorder::StartAt(const io::Tokenizer::Token& token) { 381 location_->set_span(0, token.line); 382 location_->set_span(1, token.column); 383 } 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 390 void Parser::LocationRecorder::EndAt(const io::Tokenizer::Token& token) { 391 if (token.line != location_->span(0)) { 392 location_->add_span(token.line); 393 } 394 location_->add_span(token.end_column); 395 } 396 397 void Parser::LocationRecorder::RecordLegacyLocation(const Message* descriptor, 398 DescriptorPool::ErrorCollector::ErrorLocation location) { 399 if (parser_->source_location_table_ != NULL) { 400 parser_->source_location_table_->Add( 401 descriptor, location, location_->span(0), location_->span(1)); 402 } 403 } 404 405 void Parser::LocationRecorder::AttachComments( 406 string* leading, string* trailing, 407 vector<string>* detached_comments) const { 408 GOOGLE_CHECK(!location_->has_leading_comments()); 409 GOOGLE_CHECK(!location_->has_trailing_comments()); 410 411 if (!leading->empty()) { 412 location_->mutable_leading_comments()->swap(*leading); 413 } 414 if (!trailing->empty()) { 415 location_->mutable_trailing_comments()->swap(*trailing); 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(); 422 } 423 424 // ------------------------------------------------------------------- 425 426 void Parser::SkipStatement() { 427 while (true) { 428 if (AtEnd()) { 429 return; 430 } else if (LookingAtType(io::Tokenizer::TYPE_SYMBOL)) { 431 if (TryConsumeEndOfDeclaration(";", NULL)) { 432 return; 433 } else if (TryConsume("{")) { 434 SkipRestOfBlock(); 435 return; 436 } else if (LookingAt("}")) { 437 return; 438 } 439 } 440 input_->Next(); 441 } 442 } 443 444 void Parser::SkipRestOfBlock() { 445 while (true) { 446 if (AtEnd()) { 447 return; 448 } else if (LookingAtType(io::Tokenizer::TYPE_SYMBOL)) { 449 if (TryConsumeEndOfDeclaration("}", NULL)) { 450 return; 451 } else if (TryConsume("{")) { 452 SkipRestOfBlock(); 453 } 454 } 455 input_->Next(); 456 } 457 } 458 459 // =================================================================== 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 516 bool Parser::Parse(io::Tokenizer* input, FileDescriptorProto* file) { 517 input_ = input; 518 had_errors_ = false; 519 syntax_identifier_.clear(); 520 521 // Note that |file| could be NULL at this point if 522 // stop_after_syntax_identifier_ is true. So, we conservatively allocate 523 // SourceCodeInfo on the stack, then swap it into the FileDescriptorProto 524 // later on. 525 SourceCodeInfo source_code_info; 526 source_code_info_ = &source_code_info; 527 528 vector<string> top_doc_comments; 529 if (LookingAtType(io::Tokenizer::TYPE_START)) { 530 // Advance to first token. 531 input_->NextWithComments(NULL, &upcoming_detached_comments_, 532 &upcoming_doc_comments_); 533 } 534 535 { 536 LocationRecorder root_location(this); 537 538 if (require_syntax_identifier_ || LookingAt("syntax")) { 539 if (!ParseSyntaxIdentifier(root_location)) { 540 // Don't attempt to parse the file if we didn't recognize the syntax 541 // identifier. 542 return false; 543 } 544 // Store the syntax into the file. 545 if (file != NULL) file->set_syntax(syntax_identifier_); 546 } else if (!stop_after_syntax_identifier_) { 547 GOOGLE_LOG(WARNING) << "No syntax specified for the proto file: " 548 << file->name() << ". Please use 'syntax = \"proto2\";' " 549 << "or 'syntax = \"proto3\";' to specify a syntax " 550 << "version. (Defaulted to proto2 syntax.)"; 551 syntax_identifier_ = "proto2"; 552 } 553 554 if (stop_after_syntax_identifier_) return !had_errors_; 555 556 // Repeatedly parse statements until we reach the end of the file. 557 while (!AtEnd()) { 558 if (!ParseTopLevelStatement(file, root_location)) { 559 // This statement failed to parse. Skip it, but keep looping to parse 560 // other statements. 561 SkipStatement(); 562 563 if (LookingAt("}")) { 564 AddError("Unmatched \"}\"."); 565 input_->NextWithComments(NULL, &upcoming_detached_comments_, 566 &upcoming_doc_comments_); 567 } 568 } 569 } 570 } 571 572 input_ = NULL; 573 source_code_info_ = NULL; 574 source_code_info.Swap(file->mutable_source_code_info()); 575 return !had_errors_; 576 } 577 578 bool Parser::ParseSyntaxIdentifier(const LocationRecorder& parent) { 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\";'.")); 584 DO(Consume("=")); 585 io::Tokenizer::Token syntax_token = input_->current(); 586 string syntax; 587 DO(ConsumeString(&syntax, "Expected syntax identifier.")); 588 DO(ConsumeEndOfDeclaration(";", &syntax_location)); 589 590 syntax_identifier_ = syntax; 591 592 if (syntax != "proto2" && syntax != "proto3" && 593 !stop_after_syntax_identifier_) { 594 AddError(syntax_token.line, syntax_token.column, 595 "Unrecognized syntax identifier \"" + syntax + "\". This parser " 596 "only recognizes \"proto2\" and \"proto3\"."); 597 return false; 598 } 599 600 return true; 601 } 602 603 bool Parser::ParseTopLevelStatement(FileDescriptorProto* file, 604 const LocationRecorder& root_location) { 605 if (TryConsumeEndOfDeclaration(";", NULL)) { 606 // empty statement; ignore 607 return true; 608 } else if (LookingAt("message")) { 609 LocationRecorder location(root_location, 610 FileDescriptorProto::kMessageTypeFieldNumber, file->message_type_size()); 611 return ParseMessageDefinition(file->add_message_type(), location, file); 612 } else if (LookingAt("enum")) { 613 LocationRecorder location(root_location, 614 FileDescriptorProto::kEnumTypeFieldNumber, file->enum_type_size()); 615 return ParseEnumDefinition(file->add_enum_type(), location, file); 616 } else if (LookingAt("service")) { 617 LocationRecorder location(root_location, 618 FileDescriptorProto::kServiceFieldNumber, file->service_size()); 619 return ParseServiceDefinition(file->add_service(), location, file); 620 } else if (LookingAt("extend")) { 621 LocationRecorder location(root_location, 622 FileDescriptorProto::kExtensionFieldNumber); 623 return ParseExtend(file->mutable_extension(), 624 file->mutable_message_type(), 625 root_location, 626 FileDescriptorProto::kMessageTypeFieldNumber, 627 location, file); 628 } else if (LookingAt("import")) { 629 return ParseImport(file->mutable_dependency(), 630 file->mutable_public_dependency(), 631 file->mutable_weak_dependency(), 632 root_location, file); 633 } else if (LookingAt("package")) { 634 return ParsePackage(file, root_location, file); 635 } else if (LookingAt("option")) { 636 LocationRecorder location(root_location, 637 FileDescriptorProto::kOptionsFieldNumber); 638 return ParseOption(file->mutable_options(), location, file, 639 OPTION_STATEMENT); 640 } else { 641 AddError("Expected top-level statement (e.g. \"message\")."); 642 return false; 643 } 644 } 645 646 // ------------------------------------------------------------------- 647 // Messages 648 649 bool Parser::ParseMessageDefinition( 650 DescriptorProto* message, 651 const LocationRecorder& message_location, 652 const FileDescriptorProto* containing_file) { 653 DO(Consume("message")); 654 { 655 LocationRecorder location(message_location, 656 DescriptorProto::kNameFieldNumber); 657 location.RecordLegacyLocation( 658 message, DescriptorPool::ErrorCollector::NAME); 659 DO(ConsumeIdentifier(message->mutable_name(), "Expected message name.")); 660 } 661 DO(ParseMessageBlock(message, message_location, containing_file)); 662 return true; 663 } 664 665 namespace { 666 667 const int kMaxExtensionRangeSentinel = -1; 668 669 bool IsMessageSetWireFormatMessage(const DescriptorProto& message) { 670 const MessageOptions& options = message.options(); 671 for (int i = 0; i < options.uninterpreted_option_size(); ++i) { 672 const UninterpretedOption& uninterpreted = options.uninterpreted_option(i); 673 if (uninterpreted.name_size() == 1 && 674 uninterpreted.name(0).name_part() == "message_set_wire_format" && 675 uninterpreted.identifier_value() == "true") { 676 return true; 677 } 678 } 679 return false; 680 } 681 682 // Modifies any extension ranges that specified 'max' as the end of the 683 // extension range, and sets them to the type-specific maximum. The actual max 684 // tag number can only be determined after all options have been parsed. 685 void AdjustExtensionRangesWithMaxEndNumber(DescriptorProto* message) { 686 const bool is_message_set = IsMessageSetWireFormatMessage(*message); 687 const int max_extension_number = is_message_set ? 688 kint32max : 689 FieldDescriptor::kMaxNumber + 1; 690 for (int i = 0; i < message->extension_range_size(); ++i) { 691 if (message->extension_range(i).end() == kMaxExtensionRangeSentinel) { 692 message->mutable_extension_range(i)->set_end(max_extension_number); 693 } 694 } 695 } 696 697 } // namespace 698 699 bool Parser::ParseMessageBlock(DescriptorProto* message, 700 const LocationRecorder& message_location, 701 const FileDescriptorProto* containing_file) { 702 DO(ConsumeEndOfDeclaration("{", &message_location)); 703 704 while (!TryConsumeEndOfDeclaration("}", NULL)) { 705 if (AtEnd()) { 706 AddError("Reached end of input in message definition (missing '}')."); 707 return false; 708 } 709 710 if (!ParseMessageStatement(message, message_location, containing_file)) { 711 // This statement failed to parse. Skip it, but keep looping to parse 712 // other statements. 713 SkipStatement(); 714 } 715 } 716 717 if (message->extension_range_size() > 0) { 718 AdjustExtensionRangesWithMaxEndNumber(message); 719 } 720 return true; 721 } 722 723 bool Parser::ParseMessageStatement(DescriptorProto* message, 724 const LocationRecorder& message_location, 725 const FileDescriptorProto* containing_file) { 726 if (TryConsumeEndOfDeclaration(";", NULL)) { 727 // empty statement; ignore 728 return true; 729 } else if (LookingAt("message")) { 730 LocationRecorder location(message_location, 731 DescriptorProto::kNestedTypeFieldNumber, 732 message->nested_type_size()); 733 return ParseMessageDefinition(message->add_nested_type(), location, 734 containing_file); 735 } else if (LookingAt("enum")) { 736 LocationRecorder location(message_location, 737 DescriptorProto::kEnumTypeFieldNumber, 738 message->enum_type_size()); 739 return ParseEnumDefinition(message->add_enum_type(), location, 740 containing_file); 741 } else if (LookingAt("extensions")) { 742 LocationRecorder location(message_location, 743 DescriptorProto::kExtensionRangeFieldNumber); 744 return ParseExtensions(message, location, containing_file); 745 } else if (LookingAt("reserved")) { 746 return ParseReserved(message, message_location); 747 } else if (LookingAt("extend")) { 748 LocationRecorder location(message_location, 749 DescriptorProto::kExtensionFieldNumber); 750 return ParseExtend(message->mutable_extension(), 751 message->mutable_nested_type(), 752 message_location, 753 DescriptorProto::kNestedTypeFieldNumber, 754 location, containing_file); 755 } else if (LookingAt("option")) { 756 LocationRecorder location(message_location, 757 DescriptorProto::kOptionsFieldNumber); 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); 769 } else { 770 LocationRecorder location(message_location, 771 DescriptorProto::kFieldFieldNumber, 772 message->field_size()); 773 return ParseMessageField(message->add_field(), 774 message->mutable_nested_type(), 775 message_location, 776 DescriptorProto::kNestedTypeFieldNumber, 777 location, 778 containing_file); 779 } 780 } 781 782 bool Parser::ParseMessageField(FieldDescriptorProto* field, 783 RepeatedPtrField<DescriptorProto>* messages, 784 const LocationRecorder& parent_location, 785 int location_field_number_for_nested_type, 786 const LocationRecorder& field_location, 787 const FileDescriptorProto* containing_file) { 788 { 789 LocationRecorder location(field_location, 790 FieldDescriptorProto::kLabelFieldNumber); 791 FieldDescriptorProto::Label label; 792 if (ParseLabel(&label, containing_file)) { 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 } 802 } 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. 819 { 820 LocationRecorder location(field_location); // add path later 821 location.RecordLegacyLocation(field, DescriptorPool::ErrorCollector::TYPE); 822 823 bool type_parsed = false; 824 FieldDescriptorProto::Type type = FieldDescriptorProto::TYPE_INT32; 825 string type_name; 826 827 // Special case map field. We only treat the field as a map field if the 828 // field type name starts with the word "map" with a following "<". 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); 862 } else { 863 // Handle the case where no explicit label is given for a non-map field. 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 } 886 } 887 } 888 889 // Parse name and '='. 890 io::Tokenizer::Token name_token = input_->current(); 891 { 892 LocationRecorder location(field_location, 893 FieldDescriptorProto::kNameFieldNumber); 894 location.RecordLegacyLocation(field, DescriptorPool::ErrorCollector::NAME); 895 DO(ConsumeIdentifier(field->mutable_name(), "Expected field name.")); 896 } 897 DO(Consume("=", "Missing field number.")); 898 899 // Parse field number. 900 { 901 LocationRecorder location(field_location, 902 FieldDescriptorProto::kNumberFieldNumber); 903 location.RecordLegacyLocation( 904 field, DescriptorPool::ErrorCollector::NUMBER); 905 int number; 906 DO(ConsumeInteger(&number, "Expected field number.")); 907 field->set_number(number); 908 } 909 910 // Parse options. 911 DO(ParseFieldOptions(field, field_location, containing_file)); 912 913 // Deal with groups. 914 if (field->has_type() && field->type() == FieldDescriptorProto::TYPE_GROUP) { 915 // Awkward: Since a group declares both a message type and a field, we 916 // have to create overlapping locations. 917 LocationRecorder group_location(parent_location); 918 group_location.StartAt(field_location); 919 group_location.AddPath(location_field_number_for_nested_type); 920 group_location.AddPath(messages->size()); 921 922 DescriptorProto* group = messages->Add(); 923 group->set_name(field->name()); 924 925 // Record name location to match the field name's location. 926 { 927 LocationRecorder location(group_location, 928 DescriptorProto::kNameFieldNumber); 929 location.StartAt(name_token); 930 location.EndAt(name_token); 931 location.RecordLegacyLocation( 932 group, DescriptorPool::ErrorCollector::NAME); 933 } 934 935 // The field's type_name also comes from the name. Confusing! 936 { 937 LocationRecorder location(field_location, 938 FieldDescriptorProto::kTypeNameFieldNumber); 939 location.StartAt(name_token); 940 location.EndAt(name_token); 941 } 942 943 // As a hack for backwards-compatibility, we force the group name to start 944 // with a capital letter and lower-case the field name. New code should 945 // not use groups; it should use nested messages. 946 if (group->name()[0] < 'A' || 'Z' < group->name()[0]) { 947 AddError(name_token.line, name_token.column, 948 "Group names must start with a capital letter."); 949 } 950 LowerString(field->mutable_name()); 951 952 field->set_type_name(group->name()); 953 if (LookingAt("{")) { 954 DO(ParseMessageBlock(group, group_location, containing_file)); 955 } else { 956 AddError("Missing group body."); 957 return false; 958 } 959 } else { 960 DO(ConsumeEndOfDeclaration(";", &field_location)); 961 } 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 968 return true; 969 } 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 1035 bool Parser::ParseFieldOptions(FieldDescriptorProto* field, 1036 const LocationRecorder& field_location, 1037 const FileDescriptorProto* containing_file) { 1038 if (!LookingAt("[")) return true; 1039 1040 LocationRecorder location(field_location, 1041 FieldDescriptorProto::kOptionsFieldNumber); 1042 1043 DO(Consume("[")); 1044 1045 // Parse field options. 1046 do { 1047 if (LookingAt("default")) { 1048 // We intentionally pass field_location rather than location here, since 1049 // the default value is not actually an option. 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)); 1054 } else { 1055 DO(ParseOption(field->mutable_options(), location, 1056 containing_file, OPTION_ASSIGNMENT)); 1057 } 1058 } while (TryConsume(",")); 1059 1060 DO(Consume("]")); 1061 return true; 1062 } 1063 1064 bool Parser::ParseDefaultAssignment( 1065 FieldDescriptorProto* field, 1066 const LocationRecorder& field_location, 1067 const FileDescriptorProto* containing_file) { 1068 if (field->has_default_value()) { 1069 AddError("Already set option \"default\"."); 1070 field->clear_default_value(); 1071 } 1072 1073 DO(Consume("default")); 1074 DO(Consume("=")); 1075 1076 LocationRecorder location(field_location, 1077 FieldDescriptorProto::kDefaultValueFieldNumber); 1078 location.RecordLegacyLocation( 1079 field, DescriptorPool::ErrorCollector::DEFAULT_VALUE); 1080 string* default_value = field->mutable_default_value(); 1081 1082 if (!field->has_type()) { 1083 // The field has a type name, but we don't know if it is a message or an 1084 // enum yet. (If it were a primitive type, |field| would have a type set 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(); 1094 return true; 1095 } 1096 1097 switch (field->type()) { 1098 case FieldDescriptorProto::TYPE_INT32: 1099 case FieldDescriptorProto::TYPE_INT64: 1100 case FieldDescriptorProto::TYPE_SINT32: 1101 case FieldDescriptorProto::TYPE_SINT64: 1102 case FieldDescriptorProto::TYPE_SFIXED32: 1103 case FieldDescriptorProto::TYPE_SFIXED64: { 1104 uint64 max_value = kint64max; 1105 if (field->type() == FieldDescriptorProto::TYPE_INT32 || 1106 field->type() == FieldDescriptorProto::TYPE_SINT32 || 1107 field->type() == FieldDescriptorProto::TYPE_SFIXED32) { 1108 max_value = kint32max; 1109 } 1110 1111 // These types can be negative. 1112 if (TryConsume("-")) { 1113 default_value->append("-"); 1114 // Two's complement always has one more negative value than positive. 1115 ++max_value; 1116 } 1117 // Parse the integer to verify that it is not out-of-range. 1118 uint64 value; 1119 DO(ConsumeInteger64(max_value, &value, 1120 "Expected integer for field default value.")); 1121 // And stringify it again. 1122 default_value->append(SimpleItoa(value)); 1123 break; 1124 } 1125 1126 case FieldDescriptorProto::TYPE_UINT32: 1127 case FieldDescriptorProto::TYPE_UINT64: 1128 case FieldDescriptorProto::TYPE_FIXED32: 1129 case FieldDescriptorProto::TYPE_FIXED64: { 1130 uint64 max_value = kuint64max; 1131 if (field->type() == FieldDescriptorProto::TYPE_UINT32 || 1132 field->type() == FieldDescriptorProto::TYPE_FIXED32) { 1133 max_value = kuint32max; 1134 } 1135 1136 // Numeric, not negative. 1137 if (TryConsume("-")) { 1138 AddError("Unsigned field can't have negative default value."); 1139 } 1140 // Parse the integer to verify that it is not out-of-range. 1141 uint64 value; 1142 DO(ConsumeInteger64(max_value, &value, 1143 "Expected integer for field default value.")); 1144 // And stringify it again. 1145 default_value->append(SimpleItoa(value)); 1146 break; 1147 } 1148 1149 case FieldDescriptorProto::TYPE_FLOAT: 1150 case FieldDescriptorProto::TYPE_DOUBLE: 1151 // These types can be negative. 1152 if (TryConsume("-")) { 1153 default_value->append("-"); 1154 } 1155 // Parse the integer because we have to convert hex integers to decimal 1156 // floats. 1157 double value; 1158 DO(ConsumeNumber(&value, "Expected number.")); 1159 // And stringify it again. 1160 default_value->append(SimpleDtoa(value)); 1161 break; 1162 1163 case FieldDescriptorProto::TYPE_BOOL: 1164 if (TryConsume("true")) { 1165 default_value->assign("true"); 1166 } else if (TryConsume("false")) { 1167 default_value->assign("false"); 1168 } else { 1169 AddError("Expected \"true\" or \"false\"."); 1170 return false; 1171 } 1172 break; 1173 1174 case FieldDescriptorProto::TYPE_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.")); 1180 break; 1181 1182 case FieldDescriptorProto::TYPE_BYTES: 1183 DO(ConsumeString(default_value, "Expected string.")); 1184 *default_value = CEscape(*default_value); 1185 break; 1186 1187 case FieldDescriptorProto::TYPE_ENUM: 1188 DO(ConsumeIdentifier(default_value, "Expected enum identifier for field " 1189 "default value.")); 1190 break; 1191 1192 case FieldDescriptorProto::TYPE_MESSAGE: 1193 case FieldDescriptorProto::TYPE_GROUP: 1194 AddError("Messages can't have default values."); 1195 return false; 1196 } 1197 1198 return true; 1199 } 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 1223 bool Parser::ParseOptionNamePart(UninterpretedOption* uninterpreted_option, 1224 const LocationRecorder& part_location, 1225 const FileDescriptorProto* containing_file) { 1226 UninterpretedOption::NamePart* name = uninterpreted_option->add_name(); 1227 string identifier; // We parse identifiers into this string. 1228 if (LookingAt("(")) { // This is an extension. 1229 DO(Consume("(")); 1230 1231 { 1232 LocationRecorder location( 1233 part_location, UninterpretedOption::NamePart::kNamePartFieldNumber); 1234 // An extension name consists of dot-separated identifiers, and may begin 1235 // with a dot. 1236 if (LookingAtType(io::Tokenizer::TYPE_IDENTIFIER)) { 1237 DO(ConsumeIdentifier(&identifier, "Expected identifier.")); 1238 name->mutable_name_part()->append(identifier); 1239 } 1240 while (LookingAt(".")) { 1241 DO(Consume(".")); 1242 name->mutable_name_part()->append("."); 1243 DO(ConsumeIdentifier(&identifier, "Expected identifier.")); 1244 name->mutable_name_part()->append(identifier); 1245 } 1246 } 1247 1248 DO(Consume(")")); 1249 name->set_is_extension(true); 1250 } else { // This is a regular field. 1251 LocationRecorder location( 1252 part_location, UninterpretedOption::NamePart::kNamePartFieldNumber); 1253 DO(ConsumeIdentifier(&identifier, "Expected identifier.")); 1254 name->mutable_name_part()->append(identifier); 1255 name->set_is_extension(false); 1256 } 1257 return true; 1258 } 1259 1260 bool Parser::ParseUninterpretedBlock(string* value) { 1261 // Note that enclosing braces are not added to *value. 1262 // We do NOT use ConsumeEndOfStatement for this brace because it's delimiting 1263 // an expression, not a block of statements. 1264 DO(Consume("{")); 1265 int brace_depth = 1; 1266 while (!AtEnd()) { 1267 if (LookingAt("{")) { 1268 brace_depth++; 1269 } else if (LookingAt("}")) { 1270 brace_depth--; 1271 if (brace_depth == 0) { 1272 input_->Next(); 1273 return true; 1274 } 1275 } 1276 // TODO(sanjay): Interpret line/column numbers to preserve formatting 1277 if (!value->empty()) value->push_back(' '); 1278 value->append(input_->current().text); 1279 input_->Next(); 1280 } 1281 AddError("Unexpected end of stream while parsing aggregate value."); 1282 return false; 1283 } 1284 1285 // We don't interpret the option here. Instead we store it in an 1286 // UninterpretedOption, to be interpreted later. 1287 bool Parser::ParseOption(Message* options, 1288 const LocationRecorder& options_location, 1289 const FileDescriptorProto* containing_file, 1290 OptionStyle style) { 1291 // Create an entry in the uninterpreted_option field. 1292 const FieldDescriptor* uninterpreted_option_field = options->GetDescriptor()-> 1293 FindFieldByName("uninterpreted_option"); 1294 GOOGLE_CHECK(uninterpreted_option_field != NULL) 1295 << "No field named \"uninterpreted_option\" in the Options proto."; 1296 1297 const Reflection* reflection = options->GetReflection(); 1298 1299 LocationRecorder location( 1300 options_location, uninterpreted_option_field->number(), 1301 reflection->FieldSize(*options, uninterpreted_option_field)); 1302 1303 if (style == OPTION_STATEMENT) { 1304 DO(Consume("option")); 1305 } 1306 1307 UninterpretedOption* uninterpreted_option = down_cast<UninterpretedOption*>( 1308 options->GetReflection()->AddMessage(options, 1309 uninterpreted_option_field)); 1310 1311 // Parse dot-separated name. 1312 { 1313 LocationRecorder name_location(location, 1314 UninterpretedOption::kNameFieldNumber); 1315 name_location.RecordLegacyLocation( 1316 uninterpreted_option, DescriptorPool::ErrorCollector::OPTION_NAME); 1317 1318 { 1319 LocationRecorder part_location(name_location, 1320 uninterpreted_option->name_size()); 1321 DO(ParseOptionNamePart(uninterpreted_option, part_location, 1322 containing_file)); 1323 } 1324 1325 while (LookingAt(".")) { 1326 DO(Consume(".")); 1327 LocationRecorder part_location(name_location, 1328 uninterpreted_option->name_size()); 1329 DO(ParseOptionNamePart(uninterpreted_option, part_location, 1330 containing_file)); 1331 } 1332 } 1333 1334 DO(Consume("=")); 1335 1336 { 1337 LocationRecorder value_location(location); 1338 value_location.RecordLegacyLocation( 1339 uninterpreted_option, DescriptorPool::ErrorCollector::OPTION_VALUE); 1340 1341 // All values are a single token, except for negative numbers, which consist 1342 // of a single '-' symbol, followed by a positive number. 1343 bool is_negative = TryConsume("-"); 1344 1345 switch (input_->current().type) { 1346 case io::Tokenizer::TYPE_START: 1347 GOOGLE_LOG(FATAL) << "Trying to read value before any tokens have been read."; 1348 return false; 1349 1350 case io::Tokenizer::TYPE_END: 1351 AddError("Unexpected end of stream while parsing option value."); 1352 return false; 1353 1354 case io::Tokenizer::TYPE_IDENTIFIER: { 1355 value_location.AddPath( 1356 UninterpretedOption::kIdentifierValueFieldNumber); 1357 if (is_negative) { 1358 AddError("Invalid '-' symbol before identifier."); 1359 return false; 1360 } 1361 string value; 1362 DO(ConsumeIdentifier(&value, "Expected identifier.")); 1363 uninterpreted_option->set_identifier_value(value); 1364 break; 1365 } 1366 1367 case io::Tokenizer::TYPE_INTEGER: { 1368 uint64 value; 1369 uint64 max_value = 1370 is_negative ? static_cast<uint64>(kint64max) + 1 : kuint64max; 1371 DO(ConsumeInteger64(max_value, &value, "Expected integer.")); 1372 if (is_negative) { 1373 value_location.AddPath( 1374 UninterpretedOption::kNegativeIntValueFieldNumber); 1375 uninterpreted_option->set_negative_int_value( 1376 -static_cast<int64>(value)); 1377 } else { 1378 value_location.AddPath( 1379 UninterpretedOption::kPositiveIntValueFieldNumber); 1380 uninterpreted_option->set_positive_int_value(value); 1381 } 1382 break; 1383 } 1384 1385 case io::Tokenizer::TYPE_FLOAT: { 1386 value_location.AddPath(UninterpretedOption::kDoubleValueFieldNumber); 1387 double value; 1388 DO(ConsumeNumber(&value, "Expected number.")); 1389 uninterpreted_option->set_double_value(is_negative ? -value : value); 1390 break; 1391 } 1392 1393 case io::Tokenizer::TYPE_STRING: { 1394 value_location.AddPath(UninterpretedOption::kStringValueFieldNumber); 1395 if (is_negative) { 1396 AddError("Invalid '-' symbol before string."); 1397 return false; 1398 } 1399 string value; 1400 DO(ConsumeString(&value, "Expected string.")); 1401 uninterpreted_option->set_string_value(value); 1402 break; 1403 } 1404 1405 case io::Tokenizer::TYPE_SYMBOL: 1406 if (LookingAt("{")) { 1407 value_location.AddPath( 1408 UninterpretedOption::kAggregateValueFieldNumber); 1409 DO(ParseUninterpretedBlock( 1410 uninterpreted_option->mutable_aggregate_value())); 1411 } else { 1412 AddError("Expected option value."); 1413 return false; 1414 } 1415 break; 1416 } 1417 } 1418 1419 if (style == OPTION_STATEMENT) { 1420 DO(ConsumeEndOfDeclaration(";", &location)); 1421 } 1422 1423 return true; 1424 } 1425 1426 bool Parser::ParseExtensions(DescriptorProto* message, 1427 const LocationRecorder& extensions_location, 1428 const FileDescriptorProto* containing_file) { 1429 // Parse the declaration. 1430 DO(Consume("extensions")); 1431 1432 do { 1433 // Note that kExtensionRangeFieldNumber was already pushed by the parent. 1434 LocationRecorder location(extensions_location, 1435 message->extension_range_size()); 1436 1437 DescriptorProto::ExtensionRange* range = message->add_extension_range(); 1438 location.RecordLegacyLocation( 1439 range, DescriptorPool::ErrorCollector::NUMBER); 1440 1441 int start, end; 1442 io::Tokenizer::Token start_token; 1443 1444 { 1445 LocationRecorder start_location( 1446 location, DescriptorProto::ExtensionRange::kStartFieldNumber); 1447 start_token = input_->current(); 1448 DO(ConsumeInteger(&start, "Expected field number range.")); 1449 } 1450 1451 if (TryConsume("to")) { 1452 LocationRecorder end_location( 1453 location, DescriptorProto::ExtensionRange::kEndFieldNumber); 1454 if (TryConsume("max")) { 1455 // Set to the sentinel value - 1 since we increment the value below. 1456 // The actual value of the end of the range should be set with 1457 // AdjustExtensionRangesWithMaxEndNumber. 1458 end = kMaxExtensionRangeSentinel - 1; 1459 } else { 1460 DO(ConsumeInteger(&end, "Expected integer.")); 1461 } 1462 } else { 1463 LocationRecorder end_location( 1464 location, DescriptorProto::ExtensionRange::kEndFieldNumber); 1465 end_location.StartAt(start_token); 1466 end_location.EndAt(start_token); 1467 end = start; 1468 } 1469 1470 // Users like to specify inclusive ranges, but in code we like the end 1471 // number to be exclusive. 1472 ++end; 1473 1474 range->set_start(start); 1475 range->set_end(end); 1476 } while (TryConsume(",")); 1477 1478 DO(ConsumeEndOfDeclaration(";", &extensions_location)); 1479 return true; 1480 } 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 1553 bool Parser::ParseExtend(RepeatedPtrField<FieldDescriptorProto>* extensions, 1554 RepeatedPtrField<DescriptorProto>* messages, 1555 const LocationRecorder& parent_location, 1556 int location_field_number_for_nested_type, 1557 const LocationRecorder& extend_location, 1558 const FileDescriptorProto* containing_file) { 1559 DO(Consume("extend")); 1560 1561 // Parse the extendee type. 1562 io::Tokenizer::Token extendee_start = input_->current(); 1563 string extendee; 1564 DO(ParseUserDefinedType(&extendee)); 1565 io::Tokenizer::Token extendee_end = input_->previous(); 1566 1567 // Parse the block. 1568 DO(ConsumeEndOfDeclaration("{", &extend_location)); 1569 1570 bool is_first = true; 1571 1572 do { 1573 if (AtEnd()) { 1574 AddError("Reached end of input in extend definition (missing '}')."); 1575 return false; 1576 } 1577 1578 // Note that kExtensionFieldNumber was already pushed by the parent. 1579 LocationRecorder location(extend_location, extensions->size()); 1580 1581 FieldDescriptorProto* field = extensions->Add(); 1582 1583 { 1584 LocationRecorder extendee_location( 1585 location, FieldDescriptorProto::kExtendeeFieldNumber); 1586 extendee_location.StartAt(extendee_start); 1587 extendee_location.EndAt(extendee_end); 1588 1589 if (is_first) { 1590 extendee_location.RecordLegacyLocation( 1591 field, DescriptorPool::ErrorCollector::EXTENDEE); 1592 is_first = false; 1593 } 1594 } 1595 1596 field->set_extendee(extendee); 1597 1598 if (!ParseMessageField(field, messages, parent_location, 1599 location_field_number_for_nested_type, 1600 location, 1601 containing_file)) { 1602 // This statement failed to parse. Skip it, but keep looping to parse 1603 // other statements. 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(); 1662 } 1663 } while (!TryConsumeEndOfDeclaration("}", NULL)); 1664 1665 return true; 1666 } 1667 1668 // ------------------------------------------------------------------- 1669 // Enums 1670 1671 bool Parser::ParseEnumDefinition(EnumDescriptorProto* enum_type, 1672 const LocationRecorder& enum_location, 1673 const FileDescriptorProto* containing_file) { 1674 DO(Consume("enum")); 1675 1676 { 1677 LocationRecorder location(enum_location, 1678 EnumDescriptorProto::kNameFieldNumber); 1679 location.RecordLegacyLocation( 1680 enum_type, DescriptorPool::ErrorCollector::NAME); 1681 DO(ConsumeIdentifier(enum_type->mutable_name(), "Expected enum name.")); 1682 } 1683 1684 DO(ParseEnumBlock(enum_type, enum_location, containing_file)); 1685 1686 DO(ValidateEnum(enum_type)); 1687 1688 return true; 1689 } 1690 1691 bool Parser::ParseEnumBlock(EnumDescriptorProto* enum_type, 1692 const LocationRecorder& enum_location, 1693 const FileDescriptorProto* containing_file) { 1694 DO(ConsumeEndOfDeclaration("{", &enum_location)); 1695 1696 while (!TryConsumeEndOfDeclaration("}", NULL)) { 1697 if (AtEnd()) { 1698 AddError("Reached end of input in enum definition (missing '}')."); 1699 return false; 1700 } 1701 1702 if (!ParseEnumStatement(enum_type, enum_location, containing_file)) { 1703 // This statement failed to parse. Skip it, but keep looping to parse 1704 // other statements. 1705 SkipStatement(); 1706 } 1707 } 1708 1709 return true; 1710 } 1711 1712 bool Parser::ParseEnumStatement(EnumDescriptorProto* enum_type, 1713 const LocationRecorder& enum_location, 1714 const FileDescriptorProto* containing_file) { 1715 if (TryConsumeEndOfDeclaration(";", NULL)) { 1716 // empty statement; ignore 1717 return true; 1718 } else if (LookingAt("option")) { 1719 LocationRecorder location(enum_location, 1720 EnumDescriptorProto::kOptionsFieldNumber); 1721 return ParseOption(enum_type->mutable_options(), location, 1722 containing_file, OPTION_STATEMENT); 1723 } else { 1724 LocationRecorder location(enum_location, 1725 EnumDescriptorProto::kValueFieldNumber, enum_type->value_size()); 1726 return ParseEnumConstant(enum_type->add_value(), location, containing_file); 1727 } 1728 } 1729 1730 bool Parser::ParseEnumConstant(EnumValueDescriptorProto* enum_value, 1731 const LocationRecorder& enum_value_location, 1732 const FileDescriptorProto* containing_file) { 1733 // Parse name. 1734 { 1735 LocationRecorder location(enum_value_location, 1736 EnumValueDescriptorProto::kNameFieldNumber); 1737 location.RecordLegacyLocation( 1738 enum_value, DescriptorPool::ErrorCollector::NAME); 1739 DO(ConsumeIdentifier(enum_value->mutable_name(), 1740 "Expected enum constant name.")); 1741 } 1742 1743 DO(Consume("=", "Missing numeric value for enum constant.")); 1744 1745 // Parse value. 1746 { 1747 LocationRecorder location( 1748 enum_value_location, EnumValueDescriptorProto::kNumberFieldNumber); 1749 location.RecordLegacyLocation( 1750 enum_value, DescriptorPool::ErrorCollector::NUMBER); 1751 1752 int number; 1753 DO(ConsumeSignedInteger(&number, "Expected integer.")); 1754 enum_value->set_number(number); 1755 } 1756 1757 DO(ParseEnumConstantOptions(enum_value, enum_value_location, 1758 containing_file)); 1759 1760 DO(ConsumeEndOfDeclaration(";", &enum_value_location)); 1761 1762 return true; 1763 } 1764 1765 bool Parser::ParseEnumConstantOptions( 1766 EnumValueDescriptorProto* value, 1767 const LocationRecorder& enum_value_location, 1768 const FileDescriptorProto* containing_file) { 1769 if (!LookingAt("[")) return true; 1770 1771 LocationRecorder location( 1772 enum_value_location, EnumValueDescriptorProto::kOptionsFieldNumber); 1773 1774 DO(Consume("[")); 1775 1776 do { 1777 DO(ParseOption(value->mutable_options(), location, 1778 containing_file, OPTION_ASSIGNMENT)); 1779 } while (TryConsume(",")); 1780 1781 DO(Consume("]")); 1782 return true; 1783 } 1784 1785 // ------------------------------------------------------------------- 1786 // Services 1787 1788 bool Parser::ParseServiceDefinition( 1789 ServiceDescriptorProto* service, 1790 const LocationRecorder& service_location, 1791 const FileDescriptorProto* containing_file) { 1792 DO(Consume("service")); 1793 1794 { 1795 LocationRecorder location(service_location, 1796 ServiceDescriptorProto::kNameFieldNumber); 1797 location.RecordLegacyLocation( 1798 service, DescriptorPool::ErrorCollector::NAME); 1799 DO(ConsumeIdentifier(service->mutable_name(), "Expected service name.")); 1800 } 1801 1802 DO(ParseServiceBlock(service, service_location, containing_file)); 1803 return true; 1804 } 1805 1806 bool Parser::ParseServiceBlock(ServiceDescriptorProto* service, 1807 const LocationRecorder& service_location, 1808 const FileDescriptorProto* containing_file) { 1809 DO(ConsumeEndOfDeclaration("{", &service_location)); 1810 1811 while (!TryConsumeEndOfDeclaration("}", NULL)) { 1812 if (AtEnd()) { 1813 AddError("Reached end of input in service definition (missing '}')."); 1814 return false; 1815 } 1816 1817 if (!ParseServiceStatement(service, service_location, containing_file)) { 1818 // This statement failed to parse. Skip it, but keep looping to parse 1819 // other statements. 1820 SkipStatement(); 1821 } 1822 } 1823 1824 return true; 1825 } 1826 1827 bool Parser::ParseServiceStatement(ServiceDescriptorProto* service, 1828 const LocationRecorder& service_location, 1829 const FileDescriptorProto* containing_file) { 1830 if (TryConsumeEndOfDeclaration(";", NULL)) { 1831 // empty statement; ignore 1832 return true; 1833 } else if (LookingAt("option")) { 1834 LocationRecorder location( 1835 service_location, ServiceDescriptorProto::kOptionsFieldNumber); 1836 return ParseOption(service->mutable_options(), location, 1837 containing_file, OPTION_STATEMENT); 1838 } else { 1839 LocationRecorder location(service_location, 1840 ServiceDescriptorProto::kMethodFieldNumber, service->method_size()); 1841 return ParseServiceMethod(service->add_method(), location, containing_file); 1842 } 1843 } 1844 1845 bool Parser::ParseServiceMethod(MethodDescriptorProto* method, 1846 const LocationRecorder& method_location, 1847 const FileDescriptorProto* containing_file) { 1848 DO(Consume("rpc")); 1849 1850 { 1851 LocationRecorder location(method_location, 1852 MethodDescriptorProto::kNameFieldNumber); 1853 location.RecordLegacyLocation( 1854 method, DescriptorPool::ErrorCollector::NAME); 1855 DO(ConsumeIdentifier(method->mutable_name(), "Expected method name.")); 1856 } 1857 1858 // Parse input type. 1859 DO(Consume("(")); 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 } 1870 LocationRecorder location(method_location, 1871 MethodDescriptorProto::kInputTypeFieldNumber); 1872 location.RecordLegacyLocation( 1873 method, DescriptorPool::ErrorCollector::INPUT_TYPE); 1874 DO(ParseUserDefinedType(method->mutable_input_type())); 1875 } 1876 DO(Consume(")")); 1877 1878 // Parse output type. 1879 DO(Consume("returns")); 1880 DO(Consume("(")); 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 } 1891 LocationRecorder location(method_location, 1892 MethodDescriptorProto::kOutputTypeFieldNumber); 1893 location.RecordLegacyLocation( 1894 method, DescriptorPool::ErrorCollector::OUTPUT_TYPE); 1895 DO(ParseUserDefinedType(method->mutable_output_type())); 1896 } 1897 DO(Consume(")")); 1898 1899 if (LookingAt("{")) { 1900 // Options! 1901 DO(ParseMethodOptions(method_location, containing_file, 1902 MethodDescriptorProto::kOptionsFieldNumber, 1903 method->mutable_options())); 1904 } else { 1905 DO(ConsumeEndOfDeclaration(";", &method_location)); 1906 } 1907 1908 return true; 1909 } 1910 1911 1912 bool Parser::ParseMethodOptions(const LocationRecorder& parent_location, 1913 const FileDescriptorProto* containing_file, 1914 const int optionsFieldNumber, 1915 Message* mutable_options) { 1916 // Options! 1917 ConsumeEndOfDeclaration("{", &parent_location); 1918 while (!TryConsumeEndOfDeclaration("}", NULL)) { 1919 if (AtEnd()) { 1920 AddError("Reached end of input in method options (missing '}')."); 1921 return false; 1922 } 1923 1924 if (TryConsumeEndOfDeclaration(";", NULL)) { 1925 // empty statement; ignore 1926 } else { 1927 LocationRecorder location(parent_location, 1928 optionsFieldNumber); 1929 if (!ParseOption(mutable_options, location, 1930 containing_file, OPTION_STATEMENT)) { 1931 // This statement failed to parse. Skip it, but keep looping to 1932 // parse other statements. 1933 SkipStatement(); 1934 } 1935 } 1936 } 1937 1938 return true; 1939 } 1940 1941 // ------------------------------------------------------------------- 1942 1943 bool Parser::ParseLabel(FieldDescriptorProto::Label* label, 1944 const FileDescriptorProto* containing_file) { 1945 if (TryConsume("optional")) { 1946 *label = FieldDescriptorProto::LABEL_OPTIONAL; 1947 return true; 1948 } else if (TryConsume("repeated")) { 1949 *label = FieldDescriptorProto::LABEL_REPEATED; 1950 return true; 1951 } else if (TryConsume("required")) { 1952 *label = FieldDescriptorProto::LABEL_REQUIRED; 1953 return true; 1954 } 1955 return false; 1956 } 1957 1958 bool Parser::ParseType(FieldDescriptorProto::Type* type, 1959 string* type_name) { 1960 TypeNameMap::const_iterator iter = kTypeNames.find(input_->current().text); 1961 if (iter != kTypeNames.end()) { 1962 *type = iter->second; 1963 input_->Next(); 1964 } else { 1965 DO(ParseUserDefinedType(type_name)); 1966 } 1967 return true; 1968 } 1969 1970 bool Parser::ParseUserDefinedType(string* type_name) { 1971 type_name->clear(); 1972 1973 TypeNameMap::const_iterator iter = kTypeNames.find(input_->current().text); 1974 if (iter != kTypeNames.end()) { 1975 // Note: The only place enum types are allowed is for field types, but 1976 // if we are parsing a field type then we would not get here because 1977 // primitives are allowed there as well. So this error message doesn't 1978 // need to account for enums. 1979 AddError("Expected message type."); 1980 1981 // Pretend to accept this type so that we can go on parsing. 1982 *type_name = input_->current().text; 1983 input_->Next(); 1984 return true; 1985 } 1986 1987 // A leading "." means the name is fully-qualified. 1988 if (TryConsume(".")) type_name->append("."); 1989 1990 // Consume the first part of the name. 1991 string identifier; 1992 DO(ConsumeIdentifier(&identifier, "Expected type name.")); 1993 type_name->append(identifier); 1994 1995 // Consume more parts. 1996 while (TryConsume(".")) { 1997 type_name->append("."); 1998 DO(ConsumeIdentifier(&identifier, "Expected identifier.")); 1999 type_name->append(identifier); 2000 } 2001 2002 return true; 2003 } 2004 2005 // =================================================================== 2006 2007 bool Parser::ParsePackage(FileDescriptorProto* file, 2008 const LocationRecorder& root_location, 2009 const FileDescriptorProto* containing_file) { 2010 if (file->has_package()) { 2011 AddError("Multiple package definitions."); 2012 // Don't append the new package to the old one. Just replace it. Not 2013 // that it really matters since this is an error anyway. 2014 file->clear_package(); 2015 } 2016 2017 DO(Consume("package")); 2018 2019 { 2020 LocationRecorder location(root_location, 2021 FileDescriptorProto::kPackageFieldNumber); 2022 location.RecordLegacyLocation(file, DescriptorPool::ErrorCollector::NAME); 2023 2024 while (true) { 2025 string identifier; 2026 DO(ConsumeIdentifier(&identifier, "Expected identifier.")); 2027 file->mutable_package()->append(identifier); 2028 if (!TryConsume(".")) break; 2029 file->mutable_package()->append("."); 2030 } 2031 2032 location.EndAt(input_->previous()); 2033 2034 DO(ConsumeEndOfDeclaration(";", &location)); 2035 } 2036 2037 return true; 2038 } 2039 2040 bool Parser::ParseImport(RepeatedPtrField<string>* dependency, 2041 RepeatedField<int32>* public_dependency, 2042 RepeatedField<int32>* weak_dependency, 2043 const LocationRecorder& root_location, 2044 const FileDescriptorProto* containing_file) { 2045 DO(Consume("import")); 2046 if (LookingAt("public")) { 2047 LocationRecorder location( 2048 root_location, FileDescriptorProto::kPublicDependencyFieldNumber, 2049 public_dependency->size()); 2050 DO(Consume("public")); 2051 *public_dependency->Add() = dependency->size(); 2052 } else if (LookingAt("weak")) { 2053 LocationRecorder location( 2054 root_location, FileDescriptorProto::kWeakDependencyFieldNumber, 2055 weak_dependency->size()); 2056 DO(Consume("weak")); 2057 *weak_dependency->Add() = dependency->size(); 2058 } 2059 { 2060 LocationRecorder location(root_location, 2061 FileDescriptorProto::kDependencyFieldNumber, 2062 dependency->size()); 2063 DO(ConsumeString(dependency->Add(), 2064 "Expected a string naming the file to import.")); 2065 2066 location.EndAt(input_->previous()); 2067 2068 DO(ConsumeEndOfDeclaration(";", &location)); 2069 } 2070 return true; 2071 } 2072 2073 // =================================================================== 2074 2075 SourceLocationTable::SourceLocationTable() {} 2076 SourceLocationTable::~SourceLocationTable() {} 2077 2078 bool SourceLocationTable::Find( 2079 const Message* descriptor, 2080 DescriptorPool::ErrorCollector::ErrorLocation location, 2081 int* line, int* column) const { 2082 const pair<int, int>* result = 2083 FindOrNull(location_map_, std::make_pair(descriptor, location)); 2084 if (result == NULL) { 2085 *line = -1; 2086 *column = 0; 2087 return false; 2088 } else { 2089 *line = result->first; 2090 *column = result->second; 2091 return true; 2092 } 2093 } 2094 2095 void SourceLocationTable::Add( 2096 const Message* descriptor, 2097 DescriptorPool::ErrorCollector::ErrorLocation location, 2098 int line, int column) { 2099 location_map_[std::make_pair(descriptor, location)] = 2100 std::make_pair(line, column); 2101 } 2102 2103 void SourceLocationTable::Clear() { 2104 location_map_.clear(); 2105 } 2106 2107 } // namespace compiler 2108 } // namespace protobuf 2109 } // namespace google 2110