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

#include "google/protobuf/struct.pb.h"

#include <algorithm>
#include "google/protobuf/io/coded_stream.h"
#include "google/protobuf/extension_set.h"
#include "google/protobuf/wire_format_lite.h"
#include "google/protobuf/descriptor.h"
#include "google/protobuf/generated_message_reflection.h"
#include "google/protobuf/reflection_ops.h"
#include "google/protobuf/wire_format.h"
// @@protoc_insertion_point(includes)

// Must be included last.
#include "google/protobuf/port_def.inc"
PROTOBUF_PRAGMA_INIT_SEG
namespace _pb = ::PROTOBUF_NAMESPACE_ID;
namespace _pbi = ::PROTOBUF_NAMESPACE_ID::internal;
PROTOBUF_NAMESPACE_OPEN
PROTOBUF_CONSTEXPR Struct_FieldsEntry_DoNotUse::Struct_FieldsEntry_DoNotUse(
    ::_pbi::ConstantInitialized) {}
struct Struct_FieldsEntry_DoNotUseDefaultTypeInternal {
  PROTOBUF_CONSTEXPR Struct_FieldsEntry_DoNotUseDefaultTypeInternal() : _instance(::_pbi::ConstantInitialized{}) {}
  ~Struct_FieldsEntry_DoNotUseDefaultTypeInternal() {}
  union {
    Struct_FieldsEntry_DoNotUse _instance;
  };
};

PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT
    PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 Struct_FieldsEntry_DoNotUseDefaultTypeInternal _Struct_FieldsEntry_DoNotUse_default_instance_;
PROTOBUF_CONSTEXPR Struct::Struct(
    ::_pbi::ConstantInitialized): _impl_{
    /*decltype(_impl_.fields_)*/{::_pbi::ConstantInitialized()}
  , /*decltype(_impl_._cached_size_)*/{}} {}
struct StructDefaultTypeInternal {
  PROTOBUF_CONSTEXPR StructDefaultTypeInternal() : _instance(::_pbi::ConstantInitialized{}) {}
  ~StructDefaultTypeInternal() {}
  union {
    Struct _instance;
  };
};

PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT
    PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 StructDefaultTypeInternal _Struct_default_instance_;
PROTOBUF_CONSTEXPR Value::Value(
    ::_pbi::ConstantInitialized): _impl_{
    /*decltype(_impl_.kind_)*/{}
  , /*decltype(_impl_._cached_size_)*/{}
  , /*decltype(_impl_._oneof_case_)*/{}} {}
struct ValueDefaultTypeInternal {
  PROTOBUF_CONSTEXPR ValueDefaultTypeInternal() : _instance(::_pbi::ConstantInitialized{}) {}
  ~ValueDefaultTypeInternal() {}
  union {
    Value _instance;
  };
};

PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT
    PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 ValueDefaultTypeInternal _Value_default_instance_;
PROTOBUF_CONSTEXPR ListValue::ListValue(
    ::_pbi::ConstantInitialized): _impl_{
    /*decltype(_impl_.values_)*/{}
  , /*decltype(_impl_._cached_size_)*/{}} {}
struct ListValueDefaultTypeInternal {
  PROTOBUF_CONSTEXPR ListValueDefaultTypeInternal() : _instance(::_pbi::ConstantInitialized{}) {}
  ~ListValueDefaultTypeInternal() {}
  union {
    ListValue _instance;
  };
};

PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT
    PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 ListValueDefaultTypeInternal _ListValue_default_instance_;
PROTOBUF_NAMESPACE_CLOSE
static ::_pb::Metadata file_level_metadata_google_2fprotobuf_2fstruct_2eproto[4];
static const ::_pb::EnumDescriptor* file_level_enum_descriptors_google_2fprotobuf_2fstruct_2eproto[1];
static constexpr const ::_pb::ServiceDescriptor**
    file_level_service_descriptors_google_2fprotobuf_2fstruct_2eproto = nullptr;
