diff options
Diffstat (limited to 'src/google/protobuf/compiler/parser.cc')
-rw-r--r-- | src/google/protobuf/compiler/parser.cc | 1158 |
1 files changed, 269 insertions, 889 deletions
diff --git a/src/google/protobuf/compiler/parser.cc b/src/google/protobuf/compiler/parser.cc index 474a8f8..758f70d 100644 --- a/src/google/protobuf/compiler/parser.cc +++ b/src/google/protobuf/compiler/parser.cc @@ -1,6 +1,6 @@ // Protocol Buffers - Google's data interchange format // Copyright 2008 Google Inc. All rights reserved. -// https://developers.google.com/protocol-buffers/ +// http://code.google.com/p/protobuf/ // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are @@ -46,7 +46,7 @@ #include <google/protobuf/io/tokenizer.h> #include <google/protobuf/stubs/common.h> #include <google/protobuf/stubs/strutil.h> -#include <google/protobuf/stubs/map_util.h> +#include <google/protobuf/stubs/map-util.h> namespace google { namespace protobuf { @@ -174,20 +174,6 @@ bool Parser::ConsumeInteger(int* output, const char* error) { } } -bool Parser::ConsumeSignedInteger(int* output, const char* error) { - bool is_negative = false; - uint64 max_value = kint32max; - if (TryConsume("-")) { - is_negative = true; - max_value += 1; - } - uint64 value = 0; - DO(ConsumeInteger64(max_value, &value, error)); - if (is_negative) value *= -1; - *output = value; - return true; -} - bool Parser::ConsumeInteger64(uint64 max_value, uint64* output, const char* error) { if (LookingAtType(io::Tokenizer::TYPE_INTEGER)) { @@ -251,35 +237,6 @@ bool Parser::ConsumeString(string* output, const char* error) { } } -bool Parser::TryConsumeEndOfDeclaration(const char* text, - const LocationRecorder* location) { - if (LookingAt(text)) { - string leading, trailing; - input_->NextWithComments(&trailing, NULL, &leading); - - // Save the leading comments for next time, and recall the leading comments - // from last time. - leading.swap(upcoming_doc_comments_); - - if (location != NULL) { - location->AttachComments(&leading, &trailing); - } - return true; - } else { - return false; - } -} - -bool Parser::ConsumeEndOfDeclaration(const char* text, - const LocationRecorder* location) { - if (TryConsumeEndOfDeclaration(text, location)) { - return true; - } else { - AddError("Expected \"" + string(text) + "\"."); - return false; - } -} - // ------------------------------------------------------------------- void Parser::AddError(int line, int column, const string& error) { @@ -293,87 +250,20 @@ void Parser::AddError(const string& error) { AddError(input_->current().line, input_->current().column, error); } -// ------------------------------------------------------------------- - -Parser::LocationRecorder::LocationRecorder(Parser* parser) - : parser_(parser), - location_(parser_->source_code_info_->add_location()) { - location_->add_span(parser_->input_->current().line); - location_->add_span(parser_->input_->current().column); -} - -Parser::LocationRecorder::LocationRecorder(const LocationRecorder& parent) { - Init(parent); -} - -Parser::LocationRecorder::LocationRecorder(const LocationRecorder& parent, - int path1) { - Init(parent); - AddPath(path1); -} - -Parser::LocationRecorder::LocationRecorder(const LocationRecorder& parent, - int path1, int path2) { - Init(parent); - AddPath(path1); - AddPath(path2); -} - -void Parser::LocationRecorder::Init(const LocationRecorder& parent) { - parser_ = parent.parser_; - location_ = parser_->source_code_info_->add_location(); - location_->mutable_path()->CopyFrom(parent.location_->path()); - - location_->add_span(parser_->input_->current().line); - location_->add_span(parser_->input_->current().column); -} - -Parser::LocationRecorder::~LocationRecorder() { - if (location_->span_size() <= 2) { - EndAt(parser_->input_->previous()); - } -} - -void Parser::LocationRecorder::AddPath(int path_component) { - location_->add_path(path_component); -} - -void Parser::LocationRecorder::StartAt(const io::Tokenizer::Token& token) { - location_->set_span(0, token.line); - location_->set_span(1, token.column); -} - -void Parser::LocationRecorder::StartAt(const LocationRecorder& other) { - location_->set_span(0, other.location_->span(0)); - location_->set_span(1, other.location_->span(1)); -} - -void Parser::LocationRecorder::EndAt(const io::Tokenizer::Token& token) { - if (token.line != location_->span(0)) { - location_->add_span(token.line); +void Parser::RecordLocation( + const Message* descriptor, + DescriptorPool::ErrorCollector::ErrorLocation location, + int line, int column) { + if (source_location_table_ != NULL) { + source_location_table_->Add(descriptor, location, line, column); } - location_->add_span(token.end_column); } -void Parser::LocationRecorder::RecordLegacyLocation(const Message* descriptor, +void Parser::RecordLocation( + const Message* descriptor, DescriptorPool::ErrorCollector::ErrorLocation location) { - if (parser_->source_location_table_ != NULL) { - parser_->source_location_table_->Add( - descriptor, location, location_->span(0), location_->span(1)); - } -} - -void Parser::LocationRecorder::AttachComments( - string* leading, string* trailing) const { - GOOGLE_CHECK(!location_->has_leading_comments()); - GOOGLE_CHECK(!location_->has_trailing_comments()); - - if (!leading->empty()) { - location_->mutable_leading_comments()->swap(*leading); - } - if (!trailing->empty()) { - location_->mutable_trailing_comments()->swap(*trailing); - } + RecordLocation(descriptor, location, + input_->current().line, input_->current().column); } // ------------------------------------------------------------------- @@ -383,7 +273,7 @@ void Parser::SkipStatement() { if (AtEnd()) { return; } else if (LookingAtType(io::Tokenizer::TYPE_SYMBOL)) { - if (TryConsumeEndOfDeclaration(";", NULL)) { + if (TryConsume(";")) { return; } else if (TryConsume("{")) { SkipRestOfBlock(); @@ -401,7 +291,7 @@ void Parser::SkipRestOfBlock() { if (AtEnd()) { return; } else if (LookingAtType(io::Tokenizer::TYPE_SYMBOL)) { - if (TryConsumeEndOfDeclaration("}", NULL)) { + if (TryConsume("}")) { return; } else if (TryConsume("{")) { SkipRestOfBlock(); @@ -418,51 +308,38 @@ bool Parser::Parse(io::Tokenizer* input, FileDescriptorProto* file) { had_errors_ = false; syntax_identifier_.clear(); - // Note that |file| could be NULL at this point if - // stop_after_syntax_identifier_ is true. So, we conservatively allocate - // SourceCodeInfo on the stack, then swap it into the FileDescriptorProto - // later on. - SourceCodeInfo source_code_info; - source_code_info_ = &source_code_info; - if (LookingAtType(io::Tokenizer::TYPE_START)) { // Advance to first token. - input_->NextWithComments(NULL, NULL, &upcoming_doc_comments_); + input_->Next(); } - { - LocationRecorder root_location(this); - - if (require_syntax_identifier_ || LookingAt("syntax")) { - if (!ParseSyntaxIdentifier()) { - // Don't attempt to parse the file if we didn't recognize the syntax - // identifier. - return false; - } - } else if (!stop_after_syntax_identifier_) { - syntax_identifier_ = "proto2"; + if (require_syntax_identifier_ || LookingAt("syntax")) { + if (!ParseSyntaxIdentifier()) { + // Don't attempt to parse the file if we didn't recognize the syntax + // identifier. + return false; } + } else if (!stop_after_syntax_identifier_) { + syntax_identifier_ = "proto2"; + } - if (stop_after_syntax_identifier_) return !had_errors_; + if (stop_after_syntax_identifier_) return !had_errors_; - // Repeatedly parse statements until we reach the end of the file. - while (!AtEnd()) { - if (!ParseTopLevelStatement(file, root_location)) { - // This statement failed to parse. Skip it, but keep looping to parse - // other statements. - SkipStatement(); + // Repeatedly parse statements until we reach the end of the file. + while (!AtEnd()) { + if (!ParseTopLevelStatement(file)) { + // This statement failed to parse. Skip it, but keep looping to parse + // other statements. + SkipStatement(); - if (LookingAt("}")) { - AddError("Unmatched \"}\"."); - input_->NextWithComments(NULL, NULL, &upcoming_doc_comments_); - } + if (LookingAt("}")) { + AddError("Unmatched \"}\"."); + input_->Next(); } } } input_ = NULL; - source_code_info_ = NULL; - source_code_info.Swap(file->mutable_source_code_info()); return !had_errors_; } @@ -472,7 +349,7 @@ bool Parser::ParseSyntaxIdentifier() { io::Tokenizer::Token syntax_token = input_->current(); string syntax; DO(ConsumeString(&syntax, "Expected syntax identifier.")); - DO(ConsumeEndOfDeclaration(";", NULL)); + DO(Consume(";")); syntax_identifier_ = syntax; @@ -486,43 +363,25 @@ bool Parser::ParseSyntaxIdentifier() { return true; } -bool Parser::ParseTopLevelStatement(FileDescriptorProto* file, - const LocationRecorder& root_location) { - if (TryConsumeEndOfDeclaration(";", NULL)) { +bool Parser::ParseTopLevelStatement(FileDescriptorProto* file) { + if (TryConsume(";")) { // empty statement; ignore return true; } else if (LookingAt("message")) { - LocationRecorder location(root_location, - FileDescriptorProto::kMessageTypeFieldNumber, file->message_type_size()); - return ParseMessageDefinition(file->add_message_type(), location, file); + return ParseMessageDefinition(file->add_message_type()); } else if (LookingAt("enum")) { - LocationRecorder location(root_location, - FileDescriptorProto::kEnumTypeFieldNumber, file->enum_type_size()); - return ParseEnumDefinition(file->add_enum_type(), location, file); + return ParseEnumDefinition(file->add_enum_type()); } else if (LookingAt("service")) { - LocationRecorder location(root_location, - FileDescriptorProto::kServiceFieldNumber, file->service_size()); - return ParseServiceDefinition(file->add_service(), location, file); + return ParseServiceDefinition(file->add_service()); } else if (LookingAt("extend")) { - LocationRecorder location(root_location, - FileDescriptorProto::kExtensionFieldNumber); return ParseExtend(file->mutable_extension(), - file->mutable_message_type(), - root_location, - FileDescriptorProto::kMessageTypeFieldNumber, - location, file); + file->mutable_message_type()); } else if (LookingAt("import")) { - return ParseImport(file->mutable_dependency(), - file->mutable_public_dependency(), - file->mutable_weak_dependency(), - root_location, file); + return ParseImport(file->add_dependency()); } else if (LookingAt("package")) { - return ParsePackage(file, root_location, file); + return ParsePackage(file); } else if (LookingAt("option")) { - LocationRecorder location(root_location, - FileDescriptorProto::kOptionsFieldNumber); - return ParseOption(file->mutable_options(), location, file, - OPTION_STATEMENT); + return ParseOption(file->mutable_options()); } else { AddError("Expected top-level statement (e.g. \"message\")."); return false; @@ -532,234 +391,93 @@ bool Parser::ParseTopLevelStatement(FileDescriptorProto* file, // ------------------------------------------------------------------- // Messages -bool Parser::ParseMessageDefinition( - DescriptorProto* message, - const LocationRecorder& message_location, - const FileDescriptorProto* containing_file) { +bool Parser::ParseMessageDefinition(DescriptorProto* message) { DO(Consume("message")); - { - LocationRecorder location(message_location, - DescriptorProto::kNameFieldNumber); - location.RecordLegacyLocation( - message, DescriptorPool::ErrorCollector::NAME); - DO(ConsumeIdentifier(message->mutable_name(), "Expected message name.")); - } - DO(ParseMessageBlock(message, message_location, containing_file)); + RecordLocation(message, DescriptorPool::ErrorCollector::NAME); + DO(ConsumeIdentifier(message->mutable_name(), "Expected message name.")); + DO(ParseMessageBlock(message)); return true; } -namespace { - -const int kMaxExtensionRangeSentinel = -1; - -bool IsMessageSetWireFormatMessage(const DescriptorProto& message) { - const MessageOptions& options = message.options(); - for (int i = 0; i < options.uninterpreted_option_size(); ++i) { - const UninterpretedOption& uninterpreted = options.uninterpreted_option(i); - if (uninterpreted.name_size() == 1 && - uninterpreted.name(0).name_part() == "message_set_wire_format" && - uninterpreted.identifier_value() == "true") { - return true; - } - } - return false; -} - -// Modifies any extension ranges that specified 'max' as the end of the -// extension range, and sets them to the type-specific maximum. The actual max -// tag number can only be determined after all options have been parsed. -void AdjustExtensionRangesWithMaxEndNumber(DescriptorProto* message) { - const bool is_message_set = IsMessageSetWireFormatMessage(*message); - const int max_extension_number = is_message_set ? - kint32max : - FieldDescriptor::kMaxNumber + 1; - for (int i = 0; i < message->extension_range_size(); ++i) { - if (message->extension_range(i).end() == kMaxExtensionRangeSentinel) { - message->mutable_extension_range(i)->set_end(max_extension_number); - } - } -} - -} // namespace - -bool Parser::ParseMessageBlock(DescriptorProto* message, - const LocationRecorder& message_location, - const FileDescriptorProto* containing_file) { - DO(ConsumeEndOfDeclaration("{", &message_location)); +bool Parser::ParseMessageBlock(DescriptorProto* message) { + DO(Consume("{")); - while (!TryConsumeEndOfDeclaration("}", NULL)) { + while (!TryConsume("}")) { if (AtEnd()) { AddError("Reached end of input in message definition (missing '}')."); return false; } - if (!ParseMessageStatement(message, message_location, containing_file)) { + if (!ParseMessageStatement(message)) { // This statement failed to parse. Skip it, but keep looping to parse // other statements. SkipStatement(); } } - if (message->extension_range_size() > 0) { - AdjustExtensionRangesWithMaxEndNumber(message); - } return true; } -bool Parser::ParseMessageStatement(DescriptorProto* message, - const LocationRecorder& message_location, - const FileDescriptorProto* containing_file) { - if (TryConsumeEndOfDeclaration(";", NULL)) { +bool Parser::ParseMessageStatement(DescriptorProto* message) { + if (TryConsume(";")) { // empty statement; ignore return true; } else if (LookingAt("message")) { - LocationRecorder location(message_location, - DescriptorProto::kNestedTypeFieldNumber, - message->nested_type_size()); - return ParseMessageDefinition(message->add_nested_type(), location, - containing_file); + return ParseMessageDefinition(message->add_nested_type()); } else if (LookingAt("enum")) { - LocationRecorder location(message_location, - DescriptorProto::kEnumTypeFieldNumber, - message->enum_type_size()); - return ParseEnumDefinition(message->add_enum_type(), location, - containing_file); + return ParseEnumDefinition(message->add_enum_type()); } else if (LookingAt("extensions")) { - LocationRecorder location(message_location, - DescriptorProto::kExtensionRangeFieldNumber); - return ParseExtensions(message, location, containing_file); + return ParseExtensions(message); } else if (LookingAt("extend")) { - LocationRecorder location(message_location, - DescriptorProto::kExtensionFieldNumber); return ParseExtend(message->mutable_extension(), - message->mutable_nested_type(), - message_location, - DescriptorProto::kNestedTypeFieldNumber, - location, containing_file); + message->mutable_nested_type()); } else if (LookingAt("option")) { - LocationRecorder location(message_location, - DescriptorProto::kOptionsFieldNumber); - return ParseOption(message->mutable_options(), location, - containing_file, OPTION_STATEMENT); - } else if (LookingAt("oneof")) { - int oneof_index = message->oneof_decl_size(); - LocationRecorder oneof_location(message_location, - DescriptorProto::kOneofDeclFieldNumber, - oneof_index); - - return ParseOneof(message->add_oneof_decl(), message, - oneof_index, oneof_location, message_location, - containing_file); + return ParseOption(message->mutable_options()); } else { - LocationRecorder location(message_location, - DescriptorProto::kFieldFieldNumber, - message->field_size()); return ParseMessageField(message->add_field(), - message->mutable_nested_type(), - message_location, - DescriptorProto::kNestedTypeFieldNumber, - location, - containing_file); + message->mutable_nested_type()); } } bool Parser::ParseMessageField(FieldDescriptorProto* field, - RepeatedPtrField<DescriptorProto>* messages, - const LocationRecorder& parent_location, - int location_field_number_for_nested_type, - const LocationRecorder& field_location, - const FileDescriptorProto* containing_file) { - { - LocationRecorder location(field_location, - FieldDescriptorProto::kLabelFieldNumber); - FieldDescriptorProto::Label label; - DO(ParseLabel(&label, containing_file)); - field->set_label(label); - } - - return ParseMessageFieldNoLabel(field, messages, parent_location, - location_field_number_for_nested_type, - field_location, - containing_file); -} - -bool Parser::ParseMessageFieldNoLabel( - FieldDescriptorProto* field, - RepeatedPtrField<DescriptorProto>* messages, - const LocationRecorder& parent_location, - int location_field_number_for_nested_type, - const LocationRecorder& field_location, - const FileDescriptorProto* containing_file) { - // Parse type. - { - LocationRecorder location(field_location); // add path later - location.RecordLegacyLocation(field, DescriptorPool::ErrorCollector::TYPE); - - FieldDescriptorProto::Type type = FieldDescriptorProto::TYPE_INT32; - string type_name; - DO(ParseType(&type, &type_name)); - if (type_name.empty()) { - location.AddPath(FieldDescriptorProto::kTypeFieldNumber); - field->set_type(type); - } else { - location.AddPath(FieldDescriptorProto::kTypeNameFieldNumber); - field->set_type_name(type_name); - } + RepeatedPtrField<DescriptorProto>* messages) { + // Parse label and type. + FieldDescriptorProto::Label label; + DO(ParseLabel(&label)); + field->set_label(label); + + RecordLocation(field, DescriptorPool::ErrorCollector::TYPE); + FieldDescriptorProto::Type type = FieldDescriptorProto::TYPE_INT32; + string type_name; + DO(ParseType(&type, &type_name)); + if (type_name.empty()) { + field->set_type(type); + } else { + field->set_type_name(type_name); } // Parse name and '='. + RecordLocation(field, DescriptorPool::ErrorCollector::NAME); io::Tokenizer::Token name_token = input_->current(); - { - LocationRecorder location(field_location, - FieldDescriptorProto::kNameFieldNumber); - location.RecordLegacyLocation(field, DescriptorPool::ErrorCollector::NAME); - DO(ConsumeIdentifier(field->mutable_name(), "Expected field name.")); - } + DO(ConsumeIdentifier(field->mutable_name(), "Expected field name.")); DO(Consume("=", "Missing field number.")); // Parse field number. - { - LocationRecorder location(field_location, - FieldDescriptorProto::kNumberFieldNumber); - location.RecordLegacyLocation( - field, DescriptorPool::ErrorCollector::NUMBER); - int number; - DO(ConsumeInteger(&number, "Expected field number.")); - field->set_number(number); - } + RecordLocation(field, DescriptorPool::ErrorCollector::NUMBER); + int number; + DO(ConsumeInteger(&number, "Expected field number.")); + field->set_number(number); // Parse options. - DO(ParseFieldOptions(field, field_location, containing_file)); + DO(ParseFieldOptions(field)); // Deal with groups. - if (field->has_type() && field->type() == FieldDescriptorProto::TYPE_GROUP) { - // Awkward: Since a group declares both a message type and a field, we - // have to create overlapping locations. - LocationRecorder group_location(parent_location); - group_location.StartAt(field_location); - group_location.AddPath(location_field_number_for_nested_type); - group_location.AddPath(messages->size()); - + if (type_name.empty() && type == FieldDescriptorProto::TYPE_GROUP) { DescriptorProto* group = messages->Add(); group->set_name(field->name()); - // Record name location to match the field name's location. - { - LocationRecorder location(group_location, - DescriptorProto::kNameFieldNumber); - location.StartAt(name_token); - location.EndAt(name_token); - location.RecordLegacyLocation( - group, DescriptorPool::ErrorCollector::NAME); - } - - // The field's type_name also comes from the name. Confusing! - { - LocationRecorder location(field_location, - FieldDescriptorProto::kTypeNameFieldNumber); - location.StartAt(name_token); - location.EndAt(name_token); - } + RecordLocation(group, DescriptorPool::ErrorCollector::NAME, + name_token.line, name_token.column); // As a hack for backwards-compatibility, we force the group name to start // with a capital letter and lower-case the field name. New code should @@ -772,37 +490,27 @@ bool Parser::ParseMessageFieldNoLabel( field->set_type_name(group->name()); if (LookingAt("{")) { - DO(ParseMessageBlock(group, group_location, containing_file)); + DO(ParseMessageBlock(group)); } else { AddError("Missing group body."); return false; } } else { - DO(ConsumeEndOfDeclaration(";", &field_location)); + DO(Consume(";")); } return true; } -bool Parser::ParseFieldOptions(FieldDescriptorProto* field, - const LocationRecorder& field_location, - const FileDescriptorProto* containing_file) { - if (!LookingAt("[")) return true; - - LocationRecorder location(field_location, - FieldDescriptorProto::kOptionsFieldNumber); - - DO(Consume("[")); +bool Parser::ParseFieldOptions(FieldDescriptorProto* field) { + if (!TryConsume("[")) return true; // Parse field options. do { if (LookingAt("default")) { - // We intentionally pass field_location rather than location here, since - // the default value is not actually an option. - DO(ParseDefaultAssignment(field, field_location, containing_file)); + DO(ParseDefaultAssignment(field)); } else { - DO(ParseOption(field->mutable_options(), location, - containing_file, OPTION_ASSIGNMENT)); + DO(ParseOptionAssignment(field->mutable_options())); } } while (TryConsume(",")); @@ -810,10 +518,7 @@ bool Parser::ParseFieldOptions(FieldDescriptorProto* field, return true; } -bool Parser::ParseDefaultAssignment( - FieldDescriptorProto* field, - const LocationRecorder& field_location, - const FileDescriptorProto* containing_file) { +bool Parser::ParseDefaultAssignment(FieldDescriptorProto* field) { if (field->has_default_value()) { AddError("Already set option \"default\"."); field->clear_default_value(); @@ -822,24 +527,13 @@ bool Parser::ParseDefaultAssignment( DO(Consume("default")); DO(Consume("=")); - LocationRecorder location(field_location, - FieldDescriptorProto::kDefaultValueFieldNumber); - location.RecordLegacyLocation( - field, DescriptorPool::ErrorCollector::DEFAULT_VALUE); + RecordLocation(field, DescriptorPool::ErrorCollector::DEFAULT_VALUE); string* default_value = field->mutable_default_value(); if (!field->has_type()) { // The field has a type name, but we don't know if it is a message or an - // enum yet. (If it were a primitive type, |field| would have a type set - // already.) In this case, simply take the current string as the default - // value; we will catch the error later if it is not a valid enum value. - // (N.B. that we do not check whether the current token is an identifier: - // doing so throws strange errors when the user mistypes a primitive - // typename and we assume it's an enum. E.g.: "optional int foo = 1 [default - // = 42]". In such a case the fundamental error is really that "int" is not - // a type, not that "42" is not an identifier. See b/12533582.) - *default_value = input_->current().text; - input_->Next(); + // enum yet. Assume an enum for now. + DO(ConsumeIdentifier(default_value, "Expected identifier.")); return true; } @@ -865,8 +559,7 @@ bool Parser::ParseDefaultAssignment( } // Parse the integer to verify that it is not out-of-range. uint64 value; - DO(ConsumeInteger64(max_value, &value, - "Expected integer for field default value.")); + DO(ConsumeInteger64(max_value, &value, "Expected integer.")); // And stringify it again. default_value->append(SimpleItoa(value)); break; @@ -888,8 +581,7 @@ bool Parser::ParseDefaultAssignment( } // Parse the integer to verify that it is not out-of-range. uint64 value; - DO(ConsumeInteger64(max_value, &value, - "Expected integer for field default value.")); + DO(ConsumeInteger64(max_value, &value, "Expected integer.")); // And stringify it again. default_value->append(SimpleItoa(value)); break; @@ -921,11 +613,7 @@ bool Parser::ParseDefaultAssignment( break; case FieldDescriptorProto::TYPE_STRING: - // Note: When file opton java_string_check_utf8 is true, if a - // non-string representation (eg byte[]) is later supported, it must - // be checked for UTF-8-ness. - DO(ConsumeString(default_value, "Expected string for field default " - "value.")); + DO(ConsumeString(default_value, "Expected string.")); break; case FieldDescriptorProto::TYPE_BYTES: @@ -934,8 +622,7 @@ bool Parser::ParseDefaultAssignment( break; case FieldDescriptorProto::TYPE_ENUM: - DO(ConsumeIdentifier(default_value, "Expected enum identifier for field " - "default value.")); + DO(ConsumeIdentifier(default_value, "Expected identifier.")); break; case FieldDescriptorProto::TYPE_MESSAGE: @@ -947,36 +634,26 @@ bool Parser::ParseDefaultAssignment( return true; } -bool Parser::ParseOptionNamePart(UninterpretedOption* uninterpreted_option, - const LocationRecorder& part_location, - const FileDescriptorProto* containing_file) { +bool Parser::ParseOptionNamePart(UninterpretedOption* uninterpreted_option) { UninterpretedOption::NamePart* name = uninterpreted_option->add_name(); string identifier; // We parse identifiers into this string. if (LookingAt("(")) { // This is an extension. DO(Consume("(")); - - { - LocationRecorder location( - part_location, UninterpretedOption::NamePart::kNamePartFieldNumber); - // An extension name consists of dot-separated identifiers, and may begin - // with a dot. - if (LookingAtType(io::Tokenizer::TYPE_IDENTIFIER)) { - DO(ConsumeIdentifier(&identifier, "Expected identifier.")); - name->mutable_name_part()->append(identifier); - } - while (LookingAt(".")) { - DO(Consume(".")); - name->mutable_name_part()->append("."); - DO(ConsumeIdentifier(&identifier, "Expected identifier.")); - name->mutable_name_part()->append(identifier); - } + // An extension name consists of dot-separated identifiers, and may begin + // with a dot. + if (LookingAtType(io::Tokenizer::TYPE_IDENTIFIER)) { + DO(ConsumeIdentifier(&identifier, "Expected identifier.")); + name->mutable_name_part()->append(identifier); + } + while (LookingAt(".")) { + DO(Consume(".")); + name->mutable_name_part()->append("."); + DO(ConsumeIdentifier(&identifier, "Expected identifier.")); + name->mutable_name_part()->append(identifier); } - DO(Consume(")")); name->set_is_extension(true); } else { // This is a regular field. - LocationRecorder location( - part_location, UninterpretedOption::NamePart::kNamePartFieldNumber); DO(ConsumeIdentifier(&identifier, "Expected identifier.")); name->mutable_name_part()->append(identifier); name->set_is_extension(false); @@ -984,214 +661,116 @@ bool Parser::ParseOptionNamePart(UninterpretedOption* uninterpreted_option, return true; } -bool Parser::ParseUninterpretedBlock(string* value) { - // Note that enclosing braces are not added to *value. - // We do NOT use ConsumeEndOfStatement for this brace because it's delimiting - // an expression, not a block of statements. - DO(Consume("{")); - int brace_depth = 1; - while (!AtEnd()) { - if (LookingAt("{")) { - brace_depth++; - } else if (LookingAt("}")) { - brace_depth--; - if (brace_depth == 0) { - input_->Next(); - return true; - } - } - // TODO(sanjay): Interpret line/column numbers to preserve formatting - if (!value->empty()) value->push_back(' '); - value->append(input_->current().text); - input_->Next(); - } - AddError("Unexpected end of stream while parsing aggregate value."); - return false; -} - // We don't interpret the option here. Instead we store it in an // UninterpretedOption, to be interpreted later. -bool Parser::ParseOption(Message* options, - const LocationRecorder& options_location, - const FileDescriptorProto* containing_file, - OptionStyle style) { +bool Parser::ParseOptionAssignment(Message* options) { // Create an entry in the uninterpreted_option field. const FieldDescriptor* uninterpreted_option_field = options->GetDescriptor()-> FindFieldByName("uninterpreted_option"); GOOGLE_CHECK(uninterpreted_option_field != NULL) << "No field named \"uninterpreted_option\" in the Options proto."; - const Reflection* reflection = options->GetReflection(); - - LocationRecorder location( - options_location, uninterpreted_option_field->number(), - reflection->FieldSize(*options, uninterpreted_option_field)); - - if (style == OPTION_STATEMENT) { - DO(Consume("option")); - } - UninterpretedOption* uninterpreted_option = down_cast<UninterpretedOption*>( options->GetReflection()->AddMessage(options, uninterpreted_option_field)); // Parse dot-separated name. - { - LocationRecorder name_location(location, - UninterpretedOption::kNameFieldNumber); - name_location.RecordLegacyLocation( - uninterpreted_option, DescriptorPool::ErrorCollector::OPTION_NAME); - - { - LocationRecorder part_location(name_location, - uninterpreted_option->name_size()); - DO(ParseOptionNamePart(uninterpreted_option, part_location, - containing_file)); - } + RecordLocation(uninterpreted_option, + DescriptorPool::ErrorCollector::OPTION_NAME); - while (LookingAt(".")) { - DO(Consume(".")); - LocationRecorder part_location(name_location, - uninterpreted_option->name_size()); - DO(ParseOptionNamePart(uninterpreted_option, part_location, - containing_file)); - } + DO(ParseOptionNamePart(uninterpreted_option)); + + while (LookingAt(".")) { + DO(Consume(".")); + DO(ParseOptionNamePart(uninterpreted_option)); } DO(Consume("=")); - { - LocationRecorder value_location(location); - value_location.RecordLegacyLocation( - uninterpreted_option, DescriptorPool::ErrorCollector::OPTION_VALUE); + RecordLocation(uninterpreted_option, + DescriptorPool::ErrorCollector::OPTION_VALUE); - // All values are a single token, except for negative numbers, which consist - // of a single '-' symbol, followed by a positive number. - bool is_negative = TryConsume("-"); + // All values are a single token, except for negative numbers, which consist + // of a single '-' symbol, followed by a positive number. + bool is_negative = TryConsume("-"); - switch (input_->current().type) { - case io::Tokenizer::TYPE_START: - GOOGLE_LOG(FATAL) << "Trying to read value before any tokens have been read."; - return false; + switch (input_->current().type) { + case io::Tokenizer::TYPE_START: + GOOGLE_LOG(FATAL) << "Trying to read value before any tokens have been read."; + return false; - case io::Tokenizer::TYPE_END: - AddError("Unexpected end of stream while parsing option value."); - return false; + case io::Tokenizer::TYPE_END: + AddError("Unexpected end of stream while parsing option value."); + return false; - case io::Tokenizer::TYPE_IDENTIFIER: { - value_location.AddPath( - UninterpretedOption::kIdentifierValueFieldNumber); - if (is_negative) { - AddError("Invalid '-' symbol before identifier."); - return false; - } - string value; - DO(ConsumeIdentifier(&value, "Expected identifier.")); - uninterpreted_option->set_identifier_value(value); - break; + case io::Tokenizer::TYPE_IDENTIFIER: { + if (is_negative) { + AddError("Invalid '-' symbol before identifier."); + return false; } + string value; + DO(ConsumeIdentifier(&value, "Expected identifier.")); + uninterpreted_option->set_identifier_value(value); + break; + } - case io::Tokenizer::TYPE_INTEGER: { - uint64 value; - uint64 max_value = - is_negative ? static_cast<uint64>(kint64max) + 1 : kuint64max; - DO(ConsumeInteger64(max_value, &value, "Expected integer.")); - if (is_negative) { - value_location.AddPath( - UninterpretedOption::kNegativeIntValueFieldNumber); - uninterpreted_option->set_negative_int_value( - -static_cast<int64>(value)); - } else { - value_location.AddPath( - UninterpretedOption::kPositiveIntValueFieldNumber); - uninterpreted_option->set_positive_int_value(value); - } - break; + case io::Tokenizer::TYPE_INTEGER: { + uint64 value; + uint64 max_value = + is_negative ? static_cast<uint64>(kint64max) + 1 : kuint64max; + DO(ConsumeInteger64(max_value, &value, "Expected integer.")); + if (is_negative) { + uninterpreted_option->set_negative_int_value(-value); + } else { + uninterpreted_option->set_positive_int_value(value); } + break; + } - case io::Tokenizer::TYPE_FLOAT: { - value_location.AddPath(UninterpretedOption::kDoubleValueFieldNumber); - double value; - DO(ConsumeNumber(&value, "Expected number.")); - uninterpreted_option->set_double_value(is_negative ? -value : value); - break; - } + case io::Tokenizer::TYPE_FLOAT: { + double value; + DO(ConsumeNumber(&value, "Expected number.")); + uninterpreted_option->set_double_value(is_negative ? -value : value); + break; + } - case io::Tokenizer::TYPE_STRING: { - value_location.AddPath(UninterpretedOption::kStringValueFieldNumber); - if (is_negative) { - AddError("Invalid '-' symbol before string."); - return false; - } - string value; - DO(ConsumeString(&value, "Expected string.")); - uninterpreted_option->set_string_value(value); - break; + case io::Tokenizer::TYPE_STRING: { + if (is_negative) { + AddError("Invalid '-' symbol before string."); + return false; } - - case io::Tokenizer::TYPE_SYMBOL: - if (LookingAt("{")) { - value_location.AddPath( - UninterpretedOption::kAggregateValueFieldNumber); - DO(ParseUninterpretedBlock( - uninterpreted_option->mutable_aggregate_value())); - } else { - AddError("Expected option value."); - return false; - } - break; + string value; + DO(ConsumeString(&value, "Expected string.")); + uninterpreted_option->set_string_value(value); + break; } - } - if (style == OPTION_STATEMENT) { - DO(ConsumeEndOfDeclaration(";", &location)); + case io::Tokenizer::TYPE_SYMBOL: + AddError("Expected option value."); + return false; } - return true; } -bool Parser::ParseExtensions(DescriptorProto* message, - const LocationRecorder& extensions_location, - const FileDescriptorProto* containing_file) { +bool Parser::ParseExtensions(DescriptorProto* message) { // Parse the declaration. DO(Consume("extensions")); do { - // Note that kExtensionRangeFieldNumber was already pushed by the parent. - LocationRecorder location(extensions_location, - message->extension_range_size()); - DescriptorProto::ExtensionRange* range = message->add_extension_range(); - location.RecordLegacyLocation( - range, DescriptorPool::ErrorCollector::NUMBER); + RecordLocation(range, DescriptorPool::ErrorCollector::NUMBER); int start, end; - io::Tokenizer::Token start_token; - - { - LocationRecorder start_location( - location, DescriptorProto::ExtensionRange::kStartFieldNumber); - start_token = input_->current(); - DO(ConsumeInteger(&start, "Expected field number range.")); - } + DO(ConsumeInteger(&start, "Expected field number range.")); if (TryConsume("to")) { - LocationRecorder end_location( - location, DescriptorProto::ExtensionRange::kEndFieldNumber); if (TryConsume("max")) { - // Set to the sentinel value - 1 since we increment the value below. - // The actual value of the end of the range should be set with - // AdjustExtensionRangesWithMaxEndNumber. - end = kMaxExtensionRangeSentinel - 1; + end = FieldDescriptor::kMaxNumber; } else { DO(ConsumeInteger(&end, "Expected integer.")); } } else { - LocationRecorder end_location( - location, DescriptorProto::ExtensionRange::kEndFieldNumber); - end_location.StartAt(start_token); - end_location.EndAt(start_token); end = start; } @@ -1203,26 +782,24 @@ bool Parser::ParseExtensions(DescriptorProto* message, range->set_end(end); } while (TryConsume(",")); - DO(ConsumeEndOfDeclaration(";", &extensions_location)); + DO(Consume(";")); return true; } bool Parser::ParseExtend(RepeatedPtrField<FieldDescriptorProto>* extensions, - RepeatedPtrField<DescriptorProto>* messages, - const LocationRecorder& parent_location, - int location_field_number_for_nested_type, - const LocationRecorder& extend_location, - const FileDescriptorProto* containing_file) { + RepeatedPtrField<DescriptorProto>* messages) { DO(Consume("extend")); + // We expect to see at least one extension field defined in the extend block. + // We need to create it now so we can record the extendee's location. + FieldDescriptorProto* first_field = extensions->Add(); + // Parse the extendee type. - io::Tokenizer::Token extendee_start = input_->current(); - string extendee; - DO(ParseUserDefinedType(&extendee)); - io::Tokenizer::Token extendee_end = input_->previous(); + RecordLocation(first_field, DescriptorPool::ErrorCollector::EXTENDEE); + DO(ParseUserDefinedType(first_field->mutable_extendee())); // Parse the block. - DO(ConsumeEndOfDeclaration("{", &extend_location)); + DO(Consume("{")); bool is_first = true; @@ -1232,92 +809,21 @@ bool Parser::ParseExtend(RepeatedPtrField<FieldDescriptorProto>* extensions, return false; } - // Note that kExtensionFieldNumber was already pushed by the parent. - LocationRecorder location(extend_location, extensions->size()); - - FieldDescriptorProto* field = extensions->Add(); - - { - LocationRecorder extendee_location( - location, FieldDescriptorProto::kExtendeeFieldNumber); - extendee_location.StartAt(extendee_start); - extendee_location.EndAt(extendee_end); - - if (is_first) { - extendee_location.RecordLegacyLocation( - field, DescriptorPool::ErrorCollector::EXTENDEE); - is_first = false; - } - } - - field->set_extendee(extendee); - - if (!ParseMessageField(field, messages, parent_location, - location_field_number_for_nested_type, - location, - containing_file)) { - // This statement failed to parse. Skip it, but keep looping to parse - // other statements. - SkipStatement(); - } - } while (!TryConsumeEndOfDeclaration("}", NULL)); - - return true; -} - -bool Parser::ParseOneof(OneofDescriptorProto* oneof_decl, - DescriptorProto* containing_type, - int oneof_index, - const LocationRecorder& oneof_location, - const LocationRecorder& containing_type_location, - const FileDescriptorProto* containing_file) { - DO(Consume("oneof")); - - { - LocationRecorder name_location(oneof_location, - OneofDescriptorProto::kNameFieldNumber); - DO(ConsumeIdentifier(oneof_decl->mutable_name(), "Expected oneof name.")); - } - - DO(ConsumeEndOfDeclaration("{", &oneof_location)); - - do { - if (AtEnd()) { - AddError("Reached end of input in oneof definition (missing '}')."); - return false; - } - - // Print a nice error if the user accidentally tries to place a label - // on an individual member of a oneof. - if (LookingAt("required") || - LookingAt("optional") || - LookingAt("repeated")) { - AddError("Fields in oneofs must not have labels (required / optional " - "/ repeated)."); - // We can continue parsing here because we understand what the user - // meant. The error report will still make parsing fail overall. - input_->Next(); + FieldDescriptorProto* field; + if (is_first) { + field = first_field; + is_first = false; + } else { + field = extensions->Add(); + field->set_extendee(first_field->extendee()); } - LocationRecorder field_location(containing_type_location, - DescriptorProto::kFieldFieldNumber, - containing_type->field_size()); - - FieldDescriptorProto* field = containing_type->add_field(); - field->set_label(FieldDescriptorProto::LABEL_OPTIONAL); - field->set_oneof_index(oneof_index); - - if (!ParseMessageFieldNoLabel(field, - containing_type->mutable_nested_type(), - containing_type_location, - DescriptorProto::kNestedTypeFieldNumber, - field_location, - containing_file)) { + if (!ParseMessageField(field, messages)) { // This statement failed to parse. Skip it, but keep looping to parse // other statements. SkipStatement(); } - } while (!TryConsumeEndOfDeclaration("}", NULL)); + } while(!TryConsume("}")); return true; } @@ -1325,35 +831,24 @@ bool Parser::ParseOneof(OneofDescriptorProto* oneof_decl, // ------------------------------------------------------------------- // Enums -bool Parser::ParseEnumDefinition(EnumDescriptorProto* enum_type, - const LocationRecorder& enum_location, - const FileDescriptorProto* containing_file) { +bool Parser::ParseEnumDefinition(EnumDescriptorProto* enum_type) { DO(Consume("enum")); - - { - LocationRecorder location(enum_location, - EnumDescriptorProto::kNameFieldNumber); - location.RecordLegacyLocation( - enum_type, DescriptorPool::ErrorCollector::NAME); - DO(ConsumeIdentifier(enum_type->mutable_name(), "Expected enum name.")); - } - - DO(ParseEnumBlock(enum_type, enum_location, containing_file)); + RecordLocation(enum_type, DescriptorPool::ErrorCollector::NAME); + DO(ConsumeIdentifier(enum_type->mutable_name(), "Expected enum name.")); + DO(ParseEnumBlock(enum_type)); return true; } -bool Parser::ParseEnumBlock(EnumDescriptorProto* enum_type, - const LocationRecorder& enum_location, - const FileDescriptorProto* containing_file) { - DO(ConsumeEndOfDeclaration("{", &enum_location)); +bool Parser::ParseEnumBlock(EnumDescriptorProto* enum_type) { + DO(Consume("{")); - while (!TryConsumeEndOfDeclaration("}", NULL)) { + while (!TryConsume("}")) { if (AtEnd()) { AddError("Reached end of input in enum definition (missing '}')."); return false; } - if (!ParseEnumStatement(enum_type, enum_location, containing_file)) { + if (!ParseEnumStatement(enum_type)) { // This statement failed to parse. Skip it, but keep looping to parse // other statements. SkipStatement(); @@ -1363,73 +858,41 @@ bool Parser::ParseEnumBlock(EnumDescriptorProto* enum_type, return true; } -bool Parser::ParseEnumStatement(EnumDescriptorProto* enum_type, - const LocationRecorder& enum_location, - const FileDescriptorProto* containing_file) { - if (TryConsumeEndOfDeclaration(";", NULL)) { +bool Parser::ParseEnumStatement(EnumDescriptorProto* enum_type) { + if (TryConsume(";")) { // empty statement; ignore return true; } else if (LookingAt("option")) { - LocationRecorder location(enum_location, - EnumDescriptorProto::kOptionsFieldNumber); - return ParseOption(enum_type->mutable_options(), location, - containing_file, OPTION_STATEMENT); + return ParseOption(enum_type->mutable_options()); } else { - LocationRecorder location(enum_location, - EnumDescriptorProto::kValueFieldNumber, enum_type->value_size()); - return ParseEnumConstant(enum_type->add_value(), location, containing_file); + return ParseEnumConstant(enum_type->add_value()); } } -bool Parser::ParseEnumConstant(EnumValueDescriptorProto* enum_value, - const LocationRecorder& enum_value_location, - const FileDescriptorProto* containing_file) { - // Parse name. - { - LocationRecorder location(enum_value_location, - EnumValueDescriptorProto::kNameFieldNumber); - location.RecordLegacyLocation( - enum_value, DescriptorPool::ErrorCollector::NAME); - DO(ConsumeIdentifier(enum_value->mutable_name(), - "Expected enum constant name.")); - } - +bool Parser::ParseEnumConstant(EnumValueDescriptorProto* enum_value) { + RecordLocation(enum_value, DescriptorPool::ErrorCollector::NAME); + DO(ConsumeIdentifier(enum_value->mutable_name(), + "Expected enum constant name.")); DO(Consume("=", "Missing numeric value for enum constant.")); - // Parse value. - { - LocationRecorder location( - enum_value_location, EnumValueDescriptorProto::kNumberFieldNumber); - location.RecordLegacyLocation( - enum_value, DescriptorPool::ErrorCollector::NUMBER); + bool is_negative = TryConsume("-"); + int number; + DO(ConsumeInteger(&number, "Expected integer.")); + if (is_negative) number *= -1; + enum_value->set_number(number); - int number; - DO(ConsumeSignedInteger(&number, "Expected integer.")); - enum_value->set_number(number); - } + DO(ParseEnumConstantOptions(enum_value)); - DO(ParseEnumConstantOptions(enum_value, enum_value_location, - containing_file)); - - DO(ConsumeEndOfDeclaration(";", &enum_value_location)); + DO(Consume(";")); return true; } -bool Parser::ParseEnumConstantOptions( - EnumValueDescriptorProto* value, - const LocationRecorder& enum_value_location, - const FileDescriptorProto* containing_file) { - if (!LookingAt("[")) return true; - - LocationRecorder location( - enum_value_location, EnumValueDescriptorProto::kOptionsFieldNumber); - - DO(Consume("[")); +bool Parser::ParseEnumConstantOptions(EnumValueDescriptorProto* value) { + if (!TryConsume("[")) return true; do { - DO(ParseOption(value->mutable_options(), location, - containing_file, OPTION_ASSIGNMENT)); + DO(ParseOptionAssignment(value->mutable_options())); } while (TryConsume(",")); DO(Consume("]")); @@ -1439,36 +902,24 @@ bool Parser::ParseEnumConstantOptions( // ------------------------------------------------------------------- // Services -bool Parser::ParseServiceDefinition( - ServiceDescriptorProto* service, - const LocationRecorder& service_location, - const FileDescriptorProto* containing_file) { +bool Parser::ParseServiceDefinition(ServiceDescriptorProto* service) { DO(Consume("service")); - - { - LocationRecorder location(service_location, - ServiceDescriptorProto::kNameFieldNumber); - location.RecordLegacyLocation( - service, DescriptorPool::ErrorCollector::NAME); - DO(ConsumeIdentifier(service->mutable_name(), "Expected service name.")); - } - - DO(ParseServiceBlock(service, service_location, containing_file)); + RecordLocation(service, DescriptorPool::ErrorCollector::NAME); + DO(ConsumeIdentifier(service->mutable_name(), "Expected service name.")); + DO(ParseServiceBlock(service)); return true; } -bool Parser::ParseServiceBlock(ServiceDescriptorProto* service, - const LocationRecorder& service_location, - const FileDescriptorProto* containing_file) { - DO(ConsumeEndOfDeclaration("{", &service_location)); +bool Parser::ParseServiceBlock(ServiceDescriptorProto* service) { + DO(Consume("{")); - while (!TryConsumeEndOfDeclaration("}", NULL)) { + while (!TryConsume("}")) { if (AtEnd()) { AddError("Reached end of input in service definition (missing '}')."); return false; } - if (!ParseServiceStatement(service, service_location, containing_file)) { + if (!ParseServiceStatement(service)) { // This statement failed to parse. Skip it, but keep looping to parse // other statements. SkipStatement(); @@ -1478,98 +929,55 @@ bool Parser::ParseServiceBlock(ServiceDescriptorProto* service, return true; } -bool Parser::ParseServiceStatement(ServiceDescriptorProto* service, - const LocationRecorder& service_location, - const FileDescriptorProto* containing_file) { - if (TryConsumeEndOfDeclaration(";", NULL)) { +bool Parser::ParseServiceStatement(ServiceDescriptorProto* service) { + if (TryConsume(";")) { // empty statement; ignore return true; } else if (LookingAt("option")) { - LocationRecorder location( - service_location, ServiceDescriptorProto::kOptionsFieldNumber); - return ParseOption(service->mutable_options(), location, - containing_file, OPTION_STATEMENT); + return ParseOption(service->mutable_options()); } else { - LocationRecorder location(service_location, - ServiceDescriptorProto::kMethodFieldNumber, service->method_size()); - return ParseServiceMethod(service->add_method(), location, containing_file); + return ParseServiceMethod(service->add_method()); } } -bool Parser::ParseServiceMethod(MethodDescriptorProto* method, - const LocationRecorder& method_location, - const FileDescriptorProto* containing_file) { +bool Parser::ParseServiceMethod(MethodDescriptorProto* method) { DO(Consume("rpc")); - - { - LocationRecorder location(method_location, - MethodDescriptorProto::kNameFieldNumber); - location.RecordLegacyLocation( - method, DescriptorPool::ErrorCollector::NAME); - DO(ConsumeIdentifier(method->mutable_name(), "Expected method name.")); - } + RecordLocation(method, DescriptorPool::ErrorCollector::NAME); + DO(ConsumeIdentifier(method->mutable_name(), "Expected method name.")); // Parse input type. DO(Consume("(")); - { - LocationRecorder location(method_location, - MethodDescriptorProto::kInputTypeFieldNumber); - location.RecordLegacyLocation( - method, DescriptorPool::ErrorCollector::INPUT_TYPE); - DO(ParseUserDefinedType(method->mutable_input_type())); - } + RecordLocation(method, DescriptorPool::ErrorCollector::INPUT_TYPE); + DO(ParseUserDefinedType(method->mutable_input_type())); DO(Consume(")")); // Parse output type. DO(Consume("returns")); DO(Consume("(")); - { - LocationRecorder location(method_location, - MethodDescriptorProto::kOutputTypeFieldNumber); - location.RecordLegacyLocation( - method, DescriptorPool::ErrorCollector::OUTPUT_TYPE); - DO(ParseUserDefinedType(method->mutable_output_type())); - } + RecordLocation(method, DescriptorPool::ErrorCollector::OUTPUT_TYPE); + DO(ParseUserDefinedType(method->mutable_output_type())); DO(Consume(")")); - if (LookingAt("{")) { + if (TryConsume("{")) { // Options! - DO(ParseOptions(method_location, - containing_file, - MethodDescriptorProto::kOptionsFieldNumber, - method->mutable_options())); - } else { - DO(ConsumeEndOfDeclaration(";", &method_location)); - } - - return true; -} - - -bool Parser::ParseOptions(const LocationRecorder& parent_location, - const FileDescriptorProto* containing_file, - const int optionsFieldNumber, - Message* mutable_options) { - // Options! - ConsumeEndOfDeclaration("{", &parent_location); - while (!TryConsumeEndOfDeclaration("}", NULL)) { - if (AtEnd()) { - AddError("Reached end of input in method options (missing '}')."); - return false; - } + while (!TryConsume("}")) { + if (AtEnd()) { + AddError("Reached end of input in method options (missing '}')."); + return false; + } - if (TryConsumeEndOfDeclaration(";", NULL)) { - // empty statement; ignore - } else { - LocationRecorder location(parent_location, - optionsFieldNumber); - if (!ParseOption(mutable_options, location, containing_file, - OPTION_STATEMENT)) { - // This statement failed to parse. Skip it, but keep looping to - // parse other statements. - SkipStatement(); + if (TryConsume(";")) { + // empty statement; ignore + } else { + if (!ParseOption(method->mutable_options())) { + // This statement failed to parse. Skip it, but keep looping to + // parse other statements. + SkipStatement(); + } } } + } else { + DO(Consume(";")); } return true; @@ -1577,8 +985,7 @@ bool Parser::ParseOptions(const LocationRecorder& parent_location, // ------------------------------------------------------------------- -bool Parser::ParseLabel(FieldDescriptorProto::Label* label, - const FileDescriptorProto* containing_file) { +bool Parser::ParseLabel(FieldDescriptorProto::Label* label) { if (TryConsume("optional")) { *label = FieldDescriptorProto::LABEL_OPTIONAL; return true; @@ -1646,9 +1053,7 @@ bool Parser::ParseUserDefinedType(string* type_name) { // =================================================================== -bool Parser::ParsePackage(FileDescriptorProto* file, - const LocationRecorder& root_location, - const FileDescriptorProto* containing_file) { +bool Parser::ParsePackage(FileDescriptorProto* file) { if (file->has_package()) { AddError("Multiple package definitions."); // Don't append the new package to the old one. Just replace it. Not @@ -1658,57 +1063,32 @@ bool Parser::ParsePackage(FileDescriptorProto* file, DO(Consume("package")); - { - LocationRecorder location(root_location, - FileDescriptorProto::kPackageFieldNumber); - location.RecordLegacyLocation(file, DescriptorPool::ErrorCollector::NAME); - - while (true) { - string identifier; - DO(ConsumeIdentifier(&identifier, "Expected identifier.")); - file->mutable_package()->append(identifier); - if (!TryConsume(".")) break; - file->mutable_package()->append("."); - } - - location.EndAt(input_->previous()); + RecordLocation(file, DescriptorPool::ErrorCollector::NAME); - DO(ConsumeEndOfDeclaration(";", &location)); + while (true) { + string identifier; + DO(ConsumeIdentifier(&identifier, "Expected identifier.")); + file->mutable_package()->append(identifier); + if (!TryConsume(".")) break; + file->mutable_package()->append("."); } + DO(Consume(";")); return true; } -bool Parser::ParseImport(RepeatedPtrField<string>* dependency, - RepeatedField<int32>* public_dependency, - RepeatedField<int32>* weak_dependency, - const LocationRecorder& root_location, - const FileDescriptorProto* containing_file) { +bool Parser::ParseImport(string* import_filename) { DO(Consume("import")); - if (LookingAt("public")) { - LocationRecorder location( - root_location, FileDescriptorProto::kPublicDependencyFieldNumber, - public_dependency->size()); - DO(Consume("public")); - *public_dependency->Add() = dependency->size(); - } else if (LookingAt("weak")) { - LocationRecorder location( - root_location, FileDescriptorProto::kWeakDependencyFieldNumber, - weak_dependency->size()); - DO(Consume("weak")); - *weak_dependency->Add() = dependency->size(); - } - { - LocationRecorder location(root_location, - FileDescriptorProto::kDependencyFieldNumber, - dependency->size()); - DO(ConsumeString(dependency->Add(), - "Expected a string naming the file to import.")); - - location.EndAt(input_->previous()); + DO(ConsumeString(import_filename, + "Expected a string naming the file to import.")); + DO(Consume(";")); + return true; +} - DO(ConsumeEndOfDeclaration(";", &location)); - } +bool Parser::ParseOption(Message* options) { + DO(Consume("option")); + DO(ParseOptionAssignment(options)); + DO(Consume(";")); return true; } |