// 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/stubs/logging.h"
#include "google/protobuf/port.h"
#include "absl/base/call_once.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_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_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_DCHECK(is_oneof_);
  return static_cast<int>(this - scope_.containing_oneof->field(0));
}

inline const Descriptor* FieldDescriptor::extension_scope() const {
  GOOGLE_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_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__
