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

#define INTERNAL_SUPPRESS_PROTOBUF_FIELD_DEPRECATION
#include <google/protobuf/struct.pb.h>

#include <algorithm>

#include <google/protobuf/stubs/common.h>
#include <google/protobuf/stubs/port.h>
#include <google/protobuf/stubs/once.h>
#include <google/protobuf/io/coded_stream.h>
#include <google/protobuf/wire_format_lite_inl.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)

namespace google {
namespace protobuf {
class Struct_FieldsEntryDefaultTypeInternal : public ::google::protobuf::internal::ExplicitlyConstructed<Struct::Struct_FieldsEntry> {
} _Struct_FieldsEntry_default_instance_;
class StructDefaultTypeInternal : public ::google::protobuf::internal::ExplicitlyConstructed<Struct> {
} _Struct_default_instance_;
class ValueDefaultTypeInternal : public ::google::protobuf::internal::ExplicitlyConstructed<Value> {
  public:
  int null_value_;
  double number_value_;
  ::google::protobuf::internal::ArenaStringPtr string_value_;
  bool bool_value_;
  const ::google::protobuf::Struct* struct_value_;
  const ::google::protobuf::ListValue* list_value_;
} _Value_default_instance_;
class ListValueDefaultTypeInternal : public ::google::protobuf::internal::ExplicitlyConstructed<ListValue> {
} _ListValue_default_instance_;

namespace protobuf_google_2fprotobuf_2fstruct_2eproto {


namespace {

::google::protobuf::Metadata file_level_metadata[4];
const ::google::protobuf::EnumDescriptor* file_level_enum_descriptors[1];

}  // namespace

PROTOBUF_CONSTEXPR_VAR ::google::protobuf::internal::ParseTableField
    const TableStruct::entries[] = {
  {0, 0, 0, ::google::protobuf::internal::kInvalidMask, 0, 0},
};

PROTOBUF_CONSTEXPR_VAR ::google::protobuf::internal::AuxillaryParseTableField
    const TableStruct::aux[] = {
  ::google::protobuf::internal::AuxillaryParseTableField(),
};
PROTOBUF_CONSTEXPR_VAR ::google::protobuf::internal::ParseTable const
    TableStruct::schema[] = {
  { NULL, NULL, 0, -1, -1, false },
  { NULL, NULL, 0, -1, -1, false },
  { NULL, NULL, 0, -1, -1, false },
  { NULL, NULL, 0, -1, -1, false },
};

const ::google::protobuf::uint32 TableStruct::offsets[] = {
  ~0u,  // no _has_bits_
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Struct, _internal_metadata_),
  ~0u,  // no _extensions_
  ~0u,  // no _oneof_case_
  ~0u,  // no _weak_field_map_
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Struct, fields_),
  ~0u,  // no _has_bits_
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Value, _internal_metadata_),
  ~0u,  // no _extensions_
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Value, _oneof_case_[0]),
  ~0u,  // no _weak_field_map_
  GOOGLE_PROTOBUF_GENERATED_DEFAULT_ONEOF_FIELD_OFFSET((&_Value_default_instance_), null_value_),
  GOOGLE_PROTOBUF_GENERATED_DEFAULT_ONEOF_FIELD_OFFSET((&_Value_default_instance_), number_value_),
  GOOGLE_PROTOBUF_GENERATED_DEFAULT_ONEOF_FIELD_OFFSET((&_Value_default_instance_), string_value_),
  GOOGLE_PROTOBUF_GENERATED_DEFAULT_ONEOF_FIELD_OFFSET((&_Value_default_instance_), bool_value_),
  GOOGLE_PROTOBUF_GENERATED_DEFAULT_ONEOF_FIELD_OFFSET((&_Value_default_instance_), struct_value_),
  GOOGLE_PROTOBUF_GENERATED_DEFAULT_ONEOF_FIELD_OFFSET((&_Value_default_instance_), list_value_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Value, kind_),
  ~0u,  // no _has_bits_
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ListValue, _internal_metadata_),
  ~0u,  // no _extensions_
  ~0u,  // no _oneof_case_
  ~0u,  // no _weak_field_map_
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ListValue, values_),
};

static const ::google::protobuf::internal::MigrationSchema schemas[] = {
  { 0, -1, sizeof(Struct)},
  { 6, -1, sizeof(Value)},
  { 18, -1, sizeof(ListValue)},
};

static ::google::protobuf::Message const * const file_default_instances[] = {
  reinterpret_cast<const ::google::protobuf::Message*>(&_Struct_FieldsEntry_default_instance_),
  reinterpret_cast<const ::google::protobuf::Message*>(&_Struct_default_instance_),
  reinterpret_cast<const ::google::protobuf::Message*>(&_Value_default_instance_),
  reinterpret_cast<const ::google::protobuf::Message*>(&_ListValue_default_instance_),
};

namespace {

void protobuf_AssignDescriptors() {
  AddDescriptors();
  ::google::protobuf::MessageFactory* factory = NULL;
  AssignDescriptors(
      "google/protobuf/struct.proto", schemas, file_default_instances, TableStruct::offsets, factory,
      file_level_metadata, file_level_enum_descriptors, NULL);
file_level_metadata[0].reflection = Struct::Struct_FieldsEntry::CreateReflection(file_level_metadata[0].descriptor, _Struct_FieldsEntry_default_instance_.get_mutable());
}

void protobuf_AssignDescriptorsOnce() {
  static GOOGLE_PROTOBUF_DECLARE_ONCE(once);
  ::google::protobuf::GoogleOnceInit(&once, &protobuf_AssignDescriptors);
}

void protobuf_RegisterTypes(const ::std::string&) GOOGLE_ATTRIBUTE_COLD;
void protobuf_RegisterTypes(const ::std::string&) {
  protobuf_AssignDescriptorsOnce();
  ::google::protobuf::internal::RegisterAllTypes(file_level_metadata, 4);
}

}  // namespace

void TableStruct::Shutdown() {
  _Struct_default_instance_.Shutdown();
  delete file_level_metadata[1].reflection;
  _Value_default_instance_.Shutdown();
  delete file_level_metadata[2].reflection;
  _ListValue_default_instance_.Shutdown();
  delete file_level_metadata[3].reflection;
  delete file_level_metadata[0].reflection;
}

