// Generated by the protocol buffer compiler.  DO NOT EDIT!
// source: google/protobuf/struct.proto

#ifndef GOOGLE_PROTOBUF_INCLUDED_google_2fprotobuf_2fstruct_2eproto_2epb_2eh
#define GOOGLE_PROTOBUF_INCLUDED_google_2fprotobuf_2fstruct_2eproto_2epb_2eh

#include <limits>
#include <string>
#include <type_traits>

#include "google/protobuf/port_def.inc"
#if PROTOBUF_VERSION < 3021000
#error "This file was generated by a newer version of protoc which is"
#error "incompatible with your Protocol Buffer headers. Please update"
#error "your headers."
#endif  // PROTOBUF_VERSION

#if 3021007 < PROTOBUF_MIN_PROTOC_VERSION
#error "This file was generated by an older version of protoc which is"
#error "incompatible with your Protocol Buffer headers. Please"
#error "regenerate this file with a newer version of protoc."
#endif  // PROTOBUF_MIN_PROTOC_VERSION
#include "google/protobuf/port_undef.inc"
#include "google/protobuf/io/coded_stream.h"
#include "google/protobuf/arena.h"
#include "google/protobuf/arenastring.h"
#include "google/protobuf/generated_message_util.h"
#include "google/protobuf/metadata_lite.h"
#include "google/protobuf/generated_message_reflection.h"
#include "google/protobuf/message.h"
#include "google/protobuf/repeated_field.h"  // IWYU pragma: export
#include "google/protobuf/extension_set.h"  // IWYU pragma: export
#include "google/protobuf/map.h"  // IWYU pragma: export
#include "google/protobuf/map_entry.h"
#include "google/protobuf/map_field_inl.h"
#include "google/protobuf/generated_enum_reflection.h"
#include "google/protobuf/unknown_field_set.h"
// @@protoc_insertion_point(includes)

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

#define PROTOBUF_INTERNAL_EXPORT_google_2fprotobuf_2fstruct_2eproto PROTOBUF_EXPORT

PROTOBUF_NAMESPACE_OPEN
namespace internal {
class AnyMetadata;
}  // namespace internal
PROTOBUF_NAMESPACE_CLOSE

// Internal implementation detail -- do not use these members.
struct PROTOBUF_EXPORT TableStruct_google_2fprotobuf_2fstruct_2eproto {
  static const uint32_t offsets[];
};
PROTOBUF_EXPORT extern const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable
    descriptor_table_google_2fprotobuf_2fstruct_2eproto;
PROTOBUF_NAMESPACE_OPEN
class ListValue;
struct ListValueDefaultTypeInternal;
PROTOBUF_EXPORT extern ListValueDefaultTypeInternal _ListValue_default_instance_;
class Struct;
struct StructDefaultTypeInternal;
PROTOBUF_EXPORT extern StructDefaultTypeInternal _Struct_default_instance_;
class Struct_FieldsEntry_DoNotUse;
struct Struct_FieldsEntry_DoNotUseDefaultTypeInternal;
PROTOBUF_EXPORT extern Struct_FieldsEntry_DoNotUseDefaultTypeInternal _Struct_FieldsEntry_DoNotUse_default_instance_;
class Value;
struct ValueDefaultTypeInternal;
PROTOBUF_EXPORT extern ValueDefaultTypeInternal _Value_default_instance_;
template <>
PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::ListValue* Arena::CreateMaybeMessage<::PROTOBUF_NAMESPACE_ID::ListValue>(Arena*);
template <>
PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::Struct* Arena::CreateMaybeMessage<::PROTOBUF_NAMESPACE_ID::Struct>(Arena*);
template <>
PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::Struct_FieldsEntry_DoNotUse* Arena::CreateMaybeMessage<::PROTOBUF_NAMESPACE_ID::Struct_FieldsEntry_DoNotUse>(Arena*);
template <>
PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::Value* Arena::CreateMaybeMessage<::PROTOBUF_NAMESPACE_ID::Value>(Arena*);
PROTOBUF_NAMESPACE_CLOSE

PROTOBUF_NAMESPACE_OPEN
enum NullValue : int {
  NULL_VALUE = 0,
  NullValue_INT_MIN_SENTINEL_DO_NOT_USE_ =
      std::numeric_limits<int32_t>::min(),
  NullValue_INT_MAX_SENTINEL_DO_NOT_USE_ =
      std::numeric_limits<int32_t>::max(),
};

PROTOBUF_EXPORT bool NullValue_IsValid(int value);
constexpr NullValue NullValue_MIN = static_cast<NullValue>(0);
constexpr NullValue NullValue_MAX = static_cast<NullValue>(0);
constexpr int NullValue_ARRAYSIZE = 0 + 1;
PROTOBUF_EXPORT const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor*
NullValue_descriptor();
template <typename T>
const std::string& NullValue_Name(T value) {
  static_assert(std::is_same<T, NullValue>::value ||
                    std::is_integral<T>::value,
                "Incorrect type passed to NullValue_Name().");
  return NullValue_Name(static_cast<NullValue>(value));
}
template <>
inline const std::string& NullValue_Name(NullValue value) {
  return ::PROTOBUF_NAMESPACE_ID::internal::NameOfDenseEnum<NullValue_descriptor,
                                                 0, 0>(
      static_cast<int>(value));
}
inline bool NullValue_Parse(absl::string_view name, NullValue* value) {
  return ::PROTOBUF_NAMESPACE_ID::internal::ParseNamedEnum<NullValue>(
      NullValue_descriptor(), name, value);
}

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