const uint32_t TableStruct_google_2fprotobuf_2fstruct_2eproto::offsets[] PROTOBUF_SECTION_VARIABLE(
    protodesc_cold) = {
    PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Struct_FieldsEntry_DoNotUse, _has_bits_),
    PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Struct_FieldsEntry_DoNotUse, _internal_metadata_),
    ~0u,  // no _extensions_
    ~0u,  // no _oneof_case_
    ~0u,  // no _weak_field_map_
    ~0u,  // no _inlined_string_donated_
    ~0u,  // no _split_
    ~0u,  // no sizeof(Split)
    PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Struct_FieldsEntry_DoNotUse, key_),
    PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Struct_FieldsEntry_DoNotUse, value_),
    0,
    1,
    ~0u,  // no _has_bits_
    PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Struct, _internal_metadata_),
    ~0u,  // no _extensions_
    ~0u,  // no _oneof_case_
    ~0u,  // no _weak_field_map_
    ~0u,  // no _inlined_string_donated_
    ~0u,  // no _split_
    ~0u,  // no sizeof(Split)
    PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Struct, _impl_.fields_),
    ~0u,  // no _has_bits_
    PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Value, _internal_metadata_),
    ~0u,  // no _extensions_
    PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Value, _impl_._oneof_case_[0]),
    ~0u,  // no _weak_field_map_
    ~0u,  // no _inlined_string_donated_
    ~0u,  // no _split_
    ~0u,  // no sizeof(Split)
    ::_pbi::kInvalidFieldOffsetTag,
    ::_pbi::kInvalidFieldOffsetTag,
    ::_pbi::kInvalidFieldOffsetTag,
    ::_pbi::kInvalidFieldOffsetTag,
    ::_pbi::kInvalidFieldOffsetTag,
    ::_pbi::kInvalidFieldOffsetTag,
    PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Value, _impl_.kind_),
    ~0u,  // no _has_bits_
    PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::ListValue, _internal_metadata_),
    ~0u,  // no _extensions_
    ~0u,  // no _oneof_case_
    ~0u,  // no _weak_field_map_
    ~0u,  // no _inlined_string_donated_
    ~0u,  // no _split_
    ~0u,  // no sizeof(Split)
    PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::ListValue, _impl_.values_),
};