void TableStruct::InitDefaultsImpl() {
  GOOGLE_PROTOBUF_VERIFY_VERSION;

  ::google::protobuf::internal::InitProtobufDefaults();
  _Struct_FieldsEntry_default_instance_.DefaultConstruct();
  _Struct_default_instance_.DefaultConstruct();
  _Value_default_instance_.DefaultConstruct();
  _ListValue_default_instance_.DefaultConstruct();
  _Struct_FieldsEntry_default_instance_.get_mutable()->set_default_instance(_Struct_FieldsEntry_default_instance_.get_mutable());
  _Struct_FieldsEntry_default_instance_.get_mutable()->InitAsDefaultInstance();
  _Value_default_instance_.null_value_ = 0;
  _Value_default_instance_.number_value_ = 0;
  _Value_default_instance_.string_value_.UnsafeSetDefault(
      &::google::protobuf::internal::GetEmptyStringAlreadyInited());
  _Value_default_instance_.bool_value_ = false;
  _Value_default_instance_.struct_value_ = const_cast< ::google::protobuf::Struct*>(
      ::google::protobuf::Struct::internal_default_instance());
  _Value_default_instance_.list_value_ = const_cast< ::google::protobuf::ListValue*>(
      ::google::protobuf::ListValue::internal_default_instance());
}

void InitDefaults() {
  static GOOGLE_PROTOBUF_DECLARE_ONCE(once);
  ::google::protobuf::GoogleOnceInit(&once, &TableStruct::InitDefaultsImpl);
}
void AddDescriptorsImpl() {
  InitDefaults();
  static const char descriptor[] = {
      "\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\201\001\n\023com.google.pro"
      "tobufB\013StructProtoP\001Z1github.com/golang/"
      "protobuf/ptypes/struct;structpb\370\001\001\242\002\003GPB"
      "\252\002\036Google.Protobuf.WellKnownTypesb\006proto"
      "3"
  };
  ::google::protobuf::DescriptorPool::InternalAddGeneratedFile(
      descriptor, 641);
  ::google::protobuf::MessageFactory::InternalRegisterGeneratedFile(
    "google/protobuf/struct.proto", &protobuf_RegisterTypes);
  ::google::protobuf::internal::OnShutdown(&TableStruct::Shutdown);
}

void AddDescriptors() {
  static GOOGLE_PROTOBUF_DECLARE_ONCE(once);
  ::google::protobuf::GoogleOnceInit(&once, &AddDescriptorsImpl);
}
// Force AddDescriptors() to be called at static initialization time.
struct StaticDescriptorInitializer {
  StaticDescriptorInitializer() {
    AddDescriptors();
  }
} static_descriptor_initializer;

}  // namespace protobuf_google_2fprotobuf_2fstruct_2eproto

const ::google::protobuf::EnumDescriptor* NullValue_descriptor() {
  protobuf_google_2fprotobuf_2fstruct_2eproto::protobuf_AssignDescriptorsOnce();
  return protobuf_google_2fprotobuf_2fstruct_2eproto::file_level_enum_descriptors[0];
}
bool NullValue_IsValid(int value) {
  switch (value) {
    case 0:
      return true;
    default:
      return false;
  }
}


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

Struct::Struct_FieldsEntry::Struct_FieldsEntry() {}
Struct::Struct_FieldsEntry::Struct_FieldsEntry(::google::protobuf::Arena* arena) : SuperType(arena) {}
::google::protobuf::Metadata Struct::Struct_FieldsEntry::GetMetadata() const {
  protobuf_google_2fprotobuf_2fstruct_2eproto::protobuf_AssignDescriptorsOnce();
  return protobuf_google_2fprotobuf_2fstruct_2eproto::file_level_metadata[0];
}
void Struct::Struct_FieldsEntry::MergeFrom(
    const ::google::protobuf::Message& other) {
  ::google::protobuf::Message::MergeFrom(other);
}
void Struct::Struct_FieldsEntry::MergeFrom(const Struct_FieldsEntry& other) {
  MergeFromInternal(other);
}

#if PROTOBUF_INLINE_NOT_IN_HEADERS
#endif  // PROTOBUF_INLINE_NOT_IN_HEADERS

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

#if !defined(_MSC_VER) || _MSC_VER >= 1900
const int Struct::kFieldsFieldNumber;
#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900

Struct::Struct()
  : ::google::protobuf::Message(), _internal_metadata_(NULL) {
  if (GOOGLE_PREDICT_TRUE(this != internal_default_instance())) {
    protobuf_google_2fprotobuf_2fstruct_2eproto::InitDefaults();
  }
  SharedCtor();
  // @@protoc_insertion_point(constructor:google.protobuf.Struct)
}
Struct::Struct(::google::protobuf::Arena* arena)
  : ::google::protobuf::Message(),
  _internal_metadata_(arena),
  fields_(arena) {
#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
  protobuf_google_2fprotobuf_2fstruct_2eproto::InitDefaults();
#endif  // GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
  SharedCtor();
  RegisterArenaDtor(arena);
  // @@protoc_insertion_point(arena_constructor:google.protobuf.Struct)
}
Struct::Struct(const Struct& from)
  : ::google::protobuf::Message(),
      _internal_metadata_(NULL),
      _cached_size_(0) {
  _internal_metadata_.MergeFrom(from._internal_metadata_);
  fields_.MergeFrom(from.fields_);
  // @@protoc_insertion_point(copy_constructor:google.protobuf.Struct)
}

void Struct::SharedCtor() {
  _cached_size_ = 0;
}

Struct::~Struct() {
  // @@protoc_insertion_point(destructor:google.protobuf.Struct)
  SharedDtor();
}

void Struct::SharedDtor() {
  ::google::protobuf::Arena* arena = GetArenaNoVirtual();
  if (arena != NULL) {
    return;
  }

}

void Struct::ArenaDtor(void* object) {
  Struct* _this = reinterpret_cast< Struct* >(object);
  (void)_this;
}
void Struct::RegisterArenaDtor(::google::protobuf::Arena* arena) {
}
void Struct::SetCachedSize(int size) const {
  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
  _cached_size_ = size;
  GOOGLE_SAFE_CONCURRENT_WRITES_END();
}
const ::google::protobuf::Descriptor* Struct::descriptor() {
  protobuf_google_2fprotobuf_2fstruct_2eproto::protobuf_AssignDescriptorsOnce();
  return protobuf_google_2fprotobuf_2fstruct_2eproto::file_level_metadata[kIndexInFileMessages].descriptor;
}

const Struct& Struct::default_instance() {
  protobuf_google_2fprotobuf_2fstruct_2eproto::InitDefaults();
  return *internal_default_instance();
}

Struct* Struct::New(::google::protobuf::Arena* arena) const {
  return ::google::protobuf::Arena::CreateMessage<Struct>(arena);
}

void Struct::Clear() {
// @@protoc_insertion_point(message_clear_start:google.protobuf.Struct)
  fields_.Clear();
}