// -------------------------------------------------------------------

class Struct_FieldsEntry_DoNotUse : public ::PROTOBUF_NAMESPACE_ID::internal::MapEntry<Struct_FieldsEntry_DoNotUse, 
    std::string, ::PROTOBUF_NAMESPACE_ID::Value,
    ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_STRING,
    ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_MESSAGE> {
public:
  typedef ::PROTOBUF_NAMESPACE_ID::internal::MapEntry<Struct_FieldsEntry_DoNotUse, 
    std::string, ::PROTOBUF_NAMESPACE_ID::Value,
    ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_STRING,
    ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_MESSAGE> SuperType;
  Struct_FieldsEntry_DoNotUse();
  explicit PROTOBUF_CONSTEXPR Struct_FieldsEntry_DoNotUse(
      ::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);
  explicit Struct_FieldsEntry_DoNotUse(::PROTOBUF_NAMESPACE_ID::Arena* arena);
  void MergeFrom(const Struct_FieldsEntry_DoNotUse& other);
  static const Struct_FieldsEntry_DoNotUse* internal_default_instance() { return reinterpret_cast<const Struct_FieldsEntry_DoNotUse*>(&_Struct_FieldsEntry_DoNotUse_default_instance_); }
  static bool ValidateKey(std::string* s) {
    return ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::VerifyUtf8String(s->data(), static_cast<int>(s->size()), ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::PARSE, "google.protobuf.Struct.FieldsEntry.key");
 }
  static bool ValidateValue(void*) { return true; }
  using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom;
  ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final;
  friend struct ::TableStruct_google_2fprotobuf_2fstruct_2eproto;
};
// -------------------------------------------------------------------

