LCOV - code coverage report
Current view: top level - third_party/protobuf/src/google/protobuf/compiler - parser.cc (source / functions) Hit Total Coverage
Test: tmp.zDYK9MVh93 Lines: 769 914 84.1 %
Date: 2015-10-10 Functions: 69 75 92.0 %

          Line data    Source code
       1             : // Protocol Buffers - Google's data interchange format
       2             : // Copyright 2008 Google Inc.  All rights reserved.
       3             : // https://developers.google.com/protocol-buffers/
       4             : //
       5             : // Redistribution and use in source and binary forms, with or without
       6             : // modification, are permitted provided that the following conditions are
       7             : // met:
       8             : //
       9             : //     * Redistributions of source code must retain the above copyright
      10             : // notice, this list of conditions and the following disclaimer.
      11             : //     * Redistributions in binary form must reproduce the above
      12             : // copyright notice, this list of conditions and the following disclaimer
      13             : // in the documentation and/or other materials provided with the
      14             : // distribution.
      15             : //     * Neither the name of Google Inc. nor the names of its
      16             : // contributors may be used to endorse or promote products derived from
      17             : // this software without specific prior written permission.
      18             : //
      19             : // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
      20             : // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
      21             : // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
      22             : // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
      23             : // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
      24             : // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
      25             : // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
      26             : // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
      27             : // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
      28             : // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
      29             : // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
      30             : 
      31             : // Author: kenton@google.com (Kenton Varda)
      32             : //  Based on original Protocol Buffers design by
      33             : //  Sanjay Ghemawat, Jeff Dean, and others.
      34             : //
      35             : // 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          17 : TypeNameMap MakeTypeNameTable() {
      63          17 :   TypeNameMap result;
      64             : 
      65          34 :   result["double"  ] = FieldDescriptorProto::TYPE_DOUBLE;
      66          34 :   result["float"   ] = FieldDescriptorProto::TYPE_FLOAT;
      67          34 :   result["uint64"  ] = FieldDescriptorProto::TYPE_UINT64;
      68          34 :   result["fixed64" ] = FieldDescriptorProto::TYPE_FIXED64;
      69          34 :   result["fixed32" ] = FieldDescriptorProto::TYPE_FIXED32;
      70          34 :   result["bool"    ] = FieldDescriptorProto::TYPE_BOOL;
      71          34 :   result["string"  ] = FieldDescriptorProto::TYPE_STRING;
      72          34 :   result["group"   ] = FieldDescriptorProto::TYPE_GROUP;
      73             : 
      74          34 :   result["bytes"   ] = FieldDescriptorProto::TYPE_BYTES;
      75          34 :   result["uint32"  ] = FieldDescriptorProto::TYPE_UINT32;
      76          34 :   result["sfixed32"] = FieldDescriptorProto::TYPE_SFIXED32;
      77          34 :   result["sfixed64"] = FieldDescriptorProto::TYPE_SFIXED64;
      78          34 :   result["int32"   ] = FieldDescriptorProto::TYPE_INT32;
      79          34 :   result["int64"   ] = FieldDescriptorProto::TYPE_INT64;
      80          34 :   result["sint32"  ] = FieldDescriptorProto::TYPE_SINT32;
      81          34 :   result["sint64"  ] = FieldDescriptorProto::TYPE_SINT64;
      82             : 
      83          17 :   return result;
      84             : }
      85             : 
      86          17 : 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         124 : string MapEntryName(const string& field_name) {
      91             :   string result;
      92             :   static const char kSuffix[] = "Entry";
      93         124 :   result.reserve(field_name.size() + sizeof(kSuffix));
      94             :   bool cap_next = true;
      95        3716 :   for (int i = 0; i < field_name.size(); ++i) {
      96        3592 :     if (field_name[i] == '_') {
      97             :       cap_next = true;
      98        1593 :     } else if (cap_next) {
      99             :       // Note: Do not use ctype.h due to locales.
     100         327 :       if ('a' <= field_name[i] && field_name[i] <= 'z') {
     101         327 :         result.push_back(field_name[i] - 'a' + 'A');
     102             :       } else {
     103           0 :         result.push_back(field_name[i]);
     104             :       }
     105             :       cap_next = false;
     106             :     } else {
     107        1266 :       result.push_back(field_name[i]);
     108             :     }
     109             :   }
     110         124 :   result.append(kSuffix);
     111         124 :   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          78 : Parser::Parser()
     124             :   : input_(NULL),
     125             :     error_collector_(NULL),
     126             :     source_location_table_(NULL),
     127             :     had_errors_(false),
     128             :     require_syntax_identifier_(false),
     129         234 :     stop_after_syntax_identifier_(false) {
     130          78 : }
     131             : 
     132         156 : Parser::~Parser() {
     133          78 : }
     134             : 
     135             : // ===================================================================
     136             : 
     137             : inline bool Parser::LookingAt(const char* text) {
     138       64670 :   return input_->current().text == text;
     139             : }
     140             : 
     141             : inline bool Parser::LookingAtType(io::Tokenizer::TokenType token_type) {
     142       16684 :   return input_->current().type == token_type;
     143             : }
     144             : 
     145        4481 : inline bool Parser::AtEnd() {
     146        4481 :   return LookingAtType(io::Tokenizer::TYPE_END);
     147             : }
     148             : 
     149       23462 : bool Parser::TryConsume(const char* text) {
     150       46924 :   if (LookingAt(text)) {
     151       13774 :     input_->Next();
     152       13774 :     return true;
     153             :   } else {
     154             :     return false;
     155             :   }
     156             : }
     157             : 
     158        3368 : bool Parser::Consume(const char* text, const char* error) {
     159        3368 :   if (TryConsume(text)) {
     160             :     return true;
     161             :   } else {
     162           0 :     AddError(error);
     163           0 :     return false;
     164             :   }
     165             : }
     166             : 
     167        7510 : bool Parser::Consume(const char* text) {
     168        7510 :   if (TryConsume(text)) {
     169             :     return true;
     170             :   } else {
     171           0 :     AddError("Expected \"" + string(text) + "\".");
     172           0 :     return false;
     173             :   }
     174             : }
     175             : 
     176        6085 : bool Parser::ConsumeIdentifier(string* output, const char* error) {
     177       12170 :   if (LookingAtType(io::Tokenizer::TYPE_IDENTIFIER)) {
     178        6085 :     *output = input_->current().text;
     179        6085 :     input_->Next();
     180        6085 :     return true;
     181             :   } else {
     182           0 :     AddError(error);
     183           0 :     return false;
     184             :   }
     185             : }
     186             : 
     187        3068 : bool Parser::ConsumeInteger(int* output, const char* error) {
     188        6136 :   if (LookingAtType(io::Tokenizer::TYPE_INTEGER)) {
     189        3068 :     uint64 value = 0;
     190        6136 :     if (!io::Tokenizer::ParseInteger(input_->current().text,
     191        3068 :                                      kint32max, &value)) {
     192           0 :       AddError("Integer out of range.");
     193             :       // We still return true because we did, in fact, parse an integer.
     194             :     }
     195        3068 :     *output = value;
     196        3068 :     input_->Next();
     197             :     return true;
     198             :   } else {
     199           0 :     AddError(error);
     200           0 :     return false;
     201             :   }
     202             : }
     203             : 
     204         259 : bool Parser::ConsumeSignedInteger(int* output, const char* error) {
     205         259 :   bool is_negative = false;
     206         259 :   uint64 max_value = kint32max;
     207         259 :   if (TryConsume("-")) {
     208           6 :     is_negative = true;
     209           6 :     max_value += 1;
     210             :   }
     211         259 :   uint64 value = 0;
     212         259 :   DO(ConsumeInteger64(max_value, &value, error));
     213         259 :   if (is_negative) value *= -1;
     214         259 :   *output = value;
     215         259 :   return true;
     216             : }
     217             : 
     218         371 : bool Parser::ConsumeInteger64(uint64 max_value, uint64* output,
     219         371 :                               const char* error) {
     220         742 :   if (LookingAtType(io::Tokenizer::TYPE_INTEGER)) {
     221         742 :     if (!io::Tokenizer::ParseInteger(input_->current().text, max_value,
     222         371 :                                      output)) {
     223           0 :       AddError("Integer out of range.");
     224             :       // We still return true because we did, in fact, parse an integer.
     225           0 :       *output = 0;
     226             :     }
     227         371 :     input_->Next();
     228         371 :     return true;
     229             :   } else {
     230           0 :     AddError(error);
     231           0 :     return false;
     232             :   }
     233             : }
     234             : 
     235          27 : bool Parser::ConsumeNumber(double* output, const char* error) {
     236          50 :   if (LookingAtType(io::Tokenizer::TYPE_FLOAT)) {
     237          16 :     *output = io::Tokenizer::ParseFloat(input_->current().text);
     238          16 :     input_->Next();
     239          16 :     return true;
     240          18 :   } else if (LookingAtType(io::Tokenizer::TYPE_INTEGER)) {
     241             :     // Also accept integers.
     242           3 :     uint64 value = 0;
     243           6 :     if (!io::Tokenizer::ParseInteger(input_->current().text,
     244           3 :                                      kuint64max, &value)) {
     245           0 :       AddError("Integer out of range.");
     246             :       // We still return true because we did, in fact, parse a number.
     247             :     }
     248           3 :     *output = value;
     249           3 :     input_->Next();
     250             :     return true;
     251          12 :   } else if (LookingAt("inf")) {
     252           4 :     *output = numeric_limits<double>::infinity();
     253           4 :     input_->Next();
     254           4 :     return true;
     255           4 :   } else if (LookingAt("nan")) {
     256           2 :     *output = numeric_limits<double>::quiet_NaN();
     257           2 :     input_->Next();
     258           2 :     return true;
     259             :   } else {
     260           0 :     AddError(error);
     261           0 :     return false;
     262             :   }
     263             : }
     264             : 
     265        2484 : bool Parser::ConsumeString(string* output, const char* error) {
     266        2484 :   if (LookingAtType(io::Tokenizer::TYPE_STRING)) {
     267        1242 :     io::Tokenizer::ParseString(input_->current().text, output);
     268        1242 :     input_->Next();
     269             :     // Allow C++ like concatenation of adjacent string tokens.
     270        3726 :     while (LookingAtType(io::Tokenizer::TYPE_STRING)) {
     271           0 :       io::Tokenizer::ParseStringAppend(input_->current().text, output);
     272           0 :       input_->Next();
     273             :     }
     274             :     return true;
     275             :   } else {
     276           0 :     AddError(error);
     277           0 :     return false;
     278             :   }
     279             : }
     280             : 
     281       12470 : bool Parser::TryConsumeEndOfDeclaration(
     282       12470 :     const char* text, const LocationRecorder* location) {
     283       24940 :   if (LookingAt(text)) {
     284             :     string leading, trailing;
     285        5042 :     vector<string> detached;
     286        5042 :     input_->NextWithComments(&trailing, &detached, &leading);
     287             : 
     288             :     // Save the leading comments for next time, and recall the leading comments
     289             :     // from last time.
     290        5042 :     leading.swap(upcoming_doc_comments_);
     291             : 
     292        5042 :     if (location != NULL) {
     293        4394 :       upcoming_detached_comments_.swap(detached);
     294        4394 :       location->AttachComments(&leading, &trailing, &detached);
     295         648 :     } 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         637 :       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          22 :                                          detached.begin(), detached.end());
     304             :     }
     305             : 
     306             :     return true;
     307             :   } else {
     308             :     return false;
     309             :   }
     310             : }
     311             : 
     312        4394 : bool Parser::ConsumeEndOfDeclaration(
     313             :     const char* text, const LocationRecorder* location) {
     314        4394 :   if (TryConsumeEndOfDeclaration(text, location)) {
     315             :     return true;
     316             :   } else {
     317           0 :     AddError("Expected \"" + string(text) + "\".");
     318           0 :     return false;
     319             :   }
     320             : }
     321             : 
     322             : // -------------------------------------------------------------------
     323             : 
     324           0 : void Parser::AddError(int line, int column, const string& error) {
     325           0 :   if (error_collector_ != NULL) {
     326           0 :     error_collector_->AddError(line, column, error);
     327             :   }
     328           0 :   had_errors_ = true;
     329           0 : }
     330             : 
     331           0 : void Parser::AddError(const string& error) {
     332           0 :   AddError(input_->current().line, input_->current().column, error);
     333           0 : }
     334             : 
     335             : // -------------------------------------------------------------------
     336             : 
     337          78 : Parser::LocationRecorder::LocationRecorder(Parser* parser)
     338             :   : parser_(parser),
     339         156 :     location_(parser_->source_code_info_->add_location()) {
     340          78 :   location_->add_span(parser_->input_->current().line);
     341          78 :   location_->add_span(parser_->input_->current().column);
     342          78 : }
     343             : 
     344        3463 : Parser::LocationRecorder::LocationRecorder(const LocationRecorder& parent) {
     345        3463 :   Init(parent);
     346        3463 : }
     347             : 
     348       15167 : Parser::LocationRecorder::LocationRecorder(const LocationRecorder& parent,
     349             :                                            int path1) {
     350       15167 :   Init(parent);
     351       15167 :   AddPath(path1);
     352       15167 : }
     353             : 
     354        4132 : Parser::LocationRecorder::LocationRecorder(const LocationRecorder& parent,
     355             :                                            int path1, int path2) {
     356        4132 :   Init(parent);
     357        4132 :   AddPath(path1);
     358        4132 :   AddPath(path2);
     359        4132 : }
     360             : 
     361       22762 : void Parser::LocationRecorder::Init(const LocationRecorder& parent) {
     362       22762 :   parser_ = parent.parser_;
     363       45524 :   location_ = parser_->source_code_info_->add_location();
     364       22762 :   location_->mutable_path()->CopyFrom(parent.location_->path());
     365             : 
     366       22762 :   location_->add_span(parser_->input_->current().line);
     367       22762 :   location_->add_span(parser_->input_->current().column);
     368       22762 : }
     369             : 
     370       22840 : Parser::LocationRecorder::~LocationRecorder() {
     371       45680 :   if (location_->span_size() <= 2) {
     372       22391 :     EndAt(parser_->input_->previous());
     373             :   }
     374       22840 : }
     375             : 
     376       26921 : void Parser::LocationRecorder::AddPath(int path_component) {
     377       26921 :   location_->add_path(path_component);
     378       26921 : }
     379             : 
     380         312 : void Parser::LocationRecorder::StartAt(const io::Tokenizer::Token& token) {
     381         312 :   location_->set_span(0, token.line);
     382         312 :   location_->set_span(1, token.column);
     383         312 : }
     384             : 
     385          27 : void Parser::LocationRecorder::StartAt(const LocationRecorder& other) {
     386          54 :   location_->set_span(0, other.location_->span(0));
     387          54 :   location_->set_span(1, other.location_->span(1));
     388          27 : }
     389             : 
     390       22840 : void Parser::LocationRecorder::EndAt(const io::Tokenizer::Token& token) {
     391       45680 :   if (token.line != location_->span(0)) {
     392        1537 :     location_->add_span(token.line);
     393             :   }
     394       22840 :   location_->add_span(token.end_column);
     395       22840 : }
     396             : 
     397       12526 : void Parser::LocationRecorder::RecordLegacyLocation(const Message* descriptor,
     398             :     DescriptorPool::ErrorCollector::ErrorLocation location) {
     399       12526 :   if (parser_->source_location_table_ != NULL) {
     400             :     parser_->source_location_table_->Add(
     401       37578 :         descriptor, location, location_->span(0), location_->span(1));
     402             :   }
     403       12526 : }
     404             : 
     405        4394 : void Parser::LocationRecorder::AttachComments(
     406             :     string* leading, string* trailing,
     407        9016 :     vector<string>* detached_comments) const {
     408       13182 :   GOOGLE_CHECK(!location_->has_leading_comments());
     409       13182 :   GOOGLE_CHECK(!location_->has_trailing_comments());
     410             : 
     411        4394 :   if (!leading->empty()) {
     412         647 :     location_->mutable_leading_comments()->swap(*leading);
     413             :   }
     414        4394 :   if (!trailing->empty()) {
     415          58 :     location_->mutable_trailing_comments()->swap(*trailing);
     416             :   }
     417       13638 :   for (int i = 0; i < detached_comments->size(); ++i) {
     418             :     location_->add_leading_detached_comments()->swap(
     419         342 :         (*detached_comments)[i]);
     420             :   }
     421        4394 :   detached_comments->clear();
     422        4394 : }
     423             : 
     424             : // -------------------------------------------------------------------
     425             : 
     426           0 : void Parser::SkipStatement() {
     427             :   while (true) {
     428           0 :     if (AtEnd()) {
     429             :       return;
     430           0 :     } else if (LookingAtType(io::Tokenizer::TYPE_SYMBOL)) {
     431           0 :       if (TryConsumeEndOfDeclaration(";", NULL)) {
     432             :         return;
     433           0 :       } else if (TryConsume("{")) {
     434           0 :         SkipRestOfBlock();
     435           0 :         return;
     436           0 :       } else if (LookingAt("}")) {
     437             :         return;
     438             :       }
     439             :     }
     440           0 :     input_->Next();
     441             :   }
     442             : }
     443             : 
     444           0 : void Parser::SkipRestOfBlock() {
     445             :   while (true) {
     446           0 :     if (AtEnd()) {
     447             :       return;
     448           0 :     } else if (LookingAtType(io::Tokenizer::TYPE_SYMBOL)) {
     449           0 :       if (TryConsumeEndOfDeclaration("}", NULL)) {
     450             :         return;
     451           0 :       } else if (TryConsume("{")) {
     452           0 :         SkipRestOfBlock();
     453             :       }
     454             :     }
     455           0 :     input_->Next();
     456             :   }
     457             : }
     458             : 
     459             : // ===================================================================
     460             : 
     461         234 : bool Parser::Parse(io::Tokenizer* input, FileDescriptorProto* file) {
     462          78 :   input_ = input;
     463          78 :   had_errors_ = false;
     464          78 :   syntax_identifier_.clear();
     465             : 
     466             :   // Note that |file| could be NULL at this point if
     467             :   // stop_after_syntax_identifier_ is true.  So, we conservatively allocate
     468             :   // SourceCodeInfo on the stack, then swap it into the FileDescriptorProto
     469             :   // later on.
     470          78 :   SourceCodeInfo source_code_info;
     471          78 :   source_code_info_ = &source_code_info;
     472             : 
     473          78 :   vector<string> top_doc_comments;
     474         156 :   if (LookingAtType(io::Tokenizer::TYPE_START)) {
     475             :     // Advance to first token.
     476             :     input_->NextWithComments(NULL, &upcoming_detached_comments_,
     477          78 :                              &upcoming_doc_comments_);
     478             :   }
     479             : 
     480             :   {
     481          78 :     LocationRecorder root_location(this);
     482             : 
     483         234 :     if (require_syntax_identifier_ || LookingAt("syntax")) {
     484          78 :       if (!ParseSyntaxIdentifier(root_location)) {
     485             :         // Don't attempt to parse the file if we didn't recognize the syntax
     486             :         // identifier.
     487           0 :         return false;
     488             :       }
     489             :       // Store the syntax into the file.
     490          78 :       if (file != NULL) file->set_syntax(syntax_identifier_);
     491           0 :     } else if (!stop_after_syntax_identifier_) {
     492           0 :       GOOGLE_LOG(WARNING) << "No syntax specified for the proto file. "
     493           0 :                    << "Please use 'syntax = \"proto2\";' or "
     494           0 :                    << "'syntax = \"proto3\";' to specify a syntax "
     495           0 :                    << "version. (Defaulted to proto2 syntax.)";
     496           0 :       syntax_identifier_ = "proto2";
     497             :     }
     498             : 
     499          78 :     if (stop_after_syntax_identifier_) return !had_errors_;
     500             : 
     501             :     // Repeatedly parse statements until we reach the end of the file.
     502         847 :     while (!AtEnd()) {
     503         769 :       if (!ParseTopLevelStatement(file, root_location)) {
     504             :         // This statement failed to parse.  Skip it, but keep looping to parse
     505             :         // other statements.
     506           0 :         SkipStatement();
     507             : 
     508           0 :         if (LookingAt("}")) {
     509           0 :           AddError("Unmatched \"}\".");
     510             :           input_->NextWithComments(NULL, &upcoming_detached_comments_,
     511           0 :                                    &upcoming_doc_comments_);
     512             :         }
     513             :       }
     514          78 :     }
     515             :   }
     516             : 
     517          78 :   input_ = NULL;
     518          78 :   source_code_info_ = NULL;
     519          78 :   source_code_info.Swap(file->mutable_source_code_info());
     520         156 :   return !had_errors_;
     521             : }
     522             : 
     523          78 : bool Parser::ParseSyntaxIdentifier(const LocationRecorder& parent) {
     524             :   LocationRecorder syntax_location(parent,
     525          78 :                                    FileDescriptorProto::kSyntaxFieldNumber);
     526          78 :   DO(Consume(
     527             :       "syntax",
     528             :       "File must begin with a syntax statement, e.g. 'syntax = \"proto2\";'."));
     529          78 :   DO(Consume("="));
     530          78 :   io::Tokenizer::Token syntax_token = input_->current();
     531             :   string syntax;
     532          78 :   DO(ConsumeString(&syntax, "Expected syntax identifier."));
     533          78 :   DO(ConsumeEndOfDeclaration(";", &syntax_location));
     534             : 
     535          78 :   syntax_identifier_ = syntax;
     536             : 
     537         130 :   if (syntax != "proto2" && syntax != "proto3" &&
     538           0 :       !stop_after_syntax_identifier_) {
     539             :     AddError(syntax_token.line, syntax_token.column,
     540           0 :       "Unrecognized syntax identifier \"" + syntax + "\".  This parser "
     541           0 :       "only recognizes \"proto2\" and \"proto3\".");
     542           0 :     return false;
     543             :   }
     544             : 
     545          78 :   return true;
     546             : }
     547             : 
     548         769 : bool Parser::ParseTopLevelStatement(FileDescriptorProto* file,
     549        2322 :                                     const LocationRecorder& root_location) {
     550         769 :   if (TryConsumeEndOfDeclaration(";", NULL)) {
     551             :     // empty statement; ignore
     552             :     return true;
     553        1532 :   } else if (LookingAt("message")) {
     554             :     LocationRecorder location(root_location,
     555         394 :       FileDescriptorProto::kMessageTypeFieldNumber, file->message_type_size());
     556         394 :     return ParseMessageDefinition(file->add_message_type(), location, file);
     557         744 :   } else if (LookingAt("enum")) {
     558             :     LocationRecorder location(root_location,
     559          53 :       FileDescriptorProto::kEnumTypeFieldNumber, file->enum_type_size());
     560          53 :     return ParseEnumDefinition(file->add_enum_type(), location, file);
     561         638 :   } else if (LookingAt("service")) {
     562             :     LocationRecorder location(root_location,
     563          34 :       FileDescriptorProto::kServiceFieldNumber, file->service_size());
     564          34 :     return ParseServiceDefinition(file->add_service(), location, file);
     565         570 :   } else if (LookingAt("extend")) {
     566             :     LocationRecorder location(root_location,
     567          26 :         FileDescriptorProto::kExtensionFieldNumber);
     568             :     return ParseExtend(file->mutable_extension(),
     569             :                        file->mutable_message_type(),
     570             :                        root_location,
     571             :                        FileDescriptorProto::kMessageTypeFieldNumber,
     572          26 :                        location, file);
     573         518 :   } else if (LookingAt("import")) {
     574             :     return ParseImport(file->mutable_dependency(),
     575             :                        file->mutable_public_dependency(),
     576             :                        file->mutable_weak_dependency(),
     577          60 :                        root_location, file);
     578         398 :   } else if (LookingAt("package")) {
     579          77 :     return ParsePackage(file, root_location, file);
     580         244 :   } else if (LookingAt("option")) {
     581             :     LocationRecorder location(root_location,
     582         122 :         FileDescriptorProto::kOptionsFieldNumber);
     583         122 :     return ParseOption(file->mutable_options(), location, file,
     584         122 :                        OPTION_STATEMENT);
     585             :   } else {
     586           0 :     AddError("Expected top-level statement (e.g. \"message\").");
     587           0 :     return false;
     588             :   }
     589             : }
     590             : 
     591             : // -------------------------------------------------------------------
     592             : // Messages
     593             : 
     594         425 : bool Parser::ParseMessageDefinition(
     595             :     DescriptorProto* message,
     596             :     const LocationRecorder& message_location,
     597             :     const FileDescriptorProto* containing_file) {
     598         425 :   DO(Consume("message"));
     599             :   {
     600             :     LocationRecorder location(message_location,
     601         425 :                               DescriptorProto::kNameFieldNumber);
     602             :     location.RecordLegacyLocation(
     603         425 :         message, DescriptorPool::ErrorCollector::NAME);
     604         425 :     DO(ConsumeIdentifier(message->mutable_name(), "Expected message name."));
     605             :   }
     606         425 :   DO(ParseMessageBlock(message, message_location, containing_file));
     607         425 :   return true;
     608             : }
     609             : 
     610             : namespace {
     611             : 
     612             : const int kMaxExtensionRangeSentinel = -1;
     613             : 
     614          26 : bool IsMessageSetWireFormatMessage(const DescriptorProto& message) {
     615          52 :   const MessageOptions& options = message.options();
     616          52 :   for (int i = 0; i < options.uninterpreted_option_size(); ++i) {
     617           2 :     const UninterpretedOption& uninterpreted = options.uninterpreted_option(i);
     618           4 :     if (uninterpreted.name_size() == 1 &&
     619           8 :         uninterpreted.name(0).name_part() == "message_set_wire_format" &&
     620           2 :         uninterpreted.identifier_value() == "true") {
     621             :       return true;
     622             :     }
     623             :   }
     624             :   return false;
     625             : }
     626             : 
     627             : // Modifies any extension ranges that specified 'max' as the end of the
     628             : // extension range, and sets them to the type-specific maximum. The actual max
     629             : // tag number can only be determined after all options have been parsed.
     630          26 : void AdjustExtensionRangesWithMaxEndNumber(DescriptorProto* message) {
     631          26 :   const bool is_message_set = IsMessageSetWireFormatMessage(*message);
     632             :   const int max_extension_number = is_message_set ?
     633             :       kint32max :
     634          26 :       FieldDescriptor::kMaxNumber + 1;
     635         110 :   for (int i = 0; i < message->extension_range_size(); ++i) {
     636          29 :     if (message->extension_range(i).end() == kMaxExtensionRangeSentinel) {
     637          24 :       message->mutable_extension_range(i)->set_end(max_extension_number);
     638             :     }
     639             :   }
     640          26 : }
     641             : 
     642             : }  // namespace
     643             : 
     644         452 : bool Parser::ParseMessageBlock(DescriptorProto* message,
     645             :                                const LocationRecorder& message_location,
     646             :                                const FileDescriptorProto* containing_file) {
     647         452 :   DO(ConsumeEndOfDeclaration("{", &message_location));
     648             : 
     649        3303 :   while (!TryConsumeEndOfDeclaration("}", NULL)) {
     650        2851 :     if (AtEnd()) {
     651           0 :       AddError("Reached end of input in message definition (missing '}').");
     652           0 :       return false;
     653             :     }
     654             : 
     655        2851 :     if (!ParseMessageStatement(message, message_location, containing_file)) {
     656             :       // This statement failed to parse.  Skip it, but keep looping to parse
     657             :       // other statements.
     658           0 :       SkipStatement();
     659             :     }
     660             :   }
     661             : 
     662         452 :   if (message->extension_range_size() > 0) {
     663          26 :     AdjustExtensionRangesWithMaxEndNumber(message);
     664             :   }
     665             :   return true;
     666             : }
     667             : 
     668        2851 : bool Parser::ParseMessageStatement(DescriptorProto* message,
     669             :                                    const LocationRecorder& message_location,
     670       19387 :                                    const FileDescriptorProto* containing_file) {
     671        2851 :   if (TryConsumeEndOfDeclaration(";", NULL)) {
     672             :     // empty statement; ignore
     673             :     return true;
     674        5686 :   } else if (LookingAt("message")) {
     675             :     LocationRecorder location(message_location,
     676             :                               DescriptorProto::kNestedTypeFieldNumber,
     677          31 :                               message->nested_type_size());
     678             :     return ParseMessageDefinition(message->add_nested_type(), location,
     679          31 :                                   containing_file);
     680        5624 :   } else if (LookingAt("enum")) {
     681             :     LocationRecorder location(message_location,
     682             :                               DescriptorProto::kEnumTypeFieldNumber,
     683          24 :                               message->enum_type_size());
     684             :     return ParseEnumDefinition(message->add_enum_type(), location,
     685          24 :                                containing_file);
     686        5576 :   } else if (LookingAt("extensions")) {
     687             :     LocationRecorder location(message_location,
     688          29 :                               DescriptorProto::kExtensionRangeFieldNumber);
     689          29 :     return ParseExtensions(message, location, containing_file);
     690        5518 :   } else if (LookingAt("reserved")) {
     691           2 :     return ParseReserved(message, message_location);
     692        5514 :   } else if (LookingAt("extend")) {
     693             :     LocationRecorder location(message_location,
     694          14 :                               DescriptorProto::kExtensionFieldNumber);
     695             :     return ParseExtend(message->mutable_extension(),
     696             :                        message->mutable_nested_type(),
     697             :                        message_location,
     698             :                        DescriptorProto::kNestedTypeFieldNumber,
     699          14 :                        location, containing_file);
     700        5486 :   } else if (LookingAt("option")) {
     701             :     LocationRecorder location(message_location,
     702          58 :                               DescriptorProto::kOptionsFieldNumber);
     703          58 :     return ParseOption(message->mutable_options(), location,
     704          58 :                        containing_file, OPTION_STATEMENT);
     705        5370 :   } else if (LookingAt("oneof")) {
     706          30 :     int oneof_index = message->oneof_decl_size();
     707             :     LocationRecorder oneof_location(message_location,
     708             :                                     DescriptorProto::kOneofDeclFieldNumber,
     709          30 :                                     oneof_index);
     710             : 
     711             :     return ParseOneof(message->add_oneof_decl(), message,
     712             :                       oneof_index, oneof_location, message_location,
     713          30 :                       containing_file);
     714             :   } else {
     715             :     LocationRecorder location(message_location,
     716             :                               DescriptorProto::kFieldFieldNumber,
     717        2655 :                               message->field_size());
     718             :     return ParseMessageField(message->add_field(),
     719             :                              message->mutable_nested_type(),
     720             :                              message_location,
     721             :                              DescriptorProto::kNestedTypeFieldNumber,
     722             :                              location,
     723        5310 :                              containing_file);
     724             :   }
     725             : }
     726             : 
     727        2910 : bool Parser::ParseMessageField(FieldDescriptorProto* field,
     728             :                                RepeatedPtrField<DescriptorProto>* messages,
     729             :                                const LocationRecorder& parent_location,
     730             :                                int location_field_number_for_nested_type,
     731             :                                const LocationRecorder& field_location,
     732             :                                const FileDescriptorProto* containing_file) {
     733             :   {
     734             :     LocationRecorder location(field_location,
     735        2910 :                               FieldDescriptorProto::kLabelFieldNumber);
     736             :     FieldDescriptorProto::Label label;
     737        2910 :     if (ParseLabel(&label, containing_file)) {
     738        2138 :       field->set_label(label);
     739        3763 :       if (label == FieldDescriptorProto::LABEL_OPTIONAL &&
     740        1625 :           syntax_identifier_ == "proto3") {
     741             :         AddError(
     742             :             "Explicit 'optional' labels are disallowed in the Proto3 syntax. "
     743             :             "To define 'optional' fields in Proto3, simply remove the "
     744           0 :             "'optional' label, as fields are 'optional' by default.");
     745             :       }
     746        2910 :     }
     747             :   }
     748             : 
     749             :   return ParseMessageFieldNoLabel(field, messages, parent_location,
     750             :                                   location_field_number_for_nested_type,
     751             :                                   field_location,
     752        2910 :                                   containing_file);
     753             : }
     754             : 
     755        3031 : bool Parser::ParseMessageFieldNoLabel(
     756       11224 :     FieldDescriptorProto* field,
     757             :     RepeatedPtrField<DescriptorProto>* messages,
     758             :     const LocationRecorder& parent_location,
     759             :     int location_field_number_for_nested_type,
     760             :     const LocationRecorder& field_location,
     761         151 :     const FileDescriptorProto* containing_file) {
     762             :   MapField map_field;
     763             :   // Parse type.
     764             :   {
     765        3031 :     LocationRecorder location(field_location);  // add path later
     766        3031 :     location.RecordLegacyLocation(field, DescriptorPool::ErrorCollector::TYPE);
     767             : 
     768        3031 :     bool type_parsed = false;
     769        3031 :     FieldDescriptorProto::Type type = FieldDescriptorProto::TYPE_INT32;
     770             :     string type_name;
     771             : 
     772             :     // Special case map field. We only treat the field as a map field if the
     773             :     // field type name starts with the word "map" with a following "<".
     774        3031 :     if (TryConsume("map")) {
     775         248 :       if (LookingAt("<")) {
     776         124 :         map_field.is_map_field = true;
     777             :       } else {
     778             :         // False positive
     779           0 :         type_parsed = true;
     780             :         type_name = "map";
     781             :       }
     782             :     }
     783        3031 :     if (map_field.is_map_field) {
     784         248 :       if (field->has_oneof_index()) {
     785           0 :         AddError("Map fields are not allowed in oneofs.");
     786           0 :         return false;
     787             :       }
     788         248 :       if (field->has_label()) {
     789             :         AddError(
     790             :             "Field labels (required/optional/repeated) are not allowed on "
     791           0 :             "map fields.");
     792           0 :         return false;
     793             :       }
     794         248 :       if (field->has_extendee()) {
     795           0 :         AddError("Map fields are not allowed to be extensions.");
     796           0 :         return false;
     797             :       }
     798             :       field->set_label(FieldDescriptorProto::LABEL_REPEATED);
     799         124 :       DO(Consume("<"));
     800         124 :       DO(ParseType(&map_field.key_type, &map_field.key_type_name));
     801         124 :       DO(Consume(","));
     802         124 :       DO(ParseType(&map_field.value_type, &map_field.value_type_name));
     803         124 :       DO(Consume(">"));
     804             :       // Defer setting of the type name of the map field until the
     805             :       // field name is parsed. Add the source location though.
     806         124 :       location.AddPath(FieldDescriptorProto::kTypeNameFieldNumber);
     807             :     } else {
     808             :       // Handle the case where no explicit label is given for a non-map field.
     809        6462 :       if (!field->has_label() && DefaultToOptionalFields()) {
     810             :         field->set_label(FieldDescriptorProto::LABEL_OPTIONAL);
     811             :       }
     812        5814 :       if (!field->has_label()) {
     813           0 :         AddError("Expected \"required\", \"optional\", or \"repeated\".");
     814             :         // We can actually reasonably recover here by just assuming the user
     815             :         // forgot the label altogether.
     816             :         field->set_label(FieldDescriptorProto::LABEL_OPTIONAL);
     817             :       }
     818             : 
     819             :       // Handle the case where the actual type is a message or enum named "map",
     820             :       // which we already consumed in the code above.
     821        2907 :       if (!type_parsed) {
     822        2907 :         DO(ParseType(&type, &type_name));
     823             :       }
     824        2907 :       if (type_name.empty()) {
     825        2255 :         location.AddPath(FieldDescriptorProto::kTypeFieldNumber);
     826        2255 :         field->set_type(type);
     827             :       } else {
     828         652 :         location.AddPath(FieldDescriptorProto::kTypeNameFieldNumber);
     829             :         field->set_type_name(type_name);
     830             :       }
     831        3031 :     }
     832             :   }
     833             : 
     834             :   // Parse name and '='.
     835        3031 :   io::Tokenizer::Token name_token = input_->current();
     836             :   {
     837             :     LocationRecorder location(field_location,
     838        3031 :                               FieldDescriptorProto::kNameFieldNumber);
     839        3031 :     location.RecordLegacyLocation(field, DescriptorPool::ErrorCollector::NAME);
     840        3031 :     DO(ConsumeIdentifier(field->mutable_name(), "Expected field name."));
     841             :   }
     842        3031 :   DO(Consume("=", "Missing field number."));
     843             : 
     844             :   // Parse field number.
     845             :   {
     846             :     LocationRecorder location(field_location,
     847        3031 :                               FieldDescriptorProto::kNumberFieldNumber);
     848             :     location.RecordLegacyLocation(
     849        3031 :         field, DescriptorPool::ErrorCollector::NUMBER);
     850             :     int number;
     851        3031 :     DO(ConsumeInteger(&number, "Expected field number."));
     852        6062 :     field->set_number(number);
     853             :   }
     854             : 
     855             :   // Parse options.
     856        3031 :   DO(ParseFieldOptions(field, field_location, containing_file));
     857             : 
     858             :   // Deal with groups.
     859       10572 :   if (field->has_type() && field->type() == FieldDescriptorProto::TYPE_GROUP) {
     860             :     // Awkward:  Since a group declares both a message type and a field, we
     861             :     //   have to create overlapping locations.
     862          27 :     LocationRecorder group_location(parent_location);
     863          27 :     group_location.StartAt(field_location);
     864          27 :     group_location.AddPath(location_field_number_for_nested_type);
     865          27 :     group_location.AddPath(messages->size());
     866             : 
     867          27 :     DescriptorProto* group = messages->Add();
     868          27 :     group->set_name(field->name());
     869             : 
     870             :     // Record name location to match the field name's location.
     871             :     {
     872             :       LocationRecorder location(group_location,
     873          27 :                                 DescriptorProto::kNameFieldNumber);
     874          27 :       location.StartAt(name_token);
     875          27 :       location.EndAt(name_token);
     876             :       location.RecordLegacyLocation(
     877          27 :           group, DescriptorPool::ErrorCollector::NAME);
     878             :     }
     879             : 
     880             :     // The field's type_name also comes from the name.  Confusing!
     881             :     {
     882             :       LocationRecorder location(field_location,
     883          27 :                                 FieldDescriptorProto::kTypeNameFieldNumber);
     884          27 :       location.StartAt(name_token);
     885          27 :       location.EndAt(name_token);
     886             :     }
     887             : 
     888             :     // As a hack for backwards-compatibility, we force the group name to start
     889             :     // with a capital letter and lower-case the field name.  New code should
     890             :     // not use groups; it should use nested messages.
     891          81 :     if (group->name()[0] < 'A' || 'Z' < group->name()[0]) {
     892             :       AddError(name_token.line, name_token.column,
     893           0 :         "Group names must start with a capital letter.");
     894             :     }
     895          27 :     LowerString(field->mutable_name());
     896             : 
     897          27 :     field->set_type_name(group->name());
     898          54 :     if (LookingAt("{")) {
     899          27 :       DO(ParseMessageBlock(group, group_location, containing_file));
     900             :     } else {
     901           0 :       AddError("Missing group body.");
     902           0 :       return false;
     903          27 :     }
     904             :   } else {
     905        3004 :     DO(ConsumeEndOfDeclaration(";", &field_location));
     906             :   }
     907             : 
     908             :   // Create a map entry type if this is a map field.
     909        3031 :   if (map_field.is_map_field) {
     910         124 :     GenerateMapEntry(map_field, field, messages);
     911             :   }
     912             : 
     913        3031 :   return true;
     914             : }
     915             : 
     916         124 : void Parser::GenerateMapEntry(const MapField& map_field,
     917         124 :                               FieldDescriptorProto* field,
     918             :                               RepeatedPtrField<DescriptorProto>* messages) {
     919         124 :   DescriptorProto* entry = messages->Add();
     920         124 :   string entry_name = MapEntryName(field->name());
     921             :   field->set_type_name(entry_name);
     922             :   entry->set_name(entry_name);
     923         124 :   entry->mutable_options()->set_map_entry(true);
     924         124 :   FieldDescriptorProto* key_field = entry->add_field();
     925         124 :   key_field->set_name("key");
     926             :   key_field->set_label(FieldDescriptorProto::LABEL_OPTIONAL);
     927             :   key_field->set_number(1);
     928         248 :   if (map_field.key_type_name.empty()) {
     929         124 :     key_field->set_type(map_field.key_type);
     930             :   } else {
     931           0 :     key_field->set_type_name(map_field.key_type_name);
     932             :   }
     933         124 :   FieldDescriptorProto* value_field = entry->add_field();
     934         124 :   value_field->set_name("value");
     935             :   value_field->set_label(FieldDescriptorProto::LABEL_OPTIONAL);
     936             :   value_field->set_number(2);
     937         248 :   if (map_field.value_type_name.empty()) {
     938          77 :     value_field->set_type(map_field.value_type);
     939             :   } else {
     940          47 :     value_field->set_type_name(map_field.value_type_name);
     941             :   }
     942             :   // Propagate the "enforce_utf8" option to key and value fields if they
     943             :   // are strings. This helps simplify the implementation of code generators
     944             :   // and also reflection-based parsing code.
     945             :   //
     946             :   // The following definition:
     947             :   //   message Foo {
     948             :   //     map<string, string> value = 1 [enforce_utf8 = false];
     949             :   //   }
     950             :   // will be interpreted as:
     951             :   //   message Foo {
     952             :   //     message ValueEntry {
     953             :   //       option map_entry = true;
     954             :   //       string key = 1 [enforce_utf8 = false];
     955             :   //       string value = 2 [enforce_utf8 = false];
     956             :   //     }
     957             :   //     repeated ValueEntry value = 1 [enforce_utf8 = false];
     958             :   //  }
     959             :   //
     960             :   // TODO(xiaofeng): Remove this when the "enforce_utf8" option is removed
     961             :   // from protocol compiler.
     962         372 :   for (int i = 0; i < field->options().uninterpreted_option_size(); ++i) {
     963             :     const UninterpretedOption& option =
     964           0 :         field->options().uninterpreted_option(i);
     965           0 :     if (option.name_size() == 1 &&
     966           0 :         option.name(0).name_part() == "enforce_utf8" &&
     967           0 :         !option.name(0).is_extension()) {
     968           0 :       if (key_field->type() == FieldDescriptorProto::TYPE_STRING) {
     969             :         key_field->mutable_options()->add_uninterpreted_option()
     970           0 :             ->CopyFrom(option);
     971             :       }
     972           0 :       if (value_field->type() == FieldDescriptorProto::TYPE_STRING) {
     973             :         value_field->mutable_options()->add_uninterpreted_option()
     974           0 :             ->CopyFrom(option);
     975             :       }
     976             :     }
     977             :   }
     978         124 : }
     979             : 
     980        3031 : bool Parser::ParseFieldOptions(FieldDescriptorProto* field,
     981             :                                const LocationRecorder& field_location,
     982        4405 :                                const FileDescriptorProto* containing_file) {
     983        6062 :   if (!LookingAt("[")) return true;
     984             : 
     985             :   LocationRecorder location(field_location,
     986        1359 :                             FieldDescriptorProto::kOptionsFieldNumber);
     987             : 
     988        1359 :   DO(Consume("["));
     989             : 
     990             :   // Parse field options.
     991        1374 :   do {
     992        2748 :     if (LookingAt("default")) {
     993             :       // We intentionally pass field_location rather than location here, since
     994             :       // the default value is not actually an option.
     995        1160 :       DO(ParseDefaultAssignment(field, field_location, containing_file));
     996             :     } else {
     997         214 :       DO(ParseOption(field->mutable_options(), location,
     998             :                      containing_file, OPTION_ASSIGNMENT));
     999             :     }
    1000             :   } while (TryConsume(","));
    1001             : 
    1002        1359 :   DO(Consume("]"));
    1003        1359 :   return true;
    1004             : }
    1005             : 
    1006        1160 : bool Parser::ParseDefaultAssignment(
    1007        3461 :     FieldDescriptorProto* field,
    1008             :     const LocationRecorder& field_location,
    1009             :     const FileDescriptorProto* containing_file) {
    1010        2320 :   if (field->has_default_value()) {
    1011           0 :     AddError("Already set option \"default\".");
    1012             :     field->clear_default_value();
    1013             :   }
    1014             : 
    1015        1160 :   DO(Consume("default"));
    1016        1160 :   DO(Consume("="));
    1017             : 
    1018             :   LocationRecorder location(field_location,
    1019        1160 :                             FieldDescriptorProto::kDefaultValueFieldNumber);
    1020             :   location.RecordLegacyLocation(
    1021        1160 :       field, DescriptorPool::ErrorCollector::DEFAULT_VALUE);
    1022        1160 :   string* default_value = field->mutable_default_value();
    1023             : 
    1024        2320 :   if (!field->has_type()) {
    1025             :     // The field has a type name, but we don't know if it is a message or an
    1026             :     // enum yet. (If it were a primitive type, |field| would have a type set
    1027             :     // already.) In this case, simply take the current string as the default
    1028             :     // value; we will catch the error later if it is not a valid enum value.
    1029             :     // (N.B. that we do not check whether the current token is an identifier:
    1030             :     // doing so throws strange errors when the user mistypes a primitive
    1031             :     // typename and we assume it's an enum. E.g.: "optional int foo = 1 [default
    1032             :     // = 42]". In such a case the fundamental error is really that "int" is not
    1033             :     // a type, not that "42" is not an identifier. See b/12533582.)
    1034          19 :     *default_value = input_->current().text;
    1035          19 :     input_->Next();
    1036             :     return true;
    1037             :   }
    1038             : 
    1039        2282 :   switch (field->type()) {
    1040             :     case FieldDescriptorProto::TYPE_INT32:
    1041             :     case FieldDescriptorProto::TYPE_INT64:
    1042             :     case FieldDescriptorProto::TYPE_SINT32:
    1043             :     case FieldDescriptorProto::TYPE_SINT64:
    1044             :     case FieldDescriptorProto::TYPE_SFIXED32:
    1045             :     case FieldDescriptorProto::TYPE_SFIXED64: {
    1046          36 :       uint64 max_value = kint64max;
    1047          99 :       if (field->type() == FieldDescriptorProto::TYPE_INT32 ||
    1048          58 :           field->type() == FieldDescriptorProto::TYPE_SINT32 ||
    1049          22 :           field->type() == FieldDescriptorProto::TYPE_SFIXED32) {
    1050          19 :         max_value = kint32max;
    1051             :       }
    1052             : 
    1053             :       // These types can be negative.
    1054          36 :       if (TryConsume("-")) {
    1055          14 :         default_value->append("-");
    1056             :         // Two's complement always has one more negative value than positive.
    1057          14 :         ++max_value;
    1058             :       }
    1059             :       // Parse the integer to verify that it is not out-of-range.
    1060             :       uint64 value;
    1061          36 :       DO(ConsumeInteger64(max_value, &value,
    1062             :                           "Expected integer for field default value."));
    1063             :       // And stringify it again.
    1064          72 :       default_value->append(SimpleItoa(value));
    1065          36 :       break;
    1066             :     }
    1067             : 
    1068             :     case FieldDescriptorProto::TYPE_UINT32:
    1069             :     case FieldDescriptorProto::TYPE_UINT64:
    1070             :     case FieldDescriptorProto::TYPE_FIXED32:
    1071             :     case FieldDescriptorProto::TYPE_FIXED64: {
    1072          22 :       uint64 max_value = kuint64max;
    1073          38 :       if (field->type() == FieldDescriptorProto::TYPE_UINT32 ||
    1074          16 :           field->type() == FieldDescriptorProto::TYPE_FIXED32) {
    1075          11 :         max_value = kuint32max;
    1076             :       }
    1077             : 
    1078             :       // Numeric, not negative.
    1079          22 :       if (TryConsume("-")) {
    1080           0 :         AddError("Unsigned field can't have negative default value.");
    1081             :       }
    1082             :       // Parse the integer to verify that it is not out-of-range.
    1083             :       uint64 value;
    1084          22 :       DO(ConsumeInteger64(max_value, &value,
    1085             :                           "Expected integer for field default value."));
    1086             :       // And stringify it again.
    1087          44 :       default_value->append(SimpleItoa(value));
    1088          22 :       break;
    1089             :     }
    1090             : 
    1091             :     case FieldDescriptorProto::TYPE_FLOAT:
    1092             :     case FieldDescriptorProto::TYPE_DOUBLE:
    1093             :       // These types can be negative.
    1094          23 :       if (TryConsume("-")) {
    1095           5 :         default_value->append("-");
    1096             :       }
    1097             :       // Parse the integer because we have to convert hex integers to decimal
    1098             :       // floats.
    1099             :       double value;
    1100          23 :       DO(ConsumeNumber(&value, "Expected number."));
    1101             :       // And stringify it again.
    1102          46 :       default_value->append(SimpleDtoa(value));
    1103          23 :       break;
    1104             : 
    1105             :     case FieldDescriptorProto::TYPE_BOOL:
    1106          25 :       if (TryConsume("true")) {
    1107           5 :         default_value->assign("true");
    1108          20 :       } else if (TryConsume("false")) {
    1109          20 :         default_value->assign("false");
    1110             :       } else {
    1111           0 :         AddError("Expected \"true\" or \"false\".");
    1112           0 :         return false;
    1113             :       }
    1114             :       break;
    1115             : 
    1116             :     case FieldDescriptorProto::TYPE_STRING:
    1117             :       // Note: When file opton java_string_check_utf8 is true, if a
    1118             :       // non-string representation (eg byte[]) is later supported, it must
    1119             :       // be checked for UTF-8-ness.
    1120        1027 :       DO(ConsumeString(default_value, "Expected string for field default "
    1121             :                        "value."));
    1122             :       break;
    1123             : 
    1124             :     case FieldDescriptorProto::TYPE_BYTES:
    1125           8 :       DO(ConsumeString(default_value, "Expected string."));
    1126          16 :       *default_value = CEscape(*default_value);
    1127           8 :       break;
    1128             : 
    1129             :     case FieldDescriptorProto::TYPE_ENUM:
    1130           0 :       DO(ConsumeIdentifier(default_value, "Expected enum identifier for field "
    1131             :                                           "default value."));
    1132             :       break;
    1133             : 
    1134             :     case FieldDescriptorProto::TYPE_MESSAGE:
    1135             :     case FieldDescriptorProto::TYPE_GROUP:
    1136           0 :       AddError("Messages can't have default values.");
    1137           0 :       return false;
    1138             :   }
    1139             : 
    1140        1160 :   return true;
    1141             : }
    1142             : 
    1143         436 : bool Parser::ParseOptionNamePart(UninterpretedOption* uninterpreted_option,
    1144             :                                  const LocationRecorder& part_location,
    1145         615 :                                  const FileDescriptorProto* containing_file) {
    1146         436 :   UninterpretedOption::NamePart* name = uninterpreted_option->add_name();
    1147             :   string identifier;  // We parse identifiers into this string.
    1148         872 :   if (LookingAt("(")) {  // This is an extension.
    1149          81 :     DO(Consume("("));
    1150             : 
    1151             :     {
    1152             :       LocationRecorder location(
    1153          81 :           part_location, UninterpretedOption::NamePart::kNamePartFieldNumber);
    1154             :       // An extension name consists of dot-separated identifiers, and may begin
    1155             :       // with a dot.
    1156         162 :       if (LookingAtType(io::Tokenizer::TYPE_IDENTIFIER)) {
    1157          77 :         DO(ConsumeIdentifier(&identifier, "Expected identifier."));
    1158          77 :         name->mutable_name_part()->append(identifier);
    1159             :       }
    1160         196 :       while (LookingAt(".")) {
    1161          17 :         DO(Consume("."));
    1162          17 :         name->mutable_name_part()->append(".");
    1163          17 :         DO(ConsumeIdentifier(&identifier, "Expected identifier."));
    1164          17 :         name->mutable_name_part()->append(identifier);
    1165          81 :       }
    1166             :     }
    1167             : 
    1168          81 :     DO(Consume(")"));
    1169             :     name->set_is_extension(true);
    1170             :   } else {  // This is a regular field.
    1171             :     LocationRecorder location(
    1172         355 :         part_location, UninterpretedOption::NamePart::kNamePartFieldNumber);
    1173         355 :     DO(ConsumeIdentifier(&identifier, "Expected identifier."));
    1174         355 :     name->mutable_name_part()->append(identifier);
    1175         355 :     name->set_is_extension(false);
    1176             :   }
    1177             :   return true;
    1178             : }
    1179             : 
    1180          80 : bool Parser::ParseUninterpretedBlock(string* value) {
    1181             :   // Note that enclosing braces are not added to *value.
    1182             :   // We do NOT use ConsumeEndOfStatement for this brace because it's delimiting
    1183             :   // an expression, not a block of statements.
    1184           9 :   DO(Consume("{"));
    1185             :   int brace_depth = 1;
    1186          76 :   while (!AtEnd()) {
    1187         152 :     if (LookingAt("{")) {
    1188           5 :       brace_depth++;
    1189         142 :     } else if (LookingAt("}")) {
    1190          14 :       brace_depth--;
    1191          14 :       if (brace_depth == 0) {
    1192           9 :         input_->Next();
    1193           9 :         return true;
    1194             :       }
    1195             :     }
    1196             :     // TODO(sanjay): Interpret line/column numbers to preserve formatting
    1197          67 :     if (!value->empty()) value->push_back(' ');
    1198          67 :     value->append(input_->current().text);
    1199          67 :     input_->Next();
    1200             :   }
    1201           0 :   AddError("Unexpected end of stream while parsing aggregate value.");
    1202           0 :   return false;
    1203             : }
    1204             : 
    1205             : // We don't interpret the option here. Instead we store it in an
    1206             : // UninterpretedOption, to be interpreted later.
    1207         405 : bool Parser::ParseOption(Message* options,
    1208             :                          const LocationRecorder& options_location,
    1209             :                          const FileDescriptorProto* containing_file,
    1210         436 :                          OptionStyle style) {
    1211             :   // Create an entry in the uninterpreted_option field.
    1212         405 :   const FieldDescriptor* uninterpreted_option_field = options->GetDescriptor()->
    1213        1215 :       FindFieldByName("uninterpreted_option");
    1214           0 :   GOOGLE_CHECK(uninterpreted_option_field != NULL)
    1215         810 :       << "No field named \"uninterpreted_option\" in the Options proto.";
    1216             : 
    1217         405 :   const Reflection* reflection = options->GetReflection();
    1218             : 
    1219             :   LocationRecorder location(
    1220             :       options_location, uninterpreted_option_field->number(),
    1221         810 :       reflection->FieldSize(*options, uninterpreted_option_field));
    1222             : 
    1223         405 :   if (style == OPTION_STATEMENT) {
    1224         188 :     DO(Consume("option"));
    1225             :   }
    1226             : 
    1227             :   UninterpretedOption* uninterpreted_option = down_cast<UninterpretedOption*>(
    1228         405 :       options->GetReflection()->AddMessage(options,
    1229         405 :                                            uninterpreted_option_field));
    1230             : 
    1231             :   // Parse dot-separated name.
    1232             :   {
    1233             :     LocationRecorder name_location(location,
    1234         405 :                                    UninterpretedOption::kNameFieldNumber);
    1235             :     name_location.RecordLegacyLocation(
    1236         405 :         uninterpreted_option, DescriptorPool::ErrorCollector::OPTION_NAME);
    1237             : 
    1238             :     {
    1239             :       LocationRecorder part_location(name_location,
    1240         405 :                                      uninterpreted_option->name_size());
    1241         405 :       DO(ParseOptionNamePart(uninterpreted_option, part_location,
    1242         405 :                              containing_file));
    1243             :     }
    1244             : 
    1245        1277 :     while (LookingAt(".")) {
    1246          31 :       DO(Consume("."));
    1247             :       LocationRecorder part_location(name_location,
    1248          31 :                                      uninterpreted_option->name_size());
    1249          31 :       DO(ParseOptionNamePart(uninterpreted_option, part_location,
    1250             :                              containing_file));
    1251         436 :     }
    1252             :   }
    1253             : 
    1254         405 :   DO(Consume("="));
    1255             : 
    1256             :   {
    1257         405 :     LocationRecorder value_location(location);
    1258             :     value_location.RecordLegacyLocation(
    1259         405 :         uninterpreted_option, DescriptorPool::ErrorCollector::OPTION_VALUE);
    1260             : 
    1261             :     // All values are a single token, except for negative numbers, which consist
    1262             :     // of a single '-' symbol, followed by a positive number.
    1263         405 :     bool is_negative = TryConsume("-");
    1264             : 
    1265         405 :     switch (input_->current().type) {
    1266             :       case io::Tokenizer::TYPE_START:
    1267           0 :         GOOGLE_LOG(FATAL) << "Trying to read value before any tokens have been read.";
    1268           0 :         return false;
    1269             : 
    1270             :       case io::Tokenizer::TYPE_END:
    1271           0 :         AddError("Unexpected end of stream while parsing option value.");
    1272           0 :         return false;
    1273             : 
    1274             :       case io::Tokenizer::TYPE_IDENTIFIER: {
    1275             :         value_location.AddPath(
    1276         273 :             UninterpretedOption::kIdentifierValueFieldNumber);
    1277         273 :         if (is_negative) {
    1278           0 :           AddError("Invalid '-' symbol before identifier.");
    1279           0 :           return false;
    1280             :         }
    1281             :         string value;
    1282         273 :         DO(ConsumeIdentifier(&value, "Expected identifier."));
    1283             :         uninterpreted_option->set_identifier_value(value);
    1284             :         break;
    1285             :       }
    1286             : 
    1287             :       case io::Tokenizer::TYPE_INTEGER: {
    1288             :         uint64 value;
    1289             :         uint64 max_value =
    1290          54 :             is_negative ? static_cast<uint64>(kint64max) + 1 : kuint64max;
    1291          54 :         DO(ConsumeInteger64(max_value, &value, "Expected integer."));
    1292          54 :         if (is_negative) {
    1293             :           value_location.AddPath(
    1294          12 :               UninterpretedOption::kNegativeIntValueFieldNumber);
    1295             :           uninterpreted_option->set_negative_int_value(
    1296          12 :               -static_cast<int64>(value));
    1297             :         } else {
    1298             :           value_location.AddPath(
    1299          42 :               UninterpretedOption::kPositiveIntValueFieldNumber);
    1300          42 :           uninterpreted_option->set_positive_int_value(value);
    1301             :         }
    1302          54 :         break;
    1303             :       }
    1304             : 
    1305             :       case io::Tokenizer::TYPE_FLOAT: {
    1306           2 :         value_location.AddPath(UninterpretedOption::kDoubleValueFieldNumber);
    1307             :         double value;
    1308           2 :         DO(ConsumeNumber(&value, "Expected number."));
    1309           2 :         uninterpreted_option->set_double_value(is_negative ? -value : value);
    1310           2 :         break;
    1311             :       }
    1312             : 
    1313             :       case io::Tokenizer::TYPE_STRING: {
    1314          67 :         value_location.AddPath(UninterpretedOption::kStringValueFieldNumber);
    1315          67 :         if (is_negative) {
    1316           0 :           AddError("Invalid '-' symbol before string.");
    1317           0 :           return false;
    1318             :         }
    1319             :         string value;
    1320          67 :         DO(ConsumeString(&value, "Expected string."));
    1321             :         uninterpreted_option->set_string_value(value);
    1322             :         break;
    1323             :       }
    1324             : 
    1325             :       case io::Tokenizer::TYPE_SYMBOL:
    1326          18 :         if (LookingAt("{")) {
    1327             :           value_location.AddPath(
    1328           9 :               UninterpretedOption::kAggregateValueFieldNumber);
    1329           9 :           DO(ParseUninterpretedBlock(
    1330             :               uninterpreted_option->mutable_aggregate_value()));
    1331             :         } else {
    1332           0 :           AddError("Expected option value.");
    1333           0 :           return false;
    1334             :         }
    1335             :         break;
    1336         405 :     }
    1337             :   }
    1338             : 
    1339         405 :   if (style == OPTION_STATEMENT) {
    1340         188 :     DO(ConsumeEndOfDeclaration(";", &location));
    1341             :   }
    1342             : 
    1343         405 :   return true;
    1344             : }
    1345             : 
    1346          29 : bool Parser::ParseExtensions(DescriptorProto* message,
    1347             :                              const LocationRecorder& extensions_location,
    1348             :                              const FileDescriptorProto* containing_file) {
    1349             :   // Parse the declaration.
    1350          29 :   DO(Consume("extensions"));
    1351             : 
    1352          29 :   do {
    1353             :     // Note that kExtensionRangeFieldNumber was already pushed by the parent.
    1354             :     LocationRecorder location(extensions_location,
    1355          29 :                               message->extension_range_size());
    1356             : 
    1357          29 :     DescriptorProto::ExtensionRange* range = message->add_extension_range();
    1358             :     location.RecordLegacyLocation(
    1359          29 :         range, DescriptorPool::ErrorCollector::NUMBER);
    1360             : 
    1361             :     int start, end;
    1362             :     io::Tokenizer::Token start_token;
    1363             : 
    1364             :     {
    1365             :       LocationRecorder start_location(
    1366          29 :           location, DescriptorProto::ExtensionRange::kStartFieldNumber);
    1367          29 :       start_token = input_->current();
    1368          29 :       DO(ConsumeInteger(&start, "Expected field number range."));
    1369             :     }
    1370             : 
    1371          29 :     if (TryConsume("to")) {
    1372             :       LocationRecorder end_location(
    1373          28 :           location, DescriptorProto::ExtensionRange::kEndFieldNumber);
    1374          28 :       if (TryConsume("max")) {
    1375             :         // Set to the sentinel value - 1 since we increment the value below.
    1376             :         // The actual value of the end of the range should be set with
    1377             :         // AdjustExtensionRangesWithMaxEndNumber.
    1378          24 :         end = kMaxExtensionRangeSentinel - 1;
    1379             :       } else {
    1380           4 :         DO(ConsumeInteger(&end, "Expected integer."));
    1381          28 :       }
    1382             :     } else {
    1383             :       LocationRecorder end_location(
    1384           1 :           location, DescriptorProto::ExtensionRange::kEndFieldNumber);
    1385           1 :       end_location.StartAt(start_token);
    1386           1 :       end_location.EndAt(start_token);
    1387           1 :       end = start;
    1388             :     }
    1389             : 
    1390             :     // Users like to specify inclusive ranges, but in code we like the end
    1391             :     // number to be exclusive.
    1392          29 :     ++end;
    1393             : 
    1394          29 :     range->set_start(start);
    1395          58 :     range->set_end(end);
    1396             :   } while (TryConsume(","));
    1397             : 
    1398          29 :   DO(ConsumeEndOfDeclaration(";", &extensions_location));
    1399          29 :   return true;
    1400             : }
    1401             : 
    1402             : // This is similar to extension range parsing, except that "max" is not
    1403             : // supported, and accepts field name literals.
    1404           2 : bool Parser::ParseReserved(DescriptorProto* message,
    1405           2 :                            const LocationRecorder& message_location) {
    1406             :   // Parse the declaration.
    1407           2 :   DO(Consume("reserved"));
    1408           4 :   if (LookingAtType(io::Tokenizer::TYPE_STRING)) {
    1409             :     LocationRecorder location(message_location,
    1410           1 :                               DescriptorProto::kReservedNameFieldNumber);
    1411           1 :     return ParseReservedNames(message, location);
    1412             :   } else {
    1413             :     LocationRecorder location(message_location,
    1414           1 :                               DescriptorProto::kReservedRangeFieldNumber);
    1415           1 :     return ParseReservedNumbers(message, location);
    1416             :   }
    1417             : }
    1418             : 
    1419             : 
    1420           1 : bool Parser::ParseReservedNames(DescriptorProto* message,
    1421             :                                 const LocationRecorder& parent_location) {
    1422           2 :   do {
    1423           2 :     LocationRecorder location(parent_location, message->reserved_name_size());
    1424           2 :     DO(ConsumeString(message->add_reserved_name(), "Expected field name."));
    1425             :   } while (TryConsume(","));
    1426           1 :   DO(ConsumeEndOfDeclaration(";", &parent_location));
    1427           1 :   return true;
    1428             : }
    1429             : 
    1430           1 : bool Parser::ParseReservedNumbers(DescriptorProto* message,
    1431             :                                   const LocationRecorder& parent_location) {
    1432           1 :   bool first = true;
    1433           3 :   do {
    1434           3 :     LocationRecorder location(parent_location, message->reserved_range_size());
    1435             : 
    1436           3 :     DescriptorProto::ReservedRange* range = message->add_reserved_range();
    1437             :     int start, end;
    1438             :     io::Tokenizer::Token start_token;
    1439             :     {
    1440             :       LocationRecorder start_location(
    1441           3 :           location, DescriptorProto::ReservedRange::kStartFieldNumber);
    1442           3 :       start_token = input_->current();
    1443           3 :       DO(ConsumeInteger(&start, (first ?
    1444             :                                  "Expected field name or number range." :
    1445           3 :                                  "Expected field number range.")));
    1446             :     }
    1447             : 
    1448           3 :     if (TryConsume("to")) {
    1449             :       LocationRecorder end_location(
    1450           1 :           location, DescriptorProto::ReservedRange::kEndFieldNumber);
    1451           1 :       DO(ConsumeInteger(&end, "Expected integer."));
    1452             :     } else {
    1453             :       LocationRecorder end_location(
    1454           2 :           location, DescriptorProto::ReservedRange::kEndFieldNumber);
    1455           2 :       end_location.StartAt(start_token);
    1456           2 :       end_location.EndAt(start_token);
    1457           2 :       end = start;
    1458             :     }
    1459             : 
    1460             :     // Users like to specify inclusive ranges, but in code we like the end
    1461             :     // number to be exclusive.
    1462           3 :     ++end;
    1463             : 
    1464           3 :     range->set_start(start);
    1465           3 :     range->set_end(end);
    1466           6 :     first = false;
    1467             :   } while (TryConsume(","));
    1468             : 
    1469           1 :   DO(ConsumeEndOfDeclaration(";", &parent_location));
    1470           1 :   return true;
    1471             : }
    1472             : 
    1473          40 : bool Parser::ParseExtend(RepeatedPtrField<FieldDescriptorProto>* extensions,
    1474             :                          RepeatedPtrField<DescriptorProto>* messages,
    1475             :                          const LocationRecorder& parent_location,
    1476             :                          int location_field_number_for_nested_type,
    1477             :                          const LocationRecorder& extend_location,
    1478             :                          const FileDescriptorProto* containing_file) {
    1479          40 :   DO(Consume("extend"));
    1480             : 
    1481             :   // Parse the extendee type.
    1482          40 :   io::Tokenizer::Token extendee_start = input_->current();
    1483             :   string extendee;
    1484          40 :   DO(ParseUserDefinedType(&extendee));
    1485          40 :   io::Tokenizer::Token extendee_end = input_->previous();
    1486             : 
    1487             :   // Parse the block.
    1488          40 :   DO(ConsumeEndOfDeclaration("{", &extend_location));
    1489             : 
    1490             :   bool is_first = true;
    1491             : 
    1492         255 :   do {
    1493         255 :     if (AtEnd()) {
    1494           0 :       AddError("Reached end of input in extend definition (missing '}').");
    1495           0 :       return false;
    1496             :     }
    1497             : 
    1498             :     // Note that kExtensionFieldNumber was already pushed by the parent.
    1499         255 :     LocationRecorder location(extend_location, extensions->size());
    1500             : 
    1501         255 :     FieldDescriptorProto* field = extensions->Add();
    1502             : 
    1503             :     {
    1504             :       LocationRecorder extendee_location(
    1505         255 :           location, FieldDescriptorProto::kExtendeeFieldNumber);
    1506         255 :       extendee_location.StartAt(extendee_start);
    1507         255 :       extendee_location.EndAt(extendee_end);
    1508             : 
    1509         255 :       if (is_first) {
    1510             :         extendee_location.RecordLegacyLocation(
    1511          40 :             field, DescriptorPool::ErrorCollector::EXTENDEE);
    1512             :         is_first = false;
    1513         255 :       }
    1514             :     }
    1515             : 
    1516             :     field->set_extendee(extendee);
    1517             : 
    1518         255 :     if (!ParseMessageField(field, messages, parent_location,
    1519             :                            location_field_number_for_nested_type,
    1520             :                            location,
    1521         255 :                            containing_file)) {
    1522             :       // This statement failed to parse.  Skip it, but keep looping to parse
    1523             :       // other statements.
    1524           0 :       SkipStatement();
    1525         255 :     }
    1526         255 :   } while (!TryConsumeEndOfDeclaration("}", NULL));
    1527             : 
    1528             :   return true;
    1529             : }
    1530             : 
    1531          30 : bool Parser::ParseOneof(OneofDescriptorProto* oneof_decl,
    1532             :                         DescriptorProto* containing_type,
    1533             :                         int oneof_index,
    1534             :                         const LocationRecorder& oneof_location,
    1535             :                         const LocationRecorder& containing_type_location,
    1536         242 :                         const FileDescriptorProto* containing_file) {
    1537          30 :   DO(Consume("oneof"));
    1538             : 
    1539             :   {
    1540             :     LocationRecorder name_location(oneof_location,
    1541          30 :                                    OneofDescriptorProto::kNameFieldNumber);
    1542          30 :     DO(ConsumeIdentifier(oneof_decl->mutable_name(), "Expected oneof name."));
    1543             :   }
    1544             : 
    1545          30 :   DO(ConsumeEndOfDeclaration("{", &oneof_location));
    1546             : 
    1547         121 :   do {
    1548         121 :     if (AtEnd()) {
    1549           0 :       AddError("Reached end of input in oneof definition (missing '}').");
    1550           0 :       return false;
    1551             :     }
    1552             : 
    1553             :     // Print a nice error if the user accidentally tries to place a label
    1554             :     // on an individual member of a oneof.
    1555         363 :     if (LookingAt("required") ||
    1556         363 :         LookingAt("optional") ||
    1557         121 :         LookingAt("repeated")) {
    1558             :       AddError("Fields in oneofs must not have labels (required / optional "
    1559           0 :                "/ repeated).");
    1560             :       // We can continue parsing here because we understand what the user
    1561             :       // meant.  The error report will still make parsing fail overall.
    1562           0 :       input_->Next();
    1563             :     }
    1564             : 
    1565             :     LocationRecorder field_location(containing_type_location,
    1566             :                                     DescriptorProto::kFieldFieldNumber,
    1567         121 :                                     containing_type->field_size());
    1568             : 
    1569         121 :     FieldDescriptorProto* field = containing_type->add_field();
    1570             :     field->set_label(FieldDescriptorProto::LABEL_OPTIONAL);
    1571             :     field->set_oneof_index(oneof_index);
    1572             : 
    1573         121 :     if (!ParseMessageFieldNoLabel(field,
    1574             :                                   containing_type->mutable_nested_type(),
    1575             :                                   containing_type_location,
    1576             :                                   DescriptorProto::kNestedTypeFieldNumber,
    1577             :                                   field_location,
    1578         121 :                                   containing_file)) {
    1579             :       // This statement failed to parse.  Skip it, but keep looping to parse
    1580             :       // other statements.
    1581           0 :       SkipStatement();
    1582         121 :     }
    1583         121 :   } while (!TryConsumeEndOfDeclaration("}", NULL));
    1584             : 
    1585             :   return true;
    1586             : }
    1587             : 
    1588             : // -------------------------------------------------------------------
    1589             : // Enums
    1590             : 
    1591          77 : bool Parser::ParseEnumDefinition(EnumDescriptorProto* enum_type,
    1592             :                                  const LocationRecorder& enum_location,
    1593             :                                  const FileDescriptorProto* containing_file) {
    1594          77 :   DO(Consume("enum"));
    1595             : 
    1596             :   {
    1597             :     LocationRecorder location(enum_location,
    1598          77 :                               EnumDescriptorProto::kNameFieldNumber);
    1599             :     location.RecordLegacyLocation(
    1600          77 :         enum_type, DescriptorPool::ErrorCollector::NAME);
    1601          77 :     DO(ConsumeIdentifier(enum_type->mutable_name(), "Expected enum name."));
    1602             :   }
    1603             : 
    1604          77 :   DO(ParseEnumBlock(enum_type, enum_location, containing_file));
    1605          77 :   return true;
    1606             : }
    1607             : 
    1608          77 : bool Parser::ParseEnumBlock(EnumDescriptorProto* enum_type,
    1609             :                             const LocationRecorder& enum_location,
    1610             :                             const FileDescriptorProto* containing_file) {
    1611          77 :   DO(ConsumeEndOfDeclaration("{", &enum_location));
    1612             : 
    1613         340 :   while (!TryConsumeEndOfDeclaration("}", NULL)) {
    1614         263 :     if (AtEnd()) {
    1615           0 :       AddError("Reached end of input in enum definition (missing '}').");
    1616           0 :       return false;
    1617             :     }
    1618             : 
    1619         263 :     if (!ParseEnumStatement(enum_type, enum_location, containing_file)) {
    1620             :       // This statement failed to parse.  Skip it, but keep looping to parse
    1621             :       // other statements.
    1622           0 :       SkipStatement();
    1623             :     }
    1624             :   }
    1625             : 
    1626             :   return true;
    1627             : }
    1628             : 
    1629         263 : bool Parser::ParseEnumStatement(EnumDescriptorProto* enum_type,
    1630             :                                 const LocationRecorder& enum_location,
    1631         263 :                                 const FileDescriptorProto* containing_file) {
    1632         263 :   if (TryConsumeEndOfDeclaration(";", NULL)) {
    1633             :     // empty statement; ignore
    1634             :     return true;
    1635         526 :   } else if (LookingAt("option")) {
    1636             :     LocationRecorder location(enum_location,
    1637           4 :                               EnumDescriptorProto::kOptionsFieldNumber);
    1638           4 :     return ParseOption(enum_type->mutable_options(), location,
    1639           4 :                        containing_file, OPTION_STATEMENT);
    1640             :   } else {
    1641             :     LocationRecorder location(enum_location,
    1642         259 :         EnumDescriptorProto::kValueFieldNumber, enum_type->value_size());
    1643         259 :     return ParseEnumConstant(enum_type->add_value(), location, containing_file);
    1644             :   }
    1645             : }
    1646             : 
    1647         259 : bool Parser::ParseEnumConstant(EnumValueDescriptorProto* enum_value,
    1648             :                                const LocationRecorder& enum_value_location,
    1649             :                                const FileDescriptorProto* containing_file) {
    1650             :   // Parse name.
    1651             :   {
    1652             :     LocationRecorder location(enum_value_location,
    1653         259 :                               EnumValueDescriptorProto::kNameFieldNumber);
    1654             :     location.RecordLegacyLocation(
    1655         259 :         enum_value, DescriptorPool::ErrorCollector::NAME);
    1656         259 :     DO(ConsumeIdentifier(enum_value->mutable_name(),
    1657         259 :                          "Expected enum constant name."));
    1658             :   }
    1659             : 
    1660         259 :   DO(Consume("=", "Missing numeric value for enum constant."));
    1661             : 
    1662             :   // Parse value.
    1663             :   {
    1664             :     LocationRecorder location(
    1665         259 :         enum_value_location, EnumValueDescriptorProto::kNumberFieldNumber);
    1666             :     location.RecordLegacyLocation(
    1667         259 :         enum_value, DescriptorPool::ErrorCollector::NUMBER);
    1668             : 
    1669             :     int number;
    1670         259 :     DO(ConsumeSignedInteger(&number, "Expected integer."));
    1671         518 :     enum_value->set_number(number);
    1672             :   }
    1673             : 
    1674         259 :   DO(ParseEnumConstantOptions(enum_value, enum_value_location,
    1675             :                               containing_file));
    1676             : 
    1677         259 :   DO(ConsumeEndOfDeclaration(";", &enum_value_location));
    1678             : 
    1679         259 :   return true;
    1680             : }
    1681             : 
    1682         259 : bool Parser::ParseEnumConstantOptions(
    1683             :     EnumValueDescriptorProto* value,
    1684             :     const LocationRecorder& enum_value_location,
    1685         259 :     const FileDescriptorProto* containing_file) {
    1686         518 :   if (!LookingAt("[")) return true;
    1687             : 
    1688             :   LocationRecorder location(
    1689           3 :       enum_value_location, EnumValueDescriptorProto::kOptionsFieldNumber);
    1690             : 
    1691           3 :   DO(Consume("["));
    1692             : 
    1693           3 :   do {
    1694           3 :     DO(ParseOption(value->mutable_options(), location,
    1695             :                    containing_file, OPTION_ASSIGNMENT));
    1696             :   } while (TryConsume(","));
    1697             : 
    1698           3 :   DO(Consume("]"));
    1699           3 :   return true;
    1700             : }
    1701             : 
    1702             : // -------------------------------------------------------------------
    1703             : // Services
    1704             : 
    1705          34 : bool Parser::ParseServiceDefinition(
    1706             :     ServiceDescriptorProto* service,
    1707             :     const LocationRecorder& service_location,
    1708             :     const FileDescriptorProto* containing_file) {
    1709          34 :   DO(Consume("service"));
    1710             : 
    1711             :   {
    1712             :     LocationRecorder location(service_location,
    1713          34 :                               ServiceDescriptorProto::kNameFieldNumber);
    1714             :     location.RecordLegacyLocation(
    1715          34 :         service, DescriptorPool::ErrorCollector::NAME);
    1716          34 :     DO(ConsumeIdentifier(service->mutable_name(), "Expected service name."));
    1717             :   }
    1718             : 
    1719          34 :   DO(ParseServiceBlock(service, service_location, containing_file));
    1720          34 :   return true;
    1721             : }
    1722             : 
    1723          34 : bool Parser::ParseServiceBlock(ServiceDescriptorProto* service,
    1724             :                                const LocationRecorder& service_location,
    1725             :                                const FileDescriptorProto* containing_file) {
    1726          34 :   DO(ConsumeEndOfDeclaration("{", &service_location));
    1727             : 
    1728         100 :   while (!TryConsumeEndOfDeclaration("}", NULL)) {
    1729          66 :     if (AtEnd()) {
    1730           0 :       AddError("Reached end of input in service definition (missing '}').");
    1731           0 :       return false;
    1732             :     }
    1733             : 
    1734          66 :     if (!ParseServiceStatement(service, service_location, containing_file)) {
    1735             :       // This statement failed to parse.  Skip it, but keep looping to parse
    1736             :       // other statements.
    1737           0 :       SkipStatement();
    1738             :     }
    1739             :   }
    1740             : 
    1741             :   return true;
    1742             : }
    1743             : 
    1744          66 : bool Parser::ParseServiceStatement(ServiceDescriptorProto* service,
    1745             :                                    const LocationRecorder& service_location,
    1746          66 :                                    const FileDescriptorProto* containing_file) {
    1747          66 :   if (TryConsumeEndOfDeclaration(";", NULL)) {
    1748             :     // empty statement; ignore
    1749             :     return true;
    1750         132 :   } else if (LookingAt("option")) {
    1751             :     LocationRecorder location(
    1752           2 :         service_location, ServiceDescriptorProto::kOptionsFieldNumber);
    1753           2 :     return ParseOption(service->mutable_options(), location,
    1754           2 :                        containing_file, OPTION_STATEMENT);
    1755             :   } else {
    1756             :     LocationRecorder location(service_location,
    1757          64 :         ServiceDescriptorProto::kMethodFieldNumber, service->method_size());
    1758          64 :     return ParseServiceMethod(service->add_method(), location, containing_file);
    1759             :   }
    1760             : }
    1761             : 
    1762          64 : bool Parser::ParseServiceMethod(MethodDescriptorProto* method,
    1763             :                                 const LocationRecorder& method_location,
    1764         192 :                                 const FileDescriptorProto* containing_file) {
    1765          64 :   DO(Consume("rpc"));
    1766             : 
    1767             :   {
    1768             :     LocationRecorder location(method_location,
    1769          64 :                               MethodDescriptorProto::kNameFieldNumber);
    1770             :     location.RecordLegacyLocation(
    1771          64 :         method, DescriptorPool::ErrorCollector::NAME);
    1772          64 :     DO(ConsumeIdentifier(method->mutable_name(), "Expected method name."));
    1773             :   }
    1774             : 
    1775             :   // Parse input type.
    1776          64 :   DO(Consume("("));
    1777             :   {
    1778         128 :     if (LookingAt("stream")) {
    1779             :       LocationRecorder location(
    1780          22 :           method_location, MethodDescriptorProto::kClientStreamingFieldNumber);
    1781             :       location.RecordLegacyLocation(
    1782          22 :           method, DescriptorPool::ErrorCollector::OTHER);
    1783             :       method->set_client_streaming(true);
    1784          22 :       DO(Consume("stream"));
    1785             : 
    1786             :     }
    1787             :     LocationRecorder location(method_location,
    1788          64 :                               MethodDescriptorProto::kInputTypeFieldNumber);
    1789             :     location.RecordLegacyLocation(
    1790          64 :         method, DescriptorPool::ErrorCollector::INPUT_TYPE);
    1791          64 :     DO(ParseUserDefinedType(method->mutable_input_type()));
    1792             :   }
    1793          64 :   DO(Consume(")"));
    1794             : 
    1795             :   // Parse output type.
    1796          64 :   DO(Consume("returns"));
    1797          64 :   DO(Consume("("));
    1798             :   {
    1799         128 :     if (LookingAt("stream")) {
    1800             :       LocationRecorder location(
    1801          22 :           method_location, MethodDescriptorProto::kServerStreamingFieldNumber);
    1802             :       location.RecordLegacyLocation(
    1803          22 :           method, DescriptorPool::ErrorCollector::OTHER);
    1804          22 :       DO(Consume("stream"));
    1805          22 :       method->set_server_streaming(true);
    1806             : 
    1807             :     }
    1808             :     LocationRecorder location(method_location,
    1809          64 :                               MethodDescriptorProto::kOutputTypeFieldNumber);
    1810             :     location.RecordLegacyLocation(
    1811          64 :         method, DescriptorPool::ErrorCollector::OUTPUT_TYPE);
    1812          64 :     DO(ParseUserDefinedType(method->mutable_output_type()));
    1813             :   }
    1814          64 :   DO(Consume(")"));
    1815             : 
    1816         128 :   if (LookingAt("{")) {
    1817             :     // Options!
    1818           4 :     DO(ParseMethodOptions(method_location, containing_file,
    1819             :                           MethodDescriptorProto::kOptionsFieldNumber,
    1820             :                           method->mutable_options()));
    1821             :   } else {
    1822          60 :     DO(ConsumeEndOfDeclaration(";", &method_location));
    1823             :   }
    1824             : 
    1825             :   return true;
    1826             : }
    1827             : 
    1828             : 
    1829           4 : bool Parser::ParseMethodOptions(const LocationRecorder& parent_location,
    1830             :                                 const FileDescriptorProto* containing_file,
    1831             :                                 const int optionsFieldNumber,
    1832             :                                 Message* mutable_options) {
    1833             :   // Options!
    1834           4 :   ConsumeEndOfDeclaration("{", &parent_location);
    1835          10 :   while (!TryConsumeEndOfDeclaration("}", NULL)) {
    1836           2 :     if (AtEnd()) {
    1837           0 :       AddError("Reached end of input in method options (missing '}').");
    1838           0 :       return false;
    1839             :     }
    1840             : 
    1841           2 :     if (TryConsumeEndOfDeclaration(";", NULL)) {
    1842             :       // empty statement; ignore
    1843             :     } else {
    1844             :       LocationRecorder location(parent_location,
    1845           2 :                                 optionsFieldNumber);
    1846           2 :       if (!ParseOption(mutable_options, location,
    1847           2 :                        containing_file, OPTION_STATEMENT)) {
    1848             :         // This statement failed to parse.  Skip it, but keep looping to
    1849             :         // parse other statements.
    1850           0 :         SkipStatement();
    1851           2 :       }
    1852             :     }
    1853             :   }
    1854             : 
    1855             :   return true;
    1856             : }
    1857             : 
    1858             : // -------------------------------------------------------------------
    1859             : 
    1860        2910 : bool Parser::ParseLabel(FieldDescriptorProto::Label* label,
    1861             :                         const FileDescriptorProto* containing_file) {
    1862        2910 :   if (TryConsume("optional")) {
    1863        1625 :     *label = FieldDescriptorProto::LABEL_OPTIONAL;
    1864        1625 :     return true;
    1865        1285 :   } else if (TryConsume("repeated")) {
    1866         498 :     *label = FieldDescriptorProto::LABEL_REPEATED;
    1867         498 :     return true;
    1868         787 :   } else if (TryConsume("required")) {
    1869          15 :     *label = FieldDescriptorProto::LABEL_REQUIRED;
    1870          15 :     return true;
    1871             :   }
    1872             :   return false;
    1873             : }
    1874             : 
    1875        3155 : bool Parser::ParseType(FieldDescriptorProto::Type* type,
    1876             :                        string* type_name) {
    1877        3155 :   TypeNameMap::const_iterator iter = kTypeNames.find(input_->current().text);
    1878        6310 :   if (iter != kTypeNames.end()) {
    1879        4912 :     *type = iter->second;
    1880        2456 :     input_->Next();
    1881             :   } else {
    1882         699 :     DO(ParseUserDefinedType(type_name));
    1883             :   }
    1884             :   return true;
    1885             : }
    1886             : 
    1887         867 : bool Parser::ParseUserDefinedType(string* type_name) {
    1888             :   type_name->clear();
    1889             : 
    1890         867 :   TypeNameMap::const_iterator iter = kTypeNames.find(input_->current().text);
    1891        1734 :   if (iter != kTypeNames.end()) {
    1892             :     // Note:  The only place enum types are allowed is for field types, but
    1893             :     //   if we are parsing a field type then we would not get here because
    1894             :     //   primitives are allowed there as well.  So this error message doesn't
    1895             :     //   need to account for enums.
    1896           0 :     AddError("Expected message type.");
    1897             : 
    1898             :     // Pretend to accept this type so that we can go on parsing.
    1899           0 :     *type_name = input_->current().text;
    1900           0 :     input_->Next();
    1901             :     return true;
    1902             :   }
    1903             : 
    1904             :   // A leading "." means the name is fully-qualified.
    1905         867 :   if (TryConsume(".")) type_name->append(".");
    1906             : 
    1907             :   // Consume the first part of the name.
    1908             :   string identifier;
    1909         867 :   DO(ConsumeIdentifier(&identifier, "Expected type name."));
    1910         867 :   type_name->append(identifier);
    1911             : 
    1912             :   // Consume more parts.
    1913        1281 :   while (TryConsume(".")) {
    1914         414 :     type_name->append(".");
    1915         414 :     DO(ConsumeIdentifier(&identifier, "Expected identifier."));
    1916         414 :     type_name->append(identifier);
    1917             :   }
    1918             : 
    1919             :   return true;
    1920             : }
    1921             : 
    1922             : // ===================================================================
    1923             : 
    1924          77 : bool Parser::ParsePackage(FileDescriptorProto* file,
    1925             :                           const LocationRecorder& root_location,
    1926             :                           const FileDescriptorProto* containing_file) {
    1927         154 :   if (file->has_package()) {
    1928           0 :     AddError("Multiple package definitions.");
    1929             :     // Don't append the new package to the old one.  Just replace it.  Not
    1930             :     // that it really matters since this is an error anyway.
    1931             :     file->clear_package();
    1932             :   }
    1933             : 
    1934          77 :   DO(Consume("package"));
    1935             : 
    1936             :   {
    1937             :     LocationRecorder location(root_location,
    1938          77 :                               FileDescriptorProto::kPackageFieldNumber);
    1939          77 :     location.RecordLegacyLocation(file, DescriptorPool::ErrorCollector::NAME);
    1940             : 
    1941             :     while (true) {
    1942             :       string identifier;
    1943         162 :       DO(ConsumeIdentifier(&identifier, "Expected identifier."));
    1944         162 :       file->mutable_package()->append(identifier);
    1945         162 :       if (!TryConsume(".")) break;
    1946          85 :       file->mutable_package()->append(".");
    1947             :     }
    1948             : 
    1949          77 :     location.EndAt(input_->previous());
    1950             : 
    1951          77 :     DO(ConsumeEndOfDeclaration(";", &location));
    1952             :   }
    1953             : 
    1954          77 :   return true;
    1955             : }
    1956             : 
    1957          60 : bool Parser::ParseImport(RepeatedPtrField<string>* dependency,
    1958           2 :                          RepeatedField<int32>* public_dependency,
    1959           0 :                          RepeatedField<int32>* weak_dependency,
    1960             :                          const LocationRecorder& root_location,
    1961         118 :                          const FileDescriptorProto* containing_file) {
    1962          60 :   DO(Consume("import"));
    1963         120 :   if (LookingAt("public")) {
    1964             :     LocationRecorder location(
    1965             :         root_location, FileDescriptorProto::kPublicDependencyFieldNumber,
    1966           2 :         public_dependency->size());
    1967           2 :     DO(Consume("public"));
    1968           4 :     *public_dependency->Add() = dependency->size();
    1969         116 :   } else if (LookingAt("weak")) {
    1970             :     LocationRecorder location(
    1971             :         root_location, FileDescriptorProto::kWeakDependencyFieldNumber,
    1972           0 :         weak_dependency->size());
    1973           0 :     DO(Consume("weak"));
    1974           0 :     *weak_dependency->Add() = dependency->size();
    1975             :   }
    1976             :   {
    1977             :     LocationRecorder location(root_location,
    1978             :                               FileDescriptorProto::kDependencyFieldNumber,
    1979          60 :                               dependency->size());
    1980          60 :     DO(ConsumeString(dependency->Add(),
    1981             :       "Expected a string naming the file to import."));
    1982             : 
    1983          60 :     location.EndAt(input_->previous());
    1984             : 
    1985          60 :     DO(ConsumeEndOfDeclaration(";", &location));
    1986             :   }
    1987          60 :   return true;
    1988             : }
    1989             : 
    1990             : // ===================================================================
    1991             : 
    1992          34 : SourceLocationTable::SourceLocationTable() {}
    1993          34 : SourceLocationTable::~SourceLocationTable() {}
    1994             : 
    1995           0 : bool SourceLocationTable::Find(
    1996             :     const Message* descriptor,
    1997             :     DescriptorPool::ErrorCollector::ErrorLocation location,
    1998             :     int* line, int* column) const {
    1999             :   const pair<int, int>* result =
    2000           0 :       FindOrNull(location_map_, std::make_pair(descriptor, location));
    2001           0 :   if (result == NULL) {
    2002           0 :     *line   = -1;
    2003           0 :     *column = 0;
    2004           0 :     return false;
    2005             :   } else {
    2006           0 :     *line   = result->first;
    2007           0 :     *column = result->second;
    2008           0 :     return true;
    2009             :   }
    2010             : }
    2011             : 
    2012       12526 : void SourceLocationTable::Add(
    2013             :     const Message* descriptor,
    2014             :     DescriptorPool::ErrorCollector::ErrorLocation location,
    2015             :     int line, int column) {
    2016       25052 :   location_map_[std::make_pair(descriptor, location)] =
    2017       12526 :       std::make_pair(line, column);
    2018       12526 : }
    2019             : 
    2020           0 : void SourceLocationTable::Clear() {
    2021           0 :   location_map_.clear();
    2022           0 : }
    2023             : 
    2024             : }  // namespace compiler
    2025             : }  // namespace protobuf
    2026          51 : }  // namespace google

Generated by: LCOV version 1.10