bool Struct::MergePartialFromCodedStream(
    ::google::protobuf::io::CodedInputStream* input) {
#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure
  ::google::protobuf::uint32 tag;
  // @@protoc_insertion_point(parse_start:google.protobuf.Struct)
  for (;;) {
    ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u);
    tag = p.first;
    if (!p.second) goto handle_unusual;
    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
      // map<string, .google.protobuf.Value> fields = 1;
      case 1: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(10u)) {
          Struct_FieldsEntry::Parser< ::google::protobuf::internal::MapField<
              Struct_FieldsEntry,
              ::std::string, ::google::protobuf::Value,
              ::google::protobuf::internal::WireFormatLite::TYPE_STRING,
              ::google::protobuf::internal::WireFormatLite::TYPE_MESSAGE,
              0 >,
            ::google::protobuf::Map< ::std::string, ::google::protobuf::Value > > parser(&fields_);
          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
              input, &parser));
          DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
            parser.key().data(), parser.key().length(),
            ::google::protobuf::internal::WireFormatLite::PARSE,
            "google.protobuf.Struct.FieldsEntry.key"));
        } else {
          goto handle_unusual;
        }
        break;
      }

      default: {
      handle_unusual:
        if (tag == 0 ||
            ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
            ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
          goto success;
        }
        DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag));
        break;
      }
    }
  }
success:
  // @@protoc_insertion_point(parse_success:google.protobuf.Struct)
  return true;
failure:
  // @@protoc_insertion_point(parse_failure:google.protobuf.Struct)
  return false;
#undef DO_
}

void Struct::SerializeWithCachedSizes(
    ::google::protobuf::io::CodedOutputStream* output) const {
  // @@protoc_insertion_point(serialize_start:google.protobuf.Struct)
  ::google::protobuf::uint32 cached_has_bits = 0;
  (void) cached_has_bits;

  // map<string, .google.protobuf.Value> fields = 1;
  if (!this->fields().empty()) {
    typedef ::google::protobuf::Map< ::std::string, ::google::protobuf::Value >::const_pointer
        ConstPtr;
    typedef ConstPtr SortItem;
    typedef ::google::protobuf::internal::CompareByDerefFirst<SortItem> Less;
    struct Utf8Check {
      static void Check(ConstPtr p) {
        ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
          p->first.data(), p->first.length(),
          ::google::protobuf::internal::WireFormatLite::SERIALIZE,
          "google.protobuf.Struct.FieldsEntry.key");
      }
    };

    if (output->IsSerializationDeterministic() &&
        this->fields().size() > 1) {
      ::google::protobuf::scoped_array<SortItem> items(
          new SortItem[this->fields().size()]);
      typedef ::google::protobuf::Map< ::std::string, ::google::protobuf::Value >::size_type size_type;
      size_type n = 0;
      for (::google::protobuf::Map< ::std::string, ::google::protobuf::Value >::const_iterator
          it = this->fields().begin();
          it != this->fields().end(); ++it, ++n) {
        items[n] = SortItem(&*it);
      }
      ::std::sort(&items[0], &items[n], Less());
      ::google::protobuf::scoped_ptr<Struct_FieldsEntry> entry;
      for (size_type i = 0; i < n; i++) {
        entry.reset(fields_.NewEntryWrapper(
            items[i]->first, items[i]->second));
        ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
            1, *entry, output);
        if (entry->GetArena() != NULL) {
          entry.release();
        }
        Utf8Check::Check(items[i]);
      }
    } else {
      ::google::protobuf::scoped_ptr<Struct_FieldsEntry> entry;
      for (::google::protobuf::Map< ::std::string, ::google::protobuf::Value >::const_iterator
          it = this->fields().begin();
          it != this->fields().end(); ++it) {
        entry.reset(fields_.NewEntryWrapper(
            it->first, it->second));
        ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
            1, *entry, output);
        if (entry->GetArena() != NULL) {
          entry.release();
        }
        Utf8Check::Check(&*it);
      }
    }
  }

  // @@protoc_insertion_point(serialize_end:google.protobuf.Struct)
}

::google::protobuf::uint8* Struct::InternalSerializeWithCachedSizesToArray(
    bool deterministic, ::google::protobuf::uint8* target) const {
  // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.Struct)
  ::google::protobuf::uint32 cached_has_bits = 0;
  (void) cached_has_bits;

  // map<string, .google.protobuf.Value> fields = 1;
  if (!this->fields().empty()) {
    typedef ::google::protobuf::Map< ::std::string, ::google::protobuf::Value >::const_pointer
        ConstPtr;
    typedef ConstPtr SortItem;
    typedef ::google::protobuf::internal::CompareByDerefFirst<SortItem> Less;
    struct Utf8Check {
      static void Check(ConstPtr p) {
        ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
          p->first.data(), p->first.length(),
          ::google::protobuf::internal::WireFormatLite::SERIALIZE,
          "google.protobuf.Struct.FieldsEntry.key");
      }
    };

    if (deterministic &&
        this->fields().size() > 1) {
      ::google::protobuf::scoped_array<SortItem> items(
          new SortItem[this->fields().size()]);
      typedef ::google::protobuf::Map< ::std::string, ::google::protobuf::Value >::size_type size_type;
      size_type n = 0;
      for (::google::protobuf::Map< ::std::string, ::google::protobuf::Value >::const_iterator
          it = this->fields().begin();
          it != this->fields().end(); ++it, ++n) {
        items[n] = SortItem(&*it);
      }
      ::std::sort(&items[0], &items[n], Less());
      ::google::protobuf::scoped_ptr<Struct_FieldsEntry> entry;
      for (size_type i = 0; i < n; i++) {
        entry.reset(fields_.NewEntryWrapper(
            items[i]->first, items[i]->second));
        target = ::google::protobuf::internal::WireFormatLite::
                   InternalWriteMessageNoVirtualToArray(
                       1, *entry, deterministic, target);
;
        if (entry->GetArena() != NULL) {
          entry.release();
        }
        Utf8Check::Check(items[i]);
      }
    } else {
      ::google::protobuf::scoped_ptr<Struct_FieldsEntry> entry;
      for (::google::protobuf::Map< ::std::string, ::google::protobuf::Value >::const_iterator
          it = this->fields().begin();
          it != this->fields().end(); ++it) {
        entry.reset(fields_.NewEntryWrapper(
            it->first, it->second));
        target = ::google::protobuf::internal::WireFormatLite::
                   InternalWriteMessageNoVirtualToArray(
                       1, *entry, deterministic, target);
;
        if (entry->GetArena() != NULL) {
          entry.release();
        }
        Utf8Check::Check(&*it);
      }
    }
  }

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

  // map<string, .google.protobuf.Value> fields = 1;
  total_size += 1 *
      ::google::protobuf::internal::FromIntSize(this->fields_size());
  {
    ::google::protobuf::scoped_ptr<Struct_FieldsEntry> entry;
    for (::google::protobuf::Map< ::std::string, ::google::protobuf::Value >::const_iterator
        it = this->fields().begin();
        it != this->fields().end(); ++it) {
      if (entry.get() != NULL && entry->GetArena() != NULL) {
        entry.release();
      }
      entry.reset(fields_.NewEntryWrapper(it->first, it->second));
      total_size += ::google::protobuf::internal::WireFormatLite::
          MessageSizeNoVirtual(*entry);
    }
    if (entry.get() != NULL && entry->GetArena() != NULL) {
      entry.release();
    }
  }

  int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
  _cached_size_ = cached_size;
  GOOGLE_SAFE_CONCURRENT_WRITES_END();
  return total_size;
}

