// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc.  All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//     * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

// Author: kenton@google.com (Kenton Varda)
//  Based on original Protocol Buffers design by
//  Sanjay Ghemawat, Jeff Dean, and others.
//
// This file contains classes which describe a type of protocol message.
// You can use a message's descriptor to learn at runtime what fields
// it contains and what the types of those fields are.  The Message
// interface also allows you to dynamically access and modify individual
// fields by passing the FieldDescriptor of the field you are interested
// in.
//
// Most users will not care about descriptors, because they will write
// code specific to certain protocol types and will simply use the classes
// generated by the protocol compiler directly.  Advanced users who want
// to operate on arbitrary types (not known at compile time) may want to
// read descriptors in order to learn about the contents of a message.
// A very small number of users will want to construct their own
// Descriptors, either because they are implementing Message manually or
// because they are writing something like the protocol compiler.
//
// For an example of how you might use descriptors, see the code example
// at the top of message.h.

#ifndef GOOGLE_PROTOBUF_DESCRIPTOR_H__
#define GOOGLE_PROTOBUF_DESCRIPTOR_H__

#include <atomic>
#include <cstdint>
#include <iterator>
#include <map>
#include <memory>
#include <set>
#include <string>
#include <vector>

#include "google/protobuf/stubs/common.h"
#include "google/protobuf/port.h"
#include "absl/base/call_once.h"
#include "google/protobuf/stubs/logging.h"
#include "google/protobuf/stubs/logging.h"
#include "absl/strings/string_view.h"
#include "absl/synchronization/mutex.h"
#include "google/protobuf/port.h"


// Must be included last.
#include "google/protobuf/port_def.inc"

#ifdef SWIG
#define PROTOBUF_EXPORT
#endif


namespace google {
namespace protobuf {

// Defined in this file.
class Descriptor;
class FieldDescriptor;
class OneofDescriptor;
class EnumDescriptor;
class EnumValueDescriptor;
class ServiceDescriptor;
class MethodDescriptor;
class FileDescriptor;
class DescriptorDatabase;
class DescriptorPool;

// Defined in descriptor.proto
class DescriptorProto;
class DescriptorProto_ExtensionRange;
class FieldDescriptorProto;
class OneofDescriptorProto;
class EnumDescriptorProto;
class EnumValueDescriptorProto;
class ServiceDescriptorProto;
class MethodDescriptorProto;
class FileDescriptorProto;
class MessageOptions;
class FieldOptions;
class OneofOptions;
class EnumOptions;
class EnumValueOptions;
class ExtensionRangeOptions;
class ServiceOptions;
class MethodOptions;
class FileOptions;
class UninterpretedOption;
class SourceCodeInfo;

// Defined in message.h
class Message;
class Reflection;

// Defined in descriptor.cc
class DescriptorBuilder;
class FileDescriptorTables;
class Symbol;

// Defined in unknown_field_set.h.
class UnknownField;

// Defined in command_line_interface.cc
namespace compiler {
class CommandLineInterface;
namespace cpp {
// Defined in helpers.h
class Formatter;
}  // namespace cpp
}  // namespace compiler

namespace descriptor_unittest {
class DescriptorTest;
}  // namespace descriptor_unittest

// Defined in printer.h
namespace io {
class Printer;
}  // namespace io

// NB, all indices are zero-based.
struct SourceLocation {
  int start_line;
  int end_line;
  int start_column;
  int end_column;

  // Doc comments found at the source location.
  // See the comments in SourceCodeInfo.Location (descriptor.proto) for details.
  std::string leading_comments;
  std::string trailing_comments;
  std::vector<std::string> leading_detached_comments;
};

// Options when generating machine-parsable output from a descriptor with
// DebugString().
struct DebugStringOptions {
  // include original user comments as recorded in SourceLocation entries. N.B.
  // that this must be |false| by default: several other pieces of code (for
  // example, the C++ code generation for fields in the proto compiler) rely on
  // DebugString() output being unobstructed by user comments.
  bool include_comments;
  // If true, elide the braced body in the debug string.
  bool elide_group_body;
  bool elide_oneof_body;

  DebugStringOptions()
      : include_comments(false),
        elide_group_body(false),
        elide_oneof_body(false) {
  }
};

// A class to handle the simplest cases of a lazily linked descriptor
// for a message type that isn't built at the time of cross linking,
// which is needed when a pool has lazily_build_dependencies_ set.
// Must be instantiated as mutable in a descriptor.
namespace internal {

// The classes in this file represent a significant memory footprint for the
// library. We make sure we are not accidentally making them larger by
// hardcoding the struct size for a specific platform. Use as:
//
//   PROTOBUF_INTERNAL_CHECK_CLASS_SIZE(type, expected_size_in_x84-64);
//

#if !defined(PROTOBUF_INTERNAL_CHECK_CLASS_SIZE)
#define PROTOBUF_INTERNAL_CHECK_CLASS_SIZE(t, expected)
#endif

class FlatAllocator;

class PROTOBUF_EXPORT LazyDescriptor {
 public:
  // Init function to be called at init time of a descriptor containing
  // a LazyDescriptor.
  void Init() {
    descriptor_ = nullptr;
    once_ = nullptr;
  }

  // Sets the value of the descriptor if it is known during the descriptor
  // building process. Not thread safe, should only be called during the
  // descriptor build process. Should not be called after SetLazy has been
  // called.
  void Set(const Descriptor* descriptor);

  // Sets the information needed to lazily cross link the descriptor at a later
  // time, SetLazy is not thread safe, should be called only once at descriptor
  // build time if the symbol wasn't found and building of the file containing
  // that type is delayed because lazily_build_dependencies_ is set on the pool.
  // Should not be called after Set() has been called.
  void SetLazy(absl::string_view name, const FileDescriptor* file);

  // Returns the current value of the descriptor, thread-safe. If SetLazy(...)
  // has been called, will do a one-time cross link of the type specified,
  // building the descriptor file that contains the type if necessary.
  inline const Descriptor* Get(const ServiceDescriptor* service) {
    Once(service);
    return descriptor_;
  }

 private:
  void Once(const ServiceDescriptor* service);

  const Descriptor* descriptor_;
  // The once_ flag is followed by a NUL terminated string for the type name.
  absl::once_flag* once_;
};

class PROTOBUF_EXPORT SymbolBase {
 private:
  friend class google::protobuf::Symbol;
  uint8_t symbol_type_;
};

// Some types have more than one SymbolBase because they have multiple
// identities in the table. We can't have duplicate direct bases, so we use this
// intermediate base to do so.
// See BuildEnumValue for details.
template <int N>
class PROTOBUF_EXPORT SymbolBaseN : public SymbolBase {};

}  // namespace internal

// Describes a type of protocol message, or a particular group within a
// message.  To obtain the Descriptor for a given message object, call
// Message::GetDescriptor().  Generated message classes also have a
// static method called descriptor() which returns the type's descriptor.
// Use DescriptorPool to construct your own descriptors.
class PROTOBUF_EXPORT Descriptor : private internal::SymbolBase {
 public:
  typedef DescriptorProto Proto;
#ifndef SWIG
  Descriptor(const Descriptor&) = delete;
  Descriptor& operator=(const Descriptor&) = delete;
#endif

  // The name of the message type, not including its scope.
  const std::string& name() const;

  // The fully-qualified name of the message type, scope delimited by
  // periods.  For example, message type "Foo" which is declared in package
  // "bar" has full name "bar.Foo".  If a type "Baz" is nested within
  // Foo, Baz's full_name is "bar.Foo.Baz".  To get only the part that
  // comes after the last '.', use name().
  const std::string& full_name() const;

  // Index of this descriptor within the file or containing type's message
  // type array.
  int index() const;

  // The .proto file in which this message type was defined.  Never nullptr.
  const FileDescriptor* file() const;

  // If this Descriptor describes a nested type, this returns the type
  // in which it is nested.  Otherwise, returns nullptr.
  const Descriptor* containing_type() const;

  // Get options for this message type.  These are specified in the .proto file
  // by placing lines like "option foo = 1234;" in the message definition.
  // Allowed options are defined by MessageOptions in descriptor.proto, and any
  // available extensions of that message.
  const MessageOptions& options() const;

  // Write the contents of this Descriptor into the given DescriptorProto.
  // The target DescriptorProto must be clear before calling this; if it
  // isn't, the result may be garbage.
  void CopyTo(DescriptorProto* proto) const;

  // Write the contents of this descriptor in a human-readable form. Output
  // will be suitable for re-parsing.
  std::string DebugString() const;

  // Similar to DebugString(), but additionally takes options (e.g.,
  // include original user comments in output).
  std::string DebugStringWithOptions(const DebugStringOptions& options) const;

  // Returns true if this is a placeholder for an unknown type. This will
  // only be the case if this descriptor comes from a DescriptorPool
  // with AllowUnknownDependencies() set.
  bool is_placeholder() const;

  enum WellKnownType {
    WELLKNOWNTYPE_UNSPECIFIED,  // Not a well-known type.

    // Wrapper types.
    WELLKNOWNTYPE_DOUBLEVALUE,  // google.protobuf.DoubleValue
    WELLKNOWNTYPE_FLOATVALUE,   // google.protobuf.FloatValue
    WELLKNOWNTYPE_INT64VALUE,   // google.protobuf.Int64Value
    WELLKNOWNTYPE_UINT64VALUE,  // google.protobuf.UInt64Value
    WELLKNOWNTYPE_INT32VALUE,   // google.protobuf.Int32Value
    WELLKNOWNTYPE_UINT32VALUE,  // google.protobuf.UInt32Value
    WELLKNOWNTYPE_STRINGVALUE,  // google.protobuf.StringValue
    WELLKNOWNTYPE_BYTESVALUE,   // google.protobuf.BytesValue
    WELLKNOWNTYPE_BOOLVALUE,    // google.protobuf.BoolValue

    // Other well known types.
    WELLKNOWNTYPE_ANY,        // google.protobuf.Any
    WELLKNOWNTYPE_FIELDMASK,  // google.protobuf.FieldMask
    WELLKNOWNTYPE_DURATION,   // google.protobuf.Duration
    WELLKNOWNTYPE_TIMESTAMP,  // google.protobuf.Timestamp
    WELLKNOWNTYPE_VALUE,      // google.protobuf.Value
    WELLKNOWNTYPE_LISTVALUE,  // google.protobuf.ListValue
    WELLKNOWNTYPE_STRUCT,     // google.protobuf.Struct

    // New well-known types may be added in the future.
    // Please make sure any switch() statements have a 'default' case.
    __WELLKNOWNTYPE__DO_NOT_USE__ADD_DEFAULT_INSTEAD__,
  };

  WellKnownType well_known_type() const;

  // Field stuff -----------------------------------------------------

  // The number of fields in this message type.
  int field_count() const;
  // Gets a field by index, where 0 <= index < field_count().
  // These are returned in the order they were defined in the .proto file.
  const FieldDescriptor* field(int index) const;

  // Looks up a field by declared tag number.  Returns nullptr if no such field
  // exists.
  const FieldDescriptor* FindFieldByNumber(int number) const;
  // Looks up a field by name.  Returns nullptr if no such field exists.
  const FieldDescriptor* FindFieldByName(absl::string_view name) const;

  // Looks up a field by lowercased name (as returned by lowercase_name()).
  // This lookup may be ambiguous if multiple field names differ only by case,
  // in which case the field returned is chosen arbitrarily from the matches.
  const FieldDescriptor* FindFieldByLowercaseName(
      absl::string_view lowercase_name) const;

  // Looks up a field by camel-case name (as returned by camelcase_name()).
  // This lookup may be ambiguous if multiple field names differ in a way that
  // leads them to have identical camel-case names, in which case the field
  // returned is chosen arbitrarily from the matches.
  const FieldDescriptor* FindFieldByCamelcaseName(
      absl::string_view camelcase_name) const;

  // The number of oneofs in this message type.
  int oneof_decl_count() const;
  // The number of oneofs in this message type, excluding synthetic oneofs.
  // Real oneofs always come first, so iterating up to real_oneof_decl_cout()
  // will yield all real oneofs.
  int real_oneof_decl_count() const;
  // Get a oneof by index, where 0 <= index < oneof_decl_count().
  // These are returned in the order they were defined in the .proto file.
  const OneofDescriptor* oneof_decl(int index) const;

  // Looks up a oneof by name.  Returns nullptr if no such oneof exists.
  const OneofDescriptor* FindOneofByName(absl::string_view name) const;

