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 28 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602
  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. 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. struct MapField;
  108. // =================================================================
  109. // Error recovery helpers
  110. // Consume the rest of the current statement. This consumes tokens
  111. // until it sees one of:
  112. // ';' Consumes the token and returns.
  113. // '{' Consumes the brace then calls SkipRestOfBlock().
  114. // '}' Returns without consuming.
  115. // EOF Returns (can't consume).
  116. // The Parser often calls SkipStatement() after encountering a syntax
  117. // error. This allows it to go on parsing the following lines, allowing
  118. // it to report more than just one error in the file.
  119. void SkipStatement();
  120. // Consume the rest of the current block, including nested blocks,
  121. // ending after the closing '}' is encountered and consumed, or at EOF.
  122. void SkipRestOfBlock();
  123. // -----------------------------------------------------------------
  124. // Single-token consuming helpers
  125. //
  126. // These make parsing code more readable.
  127. // True if the current token is TYPE_END.
  128. inline bool AtEnd();
  129. // True if the next token matches the given text.
  130. inline bool LookingAt(const char* text);
  131. // True if the next token is of the given type.
  132. inline bool LookingAtType(io::Tokenizer::TokenType token_type);
  133. // If the next token exactly matches the text given, consume it and return
  134. // true. Otherwise, return false without logging an error.
  135. bool TryConsume(const char* text);
  136. // These attempt to read some kind of token from the input. If successful,
  137. // they return true. Otherwise they return false and add the given error
  138. // to the error list.
  139. // Consume a token with the exact text given.
  140. bool Consume(const char* text, const char* error);
  141. // Same as above, but automatically generates the error "Expected \"text\".",
  142. // where "text" is the expected token text.
  143. bool Consume(const char* text);
  144. // Consume a token of type IDENTIFIER and store its text in "output".
  145. bool ConsumeIdentifier(std::string* output, const char* error);
  146. // Consume an integer and store its value in "output".
  147. bool ConsumeInteger(int* output, const char* error);
  148. // Consume a signed integer and store its value in "output".
  149. bool ConsumeSignedInteger(int* output, const char* error);
  150. // Consume a 64-bit integer and store its value in "output". If the value
  151. // is greater than max_value, an error will be reported.
  152. bool ConsumeInteger64(uint64_t max_value, uint64_t* output,
  153. const char* error);
  154. // Consume a number and store its value in "output". This will accept
  155. // tokens of either INTEGER or FLOAT type.
  156. bool ConsumeNumber(double* output, const char* error);
  157. // Consume a string literal and store its (unescaped) value in "output".
  158. bool ConsumeString(std::string* output, const char* error);
  159. // Consume a token representing the end of the statement. Comments between
  160. // this token and the next will be harvested for documentation. The given
  161. // LocationRecorder should refer to the declaration that was just parsed;
  162. // it will be populated with these comments.
  163. //
  164. // TODO(kenton): The LocationRecorder is const because historically locations
  165. // have been passed around by const reference, for no particularly good
  166. // reason. We should probably go through and change them all to mutable
  167. // pointer to make this more intuitive.
  168. bool TryConsumeEndOfDeclaration(const char* text,
  169. const LocationRecorder* location);
  170. bool TryConsumeEndOfDeclarationFinishScope(const char* text,
  171. const LocationRecorder* location);
  172. bool ConsumeEndOfDeclaration(const char* text,
  173. const LocationRecorder* location);
  174. // -----------------------------------------------------------------
  175. // Error logging helpers
  176. // Invokes error_collector_->AddError(), if error_collector_ is not NULL.
  177. void AddError(int line, int column, const std::string& error);
  178. // Invokes error_collector_->AddError() with the line and column number
  179. // of the current token.
  180. void AddError(const std::string& error);
  181. // Invokes error_collector_->AddWarning() with the line and column number
  182. // of the current token.
  183. void AddWarning(const std::string& warning);
  184. // Records a location in the SourceCodeInfo.location table (see
  185. // descriptor.proto). We use RAII to ensure that the start and end locations
  186. // are recorded -- the constructor records the start location and the
  187. // destructor records the end location. Since the parser is
  188. // recursive-descent, this works out beautifully.
  189. class PROTOBUF_EXPORT LocationRecorder {
  190. public:
  191. // Construct the file's "root" location.
  192. LocationRecorder(Parser* parser);
  193. // Construct a location that represents a declaration nested within the
  194. // given parent. E.g. a field's location is nested within the location
  195. // for a message type. The parent's path will be copied, so you should
  196. // call AddPath() only to add the path components leading from the parent
  197. // to the child (as opposed to leading from the root to the child).
  198. LocationRecorder(const LocationRecorder& parent);
  199. // Convenience constructors that call AddPath() one or two times.
  200. LocationRecorder(const LocationRecorder& parent, int path1);
  201. LocationRecorder(const LocationRecorder& parent, int path1, int path2);
  202. // Creates a recorder that generates locations into given source code info.
  203. LocationRecorder(const LocationRecorder& parent, int path1,
  204. SourceCodeInfo* source_code_info);
  205. ~LocationRecorder();
  206. // Add a path component. See SourceCodeInfo.Location.path in
  207. // descriptor.proto.
  208. void AddPath(int path_component);
  209. // By default the location is considered to start at the current token at
  210. // the time the LocationRecorder is created. StartAt() sets the start
  211. // location to the given token instead.
  212. void StartAt(const io::Tokenizer::Token& token);
  213. // Start at the same location as some other LocationRecorder.
  214. void StartAt(const LocationRecorder& other);
  215. // By default the location is considered to end at the previous token at
  216. // the time the LocationRecorder is destroyed. EndAt() sets the end
  217. // location to the given token instead.
  218. void EndAt(const io::Tokenizer::Token& token);
  219. // Records the start point of this location to the SourceLocationTable that
  220. // was passed to RecordSourceLocationsTo(), if any. SourceLocationTable
  221. // is an older way of keeping track of source locations which is still
  222. // used in some places.
  223. void RecordLegacyLocation(
  224. const Message* descriptor,
  225. DescriptorPool::ErrorCollector::ErrorLocation location);
  226. void RecordLegacyImportLocation(const Message* descriptor,
  227. const std::string& name);
  228. // Returns the number of path components in the recorder's current location.
  229. int CurrentPathSize() const;
  230. // Attaches leading and trailing comments to the location. The two strings
  231. // will be swapped into place, so after this is called *leading and
  232. // *trailing will be empty.
  233. //
  234. // TODO(kenton): See comment on TryConsumeEndOfDeclaration(), above, for
  235. // why this is const.
  236. void AttachComments(std::string* leading, std::string* trailing,
  237. std::vector<std::string>* detached_comments) const;
  238. private:
  239. Parser* parser_;
  240. SourceCodeInfo* source_code_info_;
  241. SourceCodeInfo::Location* location_;
  242. void Init(const LocationRecorder& parent, SourceCodeInfo* source_code_info);
  243. };
  244. // =================================================================
  245. // Parsers for various language constructs
  246. // Parses the "syntax = \"proto2\";" line at the top of the file. Returns
  247. // false if it failed to parse or if the syntax identifier was not
  248. // recognized.
  249. bool ParseSyntaxIdentifier(const LocationRecorder& parent);
  250. // These methods parse various individual bits of code. They return
  251. // false if they completely fail to parse the construct. In this case,
  252. // it is probably necessary to skip the rest of the statement to recover.
  253. // However, if these methods return true, it does NOT mean that there
  254. // were no errors; only that there were no *syntax* errors. For instance,
  255. // if a service method is defined using proper syntax but uses a primitive
  256. // type as its input or output, ParseMethodField() still returns true
  257. // and only reports the error by calling AddError(). In practice, this
  258. // makes logic much simpler for the caller.
  259. // Parse a top-level message, enum, service, etc.
  260. bool ParseTopLevelStatement(FileDescriptorProto* file,
  261. const LocationRecorder& root_location);
  262. // Parse various language high-level language construrcts.
  263. bool ParseMessageDefinition(DescriptorProto* message,
  264. const LocationRecorder& message_location,
  265. const FileDescriptorProto* containing_file);
  266. bool ParseEnumDefinition(EnumDescriptorProto* enum_type,
  267. const LocationRecorder& enum_location,
  268. const FileDescriptorProto* containing_file);
  269. bool ParseServiceDefinition(ServiceDescriptorProto* service,
  270. const LocationRecorder& service_location,
  271. const FileDescriptorProto* containing_file);
  272. bool ParsePackage(FileDescriptorProto* file,
  273. const LocationRecorder& root_location,
  274. const FileDescriptorProto* containing_file);
  275. bool ParseImport(RepeatedPtrField<std::string>* dependency,
  276. RepeatedField<int32_t>* public_dependency,
  277. RepeatedField<int32_t>* weak_dependency,
  278. const LocationRecorder& root_location,
  279. const FileDescriptorProto* containing_file);
  280. // These methods parse the contents of a message, enum, or service type and
  281. // add them to the given object. They consume the entire block including
  282. // the beginning and ending brace.
  283. bool ParseMessageBlock(DescriptorProto* message,
  284. const LocationRecorder& message_location,
  285. const FileDescriptorProto* containing_file);
  286. bool ParseEnumBlock(EnumDescriptorProto* enum_type,
  287. const LocationRecorder& enum_location,
  288. const FileDescriptorProto* containing_file);
  289. bool ParseServiceBlock(ServiceDescriptorProto* service,
  290. const LocationRecorder& service_location,
  291. const FileDescriptorProto* containing_file);
  292. // Parse one statement within a message, enum, or service block, including
  293. // final semicolon.
  294. bool ParseMessageStatement(DescriptorProto* message,
  295. const LocationRecorder& message_location,
  296. const FileDescriptorProto* containing_file);
  297. bool ParseEnumStatement(EnumDescriptorProto* message,
  298. const LocationRecorder& enum_location,
  299. const FileDescriptorProto* containing_file);
  300. bool ParseServiceStatement(ServiceDescriptorProto* message,
  301. const LocationRecorder& service_location,
  302. const FileDescriptorProto* containing_file);
  303. // Parse a field of a message. If the field is a group, its type will be
  304. // added to "messages".
  305. //
  306. // parent_location and location_field_number_for_nested_type are needed when
  307. // parsing groups -- we need to generate a nested message type within the
  308. // parent and record its location accordingly. Since the parent could be
  309. // either a FileDescriptorProto or a DescriptorProto, we must pass in the
  310. // correct field number to use.
  311. bool ParseMessageField(FieldDescriptorProto* field,
  312. RepeatedPtrField<DescriptorProto>* messages,
  313. const LocationRecorder& parent_location,
  314. int location_field_number_for_nested_type,
  315. const LocationRecorder& field_location,
  316. const FileDescriptorProto* containing_file);
  317. // Like ParseMessageField() but expects the label has already been filled in
  318. // by the caller.
  319. bool ParseMessageFieldNoLabel(FieldDescriptorProto* field,
  320. RepeatedPtrField<DescriptorProto>* messages,
  321. const LocationRecorder& parent_location,
  322. int location_field_number_for_nested_type,
  323. const LocationRecorder& field_location,
  324. const FileDescriptorProto* containing_file);
  325. bool ParseMapType(MapField* map_field, FieldDescriptorProto* field,
  326. LocationRecorder& type_name_location);
  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. // Parse a type name and fill in "type" (if it is a primitive) or
  383. // "type_name" (if it is not) with the type parsed.
  384. bool ParseType(FieldDescriptorProto::Type* type, std::string* type_name);
  385. // Parse a user-defined type and fill in "type_name" with the name.
  386. // If a primitive type is named, it is treated as an error.
  387. bool ParseUserDefinedType(std::string* type_name);
  388. // Parses field options, i.e. the stuff in square brackets at the end
  389. // of a field definition. Also parses default value.
  390. bool ParseFieldOptions(FieldDescriptorProto* field,
  391. const LocationRecorder& field_location,
  392. const FileDescriptorProto* containing_file);
  393. // Parse the "default" option. This needs special handling because its
  394. // type is the field's type.
  395. bool ParseDefaultAssignment(FieldDescriptorProto* field,
  396. const LocationRecorder& field_location,
  397. const FileDescriptorProto* containing_file);
  398. bool ParseJsonName(FieldDescriptorProto* field,
  399. const LocationRecorder& field_location,
  400. const FileDescriptorProto* containing_file);
  401. enum OptionStyle {
  402. OPTION_ASSIGNMENT, // just "name = value"
  403. OPTION_STATEMENT // "option name = value;"
  404. };
  405. // Parse a single option name/value pair, e.g. "ctype = CORD". The name
  406. // identifies a field of the given Message, and the value of that field
  407. // is set to the parsed value.
  408. bool ParseOption(Message* options, const LocationRecorder& options_location,
  409. const FileDescriptorProto* containing_file,
  410. OptionStyle style);
  411. // Parses a single part of a multipart option name. A multipart name consists
  412. // of names separated by dots. Each name is either an identifier or a series
  413. // of identifiers separated by dots and enclosed in parentheses. E.g.,
  414. // "foo.(bar.baz).moo".
  415. bool ParseOptionNamePart(UninterpretedOption* uninterpreted_option,
  416. const LocationRecorder& part_location,
  417. const FileDescriptorProto* containing_file);
  418. // Parses a string surrounded by balanced braces. Strips off the outer
  419. // braces and stores the enclosed string in *value.
  420. // E.g.,
  421. // { foo } *value gets 'foo'
  422. // { foo { bar: box } } *value gets 'foo { bar: box }'
  423. // {} *value gets ''
  424. //
  425. // REQUIRES: LookingAt("{")
  426. // When finished successfully, we are looking at the first token past
  427. // the ending brace.
  428. bool ParseUninterpretedBlock(std::string* value);
  429. struct MapField {
  430. // Whether the field is a map field.
  431. bool is_map_field;
  432. // The types of the key and value if they are primitive types.
  433. FieldDescriptorProto::Type key_type;
  434. FieldDescriptorProto::Type value_type;
  435. // Or the type names string if the types are customized types.
  436. std::string key_type_name;
  437. std::string value_type_name;
  438. MapField() : is_map_field(false) {}
  439. };
  440. // Desugar the map syntax to generate a nested map entry message.
  441. void GenerateMapEntry(const MapField& map_field, FieldDescriptorProto* field,
  442. RepeatedPtrField<DescriptorProto>* messages);
  443. // Whether fields without label default to optional fields.
  444. bool DefaultToOptionalFields() const {
  445. return syntax_identifier_ == "proto3";
  446. }
  447. bool ValidateEnum(const EnumDescriptorProto* proto);
  448. // =================================================================
  449. io::Tokenizer* input_;
  450. io::ErrorCollector* error_collector_;
  451. SourceCodeInfo* source_code_info_;
  452. SourceLocationTable* source_location_table_; // legacy
  453. bool had_errors_;
  454. bool require_syntax_identifier_;
  455. bool stop_after_syntax_identifier_;
  456. std::string syntax_identifier_;
  457. // Leading doc comments for the next declaration. These are not complete
  458. // yet; use ConsumeEndOfDeclaration() to get the complete comments.
  459. std::string upcoming_doc_comments_;
  460. // Detached comments are not connected to any syntax entities. Elements in
  461. // this vector are paragraphs of comments separated by empty lines. The
  462. // detached comments will be put into the leading_detached_comments field for
  463. // the next element (See SourceCodeInfo.Location in descriptor.proto), when
  464. // ConsumeEndOfDeclaration() is called.
  465. std::vector<std::string> upcoming_detached_comments_;
  466. GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Parser);
  467. };
  468. // A table mapping (descriptor, ErrorLocation) pairs -- as reported by
  469. // DescriptorPool when validating descriptors -- to line and column numbers
  470. // within the original source code.
  471. //
  472. // This is semi-obsolete: FileDescriptorProto.source_code_info now contains
  473. // far more complete information about source locations. However, as of this
  474. // writing you still need to use SourceLocationTable when integrating with
  475. // DescriptorPool.
  476. class PROTOBUF_EXPORT SourceLocationTable {
  477. public:
  478. SourceLocationTable();
  479. ~SourceLocationTable();
  480. // Finds the precise location of the given error and fills in *line and
  481. // *column with the line and column numbers. If not found, sets *line to
  482. // -1 and *column to 0 (since line = -1 is used to mean "error has no exact
  483. // location" in the ErrorCollector interface). Returns true if found, false
  484. // otherwise.
  485. bool Find(const Message* descriptor,
  486. DescriptorPool::ErrorCollector::ErrorLocation location, int* line,
  487. int* column) const;
  488. bool FindImport(const Message* descriptor, const std::string& name, int* line,
  489. int* column) const;
  490. // Adds a location to the table.
  491. void Add(const Message* descriptor,
  492. DescriptorPool::ErrorCollector::ErrorLocation location, int line,
  493. int column);
  494. void AddImport(const Message* descriptor, const std::string& name, int line,
  495. int column);
  496. // Clears the contents of the table.
  497. void Clear();
  498. private:
  499. typedef std::map<
  500. std::pair<const Message*, DescriptorPool::ErrorCollector::ErrorLocation>,
  501. std::pair<int, int> >
  502. LocationMap;
  503. LocationMap location_map_;
  504. std::map<std::pair<const Message*, std::string>, std::pair<int, int> >
  505. import_location_map_;
  506. };
  507. } // namespace compiler
  508. } // namespace protobuf
  509. } // namespace google
  510. #include <google/protobuf/port_undef.inc>
  511. #endif // GOOGLE_PROTOBUF_COMPILER_PARSER_H__