void Struct::MergeFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.Struct)
  GOOGLE_DCHECK_NE(&from, this);
  const Struct* source =
      ::google::protobuf::internal::DynamicCastToGenerated<const Struct>(
          &from);
  if (source == NULL) {
  // @@protoc_insertion_point(generalized_merge_from_cast_fail:google.protobuf.Struct)
    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
  } else {
  // @@protoc_insertion_point(generalized_merge_from_cast_success:google.protobuf.Struct)
    MergeFrom(*source);
  }
}

void Struct::MergeFrom(const Struct& from) {
// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.Struct)
  GOOGLE_DCHECK_NE(&from, this);
  _internal_metadata_.MergeFrom(from._internal_metadata_);
  ::google::protobuf::uint32 cached_has_bits = 0;
  (void) cached_has_bits;

  fields_.MergeFrom(from.fields_);
}

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

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::Swap(Struct* other) {
  if (other == this) return;
  if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) {
    InternalSwap(other);
  } else {
    Struct* temp = New(GetArenaNoVirtual());
    temp->MergeFrom(*other);
    other->CopyFrom(*this);
    InternalSwap(temp);
    if (GetArenaNoVirtual() == NULL) {
      delete temp;
    }
  }
}
void Struct::UnsafeArenaSwap(Struct* other) {
  if (other == this) return;
  GOOGLE_DCHECK(GetArenaNoVirtual() == other->GetArenaNoVirtual());
  InternalSwap(other);
}
void Struct::InternalSwap(Struct* other) {
  fields_.Swap(&other->fields_);
  std::swap(_cached_size_, other->_cached_size_);
}

::google::protobuf::Metadata Struct::GetMetadata() const {
  protobuf_google_2fprotobuf_2fstruct_2eproto::protobuf_AssignDescriptorsOnce();
  return protobuf_google_2fprotobuf_2fstruct_2eproto::file_level_metadata[kIndexInFileMessages];
}

#if PROTOBUF_INLINE_NOT_IN_HEADERS
// Struct

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

#endif  // PROTOBUF_INLINE_NOT_IN_HEADERS

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

#if !defined(_MSC_VER) || _MSC_VER >= 1900
const int Value::kNullValueFieldNumber;
const int Value::kNumberValueFieldNumber;
const int Value::kStringValueFieldNumber;
const int Value::kBoolValueFieldNumber;
const int Value::kStructValueFieldNumber;
const int Value::kListValueFieldNumber;
#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900

Value::Value()
  : ::google::protobuf::Message(), _internal_metadata_(NULL) {
  if (GOOGLE_PREDICT_TRUE(this != internal_default_instance())) {
    protobuf_google_2fprotobuf_2fstruct_2eproto::InitDefaults();
  }
  SharedCtor();
  // @@protoc_insertion_point(constructor:google.protobuf.Value)
}
Value::Value(::google::protobuf::Arena* arena)
  : ::google::protobuf::Message(),
  _internal_metadata_(arena) {
#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
  protobuf_google_2fprotobuf_2fstruct_2eproto::InitDefaults();
#endif  // GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
  SharedCtor();
  RegisterArenaDtor(arena);
  // @@protoc_insertion_point(arena_constructor:google.protobuf.Value)
}
Value::Value(const Value& from)
  : ::google::protobuf::Message(),
      _internal_metadata_(NULL),
      _cached_size_(0) {
  _internal_metadata_.MergeFrom(from._internal_metadata_);
  clear_has_kind();
  switch (from.kind_case()) {
    case kNullValue: {
      set_null_value(from.null_value());
      break;
    }
    case kNumberValue: {
      set_number_value(from.number_value());
      break;
    }
    case kStringValue: {
      set_string_value(from.string_value());
      break;
    }
    case kBoolValue: {
      set_bool_value(from.bool_value());
      break;
    }
    case kStructValue: {
      mutable_struct_value()->::google::protobuf::Struct::MergeFrom(from.struct_value());
      break;
    }
    case kListValue: {
      mutable_list_value()->::google::protobuf::ListValue::MergeFrom(from.list_value());
      break;
    }
    case KIND_NOT_SET: {
      break;
    }
  }
  // @@protoc_insertion_point(copy_constructor:google.protobuf.Value)
}

void Value::SharedCtor() {
  clear_has_kind();
  _cached_size_ = 0;
}

Value::~Value() {
  // @@protoc_insertion_point(destructor:google.protobuf.Value)
  SharedDtor();
}

void Value::SharedDtor() {
  ::google::protobuf::Arena* arena = GetArenaNoVirtual();
  if (arena != NULL) {
    return;
  }

  if (has_kind()) {
    clear_kind();
  }
}

void Value::ArenaDtor(void* object) {
  Value* _this = reinterpret_cast< Value* >(object);
  (void)_this;
}
void Value::RegisterArenaDtor(::google::protobuf::Arena* arena) {
}
void Value::SetCachedSize(int size) const {
  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
  _cached_size_ = size;
  GOOGLE_SAFE_CONCURRENT_WRITES_END();
}
const ::google::protobuf::Descriptor* Value::descriptor() {
  protobuf_google_2fprotobuf_2fstruct_2eproto::protobuf_AssignDescriptorsOnce();
  return protobuf_google_2fprotobuf_2fstruct_2eproto::file_level_metadata[kIndexInFileMessages].descriptor;
}

const Value& Value::default_instance() {
  protobuf_google_2fprotobuf_2fstruct_2eproto::InitDefaults();
  return *internal_default_instance();
}

Value* Value::New(::google::protobuf::Arena* arena) const {
  return ::google::protobuf::Arena::CreateMessage<Value>(arena);
}

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: {
      kind_.string_value_.Destroy(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
          GetArenaNoVirtual());
      break;
    }
    case kBoolValue: {
      // No need to clear
      break;
    }
    case kStructValue: {
      if (GetArenaNoVirtual() == NULL) {
        delete kind_.struct_value_;
      }
      break;
    }
    case kListValue: {
      if (GetArenaNoVirtual() == NULL) {
        delete kind_.list_value_;
      }
      break;
    }
    case KIND_NOT_SET: {
      break;
    }
  }
  _oneof_case_[0] = KIND_NOT_SET;
}