  // Nested type stuff -----------------------------------------------

  // The number of nested types in this message type.
  int nested_type_count() const;
  // Gets a nested type by index, where 0 <= index < nested_type_count().
  // These are returned in the order they were defined in the .proto file.
  const Descriptor* nested_type(int index) const;

  // Looks up a nested type by name.  Returns nullptr if no such nested type
  // exists.
  const Descriptor* FindNestedTypeByName(absl::string_view name) const;

  // Enum stuff ------------------------------------------------------

  // The number of enum types in this message type.
  int enum_type_count() const;
  // Gets an enum type by index, where 0 <= index < enum_type_count().
  // These are returned in the order they were defined in the .proto file.
  const EnumDescriptor* enum_type(int index) const;

  // Looks up an enum type by name.  Returns nullptr if no such enum type
  // exists.
  const EnumDescriptor* FindEnumTypeByName(absl::string_view name) const;

  // Looks up an enum value by name, among all enum types in this message.
  // Returns nullptr if no such value exists.
  const EnumValueDescriptor* FindEnumValueByName(absl::string_view name) const;

  // Extensions ------------------------------------------------------

  // A range of field numbers which are designated for third-party
  // extensions.
  struct ExtensionRange {
    typedef DescriptorProto_ExtensionRange Proto;

    typedef ExtensionRangeOptions OptionsType;

    // See Descriptor::CopyTo().
    void CopyTo(DescriptorProto_ExtensionRange* proto) const;

    int start;  // inclusive
    int end;    // exclusive

    const ExtensionRangeOptions* options_;
  };

  // The number of extension ranges in this message type.
  int extension_range_count() const;
  // Gets an extension range by index, where 0 <= index <
  // extension_range_count(). These are returned in the order they were defined
  // in the .proto file.
  const ExtensionRange* extension_range(int index) const;

  // Returns true if the number is in one of the extension ranges.
  bool IsExtensionNumber(int number) const;

  // Returns nullptr if no extension range contains the given number.
  const ExtensionRange* FindExtensionRangeContainingNumber(int number) const;

  // The number of extensions defined nested within this message type's scope.
  // See doc:
  // https://developers.google.com/protocol-buffers/docs/proto#nested-extensions
  //
  // Note that the extensions may be extending *other* messages.
  //
  // For example:
  // message M1 {
  //   extensions 1 to max;
  // }
  //
  // message M2 {
  //   extend M1 {
  //     optional int32 foo = 1;
  //   }
  // }
  //
  // In this case,
  // DescriptorPool::generated_pool()
  //     ->FindMessageTypeByName("M2")
  //     ->extension(0)
  // will return "foo", even though "foo" is an extension of M1.
  // To find all known extensions of a given message, instead use
  // DescriptorPool::FindAllExtensions.
  int extension_count() const;
  // Get an extension by index, where 0 <= index < extension_count().
  // These are returned in the order they were defined in the .proto file.
  const FieldDescriptor* extension(int index) const;

  // Looks up a named extension (which extends some *other* message type)
  // defined within this message type's scope.
  const FieldDescriptor* FindExtensionByName(absl::string_view name) const;

  // Similar to FindFieldByLowercaseName(), but finds extensions defined within
  // this message type's scope.
  const FieldDescriptor* FindExtensionByLowercaseName(
      absl::string_view name) const;

  // Similar to FindFieldByCamelcaseName(), but finds extensions defined within
  // this message type's scope.
  const FieldDescriptor* FindExtensionByCamelcaseName(
      absl::string_view name) const;

  // Reserved fields -------------------------------------------------

  // A range of reserved field numbers.
  struct ReservedRange {
    int start;  // inclusive
    int end;    // exclusive
  };

  // The number of reserved ranges in this message type.
  int reserved_range_count() const;
  // Gets an reserved range by index, where 0 <= index <
  // reserved_range_count(). These are returned in the order they were defined
  // in the .proto file.
  const ReservedRange* reserved_range(int index) const;

  // Returns true if the number is in one of the reserved ranges.
  bool IsReservedNumber(int number) const;

  // Returns nullptr if no reserved range contains the given number.
  const ReservedRange* FindReservedRangeContainingNumber(int number) const;

  // The number of reserved field names in this message type.
  int reserved_name_count() const;

  // Gets a reserved name by index, where 0 <= index < reserved_name_count().
  const std::string& reserved_name(int index) const;

  // Returns true if the field name is reserved.
  bool IsReservedName(absl::string_view name) const;

  // Source Location ---------------------------------------------------

  // Updates |*out_location| to the source location of the complete
  // extent of this message declaration.  Returns false and leaves
  // |*out_location| unchanged iff location information was not available.
  bool GetSourceLocation(SourceLocation* out_location) const;

  // Maps --------------------------------------------------------------

  // Returns the FieldDescriptor for the "key" field. If this isn't a map entry
  // field, returns nullptr.
  const FieldDescriptor* map_key() const;

  // Returns the FieldDescriptor for the "value" field. If this isn't a map
  // entry field, returns nullptr.
  const FieldDescriptor* map_value() const;

 private:
  friend class Symbol;
  typedef MessageOptions OptionsType;

  // Allows tests to test CopyTo(proto, true).
  friend class descriptor_unittest::DescriptorTest;

  // Allows access to GetLocationPath for annotations.
  friend class io::Printer;
  friend class compiler::cpp::Formatter;

  // Fill the json_name field of FieldDescriptorProto.
  void CopyJsonNameTo(DescriptorProto* proto) const;

  // Internal version of DebugString; controls the level of indenting for
  // correct depth. Takes |options| to control debug-string options, and
  // |include_opening_clause| to indicate whether the "message ... " part of the
  // clause has already been generated (this varies depending on context).
  void DebugString(int depth, std::string* contents,
                   const DebugStringOptions& options,
                   bool include_opening_clause) const;

  // Walks up the descriptor tree to generate the source location path
  // to this descriptor from the file root.
  void GetLocationPath(std::vector<int>* output) const;

  // True if this is a placeholder for an unknown type.
  bool is_placeholder_ : 1;
  // True if this is a placeholder and the type name wasn't fully-qualified.
  bool is_unqualified_placeholder_ : 1;
  // Well known type.  Stored like this to conserve space.
  uint8_t well_known_type_ : 5;

  // This points to the last field _number_ that is part of the sequence
  // starting at 1, where
  //     `desc->field(i)->number() == i + 1`
  // A value of `0` means no field matches. That is, there are no fields or the
  // first field is not field `1`.
  // Uses 16-bit to avoid extra padding. Unlikely to have more than 2^16
  // sequentially numbered fields in a message.
  uint16_t sequential_field_limit_;

  int field_count_;

  // all_names_ = [name, full_name]
  const std::string* all_names_;
  const FileDescriptor* file_;
  const Descriptor* containing_type_;
  const MessageOptions* options_;

  // These arrays are separated from their sizes to minimize padding on 64-bit.
  FieldDescriptor* fields_;
  OneofDescriptor* oneof_decls_;
  Descriptor* nested_types_;
  EnumDescriptor* enum_types_;
  ExtensionRange* extension_ranges_;
  FieldDescriptor* extensions_;
  ReservedRange* reserved_ranges_;
  const std::string** reserved_names_;

  int oneof_decl_count_;
  int real_oneof_decl_count_;
  int nested_type_count_;
  int enum_type_count_;
  int extension_range_count_;
  int extension_count_;
  int reserved_range_count_;
  int reserved_name_count_;

  // IMPORTANT:  If you add a new field, make sure to search for all instances
  // of Allocate<Descriptor>() and AllocateArray<Descriptor>() in descriptor.cc
  // and update them to initialize the field.

  // Must be constructed using DescriptorPool.
  Descriptor() {}
  friend class DescriptorBuilder;
  friend class DescriptorPool;
  friend class EnumDescriptor;
  friend class FieldDescriptor;
  friend class FileDescriptorTables;
  friend class OneofDescriptor;
  friend class MethodDescriptor;
  friend class FileDescriptor;
};

PROTOBUF_INTERNAL_CHECK_CLASS_SIZE(Descriptor, 136);

// Describes a single field of a message.  To get the descriptor for a given
// field, first get the Descriptor for the message in which it is defined,
// then call Descriptor::FindFieldByName().  To get a FieldDescriptor for
// an extension, do one of the following:
// - Get the Descriptor or FileDescriptor for its containing scope, then
//   call Descriptor::FindExtensionByName() or
//   FileDescriptor::FindExtensionByName().
// - Given a DescriptorPool, call DescriptorPool::FindExtensionByNumber() or
//   DescriptorPool::FindExtensionByPrintableName().
// Use DescriptorPool to construct your own descriptors.
class PROTOBUF_EXPORT FieldDescriptor : private internal::SymbolBase {
 public:
  typedef FieldDescriptorProto Proto;

#ifndef SWIG
  FieldDescriptor(const FieldDescriptor&) = delete;
  FieldDescriptor& operator=(const FieldDescriptor&) = delete;
#endif

  // Identifies a field type.  0 is reserved for errors.  The order is weird
  // for historical reasons.  Types 12 and up are new in proto2.
  enum Type {
    TYPE_DOUBLE = 1,    // double, exactly eight bytes on the wire.
    TYPE_FLOAT = 2,     // float, exactly four bytes on the wire.
    TYPE_INT64 = 3,     // int64, varint on the wire.  Negative numbers
                        // take 10 bytes.  Use TYPE_SINT64 if negative
                        // values are likely.
    TYPE_UINT64 = 4,    // uint64, varint on the wire.
    TYPE_INT32 = 5,     // int32, varint on the wire.  Negative numbers
                        // take 10 bytes.  Use TYPE_SINT32 if negative
                        // values are likely.
    TYPE_FIXED64 = 6,   // uint64, exactly eight bytes on the wire.
    TYPE_FIXED32 = 7,   // uint32, exactly four bytes on the wire.
    TYPE_BOOL = 8,      // bool, varint on the wire.
    TYPE_STRING = 9,    // UTF-8 text.
    TYPE_GROUP = 10,    // Tag-delimited message.  Deprecated.
    TYPE_MESSAGE = 11,  // Length-delimited message.

    TYPE_BYTES = 12,     // Arbitrary byte array.
    TYPE_UINT32 = 13,    // uint32, varint on the wire
    TYPE_ENUM = 14,      // Enum, varint on the wire
    TYPE_SFIXED32 = 15,  // int32, exactly four bytes on the wire
    TYPE_SFIXED64 = 16,  // int64, exactly eight bytes on the wire
    TYPE_SINT32 = 17,    // int32, ZigZag-encoded varint on the wire
    TYPE_SINT64 = 18,    // int64, ZigZag-encoded varint on the wire

    MAX_TYPE = 18,  // Constant useful for defining lookup tables
                    // indexed by Type.
  };

  // Specifies the C++ data type used to represent the field.  There is a
  // fixed mapping from Type to CppType where each Type maps to exactly one
  // CppType.  0 is reserved for errors.
  enum CppType {
    CPPTYPE_INT32 = 1,     // TYPE_INT32, TYPE_SINT32, TYPE_SFIXED32
    CPPTYPE_INT64 = 2,     // TYPE_INT64, TYPE_SINT64, TYPE_SFIXED64
    CPPTYPE_UINT32 = 3,    // TYPE_UINT32, TYPE_FIXED32
    CPPTYPE_UINT64 = 4,    // TYPE_UINT64, TYPE_FIXED64
    CPPTYPE_DOUBLE = 5,    // TYPE_DOUBLE
    CPPTYPE_FLOAT = 6,     // TYPE_FLOAT
    CPPTYPE_BOOL = 7,      // TYPE_BOOL
    CPPTYPE_ENUM = 8,      // TYPE_ENUM
    CPPTYPE_STRING = 9,    // TYPE_STRING, TYPE_BYTES
    CPPTYPE_MESSAGE = 10,  // TYPE_MESSAGE, TYPE_GROUP

    MAX_CPPTYPE = 10,  // Constant useful for defining lookup tables
                       // indexed by CppType.
  };

  // Identifies whether the field is optional, required, or repeated.  0 is
  // reserved for errors.
  enum Label {
    LABEL_OPTIONAL = 1,  // optional
    LABEL_REQUIRED = 2,  // required
    LABEL_REPEATED = 3,  // repeated

    MAX_LABEL = 3,  // Constant useful for defining lookup tables
                    // indexed by Label.
  };

  // Valid field numbers are positive integers up to kMaxNumber.
  static const int kMaxNumber = (1 << 29) - 1;

