parser.h 27 KB

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