// 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 < 4023000
#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 4023004 < 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 final : 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();
  template <typename = void>
  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;
  template<typename = void>
  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;
  }

  inline const ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet& unknown_fields() const {
    return _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance);
  }
  inline ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet* mutable_unknown_fields() {
    return _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
  }

  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;
    ABSL_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);
  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);
  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;
  template<typename = void>
  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;
  }

  inline const ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet& unknown_fields() const {
    return _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance);
  }
  inline ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet* mutable_unknown_fields() {
    return _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
  }

  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;
    ABSL_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);
  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);
  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;
  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;
  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;
  void clear_string_value() ;
  const std::string& string_value() const;




  template <typename Arg_ = const std::string&, typename... Args_>
  void set_string_value(Arg_&& arg, Args_... args);
  std::string* mutable_string_value();
  PROTOBUF_NODISCARD std::string* release_string_value();
  void set_allocated_string_value(std::string* ptr);

  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;
  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;
  template<typename = void>
  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;
  }

  inline const ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet& unknown_fields() const {
    return _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance);
  }
  inline ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet* mutable_unknown_fields() {
    return _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
  }

  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;
    ABSL_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);
  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);
  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();
  const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField<::PROTOBUF_NAMESPACE_ID::Value>& _internal_values() const;
  ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField<::PROTOBUF_NAMESPACE_ID::Value>* _internal_mutable_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::has_null_value() const {
  return kind_case() == kNullValue;
}
inline void Value::set_has_null_value() {
  _impl_._oneof_case_[0] = kNullValue;
}
inline void Value::clear_null_value() {
  if (kind_case() == kNullValue) {
    _impl_.kind_.null_value_ = 0;
    clear_has_kind();
  }
}
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::set_null_value(::PROTOBUF_NAMESPACE_ID::NullValue value) {
   _internal_set_null_value(value);
  // @@protoc_insertion_point(field_set:google.protobuf.Value.null_value)
}
inline ::PROTOBUF_NAMESPACE_ID::NullValue Value::_internal_null_value() const {
  if (kind_case() == kNullValue) {
    return static_cast<::PROTOBUF_NAMESPACE_ID::NullValue>(_impl_.kind_.null_value_);
  }
  return static_cast<::PROTOBUF_NAMESPACE_ID::NullValue>(0);
}
inline void Value::_internal_set_null_value(::PROTOBUF_NAMESPACE_ID::NullValue value) {
  if (kind_case() != kNullValue) {
    clear_kind();
    set_has_null_value();
  }
  _impl_.kind_.null_value_ = value;
}

// double number_value = 2;
inline bool Value::has_number_value() const {
  return kind_case() == kNumberValue;
}
inline void Value::set_has_number_value() {
  _impl_._oneof_case_[0] = kNumberValue;
}
inline void Value::clear_number_value() {
  if (kind_case() == kNumberValue) {
    _impl_.kind_.number_value_ = 0;
    clear_has_kind();
  }
}
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)
}
inline double Value::_internal_number_value() const {
  if (kind_case() == kNumberValue) {
    return _impl_.kind_.number_value_;
  }
  return 0;
}
inline void Value::_internal_set_number_value(double value) {
  if (kind_case() != kNumberValue) {
    clear_kind();
    set_has_number_value();
  }
  _impl_.kind_.number_value_ = value;
}

// string string_value = 3;
inline bool Value::has_string_value() const {
  return kind_case() == kStringValue;
}
inline void Value::set_has_string_value() {
  _impl_._oneof_case_[0] = kStringValue;
}
inline void Value::clear_string_value() {
  if (kind_case() == kStringValue) {
    _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 Arg_, typename... Args_>
inline PROTOBUF_ALWAYS_INLINE void Value::set_string_value(Arg_&& arg,
                                                     Args_... args) {
  if (kind_case() != kStringValue) {
    clear_kind();

    set_has_string_value();
    _impl_.kind_.string_value_.InitDefault();
  }
  _impl_.kind_.string_value_.Set(static_cast<Arg_&&>(arg), 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 (kind_case() != kStringValue) {
    return ::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited();
  }
  return _impl_.kind_.string_value_.Get();
}
inline void Value::_internal_set_string_value(const std::string& value) {
  if (kind_case() != kStringValue) {
    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 (kind_case() != kStringValue) {
    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 (kind_case() != kStringValue) {
    return nullptr;
  }
  clear_has_kind();
  return _impl_.kind_.string_value_.Release();
}
inline void Value::set_allocated_string_value(std::string* value) {
  if (has_kind()) {
    clear_kind();
  }
  if (value != nullptr) {
    set_has_string_value();
    _impl_.kind_.string_value_.InitAllocated(value, GetArenaForAllocation());
  }
  // @@protoc_insertion_point(field_set_allocated:google.protobuf.Value.string_value)
}

// bool bool_value = 4;
inline bool Value::has_bool_value() const {
  return kind_case() == kBoolValue;
}
inline void Value::set_has_bool_value() {
  _impl_._oneof_case_[0] = kBoolValue;
}
inline void Value::clear_bool_value() {
  if (kind_case() == kBoolValue) {
    _impl_.kind_.bool_value_ = false;
    clear_has_kind();
  }
}
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)
}
inline bool Value::_internal_bool_value() const {
  if (kind_case() == kBoolValue) {
    return _impl_.kind_.bool_value_;
  }
  return false;
}
inline void Value::_internal_set_bool_value(bool value) {
  if (kind_case() != kBoolValue) {
    clear_kind();
    set_has_bool_value();
  }
  _impl_.kind_.bool_value_ = value;
}

// .google.protobuf.Struct struct_value = 5;
inline bool Value::has_struct_value() const {
  return kind_case() == kStructValue;
}
inline bool Value::_internal_has_struct_value() const {
  return kind_case() == kStructValue;
}
inline void Value::set_has_struct_value() {
  _impl_._oneof_case_[0] = kStructValue;
}
inline void Value::clear_struct_value() {
  if (kind_case() == kStructValue) {
    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 (kind_case() == kStructValue) {
    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 kind_case() == kStructValue
      ? *_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 (kind_case() == kStructValue) {
    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 (kind_case() != kStructValue) {
    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::has_list_value() const {
  return kind_case() == kListValue;
}
inline bool Value::_internal_has_list_value() const {
  return kind_case() == kListValue;
}
inline void Value::set_has_list_value() {
  _impl_._oneof_case_[0] = kListValue;
}
inline void Value::clear_list_value() {
  if (kind_case() == kListValue) {
    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 (kind_case() == kListValue) {
    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 kind_case() == kListValue
      ? *_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 (kind_case() == kListValue) {
    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 (kind_case() != kListValue) {
    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() {
  _internal_mutable_values()->Clear();
}
inline ::PROTOBUF_NAMESPACE_ID::Value* ListValue::mutable_values(int index) {
  // @@protoc_insertion_point(field_mutable:google.protobuf.ListValue.values)
  return _internal_mutable_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 _internal_mutable_values();
}
inline const ::PROTOBUF_NAMESPACE_ID::Value& ListValue::_internal_values(int index) const {
  return _internal_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 _internal_mutable_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 _internal_values();
}
inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField<::PROTOBUF_NAMESPACE_ID::Value>&
ListValue::_internal_values() const {
  return _impl_.values_;
}
inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField<::PROTOBUF_NAMESPACE_ID::Value>*
ListValue::_internal_mutable_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