void Value::Clear() {
// @@protoc_insertion_point(message_clear_start:google.protobuf.Value)
  clear_kind();
}

bool Value::MergePartialFromCodedStream(
    ::google::protobuf::io::CodedInputStream* input) {
#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure
  ::google::protobuf::uint32 tag;
  // @@protoc_insertion_point(parse_start:google.protobuf.Value)
  for (;;) {
    ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u);
    tag = p.first;
    if (!p.second) goto handle_unusual;
    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
      // .google.protobuf.NullValue null_value = 1;
      case 1: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(8u)) {
          int value;
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
                 input, &value)));
          set_null_value(static_cast< ::google::protobuf::NullValue >(value));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // double number_value = 2;
      case 2: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(17u)) {
          clear_kind();
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   double, ::google::protobuf::internal::WireFormatLite::TYPE_DOUBLE>(
                 input, &kind_.number_value_)));
          set_has_number_value();
        } else {
          goto handle_unusual;
        }
        break;
      }

      // string string_value = 3;
      case 3: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(26u)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                input, this->mutable_string_value()));
          DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
            this->string_value().data(), this->string_value().length(),
            ::google::protobuf::internal::WireFormatLite::PARSE,
            "google.protobuf.Value.string_value"));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // bool bool_value = 4;
      case 4: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(32u)) {
          clear_kind();
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
                 input, &kind_.bool_value_)));
          set_has_bool_value();
        } else {
          goto handle_unusual;
        }
        break;
      }

      // .google.protobuf.Struct struct_value = 5;
      case 5: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(42u)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
               input, mutable_struct_value()));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // .google.protobuf.ListValue list_value = 6;
      case 6: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(50u)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
               input, mutable_list_value()));
        } else {
          goto handle_unusual;
        }
        break;
      }

      default: {
      handle_unusual:
        if (tag == 0 ||
            ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
            ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
          goto success;
        }
        DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag));
        break;
      }
    }
  }
success:
  // @@protoc_insertion_point(parse_success:google.protobuf.Value)
  return true;
failure:
  // @@protoc_insertion_point(parse_failure:google.protobuf.Value)
  return false;
#undef DO_
}

void Value::SerializeWithCachedSizes(
    ::google::protobuf::io::CodedOutputStream* output) const {
  // @@protoc_insertion_point(serialize_start:google.protobuf.Value)
  ::google::protobuf::uint32 cached_has_bits = 0;
  (void) cached_has_bits;

  // .google.protobuf.NullValue null_value = 1;
  if (has_null_value()) {
    ::google::protobuf::internal::WireFormatLite::WriteEnum(
      1, this->null_value(), output);
  }

  // double number_value = 2;
  if (has_number_value()) {
    ::google::protobuf::internal::WireFormatLite::WriteDouble(2, this->number_value(), output);
  }

  // string string_value = 3;
  if (has_string_value()) {
    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
      this->string_value().data(), this->string_value().length(),
      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
      "google.protobuf.Value.string_value");
    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
      3, this->string_value(), output);
  }

  // bool bool_value = 4;
  if (has_bool_value()) {
    ::google::protobuf::internal::WireFormatLite::WriteBool(4, this->bool_value(), output);
  }

  // .google.protobuf.Struct struct_value = 5;
  if (has_struct_value()) {
    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
      5, *kind_.struct_value_, output);
  }

  // .google.protobuf.ListValue list_value = 6;
  if (has_list_value()) {
    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
      6, *kind_.list_value_, output);
  }

  // @@protoc_insertion_point(serialize_end:google.protobuf.Value)
}

::google::protobuf::uint8* Value::InternalSerializeWithCachedSizesToArray(
    bool deterministic, ::google::protobuf::uint8* target) const {
  // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.Value)
  ::google::protobuf::uint32 cached_has_bits = 0;
  (void) cached_has_bits;

  // .google.protobuf.NullValue null_value = 1;
  if (has_null_value()) {
    target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
      1, this->null_value(), target);
  }

  // double number_value = 2;
  if (has_number_value()) {
    target = ::google::protobuf::internal::WireFormatLite::WriteDoubleToArray(2, this->number_value(), target);
  }

  // string string_value = 3;
  if (has_string_value()) {
    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
      this->string_value().data(), this->string_value().length(),
      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
      "google.protobuf.Value.string_value");
    target =
      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
        3, this->string_value(), target);
  }

  // bool bool_value = 4;
  if (has_bool_value()) {
    target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(4, this->bool_value(), target);
  }

  // .google.protobuf.Struct struct_value = 5;
  if (has_struct_value()) {
    target = ::google::protobuf::internal::WireFormatLite::
      InternalWriteMessageNoVirtualToArray(
        5, *kind_.struct_value_, deterministic, target);
  }

  // .google.protobuf.ListValue list_value = 6;
  if (has_list_value()) {
    target = ::google::protobuf::internal::WireFormatLite::
      InternalWriteMessageNoVirtualToArray(
        6, *kind_.list_value_, deterministic, target);
  }

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

  switch (kind_case()) {
    // .google.protobuf.NullValue null_value = 1;
    case kNullValue: {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::EnumSize(this->null_value());
      break;
    }
    // double number_value = 2;
    case kNumberValue: {
      total_size += 1 + 8;
      break;
    }
    // string string_value = 3;
    case kStringValue: {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::StringSize(
          this->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 +
        ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
          *kind_.struct_value_);
      break;
    }
    // .google.protobuf.ListValue list_value = 6;
    case kListValue: {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
          *kind_.list_value_);
      break;
    }
    case KIND_NOT_SET: {
      break;
    }
  }
  int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
  _cached_size_ = cached_size;
  GOOGLE_SAFE_CONCURRENT_WRITES_END();
  return total_size;
}

void Value::MergeFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.Value)
  GOOGLE_DCHECK_NE(&from, this);
  const Value* source =
      ::google::protobuf::internal::DynamicCastToGenerated<const Value>(
          &from);
  if (source == NULL) {
  // @@protoc_insertion_point(generalized_merge_from_cast_fail:google.protobuf.Value)
    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
  } else {
  // @@protoc_insertion_point(generalized_merge_from_cast_success:google.protobuf.Value)
    MergeFrom(*source);
  }
}