class PROTOBUF_EXPORT Struct final :
    public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.Struct) */ {
 public:
  inline Struct() : Struct(nullptr) {}
  ~Struct() override;
  explicit PROTOBUF_CONSTEXPR Struct(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);

  Struct(const Struct& from);
  Struct(Struct&& from) noexcept
    : Struct() {
    *this = ::std::move(from);
  }

  inline Struct& operator=(const Struct& from) {
    CopyFrom(from);
    return *this;
  }
  inline Struct& operator=(Struct&& from) noexcept {
    if (this == &from) return *this;
    if (GetOwningArena() == from.GetOwningArena()
  #ifdef PROTOBUF_FORCE_COPY_IN_MOVE
        && GetOwningArena() != nullptr
  #endif  // !PROTOBUF_FORCE_COPY_IN_MOVE
    ) {
      InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }

  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() {
    return GetDescriptor();
  }
  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() {
    return default_instance().GetMetadata().descriptor;
  }
  static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() {
    return default_instance().GetMetadata().reflection;
  }
  static const Struct& default_instance() {
    return *internal_default_instance();
  }
  static inline const Struct* internal_default_instance() {
    return reinterpret_cast<const Struct*>(
               &_Struct_default_instance_);
  }
  static constexpr int kIndexInFileMessages =
    1;

  friend void swap(Struct& a, Struct& b) {
    a.Swap(&b);
  }
  inline void Swap(Struct* other) {
    if (other == this) return;
  #ifdef PROTOBUF_FORCE_COPY_IN_SWAP
    if (GetOwningArena() != nullptr &&
        GetOwningArena() == other->GetOwningArena()) {
   #else  // PROTOBUF_FORCE_COPY_IN_SWAP
    if (GetOwningArena() == other->GetOwningArena()) {
  #endif  // !PROTOBUF_FORCE_COPY_IN_SWAP
      InternalSwap(other);
    } else {
      ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);
    }
  }
  void UnsafeArenaSwap(Struct* other) {
    if (other == this) return;
    GOOGLE_DCHECK(GetOwningArena() == other->GetOwningArena());
    InternalSwap(other);
  }

  // implements Message ----------------------------------------------

  Struct* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final {
    return CreateMaybeMessage<Struct>(arena);
  }
  using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom;
  void CopyFrom(const Struct& from);
  using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom;
  void MergeFrom( const Struct& from) {
    Struct::MergeImpl(*this, from);
  }
  private:
  static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg);
  public:
  PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
  bool IsInitialized() const final;

  size_t ByteSizeLong() const final;
  const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
  uint8_t* _InternalSerialize(
      uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
  int GetCachedSize() const final { return _impl_._cached_size_.Get(); }

  private:
  void SharedCtor(::PROTOBUF_NAMESPACE_ID::Arena* arena, bool is_message_owned);
  void SharedDtor();
  void SetCachedSize(int size) const final;
  void InternalSwap(Struct* other);

  private:
  friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
  static ::absl::string_view FullMessageName() {
    return "google.protobuf.Struct";
  }
  protected:
  explicit Struct(::PROTOBUF_NAMESPACE_ID::Arena* arena,
                       bool is_message_owned = false);
  private:
  static void ArenaDtor(void* object);
  public:

  static const ClassData _class_data_;
  const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*GetClassData() const final;

  ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final;

  // nested types ----------------------------------------------------


  // accessors -------------------------------------------------------

  enum : int {
    kFieldsFieldNumber = 1,
  };
  // map<string, .google.protobuf.Value> fields = 1;
  int fields_size() const;
  private:
  int _internal_fields_size() const;
  public:
  void clear_fields();
  private:
  const ::PROTOBUF_NAMESPACE_ID::Map< std::string, ::PROTOBUF_NAMESPACE_ID::Value >&
      _internal_fields() const;
  ::PROTOBUF_NAMESPACE_ID::Map< std::string, ::PROTOBUF_NAMESPACE_ID::Value >*
      _internal_mutable_fields();
  public:
  const ::PROTOBUF_NAMESPACE_ID::Map< std::string, ::PROTOBUF_NAMESPACE_ID::Value >&
      fields() const;
  ::PROTOBUF_NAMESPACE_ID::Map< std::string, ::PROTOBUF_NAMESPACE_ID::Value >*
      mutable_fields();

  // @@protoc_insertion_point(class_scope:google.protobuf.Struct)
 private:
  class _Internal;

  template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper;
  typedef void InternalArenaConstructable_;
  typedef void DestructorSkippable_;
  struct Impl_ {
    ::PROTOBUF_NAMESPACE_ID::internal::MapField<
        Struct_FieldsEntry_DoNotUse,
        std::string, ::PROTOBUF_NAMESPACE_ID::Value,
        ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_STRING,
        ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_MESSAGE> fields_;
    mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
  };
  union { Impl_ _impl_; };
  friend struct ::TableStruct_google_2fprotobuf_2fstruct_2eproto;
};// -------------------------------------------------------------------

class PROTOBUF_EXPORT Value final :
    public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.Value) */ {
 public:
  inline Value() : Value(nullptr) {}
  ~Value() override;
  explicit PROTOBUF_CONSTEXPR Value(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);

  Value(const Value& from);
  Value(Value&& from) noexcept
    : Value() {
    *this = ::std::move(from);
  }

  inline Value& operator=(const Value& from) {
    CopyFrom(from);
    return *this;
  }
  inline Value& operator=(Value&& from) noexcept {
    if (this == &from) return *this;
    if (GetOwningArena() == from.GetOwningArena()
  #ifdef PROTOBUF_FORCE_COPY_IN_MOVE
        && GetOwningArena() != nullptr
  #endif  // !PROTOBUF_FORCE_COPY_IN_MOVE
    ) {
      InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }

  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() {
    return GetDescriptor();
  }
  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() {
    return default_instance().GetMetadata().descriptor;
  }
  static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() {
    return default_instance().GetMetadata().reflection;
  }
  static const Value& default_instance() {
    return *internal_default_instance();
  }
  enum KindCase {
    kNullValue = 1,
    kNumberValue = 2,
    kStringValue = 3,
    kBoolValue = 4,
    kStructValue = 5,
    kListValue = 6,
    KIND_NOT_SET = 0,
  };

  static inline const Value* internal_default_instance() {
    return reinterpret_cast<const Value*>(
               &_Value_default_instance_);
  }
  static constexpr int kIndexInFileMessages =
    2;

  friend void swap(Value& a, Value& b) {
    a.Swap(&b);
  }
  inline void Swap(Value* other) {
    if (other == this) return;
  #ifdef PROTOBUF_FORCE_COPY_IN_SWAP
    if (GetOwningArena() != nullptr &&
        GetOwningArena() == other->GetOwningArena()) {
   #else  // PROTOBUF_FORCE_COPY_IN_SWAP
    if (GetOwningArena() == other->GetOwningArena()) {
  #endif  // !PROTOBUF_FORCE_COPY_IN_SWAP
      InternalSwap(other);
    } else {
      ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);
    }
  }
  void UnsafeArenaSwap(Value* other) {
    if (other == this) return;
    GOOGLE_DCHECK(GetOwningArena() == other->GetOwningArena());
    InternalSwap(other);
  }

  // implements Message ----------------------------------------------

  Value* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final {
    return CreateMaybeMessage<Value>(arena);
  }
  using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom;
  void CopyFrom(const Value& from);
  using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom;
  void MergeFrom( const Value& from) {
    Value::MergeImpl(*this, from);
  }
  private:
  static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg);
  public:
  PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
  bool IsInitialized() const final;

  size_t ByteSizeLong() const final;
  const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
  uint8_t* _InternalSerialize(
      uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
  int GetCachedSize() const final { return _impl_._cached_size_.Get(); }

  private:
  void SharedCtor(::PROTOBUF_NAMESPACE_ID::Arena* arena, bool is_message_owned);
  void SharedDtor();
  void SetCachedSize(int size) const final;
  void InternalSwap(Value* other);

  private:
  friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
  static ::absl::string_view FullMessageName() {
    return "google.protobuf.Value";
  }
  protected:
  explicit Value(::PROTOBUF_NAMESPACE_ID::Arena* arena,
                       bool is_message_owned = false);
  public:

  static const ClassData _class_data_;
  const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*GetClassData() const final;

  ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final;

  // nested types ----------------------------------------------------

  // accessors -------------------------------------------------------

  enum : int {
    kNullValueFieldNumber = 1,
    kNumberValueFieldNumber = 2,
    kStringValueFieldNumber = 3,
    kBoolValueFieldNumber = 4,
    kStructValueFieldNumber = 5,
    kListValueFieldNumber = 6,
  };
  // .google.protobuf.NullValue null_value = 1;
  bool has_null_value() const;
  private:
  bool _internal_has_null_value() const;
  public:
  void clear_null_value();
  ::PROTOBUF_NAMESPACE_ID::NullValue null_value() const;
  void set_null_value(::PROTOBUF_NAMESPACE_ID::NullValue value);
  private:
  ::PROTOBUF_NAMESPACE_ID::NullValue _internal_null_value() const;
  void _internal_set_null_value(::PROTOBUF_NAMESPACE_ID::NullValue value);
  public:

  // double number_value = 2;
  bool has_number_value() const;
  private:
  bool _internal_has_number_value() const;
  public:
  void clear_number_value();
  double number_value() const;
  void set_number_value(double value);
  private:
  double _internal_number_value() const;
  void _internal_set_number_value(double value);
  public:

  // string string_value = 3;
  bool has_string_value() const;
  private:
  bool _internal_has_string_value() const;
  public:
  void clear_string_value();
  const std::string& string_value() const;
  template <typename ArgT0 = const std::string&, typename... ArgT>
  void set_string_value(ArgT0&& arg0, ArgT... args);
  std::string* mutable_string_value();
  PROTOBUF_NODISCARD std::string* release_string_value();
  void set_allocated_string_value(std::string* string_value);
  private:
  const std::string& _internal_string_value() const;
  inline PROTOBUF_ALWAYS_INLINE void _internal_set_string_value(const std::string& value);
  std::string* _internal_mutable_string_value();
  public:

  // bool bool_value = 4;
  bool has_bool_value() const;
  private:
  bool _internal_has_bool_value() const;
  public:
  void clear_bool_value();
  bool bool_value() const;
  void set_bool_value(bool value);
  private:
  bool _internal_bool_value() const;
  void _internal_set_bool_value(bool value);
  public:

  // .google.protobuf.Struct struct_value = 5;
  bool has_struct_value() const;
  private:
  bool _internal_has_struct_value() const;
  public:
  void clear_struct_value();
  const ::PROTOBUF_NAMESPACE_ID::Struct& struct_value() const;
  PROTOBUF_NODISCARD ::PROTOBUF_NAMESPACE_ID::Struct* release_struct_value();
  ::PROTOBUF_NAMESPACE_ID::Struct* mutable_struct_value();
  void set_allocated_struct_value(::PROTOBUF_NAMESPACE_ID::Struct* struct_value);
  private:
  const ::PROTOBUF_NAMESPACE_ID::Struct& _internal_struct_value() const;
  ::PROTOBUF_NAMESPACE_ID::Struct* _internal_mutable_struct_value();
  public:
  void unsafe_arena_set_allocated_struct_value(
      ::PROTOBUF_NAMESPACE_ID::Struct* struct_value);
  ::PROTOBUF_NAMESPACE_ID::Struct* unsafe_arena_release_struct_value();

  // .google.protobuf.ListValue list_value = 6;
  bool has_list_value() const;
  private:
  bool _internal_has_list_value() const;
  public:
  void clear_list_value();
  const ::PROTOBUF_NAMESPACE_ID::ListValue& list_value() const;
  PROTOBUF_NODISCARD ::PROTOBUF_NAMESPACE_ID::ListValue* release_list_value();
  ::PROTOBUF_NAMESPACE_ID::ListValue* mutable_list_value();
  void set_allocated_list_value(::PROTOBUF_NAMESPACE_ID::ListValue* list_value);
  private:
  const ::PROTOBUF_NAMESPACE_ID::ListValue& _internal_list_value() const;
  ::PROTOBUF_NAMESPACE_ID::ListValue* _internal_mutable_list_value();
  public:
  void unsafe_arena_set_allocated_list_value(
      ::PROTOBUF_NAMESPACE_ID::ListValue* list_value);
  ::PROTOBUF_NAMESPACE_ID::ListValue* unsafe_arena_release_list_value();

  void clear_kind();
  KindCase kind_case() const;
  // @@protoc_insertion_point(class_scope:google.protobuf.Value)
 private:
  class _Internal;
  void set_has_null_value();
  void set_has_number_value();
  void set_has_string_value();
  void set_has_bool_value();
  void set_has_struct_value();
  void set_has_list_value();

  inline bool has_kind() const;
  inline void clear_has_kind();

  template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper;
  typedef void InternalArenaConstructable_;
  typedef void DestructorSkippable_;
  struct Impl_ {
    union KindUnion {
      constexpr KindUnion() : _constinit_{} {}
        ::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized _constinit_;
      int null_value_;
      double number_value_;
      ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr string_value_;
      bool bool_value_;
      ::PROTOBUF_NAMESPACE_ID::Struct* struct_value_;
      ::PROTOBUF_NAMESPACE_ID::ListValue* list_value_;
    } kind_;
    mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
    uint32_t _oneof_case_[1];

  };
  union { Impl_ _impl_; };
  friend struct ::TableStruct_google_2fprotobuf_2fstruct_2eproto;
};// -------------------------------------------------------------------

class PROTOBUF_EXPORT ListValue final :
    public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.ListValue) */ {
 public:
  inline ListValue() : ListValue(nullptr) {}
  ~ListValue() override;
  explicit PROTOBUF_CONSTEXPR ListValue(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);

  ListValue(const ListValue& from);
  ListValue(ListValue&& from) noexcept
    : ListValue() {
    *this = ::std::move(from);
  }

  inline ListValue& operator=(const ListValue& from) {
    CopyFrom(from);
    return *this;
  }
  inline ListValue& operator=(ListValue&& from) noexcept {
    if (this == &from) return *this;
    if (GetOwningArena() == from.GetOwningArena()
  #ifdef PROTOBUF_FORCE_COPY_IN_MOVE
        && GetOwningArena() != nullptr
  #endif  // !PROTOBUF_FORCE_COPY_IN_MOVE
    ) {
      InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }

  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() {
    return GetDescriptor();
  }
  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() {
    return default_instance().GetMetadata().descriptor;
  }
  static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() {
    return default_instance().GetMetadata().reflection;
  }
  static const ListValue& default_instance() {
    return *internal_default_instance();
  }
  static inline const ListValue* internal_default_instance() {
    return reinterpret_cast<const ListValue*>(
               &_ListValue_default_instance_);
  }
  static constexpr int kIndexInFileMessages =
    3;

  friend void swap(ListValue& a, ListValue& b) {
    a.Swap(&b);
  }
  inline void Swap(ListValue* other) {
    if (other == this) return;
  #ifdef PROTOBUF_FORCE_COPY_IN_SWAP
    if (GetOwningArena() != nullptr &&
        GetOwningArena() == other->GetOwningArena()) {
   #else  // PROTOBUF_FORCE_COPY_IN_SWAP
    if (GetOwningArena() == other->GetOwningArena()) {
  #endif  // !PROTOBUF_FORCE_COPY_IN_SWAP
      InternalSwap(other);
    } else {
      ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);
    }
  }
  void UnsafeArenaSwap(ListValue* other) {
    if (other == this) return;
    GOOGLE_DCHECK(GetOwningArena() == other->GetOwningArena());
    InternalSwap(other);
  }

  // implements Message ----------------------------------------------

  ListValue* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final {
    return CreateMaybeMessage<ListValue>(arena);
  }
  using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom;
  void CopyFrom(const ListValue& from);
  using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom;
  void MergeFrom( const ListValue& from) {
    ListValue::MergeImpl(*this, from);
  }
  private:
  static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg);
  public:
  PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
  bool IsInitialized() const final;

  size_t ByteSizeLong() const final;
  const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
  uint8_t* _InternalSerialize(
      uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
  int GetCachedSize() const final { return _impl_._cached_size_.Get(); }

  private:
  void SharedCtor(::PROTOBUF_NAMESPACE_ID::Arena* arena, bool is_message_owned);
  void SharedDtor();
  void SetCachedSize(int size) const final;
  void InternalSwap(ListValue* other);

  private:
  friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
  static ::absl::string_view FullMessageName() {
    return "google.protobuf.ListValue";
  }
  protected:
  explicit ListValue(::PROTOBUF_NAMESPACE_ID::Arena* arena,
                       bool is_message_owned = false);
  public:

  static const ClassData _class_data_;
  const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*GetClassData() const final;

  ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final;

  // nested types ----------------------------------------------------

  // accessors -------------------------------------------------------

  enum : int {
    kValuesFieldNumber = 1,
  };
  // repeated .google.protobuf.Value values = 1;
  int values_size() const;
  private:
  int _internal_values_size() const;
  public:
  void clear_values();
  ::PROTOBUF_NAMESPACE_ID::Value* mutable_values(int index);
  ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::Value >*
      mutable_values();
  private:
  const ::PROTOBUF_NAMESPACE_ID::Value& _internal_values(int index) const;
  ::PROTOBUF_NAMESPACE_ID::Value* _internal_add_values();
  public:
  const ::PROTOBUF_NAMESPACE_ID::Value& values(int index) const;
  ::PROTOBUF_NAMESPACE_ID::Value* add_values();
  const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::Value >&
      values() const;

  // @@protoc_insertion_point(class_scope:google.protobuf.ListValue)
 private:
  class _Internal;

  template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper;
  typedef void InternalArenaConstructable_;
  typedef void DestructorSkippable_;
  struct Impl_ {
    ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::Value > values_;
    mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
  };
  union { Impl_ _impl_; };
  friend struct ::TableStruct_google_2fprotobuf_2fstruct_2eproto;
};
// ===================================================================




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


#ifdef __GNUC__
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wstrict-aliasing"
#endif  // __GNUC__
// -------------------------------------------------------------------

// -------------------------------------------------------------------

// Struct

// map<string, .google.protobuf.Value> fields = 1;
inline int Struct::_internal_fields_size() const {
  return _impl_.fields_.size();
}
inline int Struct::fields_size() const {
  return _internal_fields_size();
}
inline void Struct::clear_fields() {
  _impl_.fields_.Clear();
}
inline const ::PROTOBUF_NAMESPACE_ID::Map< std::string, ::PROTOBUF_NAMESPACE_ID::Value >&
Struct::_internal_fields() const {
  return _impl_.fields_.GetMap();
}
inline const ::PROTOBUF_NAMESPACE_ID::Map< std::string, ::PROTOBUF_NAMESPACE_ID::Value >&
Struct::fields() const {
  // @@protoc_insertion_point(field_map:google.protobuf.Struct.fields)
  return _internal_fields();
}
inline ::PROTOBUF_NAMESPACE_ID::Map< std::string, ::PROTOBUF_NAMESPACE_ID::Value >*
Struct::_internal_mutable_fields() {
  return _impl_.fields_.MutableMap();
}
inline ::PROTOBUF_NAMESPACE_ID::Map< std::string, ::PROTOBUF_NAMESPACE_ID::Value >*
Struct::mutable_fields() {
  // @@protoc_insertion_point(field_mutable_map:google.protobuf.Struct.fields)
  return _internal_mutable_fields();
}

// -------------------------------------------------------------------

// Value

// .google.protobuf.NullValue null_value = 1;
inline bool Value::_internal_has_null_value() const {
  return kind_case() == kNullValue;
}
inline bool Value::has_null_value() const {
  return _internal_has_null_value();
}
inline void Value::set_has_null_value() {
  _impl_._oneof_case_[0] = kNullValue;
}
inline void Value::clear_null_value() {
  if (_internal_has_null_value()) {
    _impl_.kind_.null_value_ = 0;
    clear_has_kind();
  }
}
inline ::PROTOBUF_NAMESPACE_ID::NullValue Value::_internal_null_value() const {
  if (_internal_has_null_value()) {
    return static_cast< ::PROTOBUF_NAMESPACE_ID::NullValue >(_impl_.kind_.null_value_);
  }
  return static_cast< ::PROTOBUF_NAMESPACE_ID::NullValue >(0);
}
inline ::PROTOBUF_NAMESPACE_ID::NullValue Value::null_value() const {
  // @@protoc_insertion_point(field_get:google.protobuf.Value.null_value)
  return _internal_null_value();
}
inline void Value::_internal_set_null_value(::PROTOBUF_NAMESPACE_ID::NullValue value) {
  if (!_internal_has_null_value()) {
    clear_kind();
    set_has_null_value();
  }
  _impl_.kind_.null_value_ = value;
}
inline void Value::set_null_value(::PROTOBUF_NAMESPACE_ID::NullValue value) {
  _internal_set_null_value(value);
  // @@protoc_insertion_point(field_set:google.protobuf.Value.null_value)
}

// double number_value = 2;
inline bool Value::_internal_has_number_value() const {
  return kind_case() == kNumberValue;
}
inline bool Value::has_number_value() const {
  return _internal_has_number_value();
}
inline void Value::set_has_number_value() {
  _impl_._oneof_case_[0] = kNumberValue;
}
inline void Value::clear_number_value() {
  if (_internal_has_number_value()) {
    _impl_.kind_.number_value_ = 0;
    clear_has_kind();
  }
}
inline double Value::_internal_number_value() const {
  if (_internal_has_number_value()) {
    return _impl_.kind_.number_value_;
  }
  return 0;
}
inline void Value::_internal_set_number_value(double value) {
  if (!_internal_has_number_value()) {
    clear_kind();
    set_has_number_value();
  }
  _impl_.kind_.number_value_ = value;
}
inline double Value::number_value() const {
  // @@protoc_insertion_point(field_get:google.protobuf.Value.number_value)
  return _internal_number_value();
}
inline void Value::set_number_value(double value) {
  _internal_set_number_value(value);
  // @@protoc_insertion_point(field_set:google.protobuf.Value.number_value)
}

// string string_value = 3;
inline bool Value::_internal_has_string_value() const {
  return kind_case() == kStringValue;
}
inline bool Value::has_string_value() const {
  return _internal_has_string_value();
}
inline void Value::set_has_string_value() {
  _impl_._oneof_case_[0] = kStringValue;
}
inline void Value::clear_string_value() {
  if (_internal_has_string_value()) {
    _impl_.kind_.string_value_.Destroy();
    clear_has_kind();
  }
}
inline const std::string& Value::string_value() const {
  // @@protoc_insertion_point(field_get:google.protobuf.Value.string_value)
  return _internal_string_value();
}
template <typename ArgT0, typename... ArgT>
inline void Value::set_string_value(ArgT0&& arg0, ArgT... args) {
  if (!_internal_has_string_value()) {
    clear_kind();
    set_has_string_value();
    _impl_.kind_.string_value_.InitDefault();
  }
  _impl_.kind_.string_value_.Set( static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation());
  // @@protoc_insertion_point(field_set:google.protobuf.Value.string_value)
}
inline std::string* Value::mutable_string_value() {
  std::string* _s = _internal_mutable_string_value();
  // @@protoc_insertion_point(field_mutable:google.protobuf.Value.string_value)
  return _s;
}
inline const std::string& Value::_internal_string_value() const {
  if (_internal_has_string_value()) {
    return _impl_.kind_.string_value_.Get();
  }
  return ::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited();
}
inline void Value::_internal_set_string_value(const std::string& value) {
  if (!_internal_has_string_value()) {
    clear_kind();
    set_has_string_value();
    _impl_.kind_.string_value_.InitDefault();
  }
  _impl_.kind_.string_value_.Set(value, GetArenaForAllocation());
}
inline std::string* Value::_internal_mutable_string_value() {
  if (!_internal_has_string_value()) {
    clear_kind();
    set_has_string_value();
    _impl_.kind_.string_value_.InitDefault();
  }
  return _impl_.kind_.string_value_.Mutable(      GetArenaForAllocation());
}
inline std::string* Value::release_string_value() {
  // @@protoc_insertion_point(field_release:google.protobuf.Value.string_value)
  if (_internal_has_string_value()) {
    clear_has_kind();
    return _impl_.kind_.string_value_.Release();
  } else {
    return nullptr;
  }
}
inline void Value::set_allocated_string_value(std::string* string_value) {
  if (has_kind()) {
    clear_kind();
  }
  if (string_value != nullptr) {
    set_has_string_value();
    _impl_.kind_.string_value_.InitAllocated(string_value, GetArenaForAllocation());
  }
  // @@protoc_insertion_point(field_set_allocated:google.protobuf.Value.string_value)
}

// bool bool_value = 4;
inline bool Value::_internal_has_bool_value() const {
  return kind_case() == kBoolValue;
}
inline bool Value::has_bool_value() const {
  return _internal_has_bool_value();
}
inline void Value::set_has_bool_value() {
  _impl_._oneof_case_[0] = kBoolValue;
}
inline void Value::clear_bool_value() {
  if (_internal_has_bool_value()) {
    _impl_.kind_.bool_value_ = false;
    clear_has_kind();
  }
}
inline bool Value::_internal_bool_value() const {
  if (_internal_has_bool_value()) {
    return _impl_.kind_.bool_value_;
  }
  return false;
}
inline void Value::_internal_set_bool_value(bool value) {
  if (!_internal_has_bool_value()) {
    clear_kind();
    set_has_bool_value();
  }
  _impl_.kind_.bool_value_ = value;
}
inline bool Value::bool_value() const {
  // @@protoc_insertion_point(field_get:google.protobuf.Value.bool_value)
  return _internal_bool_value();
}
inline void Value::set_bool_value(bool value) {
  _internal_set_bool_value(value);
  // @@protoc_insertion_point(field_set:google.protobuf.Value.bool_value)
}

// .google.protobuf.Struct struct_value = 5;
inline bool Value::_internal_has_struct_value() const {
  return kind_case() == kStructValue;
}
inline bool Value::has_struct_value() const {
  return _internal_has_struct_value();
}
inline void Value::set_has_struct_value() {
  _impl_._oneof_case_[0] = kStructValue;
}
inline void Value::clear_struct_value() {
  if (_internal_has_struct_value()) {
    if (GetArenaForAllocation() == nullptr) {
      delete _impl_.kind_.struct_value_;
    }
    clear_has_kind();
  }
}
inline ::PROTOBUF_NAMESPACE_ID::Struct* Value::release_struct_value() {
  // @@protoc_insertion_point(field_release:google.protobuf.Value.struct_value)
  if (_internal_has_struct_value()) {
    clear_has_kind();
    ::PROTOBUF_NAMESPACE_ID::Struct* temp = _impl_.kind_.struct_value_;
    if (GetArenaForAllocation() != nullptr) {
      temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp);
    }
    _impl_.kind_.struct_value_ = nullptr;
    return temp;
  } else {
    return nullptr;
  }
}
inline const ::PROTOBUF_NAMESPACE_ID::Struct& Value::_internal_struct_value() const {
  return _internal_has_struct_value()
      ? *_impl_.kind_.struct_value_
      : reinterpret_cast< ::PROTOBUF_NAMESPACE_ID::Struct&>(::PROTOBUF_NAMESPACE_ID::_Struct_default_instance_);
}
inline const ::PROTOBUF_NAMESPACE_ID::Struct& Value::struct_value() const {
  // @@protoc_insertion_point(field_get:google.protobuf.Value.struct_value)
  return _internal_struct_value();
}
inline ::PROTOBUF_NAMESPACE_ID::Struct* Value::unsafe_arena_release_struct_value() {
  // @@protoc_insertion_point(field_unsafe_arena_release:google.protobuf.Value.struct_value)
  if (_internal_has_struct_value()) {
    clear_has_kind();
    ::PROTOBUF_NAMESPACE_ID::Struct* temp = _impl_.kind_.struct_value_;
    _impl_.kind_.struct_value_ = nullptr;
    return temp;
  } else {
    return nullptr;
  }
}
inline void Value::unsafe_arena_set_allocated_struct_value(::PROTOBUF_NAMESPACE_ID::Struct* struct_value) {
  clear_kind();
  if (struct_value) {
    set_has_struct_value();
    _impl_.kind_.struct_value_ = struct_value;
  }
  // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.Value.struct_value)
}
inline ::PROTOBUF_NAMESPACE_ID::Struct* Value::_internal_mutable_struct_value() {
  if (!_internal_has_struct_value()) {
    clear_kind();
    set_has_struct_value();
    _impl_.kind_.struct_value_ = CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::Struct >(GetArenaForAllocation());
  }
  return _impl_.kind_.struct_value_;
}
inline ::PROTOBUF_NAMESPACE_ID::Struct* Value::mutable_struct_value() {
  ::PROTOBUF_NAMESPACE_ID::Struct* _msg = _internal_mutable_struct_value();
  // @@protoc_insertion_point(field_mutable:google.protobuf.Value.struct_value)
  return _msg;
}