static const ::_pbi::MigrationSchema
    schemas[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = {
        { 0, 10, -1, sizeof(::PROTOBUF_NAMESPACE_ID::Struct_FieldsEntry_DoNotUse)},
        { 12, -1, -1, sizeof(::PROTOBUF_NAMESPACE_ID::Struct)},
        { 21, -1, -1, sizeof(::PROTOBUF_NAMESPACE_ID::Value)},
        { 36, -1, -1, sizeof(::PROTOBUF_NAMESPACE_ID::ListValue)},
};

static const ::_pb::Message* const file_default_instances[] = {
    &::PROTOBUF_NAMESPACE_ID::_Struct_FieldsEntry_DoNotUse_default_instance_._instance,
    &::PROTOBUF_NAMESPACE_ID::_Struct_default_instance_._instance,
    &::PROTOBUF_NAMESPACE_ID::_Value_default_instance_._instance,
    &::PROTOBUF_NAMESPACE_ID::_ListValue_default_instance_._instance,
};
const char descriptor_table_protodef_google_2fprotobuf_2fstruct_2eproto[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = {
    "\n\034google/protobuf/struct.proto\022\017google.p"
    "rotobuf\"\204\001\n\006Struct\0223\n\006fields\030\001 \003(\0132#.goo"
    "gle.protobuf.Struct.FieldsEntry\032E\n\013Field"
    "sEntry\022\013\n\003key\030\001 \001(\t\022%\n\005value\030\002 \001(\0132\026.goo"
    "gle.protobuf.Value:\0028\001\"\352\001\n\005Value\0220\n\nnull"
    "_value\030\001 \001(\0162\032.google.protobuf.NullValue"
    "H\000\022\026\n\014number_value\030\002 \001(\001H\000\022\026\n\014string_val"
    "ue\030\003 \001(\tH\000\022\024\n\nbool_value\030\004 \001(\010H\000\022/\n\014stru"
    "ct_value\030\005 \001(\0132\027.google.protobuf.StructH"
    "\000\0220\n\nlist_value\030\006 \001(\0132\032.google.protobuf."
    "ListValueH\000B\006\n\004kind\"3\n\tListValue\022&\n\006valu"
    "es\030\001 \003(\0132\026.google.protobuf.Value*\033\n\tNull"
    "Value\022\016\n\nNULL_VALUE\020\000B\177\n\023com.google.prot"
    "obufB\013StructProtoP\001Z/google.golang.org/p"
    "rotobuf/types/known/structpb\370\001\001\242\002\003GPB\252\002\036"
    "Google.Protobuf.WellKnownTypesb\006proto3"
};
static ::absl::once_flag descriptor_table_google_2fprotobuf_2fstruct_2eproto_once;
const ::_pbi::DescriptorTable descriptor_table_google_2fprotobuf_2fstruct_2eproto = {
    false,
    false,
    638,
    descriptor_table_protodef_google_2fprotobuf_2fstruct_2eproto,
    "google/protobuf/struct.proto",
    &descriptor_table_google_2fprotobuf_2fstruct_2eproto_once,
    nullptr,
    0,
    4,
    schemas,
    file_default_instances,
    TableStruct_google_2fprotobuf_2fstruct_2eproto::offsets,
    file_level_metadata_google_2fprotobuf_2fstruct_2eproto,
    file_level_enum_descriptors_google_2fprotobuf_2fstruct_2eproto,
    file_level_service_descriptors_google_2fprotobuf_2fstruct_2eproto,
};

// This function exists to be marked as weak.
// It can significantly speed up compilation by breaking up LLVM's SCC
// in the .pb.cc translation units. Large translation units see a
// reduction of more than 35% of walltime for optimized builds. Without
// the weak attribute all the messages in the file, including all the
// vtables and everything they use become part of the same SCC through
// a cycle like:
// GetMetadata -> descriptor table -> default instances ->
//   vtables -> GetMetadata
// By adding a weak function here we break the connection from the
// individual vtables back into the descriptor table.
PROTOBUF_ATTRIBUTE_WEAK const ::_pbi::DescriptorTable* descriptor_table_google_2fprotobuf_2fstruct_2eproto_getter() {
  return &descriptor_table_google_2fprotobuf_2fstruct_2eproto;
}
// Force running AddDescriptors() at dynamic initialization time.
PROTOBUF_ATTRIBUTE_INIT_PRIORITY2
static ::_pbi::AddDescriptorsRunner dynamic_init_dummy_google_2fprotobuf_2fstruct_2eproto(&descriptor_table_google_2fprotobuf_2fstruct_2eproto);
PROTOBUF_NAMESPACE_OPEN
const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor* NullValue_descriptor() {
  ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors(&descriptor_table_google_2fprotobuf_2fstruct_2eproto);
  return file_level_enum_descriptors_google_2fprotobuf_2fstruct_2eproto[0];
}
bool NullValue_IsValid(int value) {
  switch (value) {
    case 0:
      return true;
    default:
      return false;
  }
}
// ===================================================================

Struct_FieldsEntry_DoNotUse::Struct_FieldsEntry_DoNotUse() {}
Struct_FieldsEntry_DoNotUse::Struct_FieldsEntry_DoNotUse(::PROTOBUF_NAMESPACE_ID::Arena* arena)
    : SuperType(arena) {}
void Struct_FieldsEntry_DoNotUse::MergeFrom(const Struct_FieldsEntry_DoNotUse& other) {
  MergeFromInternal(other);
}
::PROTOBUF_NAMESPACE_ID::Metadata Struct_FieldsEntry_DoNotUse::GetMetadata() const {
  return ::_pbi::AssignDescriptors(
      &descriptor_table_google_2fprotobuf_2fstruct_2eproto_getter, &descriptor_table_google_2fprotobuf_2fstruct_2eproto_once,
      file_level_metadata_google_2fprotobuf_2fstruct_2eproto[0]);
}
// ===================================================================

class Struct::_Internal {
 public:
};

Struct::Struct(::PROTOBUF_NAMESPACE_ID::Arena* arena,
                         bool is_message_owned)
  : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned) {
  SharedCtor(arena, is_message_owned);
  if (arena != nullptr && !is_message_owned) {
    arena->OwnCustomDestructor(this, &Struct::ArenaDtor);
  }
  // @@protoc_insertion_point(arena_constructor:google.protobuf.Struct)
}
Struct::Struct(const Struct& from)
  : ::PROTOBUF_NAMESPACE_ID::Message() {
  Struct* const _this = this; (void)_this;
  new (&_impl_) Impl_{
      /*decltype(_impl_.fields_)*/{}
    , /*decltype(_impl_._cached_size_)*/{}};

  _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
  _this->_impl_.fields_.MergeFrom(from._impl_.fields_);
  // @@protoc_insertion_point(copy_constructor:google.protobuf.Struct)
}

inline void Struct::SharedCtor(
    ::_pb::Arena* arena, bool is_message_owned) {
  (void)arena;
  (void)is_message_owned;
  new (&_impl_) Impl_{
      /*decltype(_impl_.fields_)*/{::_pbi::ArenaInitialized(), arena}
    , /*decltype(_impl_._cached_size_)*/{}
  };
}

Struct::~Struct() {
  // @@protoc_insertion_point(destructor:google.protobuf.Struct)
  if (auto *arena = _internal_metadata_.DeleteReturnArena<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>()) {
  (void)arena;
    ArenaDtor(this);
    return;
  }
  SharedDtor();
}

inline void Struct::SharedDtor() {
  GOOGLE_DCHECK(GetArenaForAllocation() == nullptr);
  _impl_.fields_.Destruct();
  _impl_.fields_.~MapField();
}

void Struct::ArenaDtor(void* object) {
  Struct* _this = reinterpret_cast< Struct* >(object);
  _this->_impl_.fields_.Destruct();
}
void Struct::SetCachedSize(int size) const {
  _impl_._cached_size_.Set(size);
}

void Struct::Clear() {
// @@protoc_insertion_point(message_clear_start:google.protobuf.Struct)
  uint32_t cached_has_bits = 0;
  // Prevent compiler warnings about cached_has_bits being unused
  (void) cached_has_bits;

  _impl_.fields_.Clear();
  _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
}

const char* Struct::_InternalParse(const char* ptr, ::_pbi::ParseContext* ctx) {

#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure
  while (!ctx->Done(&ptr)) {
    uint32_t tag;
    ptr = ::_pbi::ReadTag(ptr, &tag);
    switch (tag >> 3) {
      // map<string, .google.protobuf.Value> fields = 1;
      case 1:
        if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 10)) {
          ptr -= 1;
          do {
            ptr += 1;
            ptr = ctx->ParseMessage(&_impl_.fields_, ptr);
            CHK_(ptr);
            if (!ctx->DataAvailable(ptr)) break;
          } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<10>(ptr));
        } else
          goto handle_unusual;
        continue;
      default:
        goto handle_unusual;
    }  // switch
  handle_unusual:
    if ((tag == 0) || ((tag & 7) == 4)) {
      CHK_(ptr);
      ctx->SetLastTag(tag);
      goto message_done;
    }
    ptr = UnknownFieldParse(
        tag,
        _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(),
        ptr, ctx);
    CHK_(ptr != nullptr);
  }  // while