  // First field number reserved for the protocol buffer library implementation.
  // Users may not declare fields that use reserved numbers.
  static const int kFirstReservedNumber = 19000;
  // Last field number reserved for the protocol buffer library implementation.
  // Users may not declare fields that use reserved numbers.
  static const int kLastReservedNumber = 19999;

  const std::string& name() const;  // Name of this field within the message.
  const std::string& full_name() const;  // Fully-qualified name of the field.
  const std::string& json_name() const;  // JSON name of this field.
  const FileDescriptor* file() const;  // File in which this field was defined.
  bool is_extension() const;           // Is this an extension field?
  int number() const;                  // Declared tag number.

  // Same as name() except converted to lower-case.  This (and especially the
  // FindFieldByLowercaseName() method) can be useful when parsing formats
  // which prefer to use lowercase naming style.  (Although, technically
  // field names should be lowercased anyway according to the protobuf style
  // guide, so this only makes a difference when dealing with old .proto files
  // which do not follow the guide.)
  const std::string& lowercase_name() const;

  // Same as name() except converted to camel-case.  In this conversion, any
  // time an underscore appears in the name, it is removed and the next
  // letter is capitalized.  Furthermore, the first letter of the name is
  // lower-cased.  Examples:
  //   FooBar -> fooBar
  //   foo_bar -> fooBar
  //   fooBar -> fooBar
  // This (and especially the FindFieldByCamelcaseName() method) can be useful
  // when parsing formats which prefer to use camel-case naming style.
  const std::string& camelcase_name() const;

  Type type() const;                  // Declared type of this field.
  const char* type_name() const;      // Name of the declared type.
  CppType cpp_type() const;           // C++ type of this field.
  const char* cpp_type_name() const;  // Name of the C++ type.
  Label label() const;                // optional/required/repeated

  bool is_required() const;  // shorthand for label() == LABEL_REQUIRED
  bool is_optional() const;  // shorthand for label() == LABEL_OPTIONAL
  bool is_repeated() const;  // shorthand for label() == LABEL_REPEATED
  bool is_packable() const;  // shorthand for is_repeated() &&
                             //               IsTypePackable(type())
  bool is_packed() const;    // shorthand for is_packable() &&
                             //               options().packed()
  bool is_map() const;       // shorthand for type() == TYPE_MESSAGE &&
                             // message_type()->options().map_entry()

  // Returns true if this field was syntactically written with "optional" in the
  // .proto file. Excludes singular proto3 fields that do not have a label.
  bool has_optional_keyword() const;

  // Returns true if this field tracks presence, ie. does the field
  // distinguish between "unset" and "present with default value."
  // This includes required, optional, and oneof fields. It excludes maps,
  // repeated fields, and singular proto3 fields without "optional".
  //
  // For fields where has_presence() == true, the return value of
  // Reflection::HasField() is semantically meaningful.
  bool has_presence() const;

  // Returns true if this TYPE_STRING-typed field requires UTF-8 validation on
  // parse.
  bool requires_utf8_validation() const;

  // Index of this field within the message's field array, or the file or
  // extension scope's extensions array.
  int index() const;

  // Does this field have an explicitly-declared default value?
  bool has_default_value() const;

  // Whether the user has specified the json_name field option in the .proto
  // file.
  bool has_json_name() const;

  // Get the field default value if cpp_type() == CPPTYPE_INT32.  If no
  // explicit default was defined, the default is 0.
  int32_t default_value_int32_t() const;
  int32_t default_value_int32() const { return default_value_int32_t(); }
  // Get the field default value if cpp_type() == CPPTYPE_INT64.  If no
  // explicit default was defined, the default is 0.
  int64_t default_value_int64_t() const;
  int64_t default_value_int64() const { return default_value_int64_t(); }
  // Get the field default value if cpp_type() == CPPTYPE_UINT32.  If no
  // explicit default was defined, the default is 0.
  uint32_t default_value_uint32_t() const;
  uint32_t default_value_uint32() const { return default_value_uint32_t(); }
  // Get the field default value if cpp_type() == CPPTYPE_UINT64.  If no
  // explicit default was defined, the default is 0.
  uint64_t default_value_uint64_t() const;
  uint64_t default_value_uint64() const { return default_value_uint64_t(); }
  // Get the field default value if cpp_type() == CPPTYPE_FLOAT.  If no
  // explicit default was defined, the default is 0.0.
  float default_value_float() const;
  // Get the field default value if cpp_type() == CPPTYPE_DOUBLE.  If no
  // explicit default was defined, the default is 0.0.
  double default_value_double() const;
  // Get the field default value if cpp_type() == CPPTYPE_BOOL.  If no
  // explicit default was defined, the default is false.
  bool default_value_bool() const;
  // Get the field default value if cpp_type() == CPPTYPE_ENUM.  If no
  // explicit default was defined, the default is the first value defined
  // in the enum type (all enum types are required to have at least one value).
  // This never returns nullptr.
  const EnumValueDescriptor* default_value_enum() const;
  // Get the field default value if cpp_type() == CPPTYPE_STRING.  If no
  // explicit default was defined, the default is the empty string.
  const std::string& default_value_string() const;

  // The Descriptor for the message of which this is a field.  For extensions,
  // this is the extended type.  Never nullptr.
  const Descriptor* containing_type() const;

  // If the field is a member of a oneof, this is the one, otherwise this is
  // nullptr.
  const OneofDescriptor* containing_oneof() const;

  // If the field is a member of a non-synthetic oneof, returns the descriptor
  // for the oneof, otherwise returns nullptr.
  const OneofDescriptor* real_containing_oneof() const;

  // If the field is a member of a oneof, returns the index in that oneof.
  int index_in_oneof() const;

  // An extension may be declared within the scope of another message.  If this
  // field is an extension (is_extension() is true), then extension_scope()
  // returns that message, or nullptr if the extension was declared at global
  // scope.  If this is not an extension, extension_scope() is undefined (may
  // assert-fail).
  const Descriptor* extension_scope() const;

  // If type is TYPE_MESSAGE or TYPE_GROUP, returns a descriptor for the
  // message or the group type.  Otherwise, returns null.
  const Descriptor* message_type() const;
  // If type is TYPE_ENUM, returns a descriptor for the enum.  Otherwise,
  // returns null.
  const EnumDescriptor* enum_type() const;

  // Get the FieldOptions for this field.  This includes things listed in
  // square brackets after the field definition.  E.g., the field:
  //   optional string text = 1 [ctype=CORD];
  // has the "ctype" option set.  Allowed options are defined by FieldOptions in
  // descriptor.proto, and any available extensions of that message.
  const FieldOptions& options() const;

  // See Descriptor::CopyTo().
  void CopyTo(FieldDescriptorProto* proto) const;

  // See Descriptor::DebugString().
  std::string DebugString() const;

  // See Descriptor::DebugStringWithOptions().
  std::string DebugStringWithOptions(const DebugStringOptions& options) const;

  // Helper method to get the CppType for a particular Type.
  static CppType TypeToCppType(Type type);

  // Helper method to get the name of a Type.
  static const char* TypeName(Type type);

  // Helper method to get the name of a CppType.
  static const char* CppTypeName(CppType cpp_type);

  // Return true iff [packed = true] is valid for fields of this type.
  static inline bool IsTypePackable(Type field_type);

  // Returns full_name() except if the field is a MessageSet extension,
  // in which case it returns the full_name() of the containing message type
  // for backwards compatibility with proto1.
  //
  // A MessageSet extension is defined as an optional message extension
  // whose containing type has the message_set_wire_format option set.
  // This should be true of extensions of google.protobuf.bridge.MessageSet;
  // by convention, such extensions are named "message_set_extension".
  //
  // The opposite operation (looking up an extension's FieldDescriptor given
  // its printable name) can be accomplished with
  //     message->file()->pool()->FindExtensionByPrintableName(message, name)
  // where the extension extends "message".
  const std::string& PrintableNameForExtension() const;

  // Source Location ---------------------------------------------------

  // Updates |*out_location| to the source location of the complete
  // extent of this field declaration.  Returns false and leaves
  // |*out_location| unchanged iff location information was not available.
  bool GetSourceLocation(SourceLocation* out_location) const;

 private:
  friend class Symbol;
  typedef FieldOptions OptionsType;

  // Allows access to GetLocationPath for annotations.
  friend class io::Printer;
  friend class compiler::cpp::Formatter;
  friend class Reflection;

  // Fill the json_name field of FieldDescriptorProto.
  void CopyJsonNameTo(FieldDescriptorProto* proto) const;

  // See Descriptor::DebugString().
  void DebugString(int depth, std::string* contents,
                   const DebugStringOptions& options) const;

  // formats the default value appropriately and returns it as a string.
  // Must have a default value to call this. If quote_string_type is true, then
  // types of CPPTYPE_STRING will be surrounded by quotes and CEscaped.
  std::string DefaultValueAsString(bool quote_string_type) const;

  // Helper function that returns the field type name for DebugString.
  std::string FieldTypeNameDebugString() const;

  // Walks up the descriptor tree to generate the source location path
  // to this descriptor from the file root.
  void GetLocationPath(std::vector<int>* output) const;

  // Returns true if this is a map message type.
  bool is_map_message_type() const;

  bool has_default_value_ : 1;
  bool proto3_optional_ : 1;
  // Whether the user has specified the json_name field option in the .proto
  // file.
  bool has_json_name_ : 1;
  bool is_extension_ : 1;
  bool is_oneof_ : 1;

  // Actually a `Label` but stored as uint8_t to save space.
  uint8_t label_ : 2;

  // Actually a `Type`, but stored as uint8_t to save space.
  mutable uint8_t type_;

  // Logically:
  //   all_names_ = [name, full_name, lower, camel, json]
  // However:
  //   duplicates will be omitted, so lower/camel/json might be in the same
  //   position.
  // We store the true offset for each name here, and the bit width must be
  // large enough to account for the worst case where all names are present.
  uint8_t lowercase_name_index_ : 2;
  uint8_t camelcase_name_index_ : 2;
  uint8_t json_name_index_ : 3;
  // Sadly, `number_` located here to reduce padding. Unrelated to all_names_
  // and its indices above.
  int number_;
  const std::string* all_names_;
  const FileDescriptor* file_;

  // The once_flag is followed by a NUL terminated string for the type name and
  // enum default value (or empty string if no default enum).
  absl::once_flag* type_once_;
  static void TypeOnceInit(const FieldDescriptor* to_init);
  void InternalTypeOnceInit() const;
  const Descriptor* containing_type_;
  union {
    const OneofDescriptor* containing_oneof;
    const Descriptor* extension_scope;
  } scope_;
  union {
    mutable const Descriptor* message_type;
    mutable const EnumDescriptor* enum_type;
  } type_descriptor_;
  const FieldOptions* options_;
  // IMPORTANT:  If you add a new field, make sure to search for all instances
  // of Allocate<FieldDescriptor>() and AllocateArray<FieldDescriptor>() in
  // descriptor.cc and update them to initialize the field.

  union {
    int32_t default_value_int32_t_;
    int64_t default_value_int64_t_;
    uint32_t default_value_uint32_t_;
    uint64_t default_value_uint64_t_;
    float default_value_float_;
    double default_value_double_;
    bool default_value_bool_;

    mutable const EnumValueDescriptor* default_value_enum_;
    const std::string* default_value_string_;
    mutable std::atomic<const Message*> default_generated_instance_;
  };

  static const CppType kTypeToCppTypeMap[MAX_TYPE + 1];

  static const char* const kTypeToName[MAX_TYPE + 1];

  static const char* const kCppTypeToName[MAX_CPPTYPE + 1];

  static const char* const kLabelToName[MAX_LABEL + 1];

  // Must be constructed using DescriptorPool.
  FieldDescriptor() {}
  friend class DescriptorBuilder;
  friend class FileDescriptor;
  friend class Descriptor;
  friend class OneofDescriptor;
};

PROTOBUF_INTERNAL_CHECK_CLASS_SIZE(FieldDescriptor, 72);

// Describes a oneof defined in a message type.
class PROTOBUF_EXPORT OneofDescriptor : private internal::SymbolBase {
 public:
  typedef OneofDescriptorProto Proto;

#ifndef SWIG
  OneofDescriptor(const OneofDescriptor&) = delete;
  OneofDescriptor& operator=(const OneofDescriptor&) = delete;
#endif

  const std::string& name() const;       // Name of this oneof.
  const std::string& full_name() const;  // Fully-qualified name of the oneof.