// .google.protobuf.ListValue list_value = 6;
inline bool Value::_internal_has_list_value() const {
  return kind_case() == kListValue;
}
inline bool Value::has_list_value() const {
  return _internal_has_list_value();
}
inline void Value::set_has_list_value() {
  _impl_._oneof_case_[0] = kListValue;
}
inline void Value::clear_list_value() {
  if (_internal_has_list_value()) {
    if (GetArenaForAllocation() == nullptr) {
      delete _impl_.kind_.list_value_;
    }
    clear_has_kind();
  }
}
inline ::PROTOBUF_NAMESPACE_ID::ListValue* Value::release_list_value() {
  // @@protoc_insertion_point(field_release:google.protobuf.Value.list_value)
  if (_internal_has_list_value()) {
    clear_has_kind();
    ::PROTOBUF_NAMESPACE_ID::ListValue* temp = _impl_.kind_.list_value_;
    if (GetArenaForAllocation() != nullptr) {
      temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp);
    }
    _impl_.kind_.list_value_ = nullptr;
    return temp;
  } else {
    return nullptr;
  }
}
inline const ::PROTOBUF_NAMESPACE_ID::ListValue& Value::_internal_list_value() const {
  return _internal_has_list_value()
      ? *_impl_.kind_.list_value_
      : reinterpret_cast< ::PROTOBUF_NAMESPACE_ID::ListValue&>(::PROTOBUF_NAMESPACE_ID::_ListValue_default_instance_);
}
inline const ::PROTOBUF_NAMESPACE_ID::ListValue& Value::list_value() const {
  // @@protoc_insertion_point(field_get:google.protobuf.Value.list_value)
  return _internal_list_value();
}
inline ::PROTOBUF_NAMESPACE_ID::ListValue* Value::unsafe_arena_release_list_value() {
  // @@protoc_insertion_point(field_unsafe_arena_release:google.protobuf.Value.list_value)
  if (_internal_has_list_value()) {
    clear_has_kind();
    ::PROTOBUF_NAMESPACE_ID::ListValue* temp = _impl_.kind_.list_value_;
    _impl_.kind_.list_value_ = nullptr;
    return temp;
  } else {
    return nullptr;
  }
}
inline void Value::unsafe_arena_set_allocated_list_value(::PROTOBUF_NAMESPACE_ID::ListValue* list_value) {
  clear_kind();
  if (list_value) {
    set_has_list_value();
    _impl_.kind_.list_value_ = list_value;
  }
  // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.Value.list_value)
}
inline ::PROTOBUF_NAMESPACE_ID::ListValue* Value::_internal_mutable_list_value() {
  if (!_internal_has_list_value()) {
    clear_kind();
    set_has_list_value();
    _impl_.kind_.list_value_ = CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::ListValue >(GetArenaForAllocation());
  }
  return _impl_.kind_.list_value_;
}
inline ::PROTOBUF_NAMESPACE_ID::ListValue* Value::mutable_list_value() {
  ::PROTOBUF_NAMESPACE_ID::ListValue* _msg = _internal_mutable_list_value();
  // @@protoc_insertion_point(field_mutable:google.protobuf.Value.list_value)
  return _msg;
}

