Index: third_party/protobuf/src/google/protobuf/compiler/parser.h |
diff --git a/third_party/protobuf/src/google/protobuf/compiler/parser.h b/third_party/protobuf/src/google/protobuf/compiler/parser.h |
index 72c96d0475091dbd648ba59df14bb9856105ab70..4cc90a29afce015f06525b57970e1bfef34174e7 100644 |
--- a/third_party/protobuf/src/google/protobuf/compiler/parser.h |
+++ b/third_party/protobuf/src/google/protobuf/compiler/parser.h |
@@ -74,6 +74,9 @@ class LIBPROTOBUF_EXPORT Parser { |
// Optional fetaures: |
+ // DEPRECATED: New code should use the SourceCodeInfo embedded in the |
+ // FileDescriptorProto. |
+ // |
// Requests that locations of certain definitions be recorded to the given |
// SourceLocationTable while parsing. This can be used to look up exact line |
// and column numbers for errors reported by DescriptorPool during validation. |
@@ -82,7 +85,7 @@ class LIBPROTOBUF_EXPORT Parser { |
source_location_table_ = location_table; |
} |
- // Requsets that errors be recorded to the given ErrorCollector while |
+ // Requests that errors be recorded to the given ErrorCollector while |
// parsing. Set to NULL (the default) to discard error messages. |
void RecordErrorsTo(io::ErrorCollector* error_collector) { |
error_collector_ = error_collector; |
@@ -180,16 +183,56 @@ class LIBPROTOBUF_EXPORT Parser { |
// of the current token. |
void AddError(const string& error); |
- // Record the given line and column and associate it with this descriptor |
- // in the SourceLocationTable. |
- void RecordLocation(const Message* descriptor, |
- DescriptorPool::ErrorCollector::ErrorLocation location, |
- int line, int column); |
- |
- // Record the current line and column and associate it with this descriptor |
- // in the SourceLocationTable. |
- void RecordLocation(const Message* descriptor, |
- DescriptorPool::ErrorCollector::ErrorLocation location); |
+ // Records a location in the SourceCodeInfo.location table (see |
+ // descriptor.proto). We use RAII to ensure that the start and end locations |
+ // are recorded -- the constructor records the start location and the |
+ // destructor records the end location. Since the parser is |
+ // recursive-descent, this works out beautifully. |
+ class LIBPROTOBUF_EXPORT LocationRecorder { |
+ public: |
+ // Construct the file's "root" location. |
+ LocationRecorder(Parser* parser); |
+ |
+ // Construct a location that represents a declaration nested within the |
+ // given parent. E.g. a field's location is nested within the location |
+ // for a message type. The parent's path will be copied, so you should |
+ // call AddPath() only to add the path components leading from the parent |
+ // to the child (as opposed to leading from the root to the child). |
+ LocationRecorder(const LocationRecorder& parent); |
+ |
+ // Convenience constructors that call AddPath() one or two times. |
+ LocationRecorder(const LocationRecorder& parent, int path1); |
+ LocationRecorder(const LocationRecorder& parent, int path1, int path2); |
+ |
+ ~LocationRecorder(); |
+ |
+ // Add a path component. See SourceCodeInfo.Location.path in |
+ // descriptor.proto. |
+ void AddPath(int path_component); |
+ |
+ // By default the location is considered to start at the current token at |
+ // the time the LocationRecorder is created. StartAt() sets the start |
+ // location to the given token instead. |
+ void StartAt(const io::Tokenizer::Token& token); |
+ |
+ // By default the location is considered to end at the previous token at |
+ // the time the LocationRecorder is destroyed. EndAt() sets the end |
+ // location to the given token instead. |
+ void EndAt(const io::Tokenizer::Token& token); |
+ |
+ // Records the start point of this location to the SourceLocationTable that |
+ // was passed to RecordSourceLocationsTo(), if any. SourceLocationTable |
+ // is an older way of keeping track of source locations which is still |
+ // used in some places. |
+ void RecordLegacyLocation(const Message* descriptor, |
+ DescriptorPool::ErrorCollector::ErrorLocation location); |
+ |
+ private: |
+ Parser* parser_; |
+ SourceCodeInfo::Location* location_; |
+ |
+ void Init(const LocationRecorder& parent); |
+ }; |
// ================================================================= |
// Parsers for various language constructs |
@@ -210,50 +253,81 @@ class LIBPROTOBUF_EXPORT Parser { |
// makes logic much simpler for the caller. |
// Parse a top-level message, enum, service, etc. |
- bool ParseTopLevelStatement(FileDescriptorProto* file); |
+ bool ParseTopLevelStatement(FileDescriptorProto* file, |
+ const LocationRecorder& root_location); |
// Parse various language high-level language construrcts. |
- bool ParseMessageDefinition(DescriptorProto* message); |
- bool ParseEnumDefinition(EnumDescriptorProto* enum_type); |
- bool ParseServiceDefinition(ServiceDescriptorProto* service); |
- bool ParsePackage(FileDescriptorProto* file); |
- bool ParseImport(string* import_filename); |
- bool ParseOption(Message* options); |
+ bool ParseMessageDefinition(DescriptorProto* message, |
+ const LocationRecorder& message_location); |
+ bool ParseEnumDefinition(EnumDescriptorProto* enum_type, |
+ const LocationRecorder& enum_location); |
+ bool ParseServiceDefinition(ServiceDescriptorProto* service, |
+ const LocationRecorder& service_location); |
+ bool ParsePackage(FileDescriptorProto* file, |
+ const LocationRecorder& root_location); |
+ bool ParseImport(string* import_filename, |
+ const LocationRecorder& root_location, |
+ int index); |
+ bool ParseOption(Message* options, |
+ const LocationRecorder& options_location); |
// These methods parse the contents of a message, enum, or service type and |
// add them to the given object. They consume the entire block including |
// the beginning and ending brace. |
- bool ParseMessageBlock(DescriptorProto* message); |
- bool ParseEnumBlock(EnumDescriptorProto* enum_type); |
- bool ParseServiceBlock(ServiceDescriptorProto* service); |
+ bool ParseMessageBlock(DescriptorProto* message, |
+ const LocationRecorder& message_location); |
+ bool ParseEnumBlock(EnumDescriptorProto* enum_type, |
+ const LocationRecorder& enum_location); |
+ bool ParseServiceBlock(ServiceDescriptorProto* service, |
+ const LocationRecorder& service_location); |
// Parse one statement within a message, enum, or service block, inclunding |
// final semicolon. |
- bool ParseMessageStatement(DescriptorProto* message); |
- bool ParseEnumStatement(EnumDescriptorProto* message); |
- bool ParseServiceStatement(ServiceDescriptorProto* message); |
+ bool ParseMessageStatement(DescriptorProto* message, |
+ const LocationRecorder& message_location); |
+ bool ParseEnumStatement(EnumDescriptorProto* message, |
+ const LocationRecorder& enum_location); |
+ bool ParseServiceStatement(ServiceDescriptorProto* message, |
+ const LocationRecorder& service_location); |
// Parse a field of a message. If the field is a group, its type will be |
// added to "messages". |
+ // |
+ // parent_location and location_field_number_for_nested_type are needed when |
+ // parsing groups -- we need to generate a nested message type within the |
+ // parent and record its location accordingly. Since the parent could be |
+ // either a FileDescriptorProto or a DescriptorProto, we must pass in the |
+ // correct field number to use. |
bool ParseMessageField(FieldDescriptorProto* field, |
- RepeatedPtrField<DescriptorProto>* messages); |
+ RepeatedPtrField<DescriptorProto>* messages, |
+ const LocationRecorder& parent_location, |
+ int location_field_number_for_nested_type, |
+ const LocationRecorder& field_location); |
// Parse an "extensions" declaration. |
- bool ParseExtensions(DescriptorProto* message); |
+ bool ParseExtensions(DescriptorProto* message, |
+ const LocationRecorder& extensions_location); |
- // Parse an "extend" declaration. |
+ // Parse an "extend" declaration. (See also comments for |
+ // ParseMessageField().) |
bool ParseExtend(RepeatedPtrField<FieldDescriptorProto>* extensions, |
- RepeatedPtrField<DescriptorProto>* messages); |
+ RepeatedPtrField<DescriptorProto>* messages, |
+ const LocationRecorder& parent_location, |
+ int location_field_number_for_nested_type, |
+ const LocationRecorder& extend_location); |
// Parse a single enum value within an enum block. |
- bool ParseEnumConstant(EnumValueDescriptorProto* enum_value); |
+ bool ParseEnumConstant(EnumValueDescriptorProto* enum_value, |
+ const LocationRecorder& enum_value_location); |
// Parse enum constant options, i.e. the list in square brackets at the end |
// of the enum constant value definition. |
- bool ParseEnumConstantOptions(EnumValueDescriptorProto* value); |
+ bool ParseEnumConstantOptions(EnumValueDescriptorProto* value, |
+ const LocationRecorder& enum_value_location); |
// Parse a single method within a service definition. |
- bool ParseServiceMethod(MethodDescriptorProto* method); |
+ bool ParseServiceMethod(MethodDescriptorProto* method, |
+ const LocationRecorder& method_location); |
// Parse "required", "optional", or "repeated" and fill in "label" |
// with the value. |
@@ -269,28 +343,45 @@ class LIBPROTOBUF_EXPORT Parser { |
// Parses field options, i.e. the stuff in square brackets at the end |
// of a field definition. Also parses default value. |
- bool ParseFieldOptions(FieldDescriptorProto* field); |
+ bool ParseFieldOptions(FieldDescriptorProto* field, |
+ const LocationRecorder& field_location); |
// Parse the "default" option. This needs special handling because its |
// type is the field's type. |
- bool ParseDefaultAssignment(FieldDescriptorProto* field); |
+ bool ParseDefaultAssignment(FieldDescriptorProto* field, |
+ const LocationRecorder& field_location); |
// Parse a single option name/value pair, e.g. "ctype = CORD". The name |
// identifies a field of the given Message, and the value of that field |
// is set to the parsed value. |
- bool ParseOptionAssignment(Message* options); |
+ bool ParseOptionAssignment(Message* options, |
+ const LocationRecorder& options_location); |
// Parses a single part of a multipart option name. A multipart name consists |
// of names separated by dots. Each name is either an identifier or a series |
// of identifiers separated by dots and enclosed in parentheses. E.g., |
// "foo.(bar.baz).qux". |
- bool ParseOptionNamePart(UninterpretedOption* uninterpreted_option); |
+ bool ParseOptionNamePart(UninterpretedOption* uninterpreted_option, |
+ const LocationRecorder& part_location); |
+ |
+ // Parses a string surrounded by balanced braces. Strips off the outer |
+ // braces and stores the enclosed string in *value. |
+ // E.g., |
+ // { foo } *value gets 'foo' |
+ // { foo { bar: box } } *value gets 'foo { bar: box }' |
+ // {} *value gets '' |
+ // |
+ // REQUIRES: LookingAt("{") |
+ // When finished successfully, we are looking at the first token past |
+ // the ending brace. |
+ bool ParseUninterpretedBlock(string* value); |
// ================================================================= |
io::Tokenizer* input_; |
io::ErrorCollector* error_collector_; |
- SourceLocationTable* source_location_table_; |
+ SourceCodeInfo* source_code_info_; |
+ SourceLocationTable* source_location_table_; // legacy |
bool had_errors_; |
bool require_syntax_identifier_; |
bool stop_after_syntax_identifier_; |
@@ -302,6 +393,11 @@ class LIBPROTOBUF_EXPORT Parser { |
// A table mapping (descriptor, ErrorLocation) pairs -- as reported by |
// DescriptorPool when validating descriptors -- to line and column numbers |
// within the original source code. |
+// |
+// This is semi-obsolete: FileDescriptorProto.source_code_info now contains |
+// far more complete information about source locations. However, as of this |
+// writing you still need to use SourceLocationTable when integrating with |
+// DescriptorPool. |
class LIBPROTOBUF_EXPORT SourceLocationTable { |
public: |
SourceLocationTable(); |