诸暨麻将添加redis
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

601 lines
28 KiB

  1. // Protocol Buffers - Google's data interchange format
  2. // Copyright 2008 Google Inc. All rights reserved.
  3. // https://developers.google.com/protocol-buffers/
  4. //
  5. // Redistribution and use in source and binary forms, with or without
  6. // modification, are permitted provided that the following conditions are
  7. // met:
  8. //
  9. // * Redistributions of source code must retain the above copyright
  10. // notice, this list of conditions and the following disclaimer.
  11. // * Redistributions in binary form must reproduce the above
  12. // copyright notice, this list of conditions and the following disclaimer
  13. // in the documentation and/or other materials provided with the
  14. // distribution.
  15. // * Neither the name of Google Inc. nor the names of its
  16. // contributors may be used to endorse or promote products derived from
  17. // this software without specific prior written permission.
  18. //
  19. // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  20. // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  21. // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  22. // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  23. // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  24. // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  25. // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  26. // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  27. // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  28. // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  29. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  30. // Author: kenton@google.com (Kenton Varda)
  31. // Based on original Protocol Buffers design by
  32. // Sanjay Ghemawat, Jeff Dean, and others.
  33. //
  34. // Implements parsing of .proto files to FileDescriptorProtos.
  35. #ifndef GOOGLE_PROTOBUF_COMPILER_PARSER_H__
  36. #define GOOGLE_PROTOBUF_COMPILER_PARSER_H__
  37. #include <map>
  38. #include <string>
  39. #include <utility>
  40. #include <google/protobuf/descriptor.pb.h>
  41. #include <google/protobuf/io/tokenizer.h>
  42. #include <google/protobuf/descriptor.h>
  43. #include <google/protobuf/repeated_field.h>
  44. #include <google/protobuf/port_def.inc>
  45. namespace google {
  46. namespace protobuf {
  47. class Message;
  48. namespace compiler {
  49. // Defined in this file.
  50. class Parser;
  51. class SourceLocationTable;
  52. // Implements parsing of protocol definitions (such as .proto files).
  53. //
  54. // Note that most users will be more interested in the Importer class.
  55. // Parser is a lower-level class which simply converts a single .proto file
  56. // to a FileDescriptorProto. It does not resolve import directives or perform
  57. // many other kinds of validation needed to construct a complete
  58. // FileDescriptor.
  59. class PROTOBUF_EXPORT Parser {
  60. public:
  61. Parser();
  62. ~Parser();
  63. // Parse the entire input and construct a FileDescriptorProto representing
  64. // it. Returns true if no errors occurred, false otherwise.
  65. bool Parse(io::Tokenizer* input, FileDescriptorProto* file);
  66. // Optional features:
  67. // DEPRECATED: New code should use the SourceCodeInfo embedded in the
  68. // FileDescriptorProto.
  69. //
  70. // Requests that locations of certain definitions be recorded to the given
  71. // SourceLocationTable while parsing. This can be used to look up exact line
  72. // and column numbers for errors reported by DescriptorPool during validation.
  73. // Set to NULL (the default) to discard source location information.
  74. void RecordSourceLocationsTo(SourceLocationTable* location_table) {
  75. source_location_table_ = location_table;
  76. }
  77. // Requests that errors be recorded to the given ErrorCollector while
  78. // parsing. Set to NULL (the default) to discard error messages.
  79. void RecordErrorsTo(io::ErrorCollector* error_collector) {
  80. error_collector_ = error_collector;
  81. }
  82. // Returns the identifier used in the "syntax = " declaration, if one was
  83. // seen during the last call to Parse(), or the empty string otherwise.
  84. const std::string& GetSyntaxIdentifier() { return syntax_identifier_; }
  85. // If set true, input files will be required to begin with a syntax
  86. // identifier. Otherwise, files may omit this. If a syntax identifier
  87. // is provided, it must be 'syntax = "proto2";' and must appear at the
  88. // top of this file regardless of whether or not it was required.
  89. void SetRequireSyntaxIdentifier(bool value) {
  90. require_syntax_identifier_ = value;
  91. }
  92. // Call SetStopAfterSyntaxIdentifier(true) to tell the parser to stop
  93. // parsing as soon as it has seen the syntax identifier, or lack thereof.
  94. // This is useful for quickly identifying the syntax of the file without
  95. // parsing the whole thing. If this is enabled, no error will be recorded
  96. // if the syntax identifier is something other than "proto2" (since
  97. // presumably the caller intends to deal with that), but other kinds of
  98. // errors (e.g. parse errors) will still be reported. When this is enabled,
  99. // you may pass a NULL FileDescriptorProto to Parse().
  100. void SetStopAfterSyntaxIdentifier(bool value) {
  101. stop_after_syntax_identifier_ = value;
  102. }
  103. private:
  104. class LocationRecorder;
  105. // =================================================================
  106. // Error recovery helpers
  107. // Consume the rest of the current statement. This consumes tokens
  108. // until it sees one of:
  109. // ';' Consumes the token and returns.
  110. // '{' Consumes the brace then calls SkipRestOfBlock().
  111. // '}' Returns without consuming.
  112. // EOF Returns (can't consume).
  113. // The Parser often calls SkipStatement() after encountering a syntax
  114. // error. This allows it to go on parsing the following lines, allowing
  115. // it to report more than just one error in the file.
  116. void SkipStatement();
  117. // Consume the rest of the current block, including nested blocks,
  118. // ending after the closing '}' is encountered and consumed, or at EOF.
  119. void SkipRestOfBlock();
  120. // -----------------------------------------------------------------
  121. // Single-token consuming helpers
  122. //
  123. // These make parsing code more readable.
  124. // True if the current token is TYPE_END.
  125. inline bool AtEnd();
  126. // True if the next token matches the given text.
  127. inline bool LookingAt(const char* text);
  128. // True if the next token is of the given type.
  129. inline bool LookingAtType(io::Tokenizer::TokenType token_type);
  130. // If the next token exactly matches the text given, consume it and return
  131. // true. Otherwise, return false without logging an error.
  132. bool TryConsume(const char* text);
  133. // These attempt to read some kind of token from the input. If successful,
  134. // they return true. Otherwise they return false and add the given error
  135. // to the error list.
  136. // Consume a token with the exact text given.
  137. bool Consume(const char* text, const char* error);
  138. // Same as above, but automatically generates the error "Expected \"text\".",
  139. // where "text" is the expected token text.
  140. bool Consume(const char* text);
  141. // Consume a token of type IDENTIFIER and store its text in "output".
  142. bool ConsumeIdentifier(std::string* output, const char* error);
  143. // Consume an integer and store its value in "output".
  144. bool ConsumeInteger(int* output, const char* error);
  145. // Consume a signed integer and store its value in "output".
  146. bool ConsumeSignedInteger(int* output, const char* error);
  147. // Consume a 64-bit integer and store its value in "output". If the value
  148. // is greater than max_value, an error will be reported.
  149. bool ConsumeInteger64(uint64 max_value, uint64* output, const char* error);
  150. // Consume a number and store its value in "output". This will accept
  151. // tokens of either INTEGER or FLOAT type.
  152. bool ConsumeNumber(double* output, const char* error);
  153. // Consume a string literal and store its (unescaped) value in "output".
  154. bool ConsumeString(std::string* output, const char* error);
  155. // Consume a token representing the end of the statement. Comments between
  156. // this token and the next will be harvested for documentation. The given
  157. // LocationRecorder should refer to the declaration that was just parsed;
  158. // it will be populated with these comments.
  159. //
  160. // TODO(kenton): The LocationRecorder is const because historically locations
  161. // have been passed around by const reference, for no particularly good
  162. // reason. We should probably go through and change them all to mutable
  163. // pointer to make this more intuitive.
  164. bool TryConsumeEndOfDeclaration(const char* text,
  165. const LocationRecorder* location);
  166. bool TryConsumeEndOfDeclarationFinishScope(const char* text,
  167. const LocationRecorder* location);
  168. bool ConsumeEndOfDeclaration(const char* text,
  169. const LocationRecorder* location);
  170. // -----------------------------------------------------------------
  171. // Error logging helpers
  172. // Invokes error_collector_->AddError(), if error_collector_ is not NULL.
  173. void AddError(int line, int column, const std::string& error);
  174. // Invokes error_collector_->AddError() with the line and column number
  175. // of the current token.
  176. void AddError(const std::string& error);
  177. // Invokes error_collector_->AddWarning() with the line and column number
  178. // of the current token.
  179. void AddWarning(const string& warning);
  180. // Records a location in the SourceCodeInfo.location table (see
  181. // descriptor.proto). We use RAII to ensure that the start and end locations
  182. // are recorded -- the constructor records the start location and the
  183. // destructor records the end location. Since the parser is
  184. // recursive-descent, this works out beautifully.
  185. class PROTOBUF_EXPORT LocationRecorder {
  186. public:
  187. // Construct the file's "root" location.
  188. LocationRecorder(Parser* parser);
  189. // Construct a location that represents a declaration nested within the
  190. // given parent. E.g. a field's location is nested within the location
  191. // for a message type. The parent's path will be copied, so you should
  192. // call AddPath() only to add the path components leading from the parent
  193. // to the child (as opposed to leading from the root to the child).
  194. LocationRecorder(const LocationRecorder& parent);
  195. // Convenience constructors that call AddPath() one or two times.
  196. LocationRecorder(const LocationRecorder& parent, int path1);
  197. LocationRecorder(const LocationRecorder& parent, int path1, int path2);
  198. // Creates a recorder that generates locations into given source code info.
  199. LocationRecorder(const LocationRecorder& parent, int path1,
  200. SourceCodeInfo* source_code_info);
  201. ~LocationRecorder();
  202. // Add a path component. See SourceCodeInfo.Location.path in
  203. // descriptor.proto.
  204. void AddPath(int path_component);
  205. // By default the location is considered to start at the current token at
  206. // the time the LocationRecorder is created. StartAt() sets the start
  207. // location to the given token instead.
  208. void StartAt(const io::Tokenizer::Token& token);
  209. // Start at the same location as some other LocationRecorder.
  210. void StartAt(const LocationRecorder& other);
  211. // By default the location is considered to end at the previous token at
  212. // the time the LocationRecorder is destroyed. EndAt() sets the end
  213. // location to the given token instead.
  214. void EndAt(const io::Tokenizer::Token& token);
  215. // Records the start point of this location to the SourceLocationTable that
  216. // was passed to RecordSourceLocationsTo(), if any. SourceLocationTable
  217. // is an older way of keeping track of source locations which is still
  218. // used in some places.
  219. void RecordLegacyLocation(
  220. const Message* descriptor,
  221. DescriptorPool::ErrorCollector::ErrorLocation location);
  222. void RecordLegacyImportLocation(const Message* descriptor,
  223. const string& name);
  224. // Returns the number of path components in the recorder's current location.
  225. int CurrentPathSize() const;
  226. // Attaches leading and trailing comments to the location. The two strings
  227. // will be swapped into place, so after this is called *leading and
  228. // *trailing will be empty.
  229. //
  230. // TODO(kenton): See comment on TryConsumeEndOfDeclaration(), above, for
  231. // why this is const.
  232. void AttachComments(std::string* leading, std::string* trailing,
  233. std::vector<std::string>* detached_comments) const;
  234. private:
  235. // Indexes of parent and current location in the parent
  236. // SourceCodeInfo.location repeated field. For top-level elements,
  237. // parent_index_ is -1.
  238. Parser* parser_;
  239. SourceCodeInfo* source_code_info_;
  240. SourceCodeInfo::Location* location_;
  241. void Init(const LocationRecorder& parent, SourceCodeInfo* source_code_info);
  242. };
  243. // =================================================================
  244. // Parsers for various language constructs
  245. // Parses the "syntax = \"proto2\";" line at the top of the file. Returns
  246. // false if it failed to parse or if the syntax identifier was not
  247. // recognized.
  248. bool ParseSyntaxIdentifier(const LocationRecorder& parent);
  249. // These methods parse various individual bits of code. They return
  250. // false if they completely fail to parse the construct. In this case,
  251. // it is probably necessary to skip the rest of the statement to recover.
  252. // However, if these methods return true, it does NOT mean that there
  253. // were no errors; only that there were no *syntax* errors. For instance,
  254. // if a service method is defined using proper syntax but uses a primitive
  255. // type as its input or output, ParseMethodField() still returns true
  256. // and only reports the error by calling AddError(). In practice, this
  257. // makes logic much simpler for the caller.
  258. // Parse a top-level message, enum, service, etc.
  259. bool ParseTopLevelStatement(FileDescriptorProto* file,
  260. const LocationRecorder& root_location);
  261. // Parse various language high-level language construrcts.
  262. bool ParseMessageDefinition(DescriptorProto* message,
  263. const LocationRecorder& message_location,
  264. const FileDescriptorProto* containing_file);
  265. bool ParseEnumDefinition(EnumDescriptorProto* enum_type,
  266. const LocationRecorder& enum_location,
  267. const FileDescriptorProto* containing_file);
  268. bool ParseServiceDefinition(ServiceDescriptorProto* service,
  269. const LocationRecorder& service_location,
  270. const FileDescriptorProto* containing_file);
  271. bool ParsePackage(FileDescriptorProto* file,
  272. const LocationRecorder& root_location,
  273. const FileDescriptorProto* containing_file);
  274. bool ParseImport(RepeatedPtrField<std::string>* dependency,
  275. RepeatedField<int32>* public_dependency,
  276. RepeatedField<int32>* weak_dependency,
  277. const LocationRecorder& root_location,
  278. const FileDescriptorProto* containing_file);
  279. // These methods parse the contents of a message, enum, or service type and
  280. // add them to the given object. They consume the entire block including
  281. // the beginning and ending brace.
  282. bool ParseMessageBlock(DescriptorProto* message,
  283. const LocationRecorder& message_location,
  284. const FileDescriptorProto* containing_file);
  285. bool ParseEnumBlock(EnumDescriptorProto* enum_type,
  286. const LocationRecorder& enum_location,
  287. const FileDescriptorProto* containing_file);
  288. bool ParseServiceBlock(ServiceDescriptorProto* service,
  289. const LocationRecorder& service_location,
  290. const FileDescriptorProto* containing_file);
  291. // Parse one statement within a message, enum, or service block, including
  292. // final semicolon.
  293. bool ParseMessageStatement(DescriptorProto* message,
  294. const LocationRecorder& message_location,
  295. const FileDescriptorProto* containing_file);
  296. bool ParseEnumStatement(EnumDescriptorProto* message,
  297. const LocationRecorder& enum_location,
  298. const FileDescriptorProto* containing_file);
  299. bool ParseServiceStatement(ServiceDescriptorProto* message,
  300. const LocationRecorder& service_location,
  301. const FileDescriptorProto* containing_file);
  302. // Parse a field of a message. If the field is a group, its type will be
  303. // added to "messages".
  304. //
  305. // parent_location and location_field_number_for_nested_type are needed when
  306. // parsing groups -- we need to generate a nested message type within the
  307. // parent and record its location accordingly. Since the parent could be
  308. // either a FileDescriptorProto or a DescriptorProto, we must pass in the
  309. // correct field number to use.
  310. bool ParseMessageField(FieldDescriptorProto* field,
  311. RepeatedPtrField<DescriptorProto>* messages,
  312. const LocationRecorder& parent_location,
  313. int location_field_number_for_nested_type,
  314. const LocationRecorder& field_location,
  315. const FileDescriptorProto* containing_file);
  316. // Like ParseMessageField() but expects the label has already been filled in
  317. // by the caller.
  318. bool ParseMessageFieldNoLabel(FieldDescriptorProto* field,
  319. RepeatedPtrField<DescriptorProto>* messages,
  320. const LocationRecorder& parent_location,
  321. int location_field_number_for_nested_type,
  322. const LocationRecorder& field_location,
  323. const FileDescriptorProto* containing_file);
  324. // Parse an "extensions" declaration.
  325. bool ParseExtensions(DescriptorProto* message,
  326. const LocationRecorder& extensions_location,
  327. const FileDescriptorProto* containing_file);
  328. // Parse a "reserved" declaration.
  329. bool ParseReserved(DescriptorProto* message,
  330. const LocationRecorder& message_location);
  331. bool ParseReservedNames(DescriptorProto* message,
  332. const LocationRecorder& parent_location);
  333. bool ParseReservedNumbers(DescriptorProto* message,
  334. const LocationRecorder& parent_location);
  335. bool ParseReserved(EnumDescriptorProto* message,
  336. const LocationRecorder& message_location);
  337. bool ParseReservedNames(EnumDescriptorProto* message,
  338. const LocationRecorder& parent_location);
  339. bool ParseReservedNumbers(EnumDescriptorProto* message,
  340. const LocationRecorder& parent_location);
  341. // Parse an "extend" declaration. (See also comments for
  342. // ParseMessageField().)
  343. bool ParseExtend(RepeatedPtrField<FieldDescriptorProto>* extensions,
  344. RepeatedPtrField<DescriptorProto>* messages,
  345. const LocationRecorder& parent_location,
  346. int location_field_number_for_nested_type,
  347. const LocationRecorder& extend_location,
  348. const FileDescriptorProto* containing_file);
  349. // Parse a "oneof" declaration. The caller is responsible for setting
  350. // oneof_decl->label() since it will have had to parse the label before it
  351. // knew it was parsing a oneof.
  352. bool ParseOneof(OneofDescriptorProto* oneof_decl,
  353. DescriptorProto* containing_type, int oneof_index,
  354. const LocationRecorder& oneof_location,
  355. const LocationRecorder& containing_type_location,
  356. const FileDescriptorProto* containing_file);
  357. // Parse a single enum value within an enum block.
  358. bool ParseEnumConstant(EnumValueDescriptorProto* enum_value,
  359. const LocationRecorder& enum_value_location,
  360. const FileDescriptorProto* containing_file);
  361. // Parse enum constant options, i.e. the list in square brackets at the end
  362. // of the enum constant value definition.
  363. bool ParseEnumConstantOptions(EnumValueDescriptorProto* value,
  364. const LocationRecorder& enum_value_location,
  365. const FileDescriptorProto* containing_file);
  366. // Parse a single method within a service definition.
  367. bool ParseServiceMethod(MethodDescriptorProto* method,
  368. const LocationRecorder& method_location,
  369. const FileDescriptorProto* containing_file);
  370. // Parse options of a single method or stream.
  371. bool ParseMethodOptions(const LocationRecorder& parent_location,
  372. const FileDescriptorProto* containing_file,
  373. const int optionsFieldNumber,
  374. Message* mutable_options);
  375. // Parse "required", "optional", or "repeated" and fill in "label"
  376. // with the value. Returns true if such a label is consumed.
  377. bool ParseLabel(FieldDescriptorProto::Label* label,
  378. const LocationRecorder& field_location,
  379. const FileDescriptorProto* containing_file);
  380. // Parse a type name and fill in "type" (if it is a primitive) or
  381. // "type_name" (if it is not) with the type parsed.
  382. bool ParseType(FieldDescriptorProto::Type* type, std::string* type_name);
  383. // Parse a user-defined type and fill in "type_name" with the name.
  384. // If a primitive type is named, it is treated as an error.
  385. bool ParseUserDefinedType(std::string* type_name);
  386. // Parses field options, i.e. the stuff in square brackets at the end
  387. // of a field definition. Also parses default value.
  388. bool ParseFieldOptions(FieldDescriptorProto* field,
  389. const LocationRecorder& field_location,
  390. const FileDescriptorProto* containing_file);
  391. // Parse the "default" option. This needs special handling because its
  392. // type is the field's type.
  393. bool ParseDefaultAssignment(FieldDescriptorProto* field,
  394. const LocationRecorder& field_location,
  395. const FileDescriptorProto* containing_file);
  396. bool ParseJsonName(FieldDescriptorProto* field,
  397. const LocationRecorder& field_location,
  398. const FileDescriptorProto* containing_file);
  399. enum OptionStyle {
  400. OPTION_ASSIGNMENT, // just "name = value"
  401. OPTION_STATEMENT // "option name = value;"
  402. };
  403. // Parse a single option name/value pair, e.g. "ctype = CORD". The name
  404. // identifies a field of the given Message, and the value of that field
  405. // is set to the parsed value.
  406. bool ParseOption(Message* options, const LocationRecorder& options_location,
  407. const FileDescriptorProto* containing_file,
  408. OptionStyle style);
  409. // Parses a single part of a multipart option name. A multipart name consists
  410. // of names separated by dots. Each name is either an identifier or a series
  411. // of identifiers separated by dots and enclosed in parentheses. E.g.,
  412. // "foo.(bar.baz).qux".
  413. bool ParseOptionNamePart(UninterpretedOption* uninterpreted_option,
  414. const LocationRecorder& part_location,
  415. const FileDescriptorProto* containing_file);
  416. // Parses a string surrounded by balanced braces. Strips off the outer
  417. // braces and stores the enclosed string in *value.
  418. // E.g.,
  419. // { foo } *value gets 'foo'
  420. // { foo { bar: box } } *value gets 'foo { bar: box }'
  421. // {} *value gets ''
  422. //
  423. // REQUIRES: LookingAt("{")
  424. // When finished successfully, we are looking at the first token past
  425. // the ending brace.
  426. bool ParseUninterpretedBlock(std::string* value);
  427. struct MapField {
  428. // Whether the field is a map field.
  429. bool is_map_field;
  430. // The types of the key and value if they are primitive types.
  431. FieldDescriptorProto::Type key_type;
  432. FieldDescriptorProto::Type value_type;
  433. // Or the type names string if the types are customized types.
  434. std::string key_type_name;
  435. std::string value_type_name;
  436. MapField() : is_map_field(false) {}
  437. };
  438. // Desugar the map syntax to generate a nested map entry message.
  439. void GenerateMapEntry(const MapField& map_field, FieldDescriptorProto* field,
  440. RepeatedPtrField<DescriptorProto>* messages);
  441. // Whether fields without label default to optional fields.
  442. bool DefaultToOptionalFields() const {
  443. return syntax_identifier_ == "proto3";
  444. }
  445. bool ValidateEnum(const EnumDescriptorProto* proto);
  446. // =================================================================
  447. io::Tokenizer* input_;
  448. io::ErrorCollector* error_collector_;
  449. SourceCodeInfo* source_code_info_;
  450. SourceLocationTable* source_location_table_; // legacy
  451. bool had_errors_;
  452. bool require_syntax_identifier_;
  453. bool stop_after_syntax_identifier_;
  454. std::string syntax_identifier_;
  455. // Leading doc comments for the next declaration. These are not complete
  456. // yet; use ConsumeEndOfDeclaration() to get the complete comments.
  457. std::string upcoming_doc_comments_;
  458. // Detached comments are not connected to any syntax entities. Elements in
  459. // this vector are paragraphs of comments separated by empty lines. The
  460. // detached comments will be put into the leading_detached_comments field for
  461. // the next element (See SourceCodeInfo.Location in descriptor.proto), when
  462. // ConsumeEndOfDeclaration() is called.
  463. std::vector<std::string> upcoming_detached_comments_;
  464. GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Parser);
  465. };
  466. // A table mapping (descriptor, ErrorLocation) pairs -- as reported by
  467. // DescriptorPool when validating descriptors -- to line and column numbers
  468. // within the original source code.
  469. //
  470. // This is semi-obsolete: FileDescriptorProto.source_code_info now contains
  471. // far more complete information about source locations. However, as of this
  472. // writing you still need to use SourceLocationTable when integrating with
  473. // DescriptorPool.
  474. class PROTOBUF_EXPORT SourceLocationTable {
  475. public:
  476. SourceLocationTable();
  477. ~SourceLocationTable();
  478. // Finds the precise location of the given error and fills in *line and
  479. // *column with the line and column numbers. If not found, sets *line to
  480. // -1 and *column to 0 (since line = -1 is used to mean "error has no exact
  481. // location" in the ErrorCollector interface). Returns true if found, false
  482. // otherwise.
  483. bool Find(const Message* descriptor,
  484. DescriptorPool::ErrorCollector::ErrorLocation location, int* line,
  485. int* column) const;
  486. bool FindImport(const Message* descriptor, const string& name, int* line,
  487. int* column) const;
  488. // Adds a location to the table.
  489. void Add(const Message* descriptor,
  490. DescriptorPool::ErrorCollector::ErrorLocation location, int line,
  491. int column);
  492. void AddImport(const Message* descriptor, const string& name, int line,
  493. int column);
  494. // Clears the contents of the table.
  495. void Clear();
  496. private:
  497. typedef std::map<
  498. std::pair<const Message*, DescriptorPool::ErrorCollector::ErrorLocation>,
  499. std::pair<int, int> >
  500. LocationMap;
  501. LocationMap location_map_;
  502. std::map<std::pair<const Message*, string>, std::pair<int, int> >
  503. import_location_map_;
  504. };
  505. } // namespace compiler
  506. } // namespace protobuf
  507. } // namespace google
  508. #include <google/protobuf/port_undef.inc>
  509. #endif // GOOGLE_PROTOBUF_COMPILER_PARSER_H__