inline bool Value::has_kind() const {
  return kind_case() != KIND_NOT_SET;
}
inline void Value::clear_has_kind() {
  _impl_._oneof_case_[0] = KIND_NOT_SET;
}
inline Value::KindCase Value::kind_case() const {
  return Value::KindCase(_impl_._oneof_case_[0]);
}
// -------------------------------------------------------------------

// ListValue

// repeated .google.protobuf.Value values = 1;
inline int ListValue::_internal_values_size() const {
  return _impl_.values_.size();
}
inline int ListValue::values_size() const {
  return _internal_values_size();
}
inline void ListValue::clear_values() {
  _impl_.values_.Clear();
}
inline ::PROTOBUF_NAMESPACE_ID::Value* ListValue::mutable_values(int index) {
  // @@protoc_insertion_point(field_mutable:google.protobuf.ListValue.values)
  return _impl_.values_.Mutable(index);
}
inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::Value >*
ListValue::mutable_values() {
  // @@protoc_insertion_point(field_mutable_list:google.protobuf.ListValue.values)
  return &_impl_.values_;
}
inline const ::PROTOBUF_NAMESPACE_ID::Value& ListValue::_internal_values(int index) const {
  return _impl_.values_.Get(index);
}
inline const ::PROTOBUF_NAMESPACE_ID::Value& ListValue::values(int index) const {
  // @@protoc_insertion_point(field_get:google.protobuf.ListValue.values)
  return _internal_values(index);
}
inline ::PROTOBUF_NAMESPACE_ID::Value* ListValue::_internal_add_values() {
  return _impl_.values_.Add();
}
inline ::PROTOBUF_NAMESPACE_ID::Value* ListValue::add_values() {
  ::PROTOBUF_NAMESPACE_ID::Value* _add = _internal_add_values();
  // @@protoc_insertion_point(field_add:google.protobuf.ListValue.values)
  return _add;
}
inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::Value >&
ListValue::values() const {
  // @@protoc_insertion_point(field_list:google.protobuf.ListValue.values)
  return _impl_.values_;
}

#ifdef __GNUC__
#pragma GCC diagnostic pop
#endif  // __GNUC__

// @@protoc_insertion_point(namespace_scope)
PROTOBUF_NAMESPACE_CLOSE


PROTOBUF_NAMESPACE_OPEN

template <>
struct is_proto_enum<::PROTOBUF_NAMESPACE_ID::NullValue> : std::true_type {};
template <>
inline const EnumDescriptor* GetEnumDescriptor<::PROTOBUF_NAMESPACE_ID::NullValue>() {
  return ::PROTOBUF_NAMESPACE_ID::NullValue_descriptor();
}

PROTOBUF_NAMESPACE_CLOSE

// @@protoc_insertion_point(global_scope)

#include "google/protobuf/port_undef.inc"

#endif  // GOOGLE_PROTOBUF_INCLUDED_google_2fprotobuf_2fstruct_2eproto_2epb_2eh