  // Index of this oneof within the message's oneof array.
  int index() const;

  // Returns whether this oneof was inserted by the compiler to wrap a proto3
  // optional field. If this returns true, code generators should *not* emit it.
  bool is_synthetic() const;

  // The .proto file in which this oneof was defined.  Never nullptr.
  const FileDescriptor* file() const;
  // The Descriptor for the message containing this oneof.
  const Descriptor* containing_type() const;

  // The number of (non-extension) fields which are members of this oneof.
  int field_count() const;
  // Get a member of this oneof, in the order in which they were declared in the
  // .proto file.  Does not include extensions.
  const FieldDescriptor* field(int index) const;

  const OneofOptions& options() const;

  // See Descriptor::CopyTo().
  void CopyTo(OneofDescriptorProto* proto) const;

  // See Descriptor::DebugString().
  std::string DebugString() const;

  // See Descriptor::DebugStringWithOptions().
  std::string DebugStringWithOptions(const DebugStringOptions& options) const;

  // Source Location ---------------------------------------------------

  // Updates |*out_location| to the source location of the complete
  // extent of this oneof declaration.  Returns false and leaves
  // |*out_location| unchanged iff location information was not available.
  bool GetSourceLocation(SourceLocation* out_location) const;

 private:
  friend class Symbol;
  typedef OneofOptions OptionsType;

  // Allows access to GetLocationPath for annotations.
  friend class io::Printer;
  friend class compiler::cpp::Formatter;

  // See Descriptor::DebugString().
  void DebugString(int depth, std::string* contents,
                   const DebugStringOptions& options) const;

  // Walks up the descriptor tree to generate the source location path
  // to this descriptor from the file root.
  void GetLocationPath(std::vector<int>* output) const;

  int field_count_;

  // all_names_ = [name, full_name]
  const std::string* all_names_;
  const Descriptor* containing_type_;
  const OneofOptions* options_;
  const FieldDescriptor* fields_;

  // IMPORTANT:  If you add a new field, make sure to search for all instances
  // of Allocate<OneofDescriptor>() and AllocateArray<OneofDescriptor>()
  // in descriptor.cc and update them to initialize the field.

  // Must be constructed using DescriptorPool.
  OneofDescriptor() {}
  friend class DescriptorBuilder;
  friend class Descriptor;
};

PROTOBUF_INTERNAL_CHECK_CLASS_SIZE(OneofDescriptor, 40);

// Describes an enum type defined in a .proto file.  To get the EnumDescriptor
// for a generated enum type, call TypeName_descriptor().  Use DescriptorPool
// to construct your own descriptors.
class PROTOBUF_EXPORT EnumDescriptor : private internal::SymbolBase {
 public:
  typedef EnumDescriptorProto Proto;

#ifndef SWIG
  EnumDescriptor(const EnumDescriptor&) = delete;
  EnumDescriptor& operator=(const EnumDescriptor&) = delete;
#endif

  // The name of this enum type in the containing scope.
  const std::string& name() const;

  // The fully-qualified name of the enum type, scope delimited by periods.
  const std::string& full_name() const;

  // Index of this enum within the file or containing message's enum array.
  int index() const;

  // The .proto file in which this enum type was defined.  Never nullptr.
  const FileDescriptor* file() const;

  // The number of values for this EnumDescriptor.  Guaranteed to be greater
  // than zero.
  int value_count() const;
  // Gets a value by index, where 0 <= index < value_count().
  // These are returned in the order they were defined in the .proto file.
  const EnumValueDescriptor* value(int index) const;

  // Looks up a value by name.  Returns nullptr if no such value exists.
  const EnumValueDescriptor* FindValueByName(absl::string_view name) const;
  // Looks up a value by number.  Returns nullptr if no such value exists.  If
  // multiple values have this number, the first one defined is returned.
  const EnumValueDescriptor* FindValueByNumber(int number) const;

  // If this enum type is nested in a message type, this is that message type.
  // Otherwise, nullptr.
  const Descriptor* containing_type() const;

  // Get options for this enum type.  These are specified in the .proto file by
  // placing lines like "option foo = 1234;" in the enum definition.  Allowed
  // options are defined by EnumOptions in descriptor.proto, and any available
  // extensions of that message.
  const EnumOptions& options() const;

  // See Descriptor::CopyTo().
  void CopyTo(EnumDescriptorProto* proto) const;

  // See Descriptor::DebugString().
  std::string DebugString() const;

  // See Descriptor::DebugStringWithOptions().
  std::string DebugStringWithOptions(const DebugStringOptions& options) const;

  // Returns true if this is a placeholder for an unknown enum. This will
  // only be the case if this descriptor comes from a DescriptorPool
  // with AllowUnknownDependencies() set.
  bool is_placeholder() const;

  // Returns true whether this is a "closed" enum, meaning that it:
  // - Has a fixed set of named values.
  // - Encountering values not in this set causes them to be treated as unknown
  //   fields.
  // - The first value (i.e., the default) may be nonzero.
  bool is_closed() const;

  // Reserved fields -------------------------------------------------

  // A range of reserved field numbers.
  struct ReservedRange {
    int start;  // inclusive
    int end;    // inclusive
  };

  // The number of reserved ranges in this message type.
  int reserved_range_count() const;
  // Gets an reserved range by index, where 0 <= index <
  // reserved_range_count(). These are returned in the order they were defined
  // in the .proto file.
  const EnumDescriptor::ReservedRange* reserved_range(int index) const;

  // Returns true if the number is in one of the reserved ranges.
  bool IsReservedNumber(int number) const;

  // Returns nullptr if no reserved range contains the given number.
  const EnumDescriptor::ReservedRange* FindReservedRangeContainingNumber(
      int number) const;

  // The number of reserved field names in this message type.
  int reserved_name_count() const;

  // Gets a reserved name by index, where 0 <= index < reserved_name_count().
  const std::string& reserved_name(int index) const;

  // Returns true if the field name is reserved.
  bool IsReservedName(absl::string_view name) const;

  // Source Location ---------------------------------------------------

  // Updates |*out_location| to the source location of the complete
  // extent of this enum declaration.  Returns false and leaves
  // |*out_location| unchanged iff location information was not available.
  bool GetSourceLocation(SourceLocation* out_location) const;

 private:
  friend class Symbol;
  typedef EnumOptions OptionsType;

  // Allows access to GetLocationPath for annotations.
  friend class io::Printer;
  friend class compiler::cpp::Formatter;

  // Allow access to FindValueByNumberCreatingIfUnknown.
  friend class descriptor_unittest::DescriptorTest;

  // Looks up a value by number.  If the value does not exist, dynamically
  // creates a new EnumValueDescriptor for that value, assuming that it was
  // unknown. If a new descriptor is created, this is done in a thread-safe way,
  // and future calls will return the same value descriptor pointer.
  //
  // This is private but is used by Reflection (which is friended below) to
  // return a valid EnumValueDescriptor from GetEnum() when this feature is
  // enabled.
  const EnumValueDescriptor* FindValueByNumberCreatingIfUnknown(
      int number) const;

  // See Descriptor::DebugString().
  void DebugString(int depth, std::string* contents,
                   const DebugStringOptions& options) const;

  // Walks up the descriptor tree to generate the source location path
  // to this descriptor from the file root.
  void GetLocationPath(std::vector<int>* output) const;

  // True if this is a placeholder for an unknown type.
  bool is_placeholder_ : 1;
  // True if this is a placeholder and the type name wasn't fully-qualified.
  bool is_unqualified_placeholder_ : 1;

  // This points to the last value _index_ that is part of the sequence starting
  // with the first label, where
  //   `enum->value(i)->number() == enum->value(0)->number() + i`
  // We measure relative to the first label to adapt to enum labels starting at
  // 0 or 1.
  // Uses 16-bit to avoid extra padding. Unlikely to have more than 2^15
  // sequentially numbered labels in an enum.
  int16_t sequential_value_limit_;

  int value_count_;

  // all_names_ = [name, full_name]
  const std::string* all_names_;
  const FileDescriptor* file_;
  const Descriptor* containing_type_;
  const EnumOptions* options_;
  EnumValueDescriptor* values_;

  int reserved_range_count_;
  int reserved_name_count_;
  EnumDescriptor::ReservedRange* reserved_ranges_;
  const std::string** reserved_names_;

  // IMPORTANT:  If you add a new field, make sure to search for all instances
  // of Allocate<EnumDescriptor>() and AllocateArray<EnumDescriptor>() in
  // descriptor.cc and update them to initialize the field.

  // Must be constructed using DescriptorPool.
  EnumDescriptor() {}
  friend class DescriptorBuilder;
  friend class Descriptor;
  friend class FieldDescriptor;
  friend class FileDescriptorTables;
  friend class EnumValueDescriptor;
  friend class FileDescriptor;
  friend class DescriptorPool;
  friend class Reflection;
};

PROTOBUF_INTERNAL_CHECK_CLASS_SIZE(EnumDescriptor, 72);

// Describes an individual enum constant of a particular type.  To get the
// EnumValueDescriptor for a given enum value, first get the EnumDescriptor
// for its type, then use EnumDescriptor::FindValueByName() or
// EnumDescriptor::FindValueByNumber().  Use DescriptorPool to construct
// your own descriptors.
class PROTOBUF_EXPORT EnumValueDescriptor : private internal::SymbolBaseN<0>,
                                            private internal::SymbolBaseN<1> {
 public:
  typedef EnumValueDescriptorProto Proto;

#ifndef SWIG
  EnumValueDescriptor(const EnumValueDescriptor&) = delete;
  EnumValueDescriptor& operator=(const EnumValueDescriptor&) = delete;
#endif

  const std::string& name() const;  // Name of this enum constant.
  int index() const;                // Index within the enums's Descriptor.
  int number() const;               // Numeric value of this enum constant.

  // The full_name of an enum value is a sibling symbol of the enum type.
  // e.g. the full name of FieldDescriptorProto::TYPE_INT32 is actually
  // "google.protobuf.FieldDescriptorProto.TYPE_INT32", NOT
  // "google.protobuf.FieldDescriptorProto.Type.TYPE_INT32".  This is to conform
  // with C++ scoping rules for enums.
  const std::string& full_name() const;

  // The .proto file in which this value was defined.  Never nullptr.
  const FileDescriptor* file() const;
  // The type of this value.  Never nullptr.
  const EnumDescriptor* type() const;

  // Get options for this enum value.  These are specified in the .proto file by
  // adding text like "[foo = 1234]" after an enum value definition.  Allowed
  // options are defined by EnumValueOptions in descriptor.proto, and any
  // available extensions of that message.
  const EnumValueOptions& options() const;

  // See Descriptor::CopyTo().
  void CopyTo(EnumValueDescriptorProto* proto) const;

  // See Descriptor::DebugString().
  std::string DebugString() const;

  // See Descriptor::DebugStringWithOptions().
  std::string DebugStringWithOptions(const DebugStringOptions& options) const;

  // Source Location ---------------------------------------------------

  // Updates |*out_location| to the source location of the complete
  // extent of this enum value declaration.  Returns false and leaves
  // |*out_location| unchanged iff location information was not available.
  bool GetSourceLocation(SourceLocation* out_location) const;

 private:
  friend class Symbol;
  typedef EnumValueOptions OptionsType;

  // Allows access to GetLocationPath for annotations.
  friend class io::Printer;
  friend class compiler::cpp::Formatter;

  // See Descriptor::DebugString().
  void DebugString(int depth, std::string* contents,
                   const DebugStringOptions& options) const;

  // Walks up the descriptor tree to generate the source location path
  // to this descriptor from the file root.
  void GetLocationPath(std::vector<int>* output) const;

  int number_;
  // all_names_ = [name, full_name]
  const std::string* all_names_;
  const EnumDescriptor* type_;
  const EnumValueOptions* options_;
  // IMPORTANT:  If you add a new field, make sure to search for all instances
  // of Allocate<EnumValueDescriptor>() and AllocateArray<EnumValueDescriptor>()
  // in descriptor.cc and update them to initialize the field.

  // Must be constructed using DescriptorPool.
  EnumValueDescriptor() {}
  friend class DescriptorBuilder;
  friend class EnumDescriptor;
  friend class DescriptorPool;
  friend class FileDescriptorTables;
  friend class Reflection;
};

PROTOBUF_INTERNAL_CHECK_CLASS_SIZE(EnumValueDescriptor, 32);

// Describes an RPC service. Use DescriptorPool to construct your own
// descriptors.
class PROTOBUF_EXPORT ServiceDescriptor : private internal::SymbolBase {
 public:
  typedef ServiceDescriptorProto Proto;

#ifndef SWIG
  ServiceDescriptor(const ServiceDescriptor&) = delete;
  ServiceDescriptor& operator=(const ServiceDescriptor&) = delete;
#endif