message_done:
  return ptr;
failure:
  ptr = nullptr;
  goto message_done;
#undef CHK_
}

uint8_t* Struct::_InternalSerialize(
    uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const {

  // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.Struct)
  uint32_t cached_has_bits = 0;
  (void) cached_has_bits;

  // map<string, .google.protobuf.Value> fields = 1;
  if (!this->_internal_fields().empty()) {
    using MapType = ::_pb::Map<std::string, ::PROTOBUF_NAMESPACE_ID::Value>;
    using WireHelper = Struct_FieldsEntry_DoNotUse::Funcs;
    const auto& map_field = this->_internal_fields();
    auto check_utf8 = [](const MapType::value_type& entry) {
      (void)entry;
      ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::VerifyUtf8String(
        entry.first.data(), static_cast<int>(entry.first.length()),
        ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::SERIALIZE,
        "google.protobuf.Struct.FieldsEntry.key");
    };

    if (stream->IsSerializationDeterministic() && map_field.size() > 1) {
      for (const auto& entry : ::_pbi::MapSorterPtr<MapType>(map_field)) {
        target = WireHelper::InternalSerialize(1, entry.first, entry.second, target, stream);
        check_utf8(entry);
      }
    } else {
      for (const auto& entry : map_field) {
        target = WireHelper::InternalSerialize(1, entry.first, entry.second, target, stream);
        check_utf8(entry);
      }
    }
  }

  if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) {
    target = ::_pbi::WireFormat::InternalSerializeUnknownFieldsToArray(
        _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream);
  }
  // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.Struct)
  return target;
}

size_t Struct::ByteSizeLong() const {

// @@protoc_insertion_point(message_byte_size_start:google.protobuf.Struct)
  size_t total_size = 0;

  uint32_t cached_has_bits = 0;
  // Prevent compiler warnings about cached_has_bits being unused
  (void) cached_has_bits;

  // map<string, .google.protobuf.Value> fields = 1;
  total_size += 1 *
      ::PROTOBUF_NAMESPACE_ID::internal::FromIntSize(this->_internal_fields_size());
  for (::PROTOBUF_NAMESPACE_ID::Map< std::string, ::PROTOBUF_NAMESPACE_ID::Value >::const_iterator
      it = this->_internal_fields().begin();
      it != this->_internal_fields().end(); ++it) {
    total_size += Struct_FieldsEntry_DoNotUse::Funcs::ByteSizeLong(it->first, it->second);
  }

  return MaybeComputeUnknownFieldsSize(total_size, &_impl_._cached_size_);
}

const ::PROTOBUF_NAMESPACE_ID::Message::ClassData Struct::_class_data_ = {
    ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSourceCheck,
    Struct::MergeImpl
};
const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*Struct::GetClassData() const { return &_class_data_; }


void Struct::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg) {
  auto* const _this = static_cast<Struct*>(&to_msg);
  auto& from = static_cast<const Struct&>(from_msg);

  // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.Struct)
  GOOGLE_DCHECK_NE(&from, _this);
  uint32_t cached_has_bits = 0;
  (void) cached_has_bits;

  _this->_impl_.fields_.MergeFrom(from._impl_.fields_);
  _this->_internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
}

void Struct::CopyFrom(const Struct& from) {
// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.Struct)
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

bool Struct::IsInitialized() const {
  return true;
}

void Struct::InternalSwap(Struct* other) {
  using std::swap;
  _internal_metadata_.InternalSwap(&other->_internal_metadata_);
  _impl_.fields_.InternalSwap(&other->_impl_.fields_);
}

::PROTOBUF_NAMESPACE_ID::Metadata Struct::GetMetadata() const {

  return ::_pbi::AssignDescriptors(
      &descriptor_table_google_2fprotobuf_2fstruct_2eproto_getter, &descriptor_table_google_2fprotobuf_2fstruct_2eproto_once,
      file_level_metadata_google_2fprotobuf_2fstruct_2eproto[1]);
}
// ===================================================================

class Value::_Internal {
 public:
  static constexpr int32_t kOneofCaseOffset =
    PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Value, _impl_._oneof_case_);
  static const ::PROTOBUF_NAMESPACE_ID::Struct& struct_value(const Value* msg);
  static const ::PROTOBUF_NAMESPACE_ID::ListValue& list_value(const Value* msg);
};