void Value::MergeFrom(const Value& from) {
// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.Value)
  GOOGLE_DCHECK_NE(&from, this);
  _internal_metadata_.MergeFrom(from._internal_metadata_);
  ::google::protobuf::uint32 cached_has_bits = 0;
  (void) cached_has_bits;

  switch (from.kind_case()) {
    case kNullValue: {
      set_null_value(from.null_value());
      break;
    }
    case kNumberValue: {
      set_number_value(from.number_value());
      break;
    }
    case kStringValue: {
      set_string_value(from.string_value());
      break;
    }
    case kBoolValue: {
      set_bool_value(from.bool_value());
      break;
    }
    case kStructValue: {
      mutable_struct_value()->::google::protobuf::Struct::MergeFrom(from.struct_value());
      break;
    }
    case kListValue: {
      mutable_list_value()->::google::protobuf::ListValue::MergeFrom(from.list_value());
      break;
    }
    case KIND_NOT_SET: {
      break;
    }
  }
}

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

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::Swap(Value* other) {
  if (other == this) return;
  if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) {
    InternalSwap(other);
  } else {
    Value* temp = New(GetArenaNoVirtual());
    temp->MergeFrom(*other);
    other->CopyFrom(*this);
    InternalSwap(temp);
    if (GetArenaNoVirtual() == NULL) {
      delete temp;
    }
  }
}
void Value::UnsafeArenaSwap(Value* other) {
  if (other == this) return;
  GOOGLE_DCHECK(GetArenaNoVirtual() == other->GetArenaNoVirtual());
  InternalSwap(other);
}
void Value::InternalSwap(Value* other) {
  std::swap(kind_, other->kind_);
  std::swap(_oneof_case_[0], other->_oneof_case_[0]);
  std::swap(_cached_size_, other->_cached_size_);
}

::google::protobuf::Metadata Value::GetMetadata() const {
  protobuf_google_2fprotobuf_2fstruct_2eproto::protobuf_AssignDescriptorsOnce();
  return protobuf_google_2fprotobuf_2fstruct_2eproto::file_level_metadata[kIndexInFileMessages];
}

#if PROTOBUF_INLINE_NOT_IN_HEADERS
// Value

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

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

// string string_value = 3;
bool Value::has_string_value() const {
  return kind_case() == kStringValue;
}
void Value::set_has_string_value() {
  _oneof_case_[0] = kStringValue;
}
void Value::clear_string_value() {
  if (has_string_value()) {
    kind_.string_value_.Destroy(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
        GetArenaNoVirtual());
    clear_has_kind();
  }
}
const ::std::string& Value::string_value() const {
  // @@protoc_insertion_point(field_get:google.protobuf.Value.string_value)
  if (has_string_value()) {
    return kind_.string_value_.Get();
  }
  return *&::google::protobuf::internal::GetEmptyStringAlreadyInited();
}
void Value::set_string_value(const ::std::string& value) {
  if (!has_string_value()) {
    clear_kind();
    set_has_string_value();
    kind_.string_value_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  }
  kind_.string_value_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value,
      GetArenaNoVirtual());
  // @@protoc_insertion_point(field_set:google.protobuf.Value.string_value)
}
void Value::set_string_value(const char* value) {
  GOOGLE_DCHECK(value != NULL);
  if (!has_string_value()) {
    clear_kind();
    set_has_string_value();
    kind_.string_value_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  }
  kind_.string_value_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
      ::std::string(value), GetArenaNoVirtual());
  // @@protoc_insertion_point(field_set_char:google.protobuf.Value.string_value)
}
void Value::set_string_value(const char* value,
                             size_t size) {
  if (!has_string_value()) {
    clear_kind();
    set_has_string_value();
    kind_.string_value_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  }
  kind_.string_value_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(
      reinterpret_cast<const char*>(value), size),
      GetArenaNoVirtual());
  // @@protoc_insertion_point(field_set_pointer:google.protobuf.Value.string_value)
}
::std::string* Value::mutable_string_value() {
  if (!has_string_value()) {
    clear_kind();
    set_has_string_value();
    kind_.string_value_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  }
  return kind_.string_value_.Mutable(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
      GetArenaNoVirtual());
  // @@protoc_insertion_point(field_mutable:google.protobuf.Value.string_value)
}
::std::string* Value::release_string_value() {
  // @@protoc_insertion_point(field_release:google.protobuf.Value.string_value)
  if (has_string_value()) {
    clear_has_kind();
    return kind_.string_value_.Release(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
        GetArenaNoVirtual());
  } else {
    return NULL;
  }
}
::std::string* Value::unsafe_arena_release_string_value() {
  // @@protoc_insertion_point(field_unsafe_arena_release:google.protobuf.Value.string_value)
  GOOGLE_DCHECK(GetArenaNoVirtual() != NULL);
  if (has_string_value()) {
    clear_has_kind();
    return kind_.string_value_.UnsafeArenaRelease(
        &::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual());
  } else {
    return NULL;
  }
}
void Value::set_allocated_string_value(::std::string* string_value) {
  if (!has_string_value()) {
    kind_.string_value_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  }
  clear_kind();
  if (string_value != NULL) {
    set_has_string_value();
    kind_.string_value_.SetAllocated(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), string_value,
        GetArenaNoVirtual());
  }
  // @@protoc_insertion_point(field_set_allocated:google.protobuf.Value.string_value)
}
void Value::unsafe_arena_set_allocated_string_value(::std::string* string_value) {
  GOOGLE_DCHECK(GetArenaNoVirtual() != NULL);
  if (!has_string_value()) {
    kind_.string_value_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  }
  clear_kind();
  if (string_value) {
    set_has_string_value();
    kind_.string_value_.UnsafeArenaSetAllocated(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), string_value, GetArenaNoVirtual());
  }
  // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.Value.string_value)
}

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

