Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-09-10 09:12:04

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