const ::PROTOBUF_NAMESPACE_ID::Struct&
Value::_Internal::struct_value(const Value* msg) {
  return *msg->_impl_.kind_.struct_value_;
}
const ::PROTOBUF_NAMESPACE_ID::ListValue&
Value::_Internal::list_value(const Value* msg) {
  return *msg->_impl_.kind_.list_value_;
}
void Value::set_allocated_struct_value(::PROTOBUF_NAMESPACE_ID::Struct* struct_value) {
  ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArenaForAllocation();
  clear_kind();
  if (struct_value) {
    ::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena =
      ::PROTOBUF_NAMESPACE_ID::Arena::InternalGetOwningArena(struct_value);
    if (message_arena != submessage_arena) {
      struct_value = ::PROTOBUF_NAMESPACE_ID::internal::GetOwnedMessage(
          message_arena, struct_value, submessage_arena);
    }
    set_has_struct_value();
    _impl_.kind_.struct_value_ = struct_value;
  }
  // @@protoc_insertion_point(field_set_allocated:google.protobuf.Value.struct_value)
}
void Value::set_allocated_list_value(::PROTOBUF_NAMESPACE_ID::ListValue* list_value) {
  ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArenaForAllocation();
  clear_kind();
  if (list_value) {
    ::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena =
      ::PROTOBUF_NAMESPACE_ID::Arena::InternalGetOwningArena(list_value);
    if (message_arena != submessage_arena) {
      list_value = ::PROTOBUF_NAMESPACE_ID::internal::GetOwnedMessage(
          message_arena, list_value, submessage_arena);
    }
    set_has_list_value();
    _impl_.kind_.list_value_ = list_value;
  }
  // @@protoc_insertion_point(field_set_allocated:google.protobuf.Value.list_value)
}
Value::Value(::PROTOBUF_NAMESPACE_ID::Arena* arena,
                         bool is_message_owned)
  : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned) {
  SharedCtor(arena, is_message_owned);
  // @@protoc_insertion_point(arena_constructor:google.protobuf.Value)
}
Value::Value(const Value& from)
  : ::PROTOBUF_NAMESPACE_ID::Message() {
  Value* const _this = this; (void)_this;
  new (&_impl_) Impl_{
      decltype(_impl_.kind_){}
    , /*decltype(_impl_._cached_size_)*/{}
    , /*decltype(_impl_._oneof_case_)*/{}};

  _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
  clear_has_kind();
  switch (from.kind_case()) {
    case kNullValue: {
      _this->_internal_set_null_value(from._internal_null_value());
      break;
    }
    case kNumberValue: {
      _this->_internal_set_number_value(from._internal_number_value());
      break;
    }
    case kStringValue: {
      _this->_internal_set_string_value(from._internal_string_value());
      break;
    }
    case kBoolValue: {
      _this->_internal_set_bool_value(from._internal_bool_value());
      break;
    }
    case kStructValue: {
      _this->_internal_mutable_struct_value()->::PROTOBUF_NAMESPACE_ID::Struct::MergeFrom(
          from._internal_struct_value());
      break;
    }
    case kListValue: {
      _this->_internal_mutable_list_value()->::PROTOBUF_NAMESPACE_ID::ListValue::MergeFrom(
          from._internal_list_value());
      break;
    }
    case KIND_NOT_SET: {
      break;
    }
  }
  // @@protoc_insertion_point(copy_constructor:google.protobuf.Value)
}

inline void Value::SharedCtor(
    ::_pb::Arena* arena, bool is_message_owned) {
  (void)arena;
  (void)is_message_owned;
  new (&_impl_) Impl_{
      decltype(_impl_.kind_){}
    , /*decltype(_impl_._cached_size_)*/{}
    , /*decltype(_impl_._oneof_case_)*/{}
  };
  clear_has_kind();
}

Value::~Value() {
  // @@protoc_insertion_point(destructor:google.protobuf.Value)
  if (auto *arena = _internal_metadata_.DeleteReturnArena<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>()) {
  (void)arena;
    return;
  }
  SharedDtor();
}

inline void Value::SharedDtor() {
  GOOGLE_DCHECK(GetArenaForAllocation() == nullptr);
  if (has_kind()) {
    clear_kind();
  }
}

void Value::SetCachedSize(int size) const {
  _impl_._cached_size_.Set(size);
}

void Value::clear_kind() {
// @@protoc_insertion_point(one_of_clear_start:google.protobuf.Value)
  switch (kind_case()) {
    case kNullValue: {
      // No need to clear
      break;
    }
    case kNumberValue: {
      // No need to clear
      break;
    }
    case kStringValue: {
      _impl_.kind_.string_value_.Destroy();
      break;
    }
    case kBoolValue: {
      // No need to clear
      break;
    }
    case kStructValue: {
      if (GetArenaForAllocation() == nullptr) {
        delete _impl_.kind_.struct_value_;
      }
      break;
    }
    case kListValue: {
      if (GetArenaForAllocation() == nullptr) {
        delete _impl_.kind_.list_value_;
      }
      break;
    }
    case KIND_NOT_SET: {
      break;
    }
  }
  _impl_._oneof_case_[0] = KIND_NOT_SET;
}


void Value::Clear() {
// @@protoc_insertion_point(message_clear_start:google.protobuf.Value)
  uint32_t cached_has_bits = 0;
  // Prevent compiler warnings about cached_has_bits being unused
  (void) cached_has_bits;

  clear_kind();
  _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
}