// .google.protobuf.Struct struct_value = 5;
bool Value::has_struct_value() const {
  return kind_case() == kStructValue;
}
void Value::set_has_struct_value() {
  _oneof_case_[0] = kStructValue;
}
void Value::clear_struct_value() {
  if (has_struct_value()) {
    if (GetArenaNoVirtual() == NULL) {
      delete kind_.struct_value_;
    }
    clear_has_kind();
  }
}
 const ::google::protobuf::Struct& Value::struct_value() const {
  // @@protoc_insertion_point(field_get:google.protobuf.Value.struct_value)
  return has_struct_value()
      ? *kind_.struct_value_
      : ::google::protobuf::Struct::default_instance();
}
::google::protobuf::Struct* Value::mutable_struct_value() {
  if (!has_struct_value()) {
    clear_kind();
    set_has_struct_value();
    kind_.struct_value_ = 
      ::google::protobuf::Arena::CreateMessage< ::google::protobuf::Struct >(
      GetArenaNoVirtual());
  }
  // @@protoc_insertion_point(field_mutable:google.protobuf.Value.struct_value)
  return kind_.struct_value_;
}
::google::protobuf::Struct* Value::release_struct_value() {
  // @@protoc_insertion_point(field_release:google.protobuf.Value.struct_value)
  if (has_struct_value()) {
    clear_has_kind();
    if (GetArenaNoVirtual() != NULL) {
      ::google::protobuf::Struct* temp = new ::google::protobuf::Struct(*kind_.struct_value_);
      kind_.struct_value_ = NULL;
      return temp;
    } else {
      ::google::protobuf::Struct* temp = kind_.struct_value_;
      kind_.struct_value_ = NULL;
      return temp;
    }
  } else {
    return NULL;
  }
}
void Value::set_allocated_struct_value(::google::protobuf::Struct* struct_value) {
  clear_kind();
  if (struct_value) {
    if (GetArenaNoVirtual() != NULL &&
        ::google::protobuf::Arena::GetArena(struct_value) == NULL) {
      GetArenaNoVirtual()->Own(struct_value);
    } else if (GetArenaNoVirtual() !=
               ::google::protobuf::Arena::GetArena(struct_value)) {
      ::google::protobuf::Struct* new_struct_value = 
          ::google::protobuf::Arena::CreateMessage< ::google::protobuf::Struct >(
          GetArenaNoVirtual());
      new_struct_value->CopyFrom(*struct_value);
      struct_value = new_struct_value;
    }
    set_has_struct_value();
    kind_.struct_value_ = struct_value;
  }
  // @@protoc_insertion_point(field_set_allocated:google.protobuf.Value.struct_value)
}
 ::google::protobuf::Struct* Value::unsafe_arena_release_struct_value() {
  // @@protoc_insertion_point(field_unsafe_arena_release:google.protobuf.Value.struct_value)
  if (has_struct_value()) {
    clear_has_kind();
    ::google::protobuf::Struct* temp = kind_.struct_value_;
    kind_.struct_value_ = NULL;
    return temp;
  } else {
    return NULL;
  }
}
 void Value::unsafe_arena_set_allocated_struct_value(::google::protobuf::Struct* struct_value) {
  clear_kind();
  if (struct_value) {
    set_has_struct_value();
    kind_.struct_value_ = struct_value;
  }
  // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.Value.struct_value)
}

// .google.protobuf.ListValue list_value = 6;
bool Value::has_list_value() const {
  return kind_case() == kListValue;
}
void Value::set_has_list_value() {
  _oneof_case_[0] = kListValue;
}
void Value::clear_list_value() {
  if (has_list_value()) {
    if (GetArenaNoVirtual() == NULL) {
      delete kind_.list_value_;
    }
    clear_has_kind();
  }
}
 const ::google::protobuf::ListValue& Value::list_value() const {
  // @@protoc_insertion_point(field_get:google.protobuf.Value.list_value)
  return has_list_value()
      ? *kind_.list_value_
      : ::google::protobuf::ListValue::default_instance();
}
::google::protobuf::ListValue* Value::mutable_list_value() {
  if (!has_list_value()) {
    clear_kind();
    set_has_list_value();
    kind_.list_value_ = 
      ::google::protobuf::Arena::CreateMessage< ::google::protobuf::ListValue >(
      GetArenaNoVirtual());
  }
  // @@protoc_insertion_point(field_mutable:google.protobuf.Value.list_value)
  return kind_.list_value_;
}
::google::protobuf::ListValue* Value::release_list_value() {
  // @@protoc_insertion_point(field_release:google.protobuf.Value.list_value)
  if (has_list_value()) {
    clear_has_kind();
    if (GetArenaNoVirtual() != NULL) {
      ::google::protobuf::ListValue* temp = new ::google::protobuf::ListValue(*kind_.list_value_);
      kind_.list_value_ = NULL;
      return temp;
    } else {
      ::google::protobuf::ListValue* temp = kind_.list_value_;
      kind_.list_value_ = NULL;
      return temp;
    }
  } else {
    return NULL;
  }
}
void Value::set_allocated_list_value(::google::protobuf::ListValue* list_value) {
  clear_kind();
  if (list_value) {
    if (GetArenaNoVirtual() != NULL &&
        ::google::protobuf::Arena::GetArena(list_value) == NULL) {
      GetArenaNoVirtual()->Own(list_value);
    } else if (GetArenaNoVirtual() !=
               ::google::protobuf::Arena::GetArena(list_value)) {
      ::google::protobuf::ListValue* new_list_value = 
          ::google::protobuf::Arena::CreateMessage< ::google::protobuf::ListValue >(
          GetArenaNoVirtual());
      new_list_value->CopyFrom(*list_value);
      list_value = new_list_value;
    }
    set_has_list_value();
    kind_.list_value_ = list_value;
  }
  // @@protoc_insertion_point(field_set_allocated:google.protobuf.Value.list_value)
}
 ::google::protobuf::ListValue* Value::unsafe_arena_release_list_value() {
  // @@protoc_insertion_point(field_unsafe_arena_release:google.protobuf.Value.list_value)
  if (has_list_value()) {
    clear_has_kind();
    ::google::protobuf::ListValue* temp = kind_.list_value_;
    kind_.list_value_ = NULL;
    return temp;
  } else {
    return NULL;
  }
}
 void Value::unsafe_arena_set_allocated_list_value(::google::protobuf::ListValue* list_value) {
  clear_kind();
  if (list_value) {
    set_has_list_value();
    kind_.list_value_ = list_value;
  }
  // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.Value.list_value)
}

bool Value::has_kind() const {
  return kind_case() != KIND_NOT_SET;
}
void Value::clear_has_kind() {
  _oneof_case_[0] = KIND_NOT_SET;
}
Value::KindCase Value::kind_case() const {
  return Value::KindCase(_oneof_case_[0]);
}
#endif  // PROTOBUF_INLINE_NOT_IN_HEADERS

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

#if !defined(_MSC_VER) || _MSC_VER >= 1900
const int ListValue::kValuesFieldNumber;
#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900

ListValue::ListValue()
  : ::google::protobuf::Message(), _internal_metadata_(NULL) {
  if (GOOGLE_PREDICT_TRUE(this != internal_default_instance())) {
    protobuf_google_2fprotobuf_2fstruct_2eproto::InitDefaults();
  }
  SharedCtor();
  // @@protoc_insertion_point(constructor:google.protobuf.ListValue)
}
ListValue::ListValue(::google::protobuf::Arena* arena)
  : ::google::protobuf::Message(),
  _internal_metadata_(arena),
  values_(arena) {
#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
  protobuf_google_2fprotobuf_2fstruct_2eproto::InitDefaults();
#endif  // GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
  SharedCtor();
  RegisterArenaDtor(arena);
  // @@protoc_insertion_point(arena_constructor:google.protobuf.ListValue)
}
ListValue::ListValue(const ListValue& from)
  : ::google::protobuf::Message(),
      _internal_metadata_(NULL),
      values_(from.values_),
      _cached_size_(0) {
  _internal_metadata_.MergeFrom(from._internal_metadata_);
  // @@protoc_insertion_point(copy_constructor:google.protobuf.ListValue)
}