  // The name of the service, not including its containing scope.
  const std::string& name() const;
  // The fully-qualified name of the service, scope delimited by periods.
  const std::string& full_name() const;
  // Index of this service within the file's services array.
  int index() const;

  // The .proto file in which this service was defined.  Never nullptr.
  const FileDescriptor* file() const;

  // Get options for this service type.  These are specified in the .proto file
  // by placing lines like "option foo = 1234;" in the service definition.
  // Allowed options are defined by ServiceOptions in descriptor.proto, and any
  // available extensions of that message.
  const ServiceOptions& options() const;

  // The number of methods this service defines.
  int method_count() const;
  // Gets a MethodDescriptor by index, where 0 <= index < method_count().
  // These are returned in the order they were defined in the .proto file.
  const MethodDescriptor* method(int index) const;

  // Look up a MethodDescriptor by name.
  const MethodDescriptor* FindMethodByName(absl::string_view name) const;

  // See Descriptor::CopyTo().
  void CopyTo(ServiceDescriptorProto* proto) const;

  // See Descriptor::DebugString().
  std::string DebugString() const;

  // See Descriptor::DebugStringWithOptions().
  std::string DebugStringWithOptions(const DebugStringOptions& options) const;

  // Source Location ---------------------------------------------------

  // Updates |*out_location| to the source location of the complete
  // extent of this service declaration.  Returns false and leaves
  // |*out_location| unchanged iff location information was not available.
  bool GetSourceLocation(SourceLocation* out_location) const;

 private:
  friend class Symbol;
  typedef ServiceOptions OptionsType;

  // Allows access to GetLocationPath for annotations.
  friend class io::Printer;
  friend class compiler::cpp::Formatter;

  // See Descriptor::DebugString().
  void DebugString(std::string* contents,
                   const DebugStringOptions& options) const;

  // Walks up the descriptor tree to generate the source location path
  // to this descriptor from the file root.
  void GetLocationPath(std::vector<int>* output) const;

  // all_names_ = [name, full_name]
  const std::string* all_names_;
  const FileDescriptor* file_;
  const ServiceOptions* options_;
  MethodDescriptor* methods_;
  int method_count_;
  // IMPORTANT:  If you add a new field, make sure to search for all instances
  // of Allocate<ServiceDescriptor>() and AllocateArray<ServiceDescriptor>() in
  // descriptor.cc and update them to initialize the field.

  // Must be constructed using DescriptorPool.
  ServiceDescriptor() {}
  friend class DescriptorBuilder;
  friend class FileDescriptor;
  friend class MethodDescriptor;
};

PROTOBUF_INTERNAL_CHECK_CLASS_SIZE(ServiceDescriptor, 48);

// Describes an individual service method.  To obtain a MethodDescriptor given
// a service, first get its ServiceDescriptor, then call
// ServiceDescriptor::FindMethodByName().  Use DescriptorPool to construct your
// own descriptors.
class PROTOBUF_EXPORT MethodDescriptor : private internal::SymbolBase {
 public:
  typedef MethodDescriptorProto Proto;

#ifndef SWIG
  MethodDescriptor(const MethodDescriptor&) = delete;
  MethodDescriptor& operator=(const MethodDescriptor&) = delete;
#endif

  // Name of this method, not including containing scope.
  const std::string& name() const;
  // The fully-qualified name of the method, scope delimited by periods.
  const std::string& full_name() const;
  // Index within the service's Descriptor.
  int index() const;

  // The .proto file in which this method was defined.  Never nullptr.
  const FileDescriptor* file() const;
  // Gets the service to which this method belongs.  Never nullptr.
  const ServiceDescriptor* service() const;

  // Gets the type of protocol message which this method accepts as input.
  const Descriptor* input_type() const;
  // Gets the type of protocol message which this message produces as output.
  const Descriptor* output_type() const;

  // Gets whether the client streams multiple requests.
  bool client_streaming() const;
  // Gets whether the server streams multiple responses.
  bool server_streaming() const;

  // Get options for this method.  These are specified in the .proto file by
  // placing lines like "option foo = 1234;" in curly-braces after a method
  // declaration.  Allowed options are defined by MethodOptions in
  // descriptor.proto, and any available extensions of that message.
  const MethodOptions& options() const;

  // See Descriptor::CopyTo().
  void CopyTo(MethodDescriptorProto* proto) const;

  // See Descriptor::DebugString().
  std::string DebugString() const;

  // See Descriptor::DebugStringWithOptions().
  std::string DebugStringWithOptions(const DebugStringOptions& options) const;

  // Source Location ---------------------------------------------------

  // Updates |*out_location| to the source location of the complete
  // extent of this method declaration.  Returns false and leaves
  // |*out_location| unchanged iff location information was not available.
  bool GetSourceLocation(SourceLocation* out_location) const;

 private:
  friend class Symbol;
  typedef MethodOptions OptionsType;

  // Allows access to GetLocationPath for annotations.
  friend class io::Printer;
  friend class compiler::cpp::Formatter;

  // See Descriptor::DebugString().
  void DebugString(int depth, std::string* contents,
                   const DebugStringOptions& options) const;

  // Walks up the descriptor tree to generate the source location path
  // to this descriptor from the file root.
  void GetLocationPath(std::vector<int>* output) const;

  bool client_streaming_;
  bool server_streaming_;
  // all_names_ = [name, full_name]
  const std::string* all_names_;
  const ServiceDescriptor* service_;
  mutable internal::LazyDescriptor input_type_;
  mutable internal::LazyDescriptor output_type_;
  const MethodOptions* options_;
  // IMPORTANT:  If you add a new field, make sure to search for all instances
  // of Allocate<MethodDescriptor>() and AllocateArray<MethodDescriptor>() in
  // descriptor.cc and update them to initialize the field.

  // Must be constructed using DescriptorPool.
  MethodDescriptor() {}
  friend class DescriptorBuilder;
  friend class ServiceDescriptor;
};

PROTOBUF_INTERNAL_CHECK_CLASS_SIZE(MethodDescriptor, 64);

// Describes a whole .proto file.  To get the FileDescriptor for a compiled-in
// file, get the descriptor for something defined in that file and call
// descriptor->file().  Use DescriptorPool to construct your own descriptors.
class PROTOBUF_EXPORT FileDescriptor : private internal::SymbolBase {
 public:
  typedef FileDescriptorProto Proto;

#ifndef SWIG
  FileDescriptor(const FileDescriptor&) = delete;
  FileDescriptor& operator=(const FileDescriptor&) = delete;
#endif

  // The filename, relative to the source tree.
  // e.g. "foo/bar/baz.proto"
  const std::string& name() const;

  // The package, e.g. "google.protobuf.compiler".
  const std::string& package() const;

  // The DescriptorPool in which this FileDescriptor and all its contents were
  // allocated.  Never nullptr.
  const DescriptorPool* pool() const;

  // The number of files imported by this one.
  int dependency_count() const;
  // Gets an imported file by index, where 0 <= index < dependency_count().
  // These are returned in the order they were defined in the .proto file.
  const FileDescriptor* dependency(int index) const;

  // The number of files public imported by this one.
  // The public dependency list is a subset of the dependency list.
  int public_dependency_count() const;
  // Gets a public imported file by index, where 0 <= index <
  // public_dependency_count().
  // These are returned in the order they were defined in the .proto file.
  const FileDescriptor* public_dependency(int index) const;

  // The number of files that are imported for weak fields.
  // The weak dependency list is a subset of the dependency list.
  int weak_dependency_count() const;
  // Gets a weak imported file by index, where 0 <= index <
  // weak_dependency_count().
  // These are returned in the order they were defined in the .proto file.
  const FileDescriptor* weak_dependency(int index) const;

  // Number of top-level message types defined in this file.  (This does not
  // include nested types.)
  int message_type_count() const;
  // Gets a top-level message type, where 0 <= index < message_type_count().
  // These are returned in the order they were defined in the .proto file.
  const Descriptor* message_type(int index) const;

  // Number of top-level enum types defined in this file.  (This does not
  // include nested types.)
  int enum_type_count() const;
  // Gets a top-level enum type, where 0 <= index < enum_type_count().
  // These are returned in the order they were defined in the .proto file.
  const EnumDescriptor* enum_type(int index) const;

  // Number of services defined in this file.
  int service_count() const;
  // Gets a service, where 0 <= index < service_count().
  // These are returned in the order they were defined in the .proto file.
  const ServiceDescriptor* service(int index) const;

  // Number of extensions defined at file scope.  (This does not include
  // extensions nested within message types.)
  int extension_count() const;
  // Gets an extension's descriptor, where 0 <= index < extension_count().
  // These are returned in the order they were defined in the .proto file.
  const FieldDescriptor* extension(int index) const;

  // Get options for this file.  These are specified in the .proto file by
  // placing lines like "option foo = 1234;" at the top level, outside of any
  // other definitions.  Allowed options are defined by FileOptions in
  // descriptor.proto, and any available extensions of that message.
  const FileOptions& options() const;

  // Syntax of this file.
  enum Syntax
#ifndef SWIG
      : int
#endif  // !SWIG
  {
    SYNTAX_UNKNOWN = 0,
    SYNTAX_PROTO2 = 2,
    SYNTAX_PROTO3 = 3,
  };
  Syntax syntax() const;
  static const char* SyntaxName(Syntax syntax);

  // Find a top-level message type by name (not full_name).  Returns nullptr if
  // not found.
  const Descriptor* FindMessageTypeByName(absl::string_view name) const;
  // Find a top-level enum type by name.  Returns nullptr if not found.
  const EnumDescriptor* FindEnumTypeByName(absl::string_view name) const;
  // Find an enum value defined in any top-level enum by name.  Returns nullptr
  // if not found.
  const EnumValueDescriptor* FindEnumValueByName(absl::string_view name) const;
  // Find a service definition by name.  Returns nullptr if not found.
  const ServiceDescriptor* FindServiceByName(absl::string_view name) const;
  // Find a top-level extension definition by name.  Returns nullptr if not
  // found.
  const FieldDescriptor* FindExtensionByName(absl::string_view name) const;
  // Similar to FindExtensionByName(), but searches by lowercased-name.  See
  // Descriptor::FindFieldByLowercaseName().
  const FieldDescriptor* FindExtensionByLowercaseName(
      absl::string_view name) const;
  // Similar to FindExtensionByName(), but searches by camelcased-name.  See
  // Descriptor::FindFieldByCamelcaseName().
  const FieldDescriptor* FindExtensionByCamelcaseName(
      absl::string_view name) const;

  // See Descriptor::CopyTo().
  // Notes:
  // - This method does NOT copy source code information since it is relatively
  //   large and rarely needed.  See CopySourceCodeInfoTo() below.
  void CopyTo(FileDescriptorProto* proto) const;
  // Write the source code information of this FileDescriptor into the given
  // FileDescriptorProto.  See CopyTo() above.
  void CopySourceCodeInfoTo(FileDescriptorProto* proto) const;
  // Fill the json_name field of FieldDescriptorProto for all fields. Can only
  // be called after CopyTo().
  void CopyJsonNameTo(FileDescriptorProto* proto) const;
  // Fills in the file-level settings of this file (e.g. syntax, package,
  // file options) to `proto`.
  void CopyHeadingTo(FileDescriptorProto* proto) const;

  // See Descriptor::DebugString().
  std::string DebugString() const;

  // See Descriptor::DebugStringWithOptions().
  std::string DebugStringWithOptions(const DebugStringOptions& options) const;

  // Returns true if this is a placeholder for an unknown file. This will
  // only be the case if this descriptor comes from a DescriptorPool
  // with AllowUnknownDependencies() set.
  bool is_placeholder() const;

  // Updates |*out_location| to the source location of the complete extent of
  // this file declaration (namely, the empty path).
  bool GetSourceLocation(SourceLocation* out_location) const;

  // Updates |*out_location| to the source location of the complete
  // extent of the declaration or declaration-part denoted by |path|.
  // Returns false and leaves |*out_location| unchanged iff location
  // information was not available.  (See SourceCodeInfo for
  // description of path encoding.)
  bool GetSourceLocation(const std::vector<int>& path,
                         SourceLocation* out_location) const;

 private:
  friend class Symbol;
  typedef FileOptions OptionsType;