const char* Value::_InternalParse(const char* ptr, ::_pbi::ParseContext* ctx) {

#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure
  while (!ctx->Done(&ptr)) {
    uint32_t tag;
    ptr = ::_pbi::ReadTag(ptr, &tag);
    switch (tag >> 3) {
      // .google.protobuf.NullValue null_value = 1;
      case 1:
        if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 8)) {
          uint32_t val = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint32(&ptr);
          CHK_(ptr);
          _internal_set_null_value(static_cast<::PROTOBUF_NAMESPACE_ID::NullValue>(val));
        } else
          goto handle_unusual;
        continue;
      // double number_value = 2;
      case 2:
        if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 17)) {
          _internal_set_number_value(::PROTOBUF_NAMESPACE_ID::internal::UnalignedLoad<double>(ptr));
          ptr += sizeof(double);
        } else
          goto handle_unusual;
        continue;
      // string string_value = 3;
      case 3:
        if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 26)) {
          auto str = _internal_mutable_string_value();
          ptr = ::_pbi::InlineGreedyStringParser(str, ptr, ctx);
          CHK_(ptr);
          CHK_(::_pbi::VerifyUTF8(str, "google.protobuf.Value.string_value"));
        } else
          goto handle_unusual;
        continue;
      // bool bool_value = 4;
      case 4:
        if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 32)) {
          _internal_set_bool_value(::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr));
          CHK_(ptr);
        } else
          goto handle_unusual;
        continue;
      // .google.protobuf.Struct struct_value = 5;
      case 5:
        if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 42)) {
          ptr = ctx->ParseMessage(_internal_mutable_struct_value(), ptr);
          CHK_(ptr);
        } else
          goto handle_unusual;
        continue;
      // .google.protobuf.ListValue list_value = 6;
      case 6:
        if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 50)) {
          ptr = ctx->ParseMessage(_internal_mutable_list_value(), ptr);
          CHK_(ptr);
        } else
          goto handle_unusual;
        continue;
      default:
        goto handle_unusual;
    }  // switch
  handle_unusual:
    if ((tag == 0) || ((tag & 7) == 4)) {
      CHK_(ptr);
      ctx->SetLastTag(tag);
      goto message_done;
    }
    ptr = UnknownFieldParse(
        tag,
        _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(),
        ptr, ctx);
    CHK_(ptr != nullptr);
  }  // while
message_done:
  return ptr;
failure:
  ptr = nullptr;
  goto message_done;
#undef CHK_
}

uint8_t* Value::_InternalSerialize(
    uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const {

  // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.Value)
  uint32_t cached_has_bits = 0;
  (void) cached_has_bits;

  // .google.protobuf.NullValue null_value = 1;
  if (_internal_has_null_value()) {
    target = stream->EnsureSpace(target);
    target = ::_pbi::WireFormatLite::WriteEnumToArray(
      1, this->_internal_null_value(), target);
  }

  // double number_value = 2;
  if (_internal_has_number_value()) {
    target = stream->EnsureSpace(target);
    target = ::_pbi::WireFormatLite::WriteDoubleToArray(2, this->_internal_number_value(), target);
  }

  // string string_value = 3;
  if (_internal_has_string_value()) {
    ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::VerifyUtf8String(
      this->_internal_string_value().data(), static_cast<int>(this->_internal_string_value().length()),
      ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::SERIALIZE,
      "google.protobuf.Value.string_value");
    target = stream->WriteStringMaybeAliased(
        3, this->_internal_string_value(), target);
  }

  // bool bool_value = 4;
  if (_internal_has_bool_value()) {
    target = stream->EnsureSpace(target);
    target = ::_pbi::WireFormatLite::WriteBoolToArray(4, this->_internal_bool_value(), target);
  }

  // .google.protobuf.Struct struct_value = 5;
  if (_internal_has_struct_value()) {
    target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::
      InternalWriteMessage(5, _Internal::struct_value(this),
        _Internal::struct_value(this).GetCachedSize(), target, stream);
  }

  // .google.protobuf.ListValue list_value = 6;
  if (_internal_has_list_value()) {
    target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::
      InternalWriteMessage(6, _Internal::list_value(this),
        _Internal::list_value(this).GetCachedSize(), target, stream);
  }

  if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) {
    target = ::_pbi::WireFormat::InternalSerializeUnknownFieldsToArray(
        _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream);
  }
  // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.Value)
  return target;
}

