You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

parser.h 31 kB

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