void ListValue::SharedCtor() {
  _cached_size_ = 0;
}

ListValue::~ListValue() {
  // @@protoc_insertion_point(destructor:google.protobuf.ListValue)
  SharedDtor();
}

void ListValue::SharedDtor() {
  ::google::protobuf::Arena* arena = GetArenaNoVirtual();
  if (arena != NULL) {
    return;
  }

}

void ListValue::ArenaDtor(void* object) {
  ListValue* _this = reinterpret_cast< ListValue* >(object);
  (void)_this;
}
void ListValue::RegisterArenaDtor(::google::protobuf::Arena* arena) {
}
void ListValue::SetCachedSize(int size) const {
  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
  _cached_size_ = size;
  GOOGLE_SAFE_CONCURRENT_WRITES_END();
}
const ::google::protobuf::Descriptor* ListValue::descriptor() {
  protobuf_google_2fprotobuf_2fstruct_2eproto::protobuf_AssignDescriptorsOnce();
  return protobuf_google_2fprotobuf_2fstruct_2eproto::file_level_metadata[kIndexInFileMessages].descriptor;
}

const ListValue& ListValue::default_instance() {
  protobuf_google_2fprotobuf_2fstruct_2eproto::InitDefaults();
  return *internal_default_instance();
}

ListValue* ListValue::New(::google::protobuf::Arena* arena) const {
  return ::google::protobuf::Arena::CreateMessage<ListValue>(arena);
}

void ListValue::Clear() {
// @@protoc_insertion_point(message_clear_start:google.protobuf.ListValue)
  values_.Clear();
}

bool ListValue::MergePartialFromCodedStream(
    ::google::protobuf::io::CodedInputStream* input) {
#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure
  ::google::protobuf::uint32 tag;
  // @@protoc_insertion_point(parse_start:google.protobuf.ListValue)
  for (;;) {
    ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u);
    tag = p.first;
    if (!p.second) goto handle_unusual;
    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
      // repeated .google.protobuf.Value values = 1;
      case 1: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(10u)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
                input, add_values()));
        } else {
          goto handle_unusual;
        }
        break;
      }

      default: {
      handle_unusual:
        if (tag == 0 ||
            ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
            ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
          goto success;
        }
        DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag));
        break;
      }
    }
  }
success:
  // @@protoc_insertion_point(parse_success:google.protobuf.ListValue)
  return true;
failure:
  // @@protoc_insertion_point(parse_failure:google.protobuf.ListValue)
  return false;
#undef DO_
}

void ListValue::SerializeWithCachedSizes(
    ::google::protobuf::io::CodedOutputStream* output) const {
  // @@protoc_insertion_point(serialize_start:google.protobuf.ListValue)
  ::google::protobuf::uint32 cached_has_bits = 0;
  (void) cached_has_bits;

  // repeated .google.protobuf.Value values = 1;
  for (unsigned int i = 0, n = this->values_size(); i < n; i++) {
    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
      1, this->values(i), output);
  }

  // @@protoc_insertion_point(serialize_end:google.protobuf.ListValue)
}

::google::protobuf::uint8* ListValue::InternalSerializeWithCachedSizesToArray(
    bool deterministic, ::google::protobuf::uint8* target) const {
  // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.ListValue)
  ::google::protobuf::uint32 cached_has_bits = 0;
  (void) cached_has_bits;

  // repeated .google.protobuf.Value values = 1;
  for (unsigned int i = 0, n = this->values_size(); i < n; i++) {
    target = ::google::protobuf::internal::WireFormatLite::
      InternalWriteMessageNoVirtualToArray(
        1, this->values(i), deterministic, target);
  }

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

  // repeated .google.protobuf.Value values = 1;
  {
    unsigned int count = this->values_size();
    total_size += 1UL * count;
    for (unsigned int i = 0; i < count; i++) {
      total_size +=
        ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
          this->values(i));
    }
  }

  int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
  _cached_size_ = cached_size;
  GOOGLE_SAFE_CONCURRENT_WRITES_END();
  return total_size;
}

void ListValue::MergeFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.ListValue)
  GOOGLE_DCHECK_NE(&from, this);
  const ListValue* source =
      ::google::protobuf::internal::DynamicCastToGenerated<const ListValue>(
          &from);
  if (source == NULL) {
  // @@protoc_insertion_point(generalized_merge_from_cast_fail:google.protobuf.ListValue)
    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
  } else {
  // @@protoc_insertion_point(generalized_merge_from_cast_success:google.protobuf.ListValue)
    MergeFrom(*source);
  }
}

void ListValue::MergeFrom(const ListValue& from) {
// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.ListValue)
  GOOGLE_DCHECK_NE(&from, this);
  _internal_metadata_.MergeFrom(from._internal_metadata_);
  ::google::protobuf::uint32 cached_has_bits = 0;
  (void) cached_has_bits;

  values_.MergeFrom(from.values_);
}

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

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::Swap(ListValue* other) {
  if (other == this) return;
  if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) {
    InternalSwap(other);
  } else {
    ListValue* temp = New(GetArenaNoVirtual());
    temp->MergeFrom(*other);
    other->CopyFrom(*this);
    InternalSwap(temp);
    if (GetArenaNoVirtual() == NULL) {
      delete temp;
    }
  }
}
void ListValue::UnsafeArenaSwap(ListValue* other) {
  if (other == this) return;
  GOOGLE_DCHECK(GetArenaNoVirtual() == other->GetArenaNoVirtual());
  InternalSwap(other);
}
void ListValue::InternalSwap(ListValue* other) {
  values_.InternalSwap(&other->values_);
  std::swap(_cached_size_, other->_cached_size_);
}

::google::protobuf::Metadata ListValue::GetMetadata() const {
  protobuf_google_2fprotobuf_2fstruct_2eproto::protobuf_AssignDescriptorsOnce();
  return protobuf_google_2fprotobuf_2fstruct_2eproto::file_level_metadata[kIndexInFileMessages];
}

#if PROTOBUF_INLINE_NOT_IN_HEADERS
// ListValue

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

#endif  // PROTOBUF_INLINE_NOT_IN_HEADERS

// @@protoc_insertion_point(namespace_scope)

}  // namespace protobuf
}  // namespace google

// @@protoc_insertion_point(global_scope)