size_t Value::ByteSizeLong() const {

// @@protoc_insertion_point(message_byte_size_start:google.protobuf.Value)
  size_t total_size = 0;

  uint32_t cached_has_bits = 0;
  // Prevent compiler warnings about cached_has_bits being unused
  (void) cached_has_bits;

  switch (kind_case()) {
    // .google.protobuf.NullValue null_value = 1;
    case kNullValue: {
      total_size += 1 +
        ::_pbi::WireFormatLite::EnumSize(this->_internal_null_value());
      break;
    }
    // double number_value = 2;
    case kNumberValue: {
      total_size += 1 + 8;
      break;
    }
    // string string_value = 3;
    case kStringValue: {
      total_size += 1 +
        ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize(
          this->_internal_string_value());
      break;
    }
    // bool bool_value = 4;
    case kBoolValue: {
      total_size += 1 + 1;
      break;
    }
    // .google.protobuf.Struct struct_value = 5;
    case kStructValue: {
      total_size += 1 +
        ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(
          *_impl_.kind_.struct_value_);
      break;
    }
    // .google.protobuf.ListValue list_value = 6;
    case kListValue: {
      total_size += 1 +
        ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(
          *_impl_.kind_.list_value_);
      break;
    }
    case KIND_NOT_SET: {
      break;
    }
  }
  return MaybeComputeUnknownFieldsSize(total_size, &_impl_._cached_size_);
}

const ::PROTOBUF_NAMESPACE_ID::Message::ClassData Value::_class_data_ = {
    ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSourceCheck,
    Value::MergeImpl
};
const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*Value::GetClassData() const { return &_class_data_; }


void Value::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg) {
  auto* const _this = static_cast<Value*>(&to_msg);
  auto& from = static_cast<const Value&>(from_msg);

  // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.Value)
  GOOGLE_DCHECK_NE(&from, _this);
  uint32_t cached_has_bits = 0;
  (void) cached_has_bits;

  switch (from.kind_case()) {
    case kNullValue: {
      _this->_internal_set_null_value(from._internal_null_value());
      break;
    }
    case kNumberValue: {
      _this->_internal_set_number_value(from._internal_number_value());
      break;
    }
    case kStringValue: {
      _this->_internal_set_string_value(from._internal_string_value());
      break;
    }
    case kBoolValue: {
      _this->_internal_set_bool_value(from._internal_bool_value());
      break;
    }
    case kStructValue: {
      _this->_internal_mutable_struct_value()->::PROTOBUF_NAMESPACE_ID::Struct::MergeFrom(
          from._internal_struct_value());
      break;
    }
    case kListValue: {
      _this->_internal_mutable_list_value()->::PROTOBUF_NAMESPACE_ID::ListValue::MergeFrom(
          from._internal_list_value());
      break;
    }
    case KIND_NOT_SET: {
      break;
    }
  }
  _this->_internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
}

void Value::CopyFrom(const Value& from) {
// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.Value)
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

bool Value::IsInitialized() const {
  return true;
}

void Value::InternalSwap(Value* other) {
  using std::swap;
  _internal_metadata_.InternalSwap(&other->_internal_metadata_);
  swap(_impl_.kind_, other->_impl_.kind_);
  swap(_impl_._oneof_case_[0], other->_impl_._oneof_case_[0]);
}

::PROTOBUF_NAMESPACE_ID::Metadata Value::GetMetadata() const {

  return ::_pbi::AssignDescriptors(
      &descriptor_table_google_2fprotobuf_2fstruct_2eproto_getter, &descriptor_table_google_2fprotobuf_2fstruct_2eproto_once,
      file_level_metadata_google_2fprotobuf_2fstruct_2eproto[2]);
}
// ===================================================================

class ListValue::_Internal {
 public:
};

ListValue::ListValue(::PROTOBUF_NAMESPACE_ID::Arena* arena,
                         bool is_message_owned)
  : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned) {
  SharedCtor(arena, is_message_owned);
  // @@protoc_insertion_point(arena_constructor:google.protobuf.ListValue)
}
ListValue::ListValue(const ListValue& from)
  : ::PROTOBUF_NAMESPACE_ID::Message() {
  ListValue* const _this = this; (void)_this;
  new (&_impl_) Impl_{
      decltype(_impl_.values_){from._impl_.values_}
    , /*decltype(_impl_._cached_size_)*/{}};

  _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
  // @@protoc_insertion_point(copy_constructor:google.protobuf.ListValue)
}

inline void ListValue::SharedCtor(
    ::_pb::Arena* arena, bool is_message_owned) {
  (void)arena;
  (void)is_message_owned;
  new (&_impl_) Impl_{
      decltype(_impl_.values_){arena}
    , /*decltype(_impl_._cached_size_)*/{}
  };
}

ListValue::~ListValue() {
  // @@protoc_insertion_point(destructor:google.protobuf.ListValue)
  if (auto *arena = _internal_metadata_.DeleteReturnArena<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>()) {
  (void)arena;
    return;
  }
  SharedDtor();
}

inline void ListValue::SharedDtor() {
  GOOGLE_DCHECK(GetArenaForAllocation() == nullptr);
  _impl_.values_.~RepeatedPtrField();
}

void ListValue::SetCachedSize(int size) const {
  _impl_._cached_size_.Set(size);
}

void ListValue::Clear() {
// @@protoc_insertion_point(message_clear_start:google.protobuf.ListValue)
  uint32_t cached_has_bits = 0;
  // Prevent compiler warnings about cached_has_bits being unused
  (void) cached_has_bits;

  _impl_.values_.Clear();
  _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
}