  bool is_placeholder_;
  // Indicates the FileDescriptor is completed building. Used to verify
  // that type accessor functions that can possibly build a dependent file
  // aren't called during the process of building the file.
  bool finished_building_;
  // Actually a `Syntax` but stored as uint8_t to save space.
  uint8_t syntax_;
  // This one is here to fill the padding.
  int extension_count_;

  const std::string* name_;
  const std::string* package_;
  const DescriptorPool* pool_;

  // dependencies_once_ contain a once_flag followed by N NUL terminated
  // strings. Dependencies that do not need to be loaded will be empty. ie just
  // {'\0'}
  absl::once_flag* dependencies_once_;
  static void DependenciesOnceInit(const FileDescriptor* to_init);
  void InternalDependenciesOnceInit() const;

  // These are arranged to minimize padding on 64-bit.
  int dependency_count_;
  int public_dependency_count_;
  int weak_dependency_count_;
  int message_type_count_;
  int enum_type_count_;
  int service_count_;

  mutable const FileDescriptor** dependencies_;
  int* public_dependencies_;
  int* weak_dependencies_;
  Descriptor* message_types_;
  EnumDescriptor* enum_types_;
  ServiceDescriptor* services_;
  FieldDescriptor* extensions_;
  const FileOptions* options_;

  const FileDescriptorTables* tables_;
  const SourceCodeInfo* source_code_info_;

  // IMPORTANT:  If you add a new field, make sure to search for all instances
  // of Allocate<FileDescriptor>() and AllocateArray<FileDescriptor>() in
  // descriptor.cc and update them to initialize the field.

  FileDescriptor() {}
  friend class DescriptorBuilder;
  friend class DescriptorPool;
  friend class Descriptor;
  friend class FieldDescriptor;
  friend class internal::LazyDescriptor;
  friend class OneofDescriptor;
  friend class EnumDescriptor;
  friend class EnumValueDescriptor;
  friend class MethodDescriptor;
  friend class ServiceDescriptor;
};

PROTOBUF_INTERNAL_CHECK_CLASS_SIZE(FileDescriptor, 152);

// ===================================================================

// Used to construct descriptors.
//
// Normally you won't want to build your own descriptors.  Message classes
// constructed by the protocol compiler will provide them for you.  However,
// if you are implementing Message on your own, or if you are writing a
// program which can operate on totally arbitrary types and needs to load
// them from some sort of database, you might need to.
//
// Since Descriptors are composed of a whole lot of cross-linked bits of
// data that would be a pain to put together manually, the
// DescriptorPool class is provided to make the process easier.  It can
// take a FileDescriptorProto (defined in descriptor.proto), validate it,
// and convert it to a set of nicely cross-linked Descriptors.
//
// DescriptorPool also helps with memory management.  Descriptors are
// composed of many objects containing static data and pointers to each
// other.  In all likelihood, when it comes time to delete this data,
// you'll want to delete it all at once.  In fact, it is not uncommon to
// have a whole pool of descriptors all cross-linked with each other which
// you wish to delete all at once.  This class represents such a pool, and
// handles the memory management for you.
//
// You can also search for descriptors within a DescriptorPool by name, and
// extensions by number.
class PROTOBUF_EXPORT DescriptorPool {
 public:
  // Create a normal, empty DescriptorPool.
  DescriptorPool();

  // Constructs a DescriptorPool that, when it can't find something among the
  // descriptors already in the pool, looks for it in the given
  // DescriptorDatabase.
  // Notes:
  // - If a DescriptorPool is constructed this way, its BuildFile*() methods
  //   must not be called (they will assert-fail).  The only way to populate
  //   the pool with descriptors is to call the Find*By*() methods.
  // - The Find*By*() methods may block the calling thread if the
  //   DescriptorDatabase blocks.  This in turn means that parsing messages
  //   may block if they need to look up extensions.
  // - The Find*By*() methods will use mutexes for thread-safety, thus making
  //   them slower even when they don't have to fall back to the database.
  //   In fact, even the Find*By*() methods of descriptor objects owned by
  //   this pool will be slower, since they will have to obtain locks too.
  // - An ErrorCollector may optionally be given to collect validation errors
  //   in files loaded from the database.  If not given, errors will be printed
  //   to GOOGLE_ABSL_LOG(ERROR).  Remember that files are built on-demand, so this
  //   ErrorCollector may be called from any thread that calls one of the
  //   Find*By*() methods.
  // - The DescriptorDatabase must not be mutated during the lifetime of
  //   the DescriptorPool. Even if the client takes care to avoid data races,
  //   changes to the content of the DescriptorDatabase may not be reflected
  //   in subsequent lookups in the DescriptorPool.
  class ErrorCollector;
  explicit DescriptorPool(DescriptorDatabase* fallback_database,
                          ErrorCollector* error_collector = nullptr);

#ifndef SWIG
  DescriptorPool(const DescriptorPool&) = delete;
  DescriptorPool& operator=(const DescriptorPool&) = delete;
#endif
  ~DescriptorPool();

  // Get a pointer to the generated pool.  Generated protocol message classes
  // which are compiled into the binary will allocate their descriptors in
  // this pool.  Do not add your own descriptors to this pool.
  static const DescriptorPool* generated_pool();


  // Find a FileDescriptor in the pool by file name.  Returns nullptr if not
  // found.
  const FileDescriptor* FindFileByName(absl::string_view name) const;

  // Find the FileDescriptor in the pool which defines the given symbol.
  // If any of the Find*ByName() methods below would succeed, then this is
  // equivalent to calling that method and calling the result's file() method.
  // Otherwise this returns nullptr.
  const FileDescriptor* FindFileContainingSymbol(
      absl::string_view symbol_name) const;

  // Looking up descriptors ------------------------------------------
  // These find descriptors by fully-qualified name.  These will find both
  // top-level descriptors and nested descriptors.  They return nullptr if not
  // found.

  const Descriptor* FindMessageTypeByName(absl::string_view name) const;
  const FieldDescriptor* FindFieldByName(absl::string_view name) const;
  const FieldDescriptor* FindExtensionByName(absl::string_view name) const;
  const OneofDescriptor* FindOneofByName(absl::string_view name) const;
  const EnumDescriptor* FindEnumTypeByName(absl::string_view name) const;
  const EnumValueDescriptor* FindEnumValueByName(absl::string_view name) const;
  const ServiceDescriptor* FindServiceByName(absl::string_view name) const;
  const MethodDescriptor* FindMethodByName(absl::string_view name) const;

  // Finds an extension of the given type by number.  The extendee must be
  // a member of this DescriptorPool or one of its underlays.
  const FieldDescriptor* FindExtensionByNumber(const Descriptor* extendee,
                                               int number) const;

  // Finds an extension of the given type by its printable name.
  // See comments above PrintableNameForExtension() for the definition of
  // "printable name".  The extendee must be a member of this DescriptorPool
  // or one of its underlays.  Returns nullptr if there is no known message
  // extension with the given printable name.
  const FieldDescriptor* FindExtensionByPrintableName(
      const Descriptor* extendee, absl::string_view printable_name) const;

  // Finds extensions of extendee. The extensions will be appended to
  // out in an undefined order. Only extensions defined directly in
  // this DescriptorPool or one of its underlays are guaranteed to be
  // found: extensions defined in the fallback database might not be found
  // depending on the database implementation.
  void FindAllExtensions(const Descriptor* extendee,
                         std::vector<const FieldDescriptor*>* out) const;

  // Building descriptors --------------------------------------------

  // When converting a FileDescriptorProto to a FileDescriptor, various
  // errors might be detected in the input.  The caller may handle these
  // programmatically by implementing an ErrorCollector.
  class PROTOBUF_EXPORT ErrorCollector {
   public:
    inline ErrorCollector() {}
#ifndef SWIG
    ErrorCollector(const ErrorCollector&) = delete;
    ErrorCollector& operator=(const ErrorCollector&) = delete;
#endif
    virtual ~ErrorCollector();

    // These constants specify what exact part of the construct is broken.
    // This is useful e.g. for mapping the error back to an exact location
    // in a .proto file.
    enum ErrorLocation {
      NAME,           // the symbol name, or the package name for files
      NUMBER,         // field or extension range number
      TYPE,           // field type
      EXTENDEE,       // field extendee
      DEFAULT_VALUE,  // field default value
      INPUT_TYPE,     // method input type
      OUTPUT_TYPE,    // method output type
      OPTION_NAME,    // name in assignment
      OPTION_VALUE,   // value in option assignment
      IMPORT,         // import error
      OTHER           // some other problem
    };

    // Reports an error in the FileDescriptorProto. Use this function if the
    // problem occurred should interrupt building the FileDescriptorProto.
    virtual void AddError(
        const std::string& filename,  // File name in which the error occurred.
        const std::string& element_name,  // Full name of the erroneous element.
        const Message* descriptor,  // Descriptor of the erroneous element.
        ErrorLocation location,     // One of the location constants, above.
        const std::string& message  // Human-readable error message.
        ) = 0;

    // Reports a warning in the FileDescriptorProto. Use this function if the
    // problem occurred should NOT interrupt building the FileDescriptorProto.
    virtual void AddWarning(
        const std::string& /*filename*/,      // File name in which the error
                                              // occurred.
        const std::string& /*element_name*/,  // Full name of the erroneous
                                              // element.
        const Message* /*descriptor*/,  // Descriptor of the erroneous element.
        ErrorLocation /*location*/,     // One of the location constants, above.
        const std::string& /*message*/  // Human-readable error message.
    ) {}
  };

  // Convert the FileDescriptorProto to real descriptors and place them in
  // this DescriptorPool.  All dependencies of the file must already be in
  // the pool.  Returns the resulting FileDescriptor, or nullptr if there were
  // problems with the input (e.g. the message was invalid, or dependencies
  // were missing).  Details about the errors are written to GOOGLE_ABSL_LOG(ERROR).
  const FileDescriptor* BuildFile(const FileDescriptorProto& proto);

  // Same as BuildFile() except errors are sent to the given ErrorCollector.
  const FileDescriptor* BuildFileCollectingErrors(
      const FileDescriptorProto& proto, ErrorCollector* error_collector);

  // By default, it is an error if a FileDescriptorProto contains references
  // to types or other files that are not found in the DescriptorPool (or its
  // backing DescriptorDatabase, if any).  If you call
  // AllowUnknownDependencies(), however, then unknown types and files
  // will be replaced by placeholder descriptors (which can be identified by
  // the is_placeholder() method).  This can allow you to
  // perform some useful operations with a .proto file even if you do not
  // have access to other .proto files on which it depends.  However, some
  // heuristics must be used to fill in the gaps in information, and these
  // can lead to descriptors which are inaccurate.  For example, the
  // DescriptorPool may be forced to guess whether an unknown type is a message
  // or an enum, as well as what package it resides in.  Furthermore,
  // placeholder types will not be discoverable via FindMessageTypeByName()
  // and similar methods, which could confuse some descriptor-based algorithms.
  // Generally, the results of this option should be handled with extreme care.
  void AllowUnknownDependencies() { allow_unknown_ = true; }

  // By default, weak imports are allowed to be missing, in which case we will
  // use a placeholder for the dependency and convert the field to be an Empty
  // message field. If you call EnforceWeakDependencies(true), however, the
  // DescriptorPool will report a import not found error.
  void EnforceWeakDependencies(bool enforce) { enforce_weak_ = enforce; }

  // Internal stuff --------------------------------------------------
  // These methods MUST NOT be called from outside the proto2 library.
  // These methods may contain hidden pitfalls and may be removed in a
  // future library version.

  // Create a DescriptorPool which is overlaid on top of some other pool.
  // If you search for a descriptor in the overlay and it is not found, the
  // underlay will be searched as a backup.  If the underlay has its own
  // underlay, that will be searched next, and so on.  This also means that
  // files built in the overlay will be cross-linked with the underlay's
  // descriptors if necessary.  The underlay remains property of the caller;
  // it must remain valid for the lifetime of the newly-constructed pool.
  //
  // Example:  Say you want to parse a .proto file at runtime in order to use
  // its type with a DynamicMessage.  Say this .proto file has dependencies,
  // but you know that all the dependencies will be things that are already
  // compiled into the binary.  For ease of use, you'd like to load the types
  // right out of generated_pool() rather than have to parse redundant copies
  // of all these .protos and runtime.  But, you don't want to add the parsed
  // types directly into generated_pool(): this is not allowed, and would be
  // bad design anyway.  So, instead, you could use generated_pool() as an
  // underlay for a new DescriptorPool in which you add only the new file.
  //
  // WARNING:  Use of underlays can lead to many subtle gotchas.  Instead,
  //   try to formulate what you want to do in terms of DescriptorDatabases.
  explicit DescriptorPool(const DescriptorPool* underlay);

