Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-31 10:12:00

0001 // Protocol Buffers - Google's data interchange format
0002 // Copyright 2008 Google Inc.  All rights reserved.
0003 //
0004 // Use of this source code is governed by a BSD-style
0005 // license that can be found in the LICENSE file or at
0006 // https://developers.google.com/open-source/licenses/bsd
0007 
0008 // Author: kenton@google.com (Kenton Varda)
0009 //  Based on original Protocol Buffers design by
0010 //  Sanjay Ghemawat, Jeff Dean, and others.
0011 //
0012 // Implements parsing of .proto files to FileDescriptorProtos.
0013 
0014 #ifndef GOOGLE_PROTOBUF_COMPILER_PARSER_H__
0015 #define GOOGLE_PROTOBUF_COMPILER_PARSER_H__
0016 
0017 #include <cstdint>
0018 #include <string>
0019 #include <type_traits>
0020 #include <utility>
0021 
0022 #include "absl/container/flat_hash_map.h"
0023 #include "absl/strings/string_view.h"
0024 #include "google/protobuf/descriptor.h"
0025 #include "google/protobuf/descriptor.pb.h"
0026 #include "google/protobuf/io/tokenizer.h"
0027 #include "google/protobuf/repeated_field.h"
0028 
0029 // Must be included last.
0030 #include "google/protobuf/port_def.inc"
0031 
0032 namespace google {
0033 namespace protobuf {
0034 
0035 class Message;
0036 
0037 namespace compiler {
0038 
0039 // Defined in this file.
0040 class Parser;
0041 class SourceLocationTable;
0042 
0043 // Implements parsing of protocol definitions (such as .proto files).
0044 //
0045 // Note that most users will be more interested in the Importer class.
0046 // Parser is a lower-level class which simply converts a single .proto file
0047 // to a FileDescriptorProto.  It does not resolve import directives or perform
0048 // many other kinds of validation needed to construct a complete
0049 // FileDescriptor.
0050 class PROTOBUF_EXPORT Parser final {
0051  public:
0052   Parser();
0053   Parser(const Parser&) = delete;
0054   Parser& operator=(const Parser&) = delete;
0055   ~Parser();
0056 
0057   // Parse the entire input and construct a FileDescriptorProto representing
0058   // it.  Returns true if no errors occurred, false otherwise.
0059   bool Parse(io::Tokenizer* input, FileDescriptorProto* file);
0060 
0061   // Optional features:
0062 
0063   // DEPRECATED:  New code should use the SourceCodeInfo embedded in the
0064   //   FileDescriptorProto.
0065   //
0066   // Requests that locations of certain definitions be recorded to the given
0067   // SourceLocationTable while parsing.  This can be used to look up exact line
0068   // and column numbers for errors reported by DescriptorPool during validation.
0069   // Set to NULL (the default) to discard source location information.
0070   void RecordSourceLocationsTo(SourceLocationTable* location_table) {
0071     source_location_table_ = location_table;
0072   }
0073 
0074   // Requests that errors be recorded to the given ErrorCollector while
0075   // parsing.  Set to NULL (the default) to discard error messages.
0076   void RecordErrorsTo(io::ErrorCollector* error_collector) {
0077     error_collector_ = error_collector;
0078   }
0079 
0080   // Returns the identifier used in the "syntax = " declaration, if one was
0081   // seen during the last call to Parse(), or the empty string otherwise.
0082   absl::string_view GetSyntaxIdentifier() { return syntax_identifier_; }
0083 
0084   // If set true, input files will be required to begin with a syntax
0085   // identifier.  Otherwise, files may omit this.  If a syntax identifier
0086   // is provided, it must be 'syntax = "proto2";' and must appear at the
0087   // top of this file regardless of whether or not it was required.
0088   void SetRequireSyntaxIdentifier(bool value) {
0089     require_syntax_identifier_ = value;
0090   }
0091 
0092   // Call SetStopAfterSyntaxIdentifier(true) to tell the parser to stop
0093   // parsing as soon as it has seen the syntax identifier, or lack thereof.
0094   // This is useful for quickly identifying the syntax of the file without
0095   // parsing the whole thing.  If this is enabled, no error will be recorded
0096   // if the syntax identifier is something other than "proto2" (since
0097   // presumably the caller intends to deal with that), but other kinds of
0098   // errors (e.g. parse errors) will still be reported.  When this is enabled,
0099   // you may pass a NULL FileDescriptorProto to Parse().
0100   void SetStopAfterSyntaxIdentifier(bool value) {
0101     stop_after_syntax_identifier_ = value;
0102   }
0103 
0104  private:
0105   class LocationRecorder;
0106   struct MapField;
0107 
0108   // =================================================================
0109   // Error recovery helpers
0110 
0111   // Consume the rest of the current statement.  This consumes tokens
0112   // until it sees one of:
0113   //   ';'  Consumes the token and returns.
0114   //   '{'  Consumes the brace then calls SkipRestOfBlock().
0115   //   '}'  Returns without consuming.
0116   //   EOF  Returns (can't consume).
0117   // The Parser often calls SkipStatement() after encountering a syntax
0118   // error.  This allows it to go on parsing the following lines, allowing
0119   // it to report more than just one error in the file.
0120   void SkipStatement();
0121 
0122   // Consume the rest of the current block, including nested blocks,
0123   // ending after the closing '}' is encountered and consumed, or at EOF.
0124   void SkipRestOfBlock();
0125 
0126   // -----------------------------------------------------------------
0127   // Single-token consuming helpers
0128   //
0129   // These make parsing code more readable.
0130 
0131   // True if the current token is TYPE_END.
0132   inline bool AtEnd();
0133 
0134   // True if the next token matches the given text.
0135   inline bool LookingAt(absl::string_view text);
0136   // True if the next token is of the given type.
0137   inline bool LookingAtType(io::Tokenizer::TokenType token_type);
0138 
0139   // If the next token exactly matches the text given, consume it and return
0140   // true.  Otherwise, return false without logging an error.
0141   bool TryConsume(absl::string_view text);
0142 
0143   // In the following functions the error is passed as a lazily evaluated
0144   // callable to reduce stack usage and delay the actual execution of the error
0145   // statement.
0146   // Super simple type erasure interface. Similar to absl::FunctionRef but takes
0147   // the callable by value. Optimized for lambdas with at most a single pointer
0148   // as payload.
0149   class ErrorMaker {
0150     using StorageT = void*;
0151 
0152    public:
0153     template <typename F,
0154               typename = std::enable_if_t<std::is_same<
0155                   std::string, decltype(std::declval<F>()())>::value>>
0156     ErrorMaker(F f) {
0157       static_assert(sizeof(F) <= sizeof(StorageT), "");
0158       static_assert(alignof(F) <= alignof(StorageT), "");
0159       static_assert(std::is_trivially_destructible<F>::value, "");
0160       ::new (static_cast<void*>(storage_)) F(f);
0161       func_ = [](const void* p) { return (*reinterpret_cast<const F*>(p))(); };
0162     }
0163     // This overload helps callers that just want to pass a literal string.
0164     ErrorMaker(const char* error) : error_(error), func_(nullptr) {}
0165 
0166     std::string get() const { return func_ ? func_(storage_) : error_; }
0167 
0168    private:
0169     union {
0170       alignas(StorageT) char storage_[sizeof(StorageT)];
0171       const char* error_;
0172     };
0173     std::string (*func_)(const void*);
0174   };
0175 
0176   // These attempt to read some kind of token from the input.  If successful,
0177   // they return true.  Otherwise they return false and add the given error
0178   // to the error list.
0179 
0180   // Consume a token with the exact text given.
0181   bool Consume(absl::string_view text, ErrorMaker error);
0182   // Same as above, but automatically generates the error "Expected \"text\".",
0183   // where "text" is the expected token text.
0184   bool Consume(absl::string_view text);
0185   // Consume a token of type IDENTIFIER and store its text in "output".
0186   bool ConsumeIdentifier(std::string* output, ErrorMaker error);
0187   // Consume an integer and store its value in "output".
0188   bool ConsumeInteger(int* output, ErrorMaker error);
0189   // Consume a signed integer and store its value in "output".
0190   bool ConsumeSignedInteger(int* output, ErrorMaker error);
0191   // Consume a 64-bit integer and store its value in "output".  If the value
0192   // is greater than max_value, an error will be reported.
0193   bool ConsumeInteger64(uint64_t max_value, uint64_t* output, ErrorMaker error);
0194   // Try to consume a 64-bit integer and store its value in "output".  No
0195   // error is reported on failure, allowing caller to consume token another way.
0196   bool TryConsumeInteger64(uint64_t max_value, uint64_t* output);
0197   // Consume a number and store its value in "output".  This will accept
0198   // tokens of either INTEGER or FLOAT type.
0199   bool ConsumeNumber(double* output, ErrorMaker error);
0200   // Consume a string literal and store its (unescaped) value in "output".
0201   bool ConsumeString(std::string* output, ErrorMaker error);
0202 
0203   // Consume a token representing the end of the statement.  Comments between
0204   // this token and the next will be harvested for documentation.  The given
0205   // LocationRecorder should refer to the declaration that was just parsed;
0206   // it will be populated with these comments.
0207   //
0208   // TODO:  The LocationRecorder is const because historically locations
0209   //   have been passed around by const reference, for no particularly good
0210   //   reason.  We should probably go through and change them all to mutable
0211   //   pointer to make this more intuitive.
0212   bool TryConsumeEndOfDeclaration(absl::string_view text,
0213                                   const LocationRecorder* location);
0214   bool TryConsumeEndOfDeclarationFinishScope(absl::string_view text,
0215                                              const LocationRecorder* location);
0216 
0217   bool ConsumeEndOfDeclaration(absl::string_view text,
0218                                const LocationRecorder* location);
0219 
0220   // -----------------------------------------------------------------
0221   // Error logging helpers
0222 
0223   // Invokes error_collector_->RecordError(), if error_collector_ is not NULL.
0224   PROTOBUF_NOINLINE void RecordError(int line, int column, ErrorMaker error);
0225 
0226   // Invokes error_collector_->RecordError() with the line and column number
0227   // of the current token.
0228   PROTOBUF_NOINLINE void RecordError(ErrorMaker error);
0229 
0230   // Invokes error_collector_->RecordWarning(), if error_collector_ is not NULL.
0231   PROTOBUF_NOINLINE void RecordWarning(int line, int column, ErrorMaker error);
0232 
0233   // Invokes error_collector_->RecordWarning() with the line and column number
0234   // of the current token.
0235   PROTOBUF_NOINLINE void RecordWarning(ErrorMaker error);
0236 
0237   // Records a location in the SourceCodeInfo.location table (see
0238   // descriptor.proto).  We use RAII to ensure that the start and end locations
0239   // are recorded -- the constructor records the start location and the
0240   // destructor records the end location.  Since the parser is
0241   // recursive-descent, this works out beautifully.
0242   class PROTOBUF_EXPORT LocationRecorder {
0243    public:
0244     // Construct the file's "root" location.
0245     LocationRecorder(Parser* parser);
0246 
0247     // Construct a location that represents a declaration nested within the
0248     // given parent.  E.g. a field's location is nested within the location
0249     // for a message type.  The parent's path will be copied, so you should
0250     // call AddPath() only to add the path components leading from the parent
0251     // to the child (as opposed to leading from the root to the child).
0252     LocationRecorder(const LocationRecorder& parent);
0253 
0254     // Convenience constructors that call AddPath() one or two times.
0255     LocationRecorder(const LocationRecorder& parent, int path1);
0256     LocationRecorder(const LocationRecorder& parent, int path1, int path2);
0257 
0258     // Creates a recorder that generates locations into given source code info.
0259     LocationRecorder(const LocationRecorder& parent, int path1,
0260                      SourceCodeInfo* source_code_info);
0261 
0262     ~LocationRecorder();
0263 
0264     // Add a path component.  See SourceCodeInfo.Location.path in
0265     // descriptor.proto.
0266     void AddPath(int path_component);
0267 
0268     // By default the location is considered to start at the current token at
0269     // the time the LocationRecorder is created.  StartAt() sets the start
0270     // location to the given token instead.
0271     void StartAt(const io::Tokenizer::Token& token);
0272 
0273     // Start at the same location as some other LocationRecorder.
0274     void StartAt(const LocationRecorder& other);
0275 
0276     // By default the location is considered to end at the previous token at
0277     // the time the LocationRecorder is destroyed.  EndAt() sets the end
0278     // location to the given token instead.
0279     void EndAt(const io::Tokenizer::Token& token);
0280 
0281     // Records the start point of this location to the SourceLocationTable that
0282     // was passed to RecordSourceLocationsTo(), if any.  SourceLocationTable
0283     // is an older way of keeping track of source locations which is still
0284     // used in some places.
0285     void RecordLegacyLocation(
0286         const Message* descriptor,
0287         DescriptorPool::ErrorCollector::ErrorLocation location);
0288     void RecordLegacyImportLocation(const Message* descriptor,
0289                                     const std::string& name);
0290 
0291     // Returns the number of path components in the recorder's current location.
0292     int CurrentPathSize() const;
0293 
0294     // Attaches leading and trailing comments to the location.  The two strings
0295     // will be swapped into place, so after this is called *leading and
0296     // *trailing will be empty.
0297     //
0298     // TODO:  See comment on TryConsumeEndOfDeclaration(), above, for
0299     //   why this is const.
0300     void AttachComments(std::string* leading, std::string* trailing,
0301                         std::vector<std::string>* detached_comments) const;
0302 
0303    private:
0304     Parser* parser_;
0305     SourceCodeInfo* source_code_info_;
0306     SourceCodeInfo::Location* location_;
0307 
0308     void Init(const LocationRecorder& parent, SourceCodeInfo* source_code_info);
0309   };
0310 
0311   // =================================================================
0312   // Parsers for various language constructs
0313 
0314   // Parses the "syntax = \"proto2\";" line at the top of the file.  Returns
0315   // false if it failed to parse or if the syntax identifier was not
0316   // recognized.
0317   bool ParseSyntaxIdentifier(const FileDescriptorProto* file,
0318                              const LocationRecorder& parent);
0319 
0320   // These methods parse various individual bits of code.  They return
0321   // false if they completely fail to parse the construct.  In this case,
0322   // it is probably necessary to skip the rest of the statement to recover.
0323   // However, if these methods return true, it does NOT mean that there
0324   // were no errors; only that there were no *syntax* errors.  For instance,
0325   // if a service method is defined using proper syntax but uses a primitive
0326   // type as its input or output, ParseMethodField() still returns true
0327   // and only reports the error by calling RecordError().  In practice, this
0328   // makes logic much simpler for the caller.
0329 
0330   // Parse a top-level message, enum, service, etc.
0331   bool ParseTopLevelStatement(FileDescriptorProto* file,
0332                               const LocationRecorder& root_location);
0333 
0334   // Parse various language high-level language construrcts.
0335   bool ParseMessageDefinition(DescriptorProto* message,
0336                               const LocationRecorder& message_location,
0337                               const FileDescriptorProto* containing_file);
0338   bool ParseEnumDefinition(EnumDescriptorProto* enum_type,
0339                            const LocationRecorder& enum_location,
0340                            const FileDescriptorProto* containing_file);
0341   bool ParseServiceDefinition(ServiceDescriptorProto* service,
0342                               const LocationRecorder& service_location,
0343                               const FileDescriptorProto* containing_file);
0344   bool ParsePackage(FileDescriptorProto* file,
0345                     const LocationRecorder& root_location,
0346                     const FileDescriptorProto* containing_file);
0347   bool ParseImport(RepeatedPtrField<std::string>* dependency,
0348                    RepeatedField<int32_t>* public_dependency,
0349                    RepeatedField<int32_t>* weak_dependency,
0350                    const LocationRecorder& root_location,
0351                    const FileDescriptorProto* containing_file);
0352 
0353   // These methods parse the contents of a message, enum, or service type and
0354   // add them to the given object.  They consume the entire block including
0355   // the beginning and ending brace.
0356   bool ParseMessageBlock(DescriptorProto* message,
0357                          const LocationRecorder& message_location,
0358                          const FileDescriptorProto* containing_file);
0359   bool ParseEnumBlock(EnumDescriptorProto* enum_type,
0360                       const LocationRecorder& enum_location,
0361                       const FileDescriptorProto* containing_file);
0362   bool ParseServiceBlock(ServiceDescriptorProto* service,
0363                          const LocationRecorder& service_location,
0364                          const FileDescriptorProto* containing_file);
0365 
0366   // Parse one statement within a message, enum, or service block, including
0367   // final semicolon.
0368   bool ParseMessageStatement(DescriptorProto* message,
0369                              const LocationRecorder& message_location,
0370                              const FileDescriptorProto* containing_file);
0371   bool ParseEnumStatement(EnumDescriptorProto* message,
0372                           const LocationRecorder& enum_location,
0373                           const FileDescriptorProto* containing_file);
0374   bool ParseServiceStatement(ServiceDescriptorProto* message,
0375                              const LocationRecorder& service_location,
0376                              const FileDescriptorProto* containing_file);
0377 
0378   // Parse a field of a message.  If the field is a group, its type will be
0379   // added to "messages".
0380   //
0381   // parent_location and location_field_number_for_nested_type are needed when
0382   // parsing groups -- we need to generate a nested message type within the
0383   // parent and record its location accordingly.  Since the parent could be
0384   // either a FileDescriptorProto or a DescriptorProto, we must pass in the
0385   // correct field number to use.
0386   bool ParseMessageField(FieldDescriptorProto* field,
0387                          RepeatedPtrField<DescriptorProto>* messages,
0388                          const LocationRecorder& parent_location,
0389                          int location_field_number_for_nested_type,
0390                          const LocationRecorder& field_location,
0391                          const FileDescriptorProto* containing_file);
0392 
0393   // Like ParseMessageField() but expects the label has already been filled in
0394   // by the caller.
0395   bool ParseMessageFieldNoLabel(FieldDescriptorProto* field,
0396                                 RepeatedPtrField<DescriptorProto>* messages,
0397                                 const LocationRecorder& parent_location,
0398                                 int location_field_number_for_nested_type,
0399                                 const LocationRecorder& field_location,
0400                                 const FileDescriptorProto* containing_file);
0401 
0402   bool ParseMapType(MapField* map_field, FieldDescriptorProto* field,
0403                     LocationRecorder& type_name_location);
0404 
0405   // Parse an "extensions" declaration.
0406   bool ParseExtensions(DescriptorProto* message,
0407                        const LocationRecorder& extensions_location,
0408                        const FileDescriptorProto* containing_file);
0409 
0410   // Parse a "reserved" declaration.
0411   bool ParseReserved(DescriptorProto* message,
0412                      const LocationRecorder& message_location);
0413   bool ParseReservedNames(DescriptorProto* message,
0414                           const LocationRecorder& parent_location);
0415   bool ParseReservedName(std::string* name, ErrorMaker error_message);
0416   bool ParseReservedIdentifiers(DescriptorProto* message,
0417                                 const LocationRecorder& parent_location);
0418   bool ParseReservedIdentifier(std::string* name, ErrorMaker error_message);
0419   bool ParseReservedNumbers(DescriptorProto* message,
0420                             const LocationRecorder& parent_location);
0421   bool ParseReserved(EnumDescriptorProto* message,
0422                      const LocationRecorder& message_location);
0423   bool ParseReservedNames(EnumDescriptorProto* message,
0424                           const LocationRecorder& parent_location);
0425   bool ParseReservedIdentifiers(EnumDescriptorProto* message,
0426                                 const LocationRecorder& parent_location);
0427   bool ParseReservedNumbers(EnumDescriptorProto* message,
0428                             const LocationRecorder& parent_location);
0429 
0430   // Parse an "extend" declaration.  (See also comments for
0431   // ParseMessageField().)
0432   bool ParseExtend(RepeatedPtrField<FieldDescriptorProto>* extensions,
0433                    RepeatedPtrField<DescriptorProto>* messages,
0434                    const LocationRecorder& parent_location,
0435                    int location_field_number_for_nested_type,
0436                    const LocationRecorder& extend_location,
0437                    const FileDescriptorProto* containing_file);
0438 
0439   // Parse a "oneof" declaration.  The caller is responsible for setting
0440   // oneof_decl->label() since it will have had to parse the label before it
0441   // knew it was parsing a oneof.
0442   bool ParseOneof(OneofDescriptorProto* oneof_decl,
0443                   DescriptorProto* containing_type, int oneof_index,
0444                   const LocationRecorder& oneof_location,
0445                   const LocationRecorder& containing_type_location,
0446                   const FileDescriptorProto* containing_file);
0447 
0448   // Parse a single enum value within an enum block.
0449   bool ParseEnumConstant(EnumValueDescriptorProto* enum_value,
0450                          const LocationRecorder& enum_value_location,
0451                          const FileDescriptorProto* containing_file);
0452 
0453   // Parse enum constant options, i.e. the list in square brackets at the end
0454   // of the enum constant value definition.
0455   bool ParseEnumConstantOptions(EnumValueDescriptorProto* value,
0456                                 const LocationRecorder& enum_value_location,
0457                                 const FileDescriptorProto* containing_file);
0458 
0459   // Parse a single method within a service definition.
0460   bool ParseServiceMethod(MethodDescriptorProto* method,
0461                           const LocationRecorder& method_location,
0462                           const FileDescriptorProto* containing_file);
0463 
0464   // Parse options of a single method or stream.
0465   bool ParseMethodOptions(const LocationRecorder& parent_location,
0466                           const FileDescriptorProto* containing_file,
0467                           const int optionsFieldNumber,
0468                           Message* mutable_options);
0469 
0470   // Parse "required", "optional", or "repeated" and fill in "label"
0471   // with the value. Returns true if such a label is consumed.
0472   bool ParseLabel(FieldDescriptorProto::Label* label,
0473                   const LocationRecorder& field_location);
0474 
0475   // Parse a type name and fill in "type" (if it is a primitive) or
0476   // "type_name" (if it is not) with the type parsed.
0477   bool ParseType(FieldDescriptorProto::Type* type, std::string* type_name);
0478   // Parse a user-defined type and fill in "type_name" with the name.
0479   // If a primitive type is named, it is treated as an error.
0480   bool ParseUserDefinedType(std::string* type_name);
0481 
0482   // Parses field options, i.e. the stuff in square brackets at the end
0483   // of a field definition.  Also parses default value.
0484   bool ParseFieldOptions(FieldDescriptorProto* field,
0485                          const LocationRecorder& field_location,
0486                          const FileDescriptorProto* containing_file);
0487 
0488   // Parse the "default" option.  This needs special handling because its
0489   // type is the field's type.
0490   bool ParseDefaultAssignment(FieldDescriptorProto* field,
0491                               const LocationRecorder& field_location,
0492                               const FileDescriptorProto* containing_file);
0493 
0494   bool ParseJsonName(FieldDescriptorProto* field,
0495                      const LocationRecorder& field_location,
0496                      const FileDescriptorProto* containing_file);
0497 
0498   enum OptionStyle {
0499     OPTION_ASSIGNMENT,  // just "name = value"
0500     OPTION_STATEMENT    // "option name = value;"
0501   };
0502 
0503   // Parse a single option name/value pair, e.g. "ctype = CORD".  The name
0504   // identifies a field of the given Message, and the value of that field
0505   // is set to the parsed value.
0506   bool ParseOption(Message* options, const LocationRecorder& options_location,
0507                    const FileDescriptorProto* containing_file,
0508                    OptionStyle style);
0509 
0510   // Parses a single part of a multipart option name. A multipart name consists
0511   // of names separated by dots. Each name is either an identifier or a series
0512   // of identifiers separated by dots and enclosed in parentheses. E.g.,
0513   // "foo.(bar.baz).moo".
0514   bool ParseOptionNamePart(UninterpretedOption* uninterpreted_option,
0515                            const LocationRecorder& part_location,
0516                            const FileDescriptorProto* containing_file);
0517 
0518   // Parses a string surrounded by balanced braces.  Strips off the outer
0519   // braces and stores the enclosed string in *value.
0520   // E.g.,
0521   //     { foo }                     *value gets 'foo'
0522   //     { foo { bar: box } }        *value gets 'foo { bar: box }'
0523   //     {}                          *value gets ''
0524   //
0525   // REQUIRES: LookingAt("{")
0526   // When finished successfully, we are looking at the first token past
0527   // the ending brace.
0528   bool ParseUninterpretedBlock(std::string* value);
0529 
0530   struct MapField {
0531     // Whether the field is a map field.
0532     bool is_map_field;
0533     // The types of the key and value if they are primitive types.
0534     FieldDescriptorProto::Type key_type;
0535     FieldDescriptorProto::Type value_type;
0536     // Or the type names string if the types are customized types.
0537     std::string key_type_name;
0538     std::string value_type_name;
0539 
0540     MapField() : is_map_field(false) {}
0541   };
0542   // Desugar the map syntax to generate a nested map entry message.
0543   void GenerateMapEntry(const MapField& map_field, FieldDescriptorProto* field,
0544                         RepeatedPtrField<DescriptorProto>* messages);
0545 
0546   // Whether fields without label default to optional fields.
0547   bool DefaultToOptionalFields() const {
0548     if (syntax_identifier_ == "editions") return true;
0549     return syntax_identifier_ == "proto3";
0550   }
0551 
0552   bool ValidateMessage(const DescriptorProto* proto);
0553   bool ValidateEnum(const EnumDescriptorProto* proto);
0554 
0555   // =================================================================
0556 
0557   io::Tokenizer* input_;
0558   io::ErrorCollector* error_collector_;
0559   SourceCodeInfo* source_code_info_;
0560   SourceLocationTable* source_location_table_;  // legacy
0561   bool had_errors_;
0562   bool require_syntax_identifier_;
0563   bool stop_after_syntax_identifier_;
0564   std::string syntax_identifier_;
0565   Edition edition_ = Edition::EDITION_UNKNOWN;
0566   int recursion_depth_;
0567 
0568   // Leading doc comments for the next declaration.  These are not complete
0569   // yet; use ConsumeEndOfDeclaration() to get the complete comments.
0570   std::string upcoming_doc_comments_;
0571 
0572   // Detached comments are not connected to any syntax entities. Elements in
0573   // this vector are paragraphs of comments separated by empty lines. The
0574   // detached comments will be put into the leading_detached_comments field for
0575   // the next element (See SourceCodeInfo.Location in descriptor.proto), when
0576   // ConsumeEndOfDeclaration() is called.
0577   std::vector<std::string> upcoming_detached_comments_;
0578 };
0579 
0580 // A table mapping (descriptor, ErrorLocation) pairs -- as reported by
0581 // DescriptorPool when validating descriptors -- to line and column numbers
0582 // within the original source code.
0583 //
0584 // This is semi-obsolete:  FileDescriptorProto.source_code_info now contains
0585 // far more complete information about source locations.  However, as of this
0586 // writing you still need to use SourceLocationTable when integrating with
0587 // DescriptorPool.
0588 class PROTOBUF_EXPORT SourceLocationTable {
0589  public:
0590   SourceLocationTable();
0591   ~SourceLocationTable();
0592 
0593   // Finds the precise location of the given error and fills in *line and
0594   // *column with the line and column numbers.  If not found, sets *line to
0595   // -1 and *column to 0 (since line = -1 is used to mean "error has no exact
0596   // location" in the ErrorCollector interface).  Returns true if found, false
0597   // otherwise.
0598   bool Find(const Message* descriptor,
0599             DescriptorPool::ErrorCollector::ErrorLocation location, int* line,
0600             int* column) const;
0601   bool FindImport(const Message* descriptor, absl::string_view name, int* line,
0602                   int* column) const;
0603 
0604   // Adds a location to the table.
0605   void Add(const Message* descriptor,
0606            DescriptorPool::ErrorCollector::ErrorLocation location, int line,
0607            int column);
0608   void AddImport(const Message* descriptor, const std::string& name, int line,
0609                  int column);
0610 
0611   // Clears the contents of the table.
0612   void Clear();
0613 
0614  private:
0615   using LocationMap = absl::flat_hash_map<
0616       std::pair<const Message*, DescriptorPool::ErrorCollector::ErrorLocation>,
0617       std::pair<int, int>>;
0618   LocationMap location_map_;
0619   absl::flat_hash_map<std::pair<const Message*, std::string>,
0620                       std::pair<int, int>>
0621       import_location_map_;
0622 };
0623 
0624 }  // namespace compiler
0625 }  // namespace protobuf
0626 }  // namespace google
0627 
0628 #include "google/protobuf/port_undef.inc"
0629 
0630 #endif  // GOOGLE_PROTOBUF_COMPILER_PARSER_H__