const char* ListValue::_InternalParse(const char* ptr, ::_pbi::ParseContext* ctx) {

#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure
  while (!ctx->Done(&ptr)) {
    uint32_t tag;
    ptr = ::_pbi::ReadTag(ptr, &tag);
    switch (tag >> 3) {
      // repeated .google.protobuf.Value values = 1;
      case 1:
        if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 10)) {
          ptr -= 1;
          do {
            ptr += 1;
            ptr = ctx->ParseMessage(_internal_add_values(), ptr);
            CHK_(ptr);
            if (!ctx->DataAvailable(ptr)) break;
          } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<10>(ptr));
        } else
          goto handle_unusual;
        continue;
      default:
        goto handle_unusual;
    }  // switch
  handle_unusual:
    if ((tag == 0) || ((tag & 7) == 4)) {
      CHK_(ptr);
      ctx->SetLastTag(tag);
      goto message_done;
    }
    ptr = UnknownFieldParse(
        tag,
        _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(),
        ptr, ctx);
    CHK_(ptr != nullptr);
  }  // while
message_done:
  return ptr;
failure:
  ptr = nullptr;
  goto message_done;
#undef CHK_
}

uint8_t* ListValue::_InternalSerialize(
    uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const {

  // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.ListValue)
  uint32_t cached_has_bits = 0;
  (void) cached_has_bits;

  // repeated .google.protobuf.Value values = 1;
  for (unsigned i = 0,
      n = static_cast<unsigned>(this->_internal_values_size()); i < n; i++) {
    const auto& repfield = this->_internal_values(i);
    target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::
        InternalWriteMessage(1, repfield, repfield.GetCachedSize(), target, stream);
  }

  if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) {
    target = ::_pbi::WireFormat::InternalSerializeUnknownFieldsToArray(
        _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream);
  }
  // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.ListValue)
  return target;
}

size_t ListValue::ByteSizeLong() const {

// @@protoc_insertion_point(message_byte_size_start:google.protobuf.ListValue)
  size_t total_size = 0;

  uint32_t cached_has_bits = 0;
  // Prevent compiler warnings about cached_has_bits being unused
  (void) cached_has_bits;

  // repeated .google.protobuf.Value values = 1;
  total_size += 1UL * this->_internal_values_size();
  for (const auto& msg : this->_impl_.values_) {
    total_size +=
      ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(msg);
  }

  return MaybeComputeUnknownFieldsSize(total_size, &_impl_._cached_size_);
}

const ::PROTOBUF_NAMESPACE_ID::Message::ClassData ListValue::_class_data_ = {
    ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSourceCheck,
    ListValue::MergeImpl
};
const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*ListValue::GetClassData() const { return &_class_data_; }


void ListValue::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg) {
  auto* const _this = static_cast<ListValue*>(&to_msg);
  auto& from = static_cast<const ListValue&>(from_msg);

  // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.ListValue)
  GOOGLE_DCHECK_NE(&from, _this);
  uint32_t cached_has_bits = 0;
  (void) cached_has_bits;

  _this->_impl_.values_.MergeFrom(from._impl_.values_);
  _this->_internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
}

void ListValue::CopyFrom(const ListValue& from) {
// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.ListValue)
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

bool ListValue::IsInitialized() const {
  return true;
}

void ListValue::InternalSwap(ListValue* other) {
  using std::swap;
  _internal_metadata_.InternalSwap(&other->_internal_metadata_);
  _impl_.values_.InternalSwap(&other->_impl_.values_);
}

::PROTOBUF_NAMESPACE_ID::Metadata ListValue::GetMetadata() const {

  return ::_pbi::AssignDescriptors(
      &descriptor_table_google_2fprotobuf_2fstruct_2eproto_getter, &descriptor_table_google_2fprotobuf_2fstruct_2eproto_once,
      file_level_metadata_google_2fprotobuf_2fstruct_2eproto[3]);
}
// @@protoc_insertion_point(namespace_scope)
PROTOBUF_NAMESPACE_CLOSE
PROTOBUF_NAMESPACE_OPEN
template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::Struct_FieldsEntry_DoNotUse*
Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::Struct_FieldsEntry_DoNotUse >(Arena* arena) {
  return Arena::CreateMessageInternal< ::PROTOBUF_NAMESPACE_ID::Struct_FieldsEntry_DoNotUse >(arena);
}
template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::Struct*
Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::Struct >(Arena* arena) {
  return Arena::CreateMessageInternal< ::PROTOBUF_NAMESPACE_ID::Struct >(arena);
}
template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::Value*
Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::Value >(Arena* arena) {
  return Arena::CreateMessageInternal< ::PROTOBUF_NAMESPACE_ID::Value >(arena);
}
template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::ListValue*
Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::ListValue >(Arena* arena) {
  return Arena::CreateMessageInternal< ::PROTOBUF_NAMESPACE_ID::ListValue >(arena);
}
PROTOBUF_NAMESPACE_CLOSE
// @@protoc_insertion_point(global_scope)
#include "google/protobuf/port_undef.inc"
