// 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 <map>
#include <memory>
#include <set>
#include <string>
#include <vector>

#include <google/protobuf/stubs/common.h>
#include <google/protobuf/stubs/mutex.h>
#include <google/protobuf/stubs/once.h>
#include <google/protobuf/port.h>
#include <google/protobuf/port_def.inc>

// TYPE_BOOL is defined in the MacOS's ConditionalMacros.h.
#ifdef TYPE_BOOL
#undef TYPE_BOOL
#endif  // TYPE_BOOL

#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;
struct 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 {
class PROTOBUF_EXPORT LazyDescriptor {
 public:
  // Init function to be called at init time of a descriptor containing
  // a LazyDescriptor.
  void Init() {
    descriptor_ = nullptr;
    name_ = nullptr;
    once_ = nullptr;
    file_ = 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(StringPiece 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() {
    Once();
    return descriptor_;
  }

 private:
  static void OnceStatic(LazyDescriptor* lazy);
  void OnceInternal();
  void Once();

  const Descriptor* descriptor_;
  const std::string* name_;
  internal::once_flag* once_;
  const FileDescriptor* file_;
};
}  // 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 {
 public:
  typedef DescriptorProto Proto;

  // 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(ConstStringParam 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(
      ConstStringParam 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(
      ConstStringParam 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(ConstStringParam 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(ConstStringParam 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(ConstStringParam 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(ConstStringParam 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(ConstStringParam name) const;

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

  // Similar to FindFieldByCamelcaseName(), but finds extensions defined within
  // this message type's scope.
  const FieldDescriptor* FindExtensionByCamelcaseName(
      ConstStringParam 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(ConstStringParam 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:
  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;

  const std::string* name_;
  const std::string* full_name_;
  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 field_count_;
  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_;

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

  // 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 OneofDescriptor;
  friend class MethodDescriptor;
  friend class FileDescriptor;
  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Descriptor);
};


// 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 {
 public:
  typedef FieldDescriptorProto Proto;

  // 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;

  // 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 default_value_int32() const;
  // Get the field default value if cpp_type() == CPPTYPE_INT64.  If no
  // explicit default was defined, the default is 0.
  int64 default_value_int64() const;
  // Get the field default value if cpp_type() == CPPTYPE_UINT32.  If no
  // explicit default was defined, the default is 0.
  uint32 default_value_uint32() const;
  // Get the field default value if cpp_type() == CPPTYPE_UINT64.  If no
  // explicit default was defined, the default is 0.
  uint64 default_value_uint64() const;
  // 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:
  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 whill 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;

  const std::string* name_;
  const std::string* full_name_;
  const std::string* lowercase_name_;
  const std::string* camelcase_name_;
  // If has_json_name_ is true, it's the value specified by the user.
  // Otherwise, it has the same value as camelcase_name_.
  const std::string* json_name_;
  const FileDescriptor* file_;
  internal::once_flag* type_once_;
  static void TypeOnceInit(const FieldDescriptor* to_init);
  void InternalTypeOnceInit() const;
  mutable Type type_;
  Label label_;
  bool has_default_value_;
  bool proto3_optional_;
  // Whether the user has specified the json_name field option in the .proto
  // file.
  bool has_json_name_;
  bool is_extension_;
  int number_;
  int index_in_oneof_;
  const Descriptor* containing_type_;
  const OneofDescriptor* containing_oneof_;
  const Descriptor* extension_scope_;
  mutable const Descriptor* message_type_;
  mutable const EnumDescriptor* enum_type_;
  const FieldOptions* options_;
  const std::string* type_name_;
  const std::string* default_value_enum_name_;
  // 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 default_value_int32_;
    int64 default_value_int64_;
    uint32 default_value_uint32_;
    uint64 default_value_uint64_;
    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;
  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FieldDescriptor);
};


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

  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:
  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;

  const std::string* name_;
  const std::string* full_name_;
  const Descriptor* containing_type_;
  int field_count_;
  const FieldDescriptor** fields_;
  const OneofOptions* options_;

  // 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;
  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(OneofDescriptor);
};

// 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 {
 public:
  typedef EnumDescriptorProto Proto;

  // 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(ConstStringParam 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;

  // 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(ConstStringParam 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:
  typedef EnumOptions OptionsType;

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

  // 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;

  const std::string* name_;
  const std::string* full_name_;
  const FileDescriptor* file_;
  const Descriptor* containing_type_;
  const EnumOptions* options_;

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

  int value_count_;
  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 EnumValueDescriptor;
  friend class FileDescriptor;
  friend class DescriptorPool;
  friend class Reflection;
  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(EnumDescriptor);
};

// 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 {
 public:
  typedef EnumValueDescriptorProto Proto;

  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:
  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;

  const std::string* name_;
  const std::string* full_name_;
  int number_;
  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;
  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(EnumValueDescriptor);
};

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

