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