summaryrefslogtreecommitdiffstats
path: root/src/google/protobuf/compiler/parser.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/google/protobuf/compiler/parser.cc')
-rw-r--r--src/google/protobuf/compiler/parser.cc1158
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;
}