  // Called by generated classes at init time to add their descriptors to
  // generated_pool.  Do NOT call this in your own code!  filename must be a
  // permanent string (e.g. a string literal).
  static void InternalAddGeneratedFile(const void* encoded_file_descriptor,
                                       int size);

  // Disallow [enforce_utf8 = false] in .proto files.
  void DisallowEnforceUtf8() { disallow_enforce_utf8_ = true; }


  // For internal use only:  Gets a non-const pointer to the generated pool.
  // This is called at static-initialization time only, so thread-safety is
  // not a concern.  If both an underlay and a fallback database are present,
  // the underlay takes precedence.
  static DescriptorPool* internal_generated_pool();

  // For internal use only:  Gets a non-const pointer to the generated
  // descriptor database.
  // Only used for testing.
  static DescriptorDatabase* internal_generated_database();

  // For internal use only:  Changes the behavior of BuildFile() such that it
  // allows the file to make reference to message types declared in other files
  // which it did not officially declare as dependencies.
  void InternalDontEnforceDependencies();

  // For internal use only: Enables lazy building of dependencies of a file.
  // Delay the building of dependencies of a file descriptor until absolutely
  // necessary, like when message_type() is called on a field that is defined
  // in that dependency's file. This will cause functional issues if a proto
  // or one of its dependencies has errors. Should only be enabled for the
  // generated_pool_ (because no descriptor build errors are guaranteed by
  // the compilation generation process), testing, or if a lack of descriptor
  // build errors can be guaranteed for a pool.
  void InternalSetLazilyBuildDependencies() {
    lazily_build_dependencies_ = true;
    // This needs to be set when lazily building dependencies, as it breaks
    // dependency checking.
    InternalDontEnforceDependencies();
  }

  // For internal use only.
  void internal_set_underlay(const DescriptorPool* underlay) {
    underlay_ = underlay;
  }

  // For internal (unit test) use only:  Returns true if a FileDescriptor has
  // been constructed for the given file, false otherwise.  Useful for testing
  // lazy descriptor initialization behavior.
  bool InternalIsFileLoaded(absl::string_view filename) const;

  // Add a file to unused_import_track_files_. DescriptorBuilder will log
  // warnings or errors for those files if there is any unused import.
  void AddUnusedImportTrackFile(absl::string_view file_name,
                                bool is_error = false);
  void ClearUnusedImportTrackFiles();

 private:
  friend class Descriptor;
  friend class internal::LazyDescriptor;
  friend class FieldDescriptor;
  friend class EnumDescriptor;
  friend class ServiceDescriptor;
  friend class MethodDescriptor;
  friend class FileDescriptor;
  friend class DescriptorBuilder;
  friend class FileDescriptorTables;

  // Return true if the given name is a sub-symbol of any non-package
  // descriptor that already exists in the descriptor pool.  (The full
  // definition of such types is already known.)
  bool IsSubSymbolOfBuiltType(absl::string_view name) const;

  // Tries to find something in the fallback database and link in the
  // corresponding proto file.  Returns true if successful, in which case
  // the caller should search for the thing again.  These are declared
  // const because they are called by (semantically) const methods.
  bool TryFindFileInFallbackDatabase(absl::string_view name) const;
  bool TryFindSymbolInFallbackDatabase(absl::string_view name) const;
  bool TryFindExtensionInFallbackDatabase(const Descriptor* containing_type,
                                          int field_number) const;

  // This internal find extension method only check with its table and underlay
  // descriptor_pool's table. It does not check with fallback DB and no
  // additional proto file will be build in this method.
  const FieldDescriptor* InternalFindExtensionByNumberNoLock(
      const Descriptor* extendee, int number) const;

  // Like BuildFile() but called internally when the file has been loaded from
  // fallback_database_.  Declared const because it is called by (semantically)
  // const methods.
  const FileDescriptor* BuildFileFromDatabase(
      const FileDescriptorProto& proto) const;

  // Helper for when lazily_build_dependencies_ is set, can look up a symbol
  // after the file's descriptor is built, and can build the file where that
  // symbol is defined if necessary. Will create a placeholder if the type
  // doesn't exist in the fallback database, or the file doesn't build
  // successfully.
  Symbol CrossLinkOnDemandHelper(absl::string_view name,
                                 bool expecting_enum) const;

  // Create a placeholder FileDescriptor of the specified name
  FileDescriptor* NewPlaceholderFile(absl::string_view name) const;
  FileDescriptor* NewPlaceholderFileWithMutexHeld(
      absl::string_view name, internal::FlatAllocator& alloc) const;

  enum PlaceholderType {
    PLACEHOLDER_MESSAGE,
    PLACEHOLDER_ENUM,
    PLACEHOLDER_EXTENDABLE_MESSAGE
  };
  // Create a placeholder Descriptor of the specified name
  Symbol NewPlaceholder(absl::string_view name,
                        PlaceholderType placeholder_type) const;
  Symbol NewPlaceholderWithMutexHeld(absl::string_view name,
                                     PlaceholderType placeholder_type) const;

  // If fallback_database_ is nullptr, this is nullptr.  Otherwise, this is a
  // mutex which must be locked while accessing tables_.
  absl::Mutex* mutex_;

  // See constructor.
  DescriptorDatabase* fallback_database_;
  ErrorCollector* default_error_collector_;
  const DescriptorPool* underlay_;

  // This class contains a lot of hash maps with complicated types that
  // we'd like to keep out of the header.
  class Tables;
  std::unique_ptr<Tables> tables_;

  bool enforce_dependencies_;
  bool lazily_build_dependencies_;
  bool allow_unknown_;
  bool enforce_weak_;
  bool disallow_enforce_utf8_;

  // Set of files to track for unused imports. The bool value when true means
  // unused imports are treated as errors (and as warnings when false).
  std::map<std::string, bool> unused_import_track_files_;
};


// inline methods ====================================================

// These macros makes this repetitive code more readable.
#define PROTOBUF_DEFINE_ACCESSOR(CLASS, FIELD, TYPE) \
  inline TYPE CLASS::FIELD() const { return FIELD##_; }

// Strings fields are stored as pointers but returned as const references.
#define PROTOBUF_DEFINE_STRING_ACCESSOR(CLASS, FIELD) \
  inline const std::string& CLASS::FIELD() const { return *FIELD##_; }

// Name and full name are stored in a single array to save space.
#define PROTOBUF_DEFINE_NAME_ACCESSOR(CLASS)                              \
  inline const std::string& CLASS::name() const { return all_names_[0]; } \
  inline const std::string& CLASS::full_name() const { return all_names_[1]; }

// Arrays take an index parameter, obviously.
#define PROTOBUF_DEFINE_ARRAY_ACCESSOR(CLASS, FIELD, TYPE) \
  inline TYPE CLASS::FIELD(int index) const { return FIELD##s_ + index; }

#define PROTOBUF_DEFINE_OPTIONS_ACCESSOR(CLASS, TYPE) \
  inline const TYPE& CLASS::options() const { return *options_; }

PROTOBUF_DEFINE_NAME_ACCESSOR(Descriptor)
PROTOBUF_DEFINE_ACCESSOR(Descriptor, file, const FileDescriptor*)
PROTOBUF_DEFINE_ACCESSOR(Descriptor, containing_type, const Descriptor*)

PROTOBUF_DEFINE_ACCESSOR(Descriptor, field_count, int)
PROTOBUF_DEFINE_ACCESSOR(Descriptor, oneof_decl_count, int)
PROTOBUF_DEFINE_ACCESSOR(Descriptor, real_oneof_decl_count, int)
PROTOBUF_DEFINE_ACCESSOR(Descriptor, nested_type_count, int)
PROTOBUF_DEFINE_ACCESSOR(Descriptor, enum_type_count, int)

PROTOBUF_DEFINE_ARRAY_ACCESSOR(Descriptor, field, const FieldDescriptor*)
PROTOBUF_DEFINE_ARRAY_ACCESSOR(Descriptor, oneof_decl, const OneofDescriptor*)
PROTOBUF_DEFINE_ARRAY_ACCESSOR(Descriptor, nested_type, const Descriptor*)
PROTOBUF_DEFINE_ARRAY_ACCESSOR(Descriptor, enum_type, const EnumDescriptor*)

PROTOBUF_DEFINE_ACCESSOR(Descriptor, extension_range_count, int)
PROTOBUF_DEFINE_ACCESSOR(Descriptor, extension_count, int)
PROTOBUF_DEFINE_ARRAY_ACCESSOR(Descriptor, extension_range,
                               const Descriptor::ExtensionRange*)
PROTOBUF_DEFINE_ARRAY_ACCESSOR(Descriptor, extension, const FieldDescriptor*)

PROTOBUF_DEFINE_ACCESSOR(Descriptor, reserved_range_count, int)
PROTOBUF_DEFINE_ARRAY_ACCESSOR(Descriptor, reserved_range,
                               const Descriptor::ReservedRange*)
PROTOBUF_DEFINE_ACCESSOR(Descriptor, reserved_name_count, int)

PROTOBUF_DEFINE_OPTIONS_ACCESSOR(Descriptor, MessageOptions)
PROTOBUF_DEFINE_ACCESSOR(Descriptor, is_placeholder, bool)

PROTOBUF_DEFINE_NAME_ACCESSOR(FieldDescriptor)
PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, file, const FileDescriptor*)
PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, number, int)
PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, is_extension, bool)
PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, containing_type, const Descriptor*)
PROTOBUF_DEFINE_OPTIONS_ACCESSOR(FieldDescriptor, FieldOptions)
PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, has_default_value, bool)
PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, has_json_name, bool)
PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, default_value_int32_t, int32_t)
PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, default_value_int64_t, int64_t)
PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, default_value_uint32_t, uint32_t)
PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, default_value_uint64_t, uint64_t)
PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, default_value_float, float)
PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, default_value_double, double)
PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, default_value_bool, bool)
PROTOBUF_DEFINE_STRING_ACCESSOR(FieldDescriptor, default_value_string)

PROTOBUF_DEFINE_NAME_ACCESSOR(OneofDescriptor)
PROTOBUF_DEFINE_ACCESSOR(OneofDescriptor, containing_type, const Descriptor*)
PROTOBUF_DEFINE_ACCESSOR(OneofDescriptor, field_count, int)
PROTOBUF_DEFINE_ARRAY_ACCESSOR(OneofDescriptor, field, const FieldDescriptor*)
PROTOBUF_DEFINE_OPTIONS_ACCESSOR(OneofDescriptor, OneofOptions)

PROTOBUF_DEFINE_NAME_ACCESSOR(EnumDescriptor)
PROTOBUF_DEFINE_ACCESSOR(EnumDescriptor, file, const FileDescriptor*)
PROTOBUF_DEFINE_ACCESSOR(EnumDescriptor, containing_type, const Descriptor*)
PROTOBUF_DEFINE_ACCESSOR(EnumDescriptor, value_count, int)
PROTOBUF_DEFINE_ARRAY_ACCESSOR(EnumDescriptor, value,
                               const EnumValueDescriptor*)
PROTOBUF_DEFINE_OPTIONS_ACCESSOR(EnumDescriptor, EnumOptions)
PROTOBUF_DEFINE_ACCESSOR(EnumDescriptor, is_placeholder, bool)
PROTOBUF_DEFINE_ACCESSOR(EnumDescriptor, reserved_range_count, int)
PROTOBUF_DEFINE_ARRAY_ACCESSOR(EnumDescriptor, reserved_range,
                               const EnumDescriptor::ReservedRange*)
PROTOBUF_DEFINE_ACCESSOR(EnumDescriptor, reserved_name_count, int)

inline bool EnumDescriptor::is_closed() const {
  return file()->syntax() != FileDescriptor::SYNTAX_PROTO3;
}

PROTOBUF_DEFINE_NAME_ACCESSOR(EnumValueDescriptor)
PROTOBUF_DEFINE_ACCESSOR(EnumValueDescriptor, number, int)
PROTOBUF_DEFINE_ACCESSOR(EnumValueDescriptor, type, const EnumDescriptor*)
PROTOBUF_DEFINE_OPTIONS_ACCESSOR(EnumValueDescriptor, EnumValueOptions)

PROTOBUF_DEFINE_NAME_ACCESSOR(ServiceDescriptor)
PROTOBUF_DEFINE_ACCESSOR(ServiceDescriptor, file, const FileDescriptor*)
PROTOBUF_DEFINE_ACCESSOR(ServiceDescriptor, method_count, int)
PROTOBUF_DEFINE_ARRAY_ACCESSOR(ServiceDescriptor, method,
                               const MethodDescriptor*)
PROTOBUF_DEFINE_OPTIONS_ACCESSOR(ServiceDescriptor, ServiceOptions)

PROTOBUF_DEFINE_NAME_ACCESSOR(MethodDescriptor)
PROTOBUF_DEFINE_ACCESSOR(MethodDescriptor, service, const ServiceDescriptor*)
PROTOBUF_DEFINE_OPTIONS_ACCESSOR(MethodDescriptor, MethodOptions)
PROTOBUF_DEFINE_ACCESSOR(MethodDescriptor, client_streaming, bool)
PROTOBUF_DEFINE_ACCESSOR(MethodDescriptor, server_streaming, bool)

PROTOBUF_DEFINE_STRING_ACCESSOR(FileDescriptor, name)
PROTOBUF_DEFINE_STRING_ACCESSOR(FileDescriptor, package)
PROTOBUF_DEFINE_ACCESSOR(FileDescriptor, pool, const DescriptorPool*)
PROTOBUF_DEFINE_ACCESSOR(FileDescriptor, dependency_count, int)
PROTOBUF_DEFINE_ACCESSOR(FileDescriptor, public_dependency_count, int)
PROTOBUF_DEFINE_ACCESSOR(FileDescriptor, weak_dependency_count, int)
PROTOBUF_DEFINE_ACCESSOR(FileDescriptor, message_type_count, int)
PROTOBUF_DEFINE_ACCESSOR(FileDescriptor, enum_type_count, int)
PROTOBUF_DEFINE_ACCESSOR(FileDescriptor, service_count, int)
PROTOBUF_DEFINE_ACCESSOR(FileDescriptor, extension_count, int)
PROTOBUF_DEFINE_OPTIONS_ACCESSOR(FileDescriptor, FileOptions)
PROTOBUF_DEFINE_ACCESSOR(FileDescriptor, is_placeholder, bool)

PROTOBUF_DEFINE_ARRAY_ACCESSOR(FileDescriptor, message_type, const Descriptor*)
PROTOBUF_DEFINE_ARRAY_ACCESSOR(FileDescriptor, enum_type, const EnumDescriptor*)
PROTOBUF_DEFINE_ARRAY_ACCESSOR(FileDescriptor, service,
                               const ServiceDescriptor*)
PROTOBUF_DEFINE_ARRAY_ACCESSOR(FileDescriptor, extension,
                               const FieldDescriptor*)

#undef PROTOBUF_DEFINE_ACCESSOR
#undef PROTOBUF_DEFINE_STRING_ACCESSOR
#undef PROTOBUF_DEFINE_ARRAY_ACCESSOR

// A few accessors differ from the macros...

inline Descriptor::WellKnownType Descriptor::well_known_type() const {
  return static_cast<Descriptor::WellKnownType>(well_known_type_);
}

inline bool Descriptor::IsExtensionNumber(int number) const {
  return FindExtensionRangeContainingNumber(number) != nullptr;
}

inline bool Descriptor::IsReservedNumber(int number) const {
  return FindReservedRangeContainingNumber(number) != nullptr;
}

inline bool Descriptor::IsReservedName(absl::string_view name) const {
  for (int i = 0; i < reserved_name_count(); i++) {
    if (name == static_cast<absl::string_view>(reserved_name(i))) {
      return true;
    }
  }
  return false;
}

// Can't use PROTOBUF_DEFINE_ARRAY_ACCESSOR because reserved_names_ is actually
// an array of pointers rather than the usual array of objects.
inline const std::string& Descriptor::reserved_name(int index) const {
  return *reserved_names_[index];
}

inline bool EnumDescriptor::IsReservedNumber(int number) const {
  return FindReservedRangeContainingNumber(number) != nullptr;
}

inline bool EnumDescriptor::IsReservedName(absl::string_view name) const {
  for (int i = 0; i < reserved_name_count(); i++) {
    if (name == static_cast<absl::string_view>(reserved_name(i))) {
      return true;
    }
  }
  return false;
}

// Can't use PROTOBUF_DEFINE_ARRAY_ACCESSOR because reserved_names_ is actually
// an array of pointers rather than the usual array of objects.
inline const std::string& EnumDescriptor::reserved_name(int index) const {
  return *reserved_names_[index];
}

inline const std::string& FieldDescriptor::lowercase_name() const {
  return all_names_[lowercase_name_index_];
}

inline const std::string& FieldDescriptor::camelcase_name() const {
  return all_names_[camelcase_name_index_];
}

inline const std::string& FieldDescriptor::json_name() const {
  return all_names_[json_name_index_];
}

inline const OneofDescriptor* FieldDescriptor::containing_oneof() const {
  return is_oneof_ ? scope_.containing_oneof : nullptr;
}

inline int FieldDescriptor::index_in_oneof() const {
  GOOGLE_ABSL_DCHECK(is_oneof_);
  return static_cast<int>(this - scope_.containing_oneof->field(0));
}

inline const Descriptor* FieldDescriptor::extension_scope() const {
  GOOGLE_ABSL_CHECK(is_extension_);
  return scope_.extension_scope;
}

inline FieldDescriptor::Label FieldDescriptor::label() const {
  return static_cast<Label>(label_);
}

inline FieldDescriptor::Type FieldDescriptor::type() const {
  if (type_once_) {
    absl::call_once(*type_once_, &FieldDescriptor::TypeOnceInit, this);
  }
  return static_cast<Type>(type_);
}

inline bool FieldDescriptor::is_required() const {
  return label() == LABEL_REQUIRED;
}

inline bool FieldDescriptor::is_optional() const {
  return label() == LABEL_OPTIONAL;
}

inline bool FieldDescriptor::is_repeated() const {
  return label() == LABEL_REPEATED;
}

inline bool FieldDescriptor::is_packable() const {
  return is_repeated() && IsTypePackable(type());
}

inline bool FieldDescriptor::is_map() const {
  return type() == TYPE_MESSAGE && is_map_message_type();
}

inline bool FieldDescriptor::has_optional_keyword() const {
  return proto3_optional_ ||
         (file()->syntax() == FileDescriptor::SYNTAX_PROTO2 && is_optional() &&
          !containing_oneof());
}

inline const OneofDescriptor* FieldDescriptor::real_containing_oneof() const {
  auto* oneof = containing_oneof();
  return oneof && !oneof->is_synthetic() ? oneof : nullptr;
}

inline bool FieldDescriptor::has_presence() const {
  if (is_repeated()) return false;
  return cpp_type() == CPPTYPE_MESSAGE || containing_oneof() ||
         file()->syntax() == FileDescriptor::SYNTAX_PROTO2;
}

inline bool FieldDescriptor::requires_utf8_validation() const {
  return type() == TYPE_STRING &&
         file()->syntax() == FileDescriptor::SYNTAX_PROTO3;
}

// To save space, index() is computed by looking at the descriptor's position
// in the parent's array of children.
inline int FieldDescriptor::index() const {
  if (!is_extension_) {
    return static_cast<int>(this - containing_type()->fields_);
  } else if (extension_scope() != nullptr) {
    return static_cast<int>(this - extension_scope()->extensions_);
  } else {
    return static_cast<int>(this - file_->extensions_);
  }
}

inline int Descriptor::index() const {
  if (containing_type_ == nullptr) {
    return static_cast<int>(this - file_->message_types_);
  } else {
    return static_cast<int>(this - containing_type_->nested_types_);
  }
}

inline const FileDescriptor* OneofDescriptor::file() const {
  return containing_type()->file();
}

inline int OneofDescriptor::index() const {
  return static_cast<int>(this - containing_type_->oneof_decls_);
}

inline bool OneofDescriptor::is_synthetic() const {
  return field_count() == 1 && field(0)->proto3_optional_;
}

inline int EnumDescriptor::index() const {
  if (containing_type_ == nullptr) {
    return static_cast<int>(this - file_->enum_types_);
  } else {
    return static_cast<int>(this - containing_type_->enum_types_);
  }
}

inline const FileDescriptor* EnumValueDescriptor::file() const {
  return type()->file();
}

inline int EnumValueDescriptor::index() const {
  return static_cast<int>(this - type_->values_);
}

inline int ServiceDescriptor::index() const {
  return static_cast<int>(this - file_->services_);
}

inline const FileDescriptor* MethodDescriptor::file() const {
  return service()->file();
}

inline int MethodDescriptor::index() const {
  return static_cast<int>(this - service_->methods_);
}

inline const char* FieldDescriptor::type_name() const {
  return kTypeToName[type()];
}

inline FieldDescriptor::CppType FieldDescriptor::cpp_type() const {
  return kTypeToCppTypeMap[type()];
}

inline const char* FieldDescriptor::cpp_type_name() const {
  return kCppTypeToName[kTypeToCppTypeMap[type()]];
}

inline FieldDescriptor::CppType FieldDescriptor::TypeToCppType(Type type) {
  return kTypeToCppTypeMap[type];
}

inline const char* FieldDescriptor::TypeName(Type type) {
  return kTypeToName[type];
}

inline const char* FieldDescriptor::CppTypeName(CppType cpp_type) {
  return kCppTypeToName[cpp_type];
}

inline bool FieldDescriptor::IsTypePackable(Type field_type) {
  return (field_type != FieldDescriptor::TYPE_STRING &&
          field_type != FieldDescriptor::TYPE_GROUP &&
          field_type != FieldDescriptor::TYPE_MESSAGE &&
          field_type != FieldDescriptor::TYPE_BYTES);
}

inline const FileDescriptor* FileDescriptor::public_dependency(
    int index) const {
  return dependency(public_dependencies_[index]);
}

inline const FileDescriptor* FileDescriptor::weak_dependency(int index) const {
  return dependency(weak_dependencies_[index]);
}

inline FileDescriptor::Syntax FileDescriptor::syntax() const {
  return static_cast<Syntax>(syntax_);
}

namespace internal {

// FieldRange(desc) provides an iterable range for the fields of a
// descriptor type, appropriate for range-for loops.

template <typename T>
struct FieldRangeImpl;

template <typename T>
FieldRangeImpl<T> FieldRange(const T* desc) {
  return {desc};
}

template <typename T>
struct FieldRangeImpl {
  struct Iterator {
    using iterator_category = std::forward_iterator_tag;
    using value_type = const FieldDescriptor*;
    using difference_type = int;

    value_type operator*() { return descriptor->field(idx); }

    friend bool operator==(const Iterator& a, const Iterator& b) {
      GOOGLE_ABSL_DCHECK(a.descriptor == b.descriptor);
      return a.idx == b.idx;
    }
    friend bool operator!=(const Iterator& a, const Iterator& b) {
      return !(a == b);
    }

    Iterator& operator++() {
      idx++;
      return *this;
    }

    int idx;
    const T* descriptor;
  };

  Iterator begin() const { return {0, descriptor}; }
  Iterator end() const { return {descriptor->field_count(), descriptor}; }

  const T* descriptor;
};

// The context for these functions under `cpp` is "for the C++ implementation".
// In particular, questions like "does this field have a has bit?" have a
// different answer depending on the language.
namespace cpp {
// Returns true if 'enum' semantics are such that unknown values are preserved
// in the enum field itself, rather than going to the UnknownFieldSet.
PROTOBUF_EXPORT bool HasPreservingUnknownEnumSemantics(
    const FieldDescriptor* field);

PROTOBUF_EXPORT bool HasHasbit(const FieldDescriptor* field);

#ifndef SWIG
enum class Utf8CheckMode {
  kStrict = 0,  // Parsing will fail if non UTF-8 data is in string fields.
  kVerify = 1,  // Only log an error but parsing will succeed.
  kNone = 2,    // No UTF-8 check.
};
PROTOBUF_EXPORT Utf8CheckMode GetUtf8CheckMode(const FieldDescriptor* field,
                                               bool is_lite);
#endif  // !SWIG

}  // namespace cpp
}  // namespace internal

}  // namespace protobuf
}  // namespace google

#undef PROTOBUF_INTERNAL_CHECK_CLASS_SIZE
#include "google/protobuf/port_undef.inc"

#endif  // GOOGLE_PROTOBUF_DESCRIPTOR_H__