  // 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(ConstStringParam 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:
  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;

  const std::string* name_;
  const std::string* full_name_;
  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;
  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ServiceDescriptor);
};


// 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 {
 public:
  typedef MethodDescriptorProto Proto;

  // 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:
  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;

  const std::string* name_;
  const std::string* full_name_;
  const ServiceDescriptor* service_;
  mutable internal::LazyDescriptor input_type_;
  mutable internal::LazyDescriptor output_type_;
  const MethodOptions* options_;
  bool client_streaming_;
  bool server_streaming_;
  // 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;
  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MethodDescriptor);
};


// 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 {
 public:
  typedef FileDescriptorProto Proto;

  // 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 {
    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(ConstStringParam name) const;
  // Find a top-level enum type by name.  Returns nullptr if not found.
  const EnumDescriptor* FindEnumTypeByName(ConstStringParam name) const;
  // Find an enum value defined in any top-level enum by name.  Returns nullptr
  // if not found.
  const EnumValueDescriptor* FindEnumValueByName(ConstStringParam name) const;
  // Find a service definition by name.  Returns nullptr if not found.
  const ServiceDescriptor* FindServiceByName(ConstStringParam name) const;
  // Find a top-level extension definition by name.  Returns nullptr if not
  // found.
  const FieldDescriptor* FindExtensionByName(ConstStringParam name) const;
  // Similar to FindExtensionByName(), but searches by lowercased-name.  See
  // Descriptor::FindFieldByLowercaseName().
  const FieldDescriptor* FindExtensionByLowercaseName(
      ConstStringParam name) const;
  // Similar to FindExtensionByName(), but searches by camelcased-name.  See
  // Descriptor::FindFieldByCamelcaseName().
  const FieldDescriptor* FindExtensionByCamelcaseName(
      ConstStringParam 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;

  // 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:
  typedef FileOptions OptionsType;

  const std::string* name_;
  const std::string* package_;
  const DescriptorPool* pool_;
  internal::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_;
  int extension_count_;
  Syntax syntax_;
  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_;

  mutable const FileDescriptor** dependencies_;
  const std::string** dependencies_names_;
  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;
  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FileDescriptor);
};


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

// 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);

  ~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(ConstStringParam 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(
      ConstStringParam 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(ConstStringParam name) const;
  const FieldDescriptor* FindFieldByName(ConstStringParam name) const;
  const FieldDescriptor* FindExtensionByName(ConstStringParam name) const;
  const OneofDescriptor* FindOneofByName(ConstStringParam name) const;
  const EnumDescriptor* FindEnumTypeByName(ConstStringParam name) const;
  const EnumValueDescriptor* FindEnumValueByName(ConstStringParam name) const;
  const ServiceDescriptor* FindServiceByName(ConstStringParam name) const;
  const MethodDescriptor* FindMethodByName(ConstStringParam 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, ConstStringParam 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() {}
    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.
    ) {}

   private:
    GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ErrorCollector);
  };

  // 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(ConstStringParam 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(ConstStringParam 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 StreamDescriptor;
  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(StringPiece 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(StringPiece name) const;
  bool TryFindSymbolInFallbackDatabase(StringPiece 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(StringPiece name,
                                 bool expecting_enum) const;

  // Create a placeholder FileDescriptor of the specified name
  FileDescriptor* NewPlaceholderFile(StringPiece name) const;
  FileDescriptor* NewPlaceholderFileWithMutexHeld(StringPiece name) const;

  enum PlaceholderType {
    PLACEHOLDER_MESSAGE,
    PLACEHOLDER_ENUM,
    PLACEHOLDER_EXTENDABLE_MESSAGE
  };
  // Create a placeholder Descriptor of the specified name
  Symbol NewPlaceholder(StringPiece name,
                        PlaceholderType placeholder_type) const;
  Symbol NewPlaceholderWithMutexHeld(StringPiece 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_.
  internal::WrappedMutex* 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_;

  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(DescriptorPool);
};


// 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##_; }

// 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_STRING_ACCESSOR(Descriptor, name)
PROTOBUF_DEFINE_STRING_ACCESSOR(Descriptor, full_name)
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_STRING_ACCESSOR(FieldDescriptor, name)
PROTOBUF_DEFINE_STRING_ACCESSOR(FieldDescriptor, full_name)
PROTOBUF_DEFINE_STRING_ACCESSOR(FieldDescriptor, json_name)
PROTOBUF_DEFINE_STRING_ACCESSOR(FieldDescriptor, lowercase_name)
PROTOBUF_DEFINE_STRING_ACCESSOR(FieldDescriptor, camelcase_name)
PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, file, const FileDescriptor*)
PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, number, int)
PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, is_extension, bool)
PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, label, FieldDescriptor::Label)
PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, containing_type, const Descriptor*)
PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, containing_oneof,
                         const OneofDescriptor*)
PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, index_in_oneof, int)
PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, extension_scope, 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, int32)
PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, default_value_int64, int64)
PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, default_value_uint32, uint32)
PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, default_value_uint64, uint64)
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_STRING_ACCESSOR(OneofDescriptor, name)
PROTOBUF_DEFINE_STRING_ACCESSOR(OneofDescriptor, full_name)
PROTOBUF_DEFINE_ACCESSOR(OneofDescriptor, containing_type, const Descriptor*)
PROTOBUF_DEFINE_ACCESSOR(OneofDescriptor, field_count, int)
PROTOBUF_DEFINE_OPTIONS_ACCESSOR(OneofDescriptor, OneofOptions)

PROTOBUF_DEFINE_STRING_ACCESSOR(EnumDescriptor, name)
PROTOBUF_DEFINE_STRING_ACCESSOR(EnumDescriptor, full_name)
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)

PROTOBUF_DEFINE_STRING_ACCESSOR(EnumValueDescriptor, name)
PROTOBUF_DEFINE_STRING_ACCESSOR(EnumValueDescriptor, full_name)
PROTOBUF_DEFINE_ACCESSOR(EnumValueDescriptor, number, int)
PROTOBUF_DEFINE_ACCESSOR(EnumValueDescriptor, type, const EnumDescriptor*)
PROTOBUF_DEFINE_OPTIONS_ACCESSOR(EnumValueDescriptor, EnumValueOptions)

PROTOBUF_DEFINE_STRING_ACCESSOR(ServiceDescriptor, name)
PROTOBUF_DEFINE_STRING_ACCESSOR(ServiceDescriptor, full_name)
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_STRING_ACCESSOR(MethodDescriptor, name)
PROTOBUF_DEFINE_STRING_ACCESSOR(MethodDescriptor, full_name)
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(ConstStringParam name) const {
  for (int i = 0; i < reserved_name_count(); i++) {
    if (name == static_cast<ConstStringParam>(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(ConstStringParam name) const {
  for (int i = 0; i < reserved_name_count(); i++) {
    if (name == static_cast<ConstStringParam>(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 FieldDescriptor::Type FieldDescriptor::type() const {
  if (type_once_) {
    internal::call_once(*type_once_, &FieldDescriptor::TypeOnceInit, this);
  }
  return 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 {
  return containing_oneof_ && !containing_oneof_->is_synthetic()
             ? containing_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;
}

// 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 syntax_; }

// Can't use PROTOBUF_DEFINE_ARRAY_ACCESSOR because fields_ is actually an array
// of pointers rather than the usual array of objects.
inline const FieldDescriptor* OneofDescriptor::field(int index) const {
  return fields_[index];
}

}  // namespace protobuf
}  // namespace google

#include <google/protobuf/port_undef.inc>

#endif  // GOOGLE_PROTOBUF_DESCRIPTOR_H__
