// Generated by the protocol buffer compiler.  DO NOT EDIT!
// source: UserBitShared.proto

#include "UserBitShared.pb.h"

#include <algorithm>

#include <google/protobuf/stubs/common.h>
#include <google/protobuf/stubs/port.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>
// This is a temporary google only hack
#ifdef GOOGLE_PROTOBUF_ENFORCE_UNIQUENESS
#include "third_party/protobuf/version.h"
#endif
// @@protoc_insertion_point(includes)

namespace protobuf_Coordination_2eproto {
extern PROTOBUF_INTERNAL_EXPORT_protobuf_Coordination_2eproto ::google::protobuf::internal::SCCInfo<1> scc_info_DrillbitEndpoint;
}  // namespace protobuf_Coordination_2eproto
namespace protobuf_Types_2eproto {
extern PROTOBUF_INTERNAL_EXPORT_protobuf_Types_2eproto ::google::protobuf::internal::SCCInfo<0> scc_info_MajorType;
}  // namespace protobuf_Types_2eproto
namespace protobuf_UserBitShared_2eproto {
extern PROTOBUF_INTERNAL_EXPORT_protobuf_UserBitShared_2eproto ::google::protobuf::internal::SCCInfo<0> scc_info_Jar;
extern PROTOBUF_INTERNAL_EXPORT_protobuf_UserBitShared_2eproto ::google::protobuf::internal::SCCInfo<0> scc_info_MetricValue;
extern PROTOBUF_INTERNAL_EXPORT_protobuf_UserBitShared_2eproto ::google::protobuf::internal::SCCInfo<0> scc_info_NamePart;
extern PROTOBUF_INTERNAL_EXPORT_protobuf_UserBitShared_2eproto ::google::protobuf::internal::SCCInfo<0> scc_info_ParsingError;
extern PROTOBUF_INTERNAL_EXPORT_protobuf_UserBitShared_2eproto ::google::protobuf::internal::SCCInfo<0> scc_info_QueryId;
extern PROTOBUF_INTERNAL_EXPORT_protobuf_UserBitShared_2eproto ::google::protobuf::internal::SCCInfo<0> scc_info_StackTraceElementWrapper;
extern PROTOBUF_INTERNAL_EXPORT_protobuf_UserBitShared_2eproto ::google::protobuf::internal::SCCInfo<0> scc_info_StreamProfile;
extern PROTOBUF_INTERNAL_EXPORT_protobuf_UserBitShared_2eproto ::google::protobuf::internal::SCCInfo<1> scc_info_ExceptionWrapper;
extern PROTOBUF_INTERNAL_EXPORT_protobuf_UserBitShared_2eproto ::google::protobuf::internal::SCCInfo<1> scc_info_MajorFragmentProfile;
extern PROTOBUF_INTERNAL_EXPORT_protobuf_UserBitShared_2eproto ::google::protobuf::internal::SCCInfo<1> scc_info_RecordBatchDef;
extern PROTOBUF_INTERNAL_EXPORT_protobuf_UserBitShared_2eproto ::google::protobuf::internal::SCCInfo<2> scc_info_OperatorProfile;
extern PROTOBUF_INTERNAL_EXPORT_protobuf_UserBitShared_2eproto ::google::protobuf::internal::SCCInfo<2> scc_info_SerializedField;
extern PROTOBUF_INTERNAL_EXPORT_protobuf_UserBitShared_2eproto ::google::protobuf::internal::SCCInfo<3> scc_info_DrillPBError;
extern PROTOBUF_INTERNAL_EXPORT_protobuf_UserBitShared_2eproto ::google::protobuf::internal::SCCInfo<3> scc_info_MinorFragmentProfile;
}  // namespace protobuf_UserBitShared_2eproto
namespace exec {
namespace shared {
class UserCredentialsDefaultTypeInternal {
 public:
  ::google::protobuf::internal::ExplicitlyConstructed<UserCredentials>
      _instance;
} _UserCredentials_default_instance_;
class QueryIdDefaultTypeInternal {
 public:
  ::google::protobuf::internal::ExplicitlyConstructed<QueryId>
      _instance;
} _QueryId_default_instance_;
class DrillPBErrorDefaultTypeInternal {
 public:
  ::google::protobuf::internal::ExplicitlyConstructed<DrillPBError>
      _instance;
} _DrillPBError_default_instance_;
class ExceptionWrapperDefaultTypeInternal {
 public:
  ::google::protobuf::internal::ExplicitlyConstructed<ExceptionWrapper>
      _instance;
} _ExceptionWrapper_default_instance_;
class StackTraceElementWrapperDefaultTypeInternal {
 public:
  ::google::protobuf::internal::ExplicitlyConstructed<StackTraceElementWrapper>
      _instance;
} _StackTraceElementWrapper_default_instance_;
class ParsingErrorDefaultTypeInternal {
 public:
  ::google::protobuf::internal::ExplicitlyConstructed<ParsingError>
      _instance;
} _ParsingError_default_instance_;
class RecordBatchDefDefaultTypeInternal {
 public:
  ::google::protobuf::internal::ExplicitlyConstructed<RecordBatchDef>
      _instance;
} _RecordBatchDef_default_instance_;
class NamePartDefaultTypeInternal {
 public:
  ::google::protobuf::internal::ExplicitlyConstructed<NamePart>
      _instance;
} _NamePart_default_instance_;
class SerializedFieldDefaultTypeInternal {
 public:
  ::google::protobuf::internal::ExplicitlyConstructed<SerializedField>
      _instance;
} _SerializedField_default_instance_;
class NodeStatusDefaultTypeInternal {
 public:
  ::google::protobuf::internal::ExplicitlyConstructed<NodeStatus>
      _instance;
} _NodeStatus_default_instance_;
class QueryResultDefaultTypeInternal {
 public:
  ::google::protobuf::internal::ExplicitlyConstructed<QueryResult>
      _instance;
} _QueryResult_default_instance_;
class QueryDataDefaultTypeInternal {
 public:
  ::google::protobuf::internal::ExplicitlyConstructed<QueryData>
      _instance;
} _QueryData_default_instance_;
class QueryInfoDefaultTypeInternal {
 public:
  ::google::protobuf::internal::ExplicitlyConstructed<QueryInfo>
      _instance;
} _QueryInfo_default_instance_;
class QueryProfileDefaultTypeInternal {
 public:
  ::google::protobuf::internal::ExplicitlyConstructed<QueryProfile>
      _instance;
} _QueryProfile_default_instance_;
class MajorFragmentProfileDefaultTypeInternal {
 public:
  ::google::protobuf::internal::ExplicitlyConstructed<MajorFragmentProfile>
      _instance;
} _MajorFragmentProfile_default_instance_;
class MinorFragmentProfileDefaultTypeInternal {
 public:
  ::google::protobuf::internal::ExplicitlyConstructed<MinorFragmentProfile>
      _instance;
} _MinorFragmentProfile_default_instance_;
class OperatorProfileDefaultTypeInternal {
 public:
  ::google::protobuf::internal::ExplicitlyConstructed<OperatorProfile>
      _instance;
} _OperatorProfile_default_instance_;
class StreamProfileDefaultTypeInternal {
 public:
  ::google::protobuf::internal::ExplicitlyConstructed<StreamProfile>
      _instance;
} _StreamProfile_default_instance_;
class MetricValueDefaultTypeInternal {
 public:
  ::google::protobuf::internal::ExplicitlyConstructed<MetricValue>
      _instance;
} _MetricValue_default_instance_;
class RegistryDefaultTypeInternal {
 public:
  ::google::protobuf::internal::ExplicitlyConstructed<Registry>
      _instance;
} _Registry_default_instance_;
class JarDefaultTypeInternal {
 public:
  ::google::protobuf::internal::ExplicitlyConstructed<Jar>
      _instance;
} _Jar_default_instance_;
class SaslMessageDefaultTypeInternal {
 public:
  ::google::protobuf::internal::ExplicitlyConstructed<SaslMessage>
      _instance;
} _SaslMessage_default_instance_;
}  // namespace shared
}  // namespace exec
namespace protobuf_UserBitShared_2eproto {
static void InitDefaultsUserCredentials() {
  GOOGLE_PROTOBUF_VERIFY_VERSION;

  {
    void* ptr = &::exec::shared::_UserCredentials_default_instance_;
    new (ptr) ::exec::shared::UserCredentials();
    ::google::protobuf::internal::OnShutdownDestroyMessage(ptr);
  }
  ::exec::shared::UserCredentials::InitAsDefaultInstance();
}

::google::protobuf::internal::SCCInfo<0> scc_info_UserCredentials =
    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 0, InitDefaultsUserCredentials}, {}};

static void InitDefaultsQueryId() {
  GOOGLE_PROTOBUF_VERIFY_VERSION;

  {
    void* ptr = &::exec::shared::_QueryId_default_instance_;
    new (ptr) ::exec::shared::QueryId();
    ::google::protobuf::internal::OnShutdownDestroyMessage(ptr);
  }
  ::exec::shared::QueryId::InitAsDefaultInstance();
}

::google::protobuf::internal::SCCInfo<0> scc_info_QueryId =
    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 0, InitDefaultsQueryId}, {}};

static void InitDefaultsDrillPBError() {
  GOOGLE_PROTOBUF_VERIFY_VERSION;

  {
    void* ptr = &::exec::shared::_DrillPBError_default_instance_;
    new (ptr) ::exec::shared::DrillPBError();
    ::google::protobuf::internal::OnShutdownDestroyMessage(ptr);
  }
  ::exec::shared::DrillPBError::InitAsDefaultInstance();
}

::google::protobuf::internal::SCCInfo<3> scc_info_DrillPBError =
    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 3, InitDefaultsDrillPBError}, {
      &protobuf_Coordination_2eproto::scc_info_DrillbitEndpoint.base,
      &protobuf_UserBitShared_2eproto::scc_info_ExceptionWrapper.base,
      &protobuf_UserBitShared_2eproto::scc_info_ParsingError.base,}};

static void InitDefaultsExceptionWrapper() {
  GOOGLE_PROTOBUF_VERIFY_VERSION;

  {
    void* ptr = &::exec::shared::_ExceptionWrapper_default_instance_;
    new (ptr) ::exec::shared::ExceptionWrapper();
    ::google::protobuf::internal::OnShutdownDestroyMessage(ptr);
  }
  ::exec::shared::ExceptionWrapper::InitAsDefaultInstance();
}

::google::protobuf::internal::SCCInfo<1> scc_info_ExceptionWrapper =
    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 1, InitDefaultsExceptionWrapper}, {
      &protobuf_UserBitShared_2eproto::scc_info_StackTraceElementWrapper.base,}};

static void InitDefaultsStackTraceElementWrapper() {
  GOOGLE_PROTOBUF_VERIFY_VERSION;

  {
    void* ptr = &::exec::shared::_StackTraceElementWrapper_default_instance_;
    new (ptr) ::exec::shared::StackTraceElementWrapper();
    ::google::protobuf::internal::OnShutdownDestroyMessage(ptr);
  }
  ::exec::shared::StackTraceElementWrapper::InitAsDefaultInstance();
}

::google::protobuf::internal::SCCInfo<0> scc_info_StackTraceElementWrapper =
    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 0, InitDefaultsStackTraceElementWrapper}, {}};

static void InitDefaultsParsingError() {
  GOOGLE_PROTOBUF_VERIFY_VERSION;

  {
    void* ptr = &::exec::shared::_ParsingError_default_instance_;
    new (ptr) ::exec::shared::ParsingError();
    ::google::protobuf::internal::OnShutdownDestroyMessage(ptr);
  }
  ::exec::shared::ParsingError::InitAsDefaultInstance();
}

::google::protobuf::internal::SCCInfo<0> scc_info_ParsingError =
    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 0, InitDefaultsParsingError}, {}};

static void InitDefaultsRecordBatchDef() {
  GOOGLE_PROTOBUF_VERIFY_VERSION;

  {
    void* ptr = &::exec::shared::_RecordBatchDef_default_instance_;
    new (ptr) ::exec::shared::RecordBatchDef();
    ::google::protobuf::internal::OnShutdownDestroyMessage(ptr);
  }
  ::exec::shared::RecordBatchDef::InitAsDefaultInstance();
}

::google::protobuf::internal::SCCInfo<1> scc_info_RecordBatchDef =
    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 1, InitDefaultsRecordBatchDef}, {
      &protobuf_UserBitShared_2eproto::scc_info_SerializedField.base,}};

static void InitDefaultsNamePart() {
  GOOGLE_PROTOBUF_VERIFY_VERSION;

  {
    void* ptr = &::exec::shared::_NamePart_default_instance_;
    new (ptr) ::exec::shared::NamePart();
    ::google::protobuf::internal::OnShutdownDestroyMessage(ptr);
  }
  ::exec::shared::NamePart::InitAsDefaultInstance();
}

::google::protobuf::internal::SCCInfo<0> scc_info_NamePart =
    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 0, InitDefaultsNamePart}, {}};

static void InitDefaultsSerializedField() {
  GOOGLE_PROTOBUF_VERIFY_VERSION;

  {
    void* ptr = &::exec::shared::_SerializedField_default_instance_;
    new (ptr) ::exec::shared::SerializedField();
    ::google::protobuf::internal::OnShutdownDestroyMessage(ptr);
  }
  ::exec::shared::SerializedField::InitAsDefaultInstance();
}

::google::protobuf::internal::SCCInfo<2> scc_info_SerializedField =
    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 2, InitDefaultsSerializedField}, {
      &protobuf_Types_2eproto::scc_info_MajorType.base,
      &protobuf_UserBitShared_2eproto::scc_info_NamePart.base,}};

static void InitDefaultsNodeStatus() {
  GOOGLE_PROTOBUF_VERIFY_VERSION;

  {
    void* ptr = &::exec::shared::_NodeStatus_default_instance_;
    new (ptr) ::exec::shared::NodeStatus();
    ::google::protobuf::internal::OnShutdownDestroyMessage(ptr);
  }
  ::exec::shared::NodeStatus::InitAsDefaultInstance();
}

::google::protobuf::internal::SCCInfo<0> scc_info_NodeStatus =
    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 0, InitDefaultsNodeStatus}, {}};

static void InitDefaultsQueryResult() {
  GOOGLE_PROTOBUF_VERIFY_VERSION;

  {
    void* ptr = &::exec::shared::_QueryResult_default_instance_;
    new (ptr) ::exec::shared::QueryResult();
    ::google::protobuf::internal::OnShutdownDestroyMessage(ptr);
  }
  ::exec::shared::QueryResult::InitAsDefaultInstance();
}

::google::protobuf::internal::SCCInfo<2> scc_info_QueryResult =
    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 2, InitDefaultsQueryResult}, {
      &protobuf_UserBitShared_2eproto::scc_info_QueryId.base,
      &protobuf_UserBitShared_2eproto::scc_info_DrillPBError.base,}};

static void InitDefaultsQueryData() {
  GOOGLE_PROTOBUF_VERIFY_VERSION;

  {
    void* ptr = &::exec::shared::_QueryData_default_instance_;
    new (ptr) ::exec::shared::QueryData();
    ::google::protobuf::internal::OnShutdownDestroyMessage(ptr);
  }
  ::exec::shared::QueryData::InitAsDefaultInstance();
}

::google::protobuf::internal::SCCInfo<2> scc_info_QueryData =
    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 2, InitDefaultsQueryData}, {
      &protobuf_UserBitShared_2eproto::scc_info_QueryId.base,
      &protobuf_UserBitShared_2eproto::scc_info_RecordBatchDef.base,}};

static void InitDefaultsQueryInfo() {
  GOOGLE_PROTOBUF_VERIFY_VERSION;

  ::exec::shared::QueryInfo::_i_give_permission_to_break_this_code_default_user_.DefaultConstruct();
  *::exec::shared::QueryInfo::_i_give_permission_to_break_this_code_default_user_.get_mutable() = ::std::string("-", 1);
  ::google::protobuf::internal::OnShutdownDestroyString(
      ::exec::shared::QueryInfo::_i_give_permission_to_break_this_code_default_user_.get_mutable());
  ::exec::shared::QueryInfo::_i_give_permission_to_break_this_code_default_queue_name_.DefaultConstruct();
  *::exec::shared::QueryInfo::_i_give_permission_to_break_this_code_default_queue_name_.get_mutable() = ::std::string("-", 1);
  ::google::protobuf::internal::OnShutdownDestroyString(
      ::exec::shared::QueryInfo::_i_give_permission_to_break_this_code_default_queue_name_.get_mutable());
  {
    void* ptr = &::exec::shared::_QueryInfo_default_instance_;
    new (ptr) ::exec::shared::QueryInfo();
    ::google::protobuf::internal::OnShutdownDestroyMessage(ptr);
  }
  ::exec::shared::QueryInfo::InitAsDefaultInstance();
}

::google::protobuf::internal::SCCInfo<1> scc_info_QueryInfo =
    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 1, InitDefaultsQueryInfo}, {
      &protobuf_Coordination_2eproto::scc_info_DrillbitEndpoint.base,}};

static void InitDefaultsQueryProfile() {
  GOOGLE_PROTOBUF_VERIFY_VERSION;

  ::exec::shared::QueryProfile::_i_give_permission_to_break_this_code_default_user_.DefaultConstruct();
  *::exec::shared::QueryProfile::_i_give_permission_to_break_this_code_default_user_.get_mutable() = ::std::string("-", 1);
  ::google::protobuf::internal::OnShutdownDestroyString(
      ::exec::shared::QueryProfile::_i_give_permission_to_break_this_code_default_user_.get_mutable());
  ::exec::shared::QueryProfile::_i_give_permission_to_break_this_code_default_queue_name_.DefaultConstruct();
  *::exec::shared::QueryProfile::_i_give_permission_to_break_this_code_default_queue_name_.get_mutable() = ::std::string("-", 1);
  ::google::protobuf::internal::OnShutdownDestroyString(
      ::exec::shared::QueryProfile::_i_give_permission_to_break_this_code_default_queue_name_.get_mutable());
  {
    void* ptr = &::exec::shared::_QueryProfile_default_instance_;
    new (ptr) ::exec::shared::QueryProfile();
    ::google::protobuf::internal::OnShutdownDestroyMessage(ptr);
  }
  ::exec::shared::QueryProfile::InitAsDefaultInstance();
}

::google::protobuf::internal::SCCInfo<3> scc_info_QueryProfile =
    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 3, InitDefaultsQueryProfile}, {
      &protobuf_UserBitShared_2eproto::scc_info_QueryId.base,
      &protobuf_Coordination_2eproto::scc_info_DrillbitEndpoint.base,
      &protobuf_UserBitShared_2eproto::scc_info_MajorFragmentProfile.base,}};

static void InitDefaultsMajorFragmentProfile() {
  GOOGLE_PROTOBUF_VERIFY_VERSION;

  {
    void* ptr = &::exec::shared::_MajorFragmentProfile_default_instance_;
    new (ptr) ::exec::shared::MajorFragmentProfile();
    ::google::protobuf::internal::OnShutdownDestroyMessage(ptr);
  }
  ::exec::shared::MajorFragmentProfile::InitAsDefaultInstance();
}

::google::protobuf::internal::SCCInfo<1> scc_info_MajorFragmentProfile =
    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 1, InitDefaultsMajorFragmentProfile}, {
      &protobuf_UserBitShared_2eproto::scc_info_MinorFragmentProfile.base,}};

static void InitDefaultsMinorFragmentProfile() {
  GOOGLE_PROTOBUF_VERIFY_VERSION;

  {
    void* ptr = &::exec::shared::_MinorFragmentProfile_default_instance_;
    new (ptr) ::exec::shared::MinorFragmentProfile();
    ::google::protobuf::internal::OnShutdownDestroyMessage(ptr);
  }
  ::exec::shared::MinorFragmentProfile::InitAsDefaultInstance();
}

::google::protobuf::internal::SCCInfo<3> scc_info_MinorFragmentProfile =
    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 3, InitDefaultsMinorFragmentProfile}, {
      &protobuf_UserBitShared_2eproto::scc_info_DrillPBError.base,
      &protobuf_UserBitShared_2eproto::scc_info_OperatorProfile.base,
      &protobuf_Coordination_2eproto::scc_info_DrillbitEndpoint.base,}};

static void InitDefaultsOperatorProfile() {
  GOOGLE_PROTOBUF_VERIFY_VERSION;

  {
    void* ptr = &::exec::shared::_OperatorProfile_default_instance_;
    new (ptr) ::exec::shared::OperatorProfile();
    ::google::protobuf::internal::OnShutdownDestroyMessage(ptr);
  }
  ::exec::shared::OperatorProfile::InitAsDefaultInstance();
}

::google::protobuf::internal::SCCInfo<2> scc_info_OperatorProfile =
    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 2, InitDefaultsOperatorProfile}, {
      &protobuf_UserBitShared_2eproto::scc_info_StreamProfile.base,
      &protobuf_UserBitShared_2eproto::scc_info_MetricValue.base,}};

static void InitDefaultsStreamProfile() {
  GOOGLE_PROTOBUF_VERIFY_VERSION;

  {
    void* ptr = &::exec::shared::_StreamProfile_default_instance_;
    new (ptr) ::exec::shared::StreamProfile();
    ::google::protobuf::internal::OnShutdownDestroyMessage(ptr);
  }
  ::exec::shared::StreamProfile::InitAsDefaultInstance();
}

::google::protobuf::internal::SCCInfo<0> scc_info_StreamProfile =
    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 0, InitDefaultsStreamProfile}, {}};

static void InitDefaultsMetricValue() {
  GOOGLE_PROTOBUF_VERIFY_VERSION;

  {
    void* ptr = &::exec::shared::_MetricValue_default_instance_;
    new (ptr) ::exec::shared::MetricValue();
    ::google::protobuf::internal::OnShutdownDestroyMessage(ptr);
  }
  ::exec::shared::MetricValue::InitAsDefaultInstance();
}

::google::protobuf::internal::SCCInfo<0> scc_info_MetricValue =
    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 0, InitDefaultsMetricValue}, {}};

static void InitDefaultsRegistry() {
  GOOGLE_PROTOBUF_VERIFY_VERSION;

  {
    void* ptr = &::exec::shared::_Registry_default_instance_;
    new (ptr) ::exec::shared::Registry();
    ::google::protobuf::internal::OnShutdownDestroyMessage(ptr);
  }
  ::exec::shared::Registry::InitAsDefaultInstance();
}

::google::protobuf::internal::SCCInfo<1> scc_info_Registry =
    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 1, InitDefaultsRegistry}, {
      &protobuf_UserBitShared_2eproto::scc_info_Jar.base,}};

static void InitDefaultsJar() {
  GOOGLE_PROTOBUF_VERIFY_VERSION;

  {
    void* ptr = &::exec::shared::_Jar_default_instance_;
    new (ptr) ::exec::shared::Jar();
    ::google::protobuf::internal::OnShutdownDestroyMessage(ptr);
  }
  ::exec::shared::Jar::InitAsDefaultInstance();
}

::google::protobuf::internal::SCCInfo<0> scc_info_Jar =
    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 0, InitDefaultsJar}, {}};

static void InitDefaultsSaslMessage() {
  GOOGLE_PROTOBUF_VERIFY_VERSION;

  {
    void* ptr = &::exec::shared::_SaslMessage_default_instance_;
    new (ptr) ::exec::shared::SaslMessage();
    ::google::protobuf::internal::OnShutdownDestroyMessage(ptr);
  }
  ::exec::shared::SaslMessage::InitAsDefaultInstance();
}

::google::protobuf::internal::SCCInfo<0> scc_info_SaslMessage =
    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 0, InitDefaultsSaslMessage}, {}};

void InitDefaults() {
  ::google::protobuf::internal::InitSCC(&scc_info_UserCredentials.base);
  ::google::protobuf::internal::InitSCC(&scc_info_QueryId.base);
  ::google::protobuf::internal::InitSCC(&scc_info_DrillPBError.base);
  ::google::protobuf::internal::InitSCC(&scc_info_ExceptionWrapper.base);
  ::google::protobuf::internal::InitSCC(&scc_info_StackTraceElementWrapper.base);
  ::google::protobuf::internal::InitSCC(&scc_info_ParsingError.base);
  ::google::protobuf::internal::InitSCC(&scc_info_RecordBatchDef.base);
  ::google::protobuf::internal::InitSCC(&scc_info_NamePart.base);
  ::google::protobuf::internal::InitSCC(&scc_info_SerializedField.base);
  ::google::protobuf::internal::InitSCC(&scc_info_NodeStatus.base);
  ::google::protobuf::internal::InitSCC(&scc_info_QueryResult.base);
  ::google::protobuf::internal::InitSCC(&scc_info_QueryData.base);
  ::google::protobuf::internal::InitSCC(&scc_info_QueryInfo.base);
  ::google::protobuf::internal::InitSCC(&scc_info_QueryProfile.base);
  ::google::protobuf::internal::InitSCC(&scc_info_MajorFragmentProfile.base);
  ::google::protobuf::internal::InitSCC(&scc_info_MinorFragmentProfile.base);
  ::google::protobuf::internal::InitSCC(&scc_info_OperatorProfile.base);
  ::google::protobuf::internal::InitSCC(&scc_info_StreamProfile.base);
  ::google::protobuf::internal::InitSCC(&scc_info_MetricValue.base);
  ::google::protobuf::internal::InitSCC(&scc_info_Registry.base);
  ::google::protobuf::internal::InitSCC(&scc_info_Jar.base);
  ::google::protobuf::internal::InitSCC(&scc_info_SaslMessage.base);
}

::google::protobuf::Metadata file_level_metadata[22];
const ::google::protobuf::EnumDescriptor* file_level_enum_descriptors[8];

const ::google::protobuf::uint32 TableStruct::offsets[] GOOGLE_PROTOBUF_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = {
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::exec::shared::UserCredentials, _has_bits_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::exec::shared::UserCredentials, _internal_metadata_),
  ~0u,  // no _extensions_
  ~0u,  // no _oneof_case_
  ~0u,  // no _weak_field_map_
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::exec::shared::UserCredentials, user_name_),
  0,
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::exec::shared::QueryId, _has_bits_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::exec::shared::QueryId, _internal_metadata_),
  ~0u,  // no _extensions_
  ~0u,  // no _oneof_case_
  ~0u,  // no _weak_field_map_
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::exec::shared::QueryId, part1_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::exec::shared::QueryId, part2_),
  0,
  1,
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::exec::shared::DrillPBError, _has_bits_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::exec::shared::DrillPBError, _internal_metadata_),
  ~0u,  // no _extensions_
  ~0u,  // no _oneof_case_
  ~0u,  // no _weak_field_map_
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::exec::shared::DrillPBError, error_id_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::exec::shared::DrillPBError, endpoint_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::exec::shared::DrillPBError, error_type_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::exec::shared::DrillPBError, message_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::exec::shared::DrillPBError, exception_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::exec::shared::DrillPBError, parsing_error_),
  0,
  2,
  4,
  1,
  3,
  ~0u,
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::exec::shared::ExceptionWrapper, _has_bits_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::exec::shared::ExceptionWrapper, _internal_metadata_),
  ~0u,  // no _extensions_
  ~0u,  // no _oneof_case_
  ~0u,  // no _weak_field_map_
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::exec::shared::ExceptionWrapper, exception_class_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::exec::shared::ExceptionWrapper, message_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::exec::shared::ExceptionWrapper, stack_trace_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::exec::shared::ExceptionWrapper, cause_),
  0,
  1,
  ~0u,
  2,
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::exec::shared::StackTraceElementWrapper, _has_bits_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::exec::shared::StackTraceElementWrapper, _internal_metadata_),
  ~0u,  // no _extensions_
  ~0u,  // no _oneof_case_
  ~0u,  // no _weak_field_map_
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::exec::shared::StackTraceElementWrapper, class_name_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::exec::shared::StackTraceElementWrapper, file_name_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::exec::shared::StackTraceElementWrapper, line_number_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::exec::shared::StackTraceElementWrapper, method_name_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::exec::shared::StackTraceElementWrapper, is_native_method_),
  0,
  1,
  3,
  2,
  4,
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::exec::shared::ParsingError, _has_bits_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::exec::shared::ParsingError, _internal_metadata_),
  ~0u,  // no _extensions_
  ~0u,  // no _oneof_case_
  ~0u,  // no _weak_field_map_
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::exec::shared::ParsingError, start_column_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::exec::shared::ParsingError, start_row_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::exec::shared::ParsingError, end_column_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::exec::shared::ParsingError, end_row_),
  0,
  1,
  2,
  3,
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::exec::shared::RecordBatchDef, _has_bits_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::exec::shared::RecordBatchDef, _internal_metadata_),
  ~0u,  // no _extensions_
  ~0u,  // no _oneof_case_
  ~0u,  // no _weak_field_map_
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::exec::shared::RecordBatchDef, record_count_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::exec::shared::RecordBatchDef, field_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::exec::shared::RecordBatchDef, carries_two_byte_selection_vector_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::exec::shared::RecordBatchDef, affected_rows_count_),
  0,
  ~0u,
  1,
  2,
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::exec::shared::NamePart, _has_bits_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::exec::shared::NamePart, _internal_metadata_),
  ~0u,  // no _extensions_
  ~0u,  // no _oneof_case_
  ~0u,  // no _weak_field_map_
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::exec::shared::NamePart, type_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::exec::shared::NamePart, name_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::exec::shared::NamePart, child_),
  2,
  0,
  1,
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::exec::shared::SerializedField, _has_bits_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::exec::shared::SerializedField, _internal_metadata_),
  ~0u,  // no _extensions_
  ~0u,  // no _oneof_case_
  ~0u,  // no _weak_field_map_
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::exec::shared::SerializedField, major_type_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::exec::shared::SerializedField, name_part_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::exec::shared::SerializedField, child_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::exec::shared::SerializedField, value_count_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::exec::shared::SerializedField, var_byte_length_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::exec::shared::SerializedField, buffer_length_),
  0,
  1,
  ~0u,
  2,
  3,
  4,
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::exec::shared::NodeStatus, _has_bits_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::exec::shared::NodeStatus, _internal_metadata_),
  ~0u,  // no _extensions_
  ~0u,  // no _oneof_case_
  ~0u,  // no _weak_field_map_
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::exec::shared::NodeStatus, node_id_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::exec::shared::NodeStatus, memory_footprint_),
  1,
  0,
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::exec::shared::QueryResult, _has_bits_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::exec::shared::QueryResult, _internal_metadata_),
  ~0u,  // no _extensions_
  ~0u,  // no _oneof_case_
  ~0u,  // no _weak_field_map_
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::exec::shared::QueryResult, query_state_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::exec::shared::QueryResult, query_id_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::exec::shared::QueryResult, error_),
  1,
  0,
  ~0u,
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::exec::shared::QueryData, _has_bits_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::exec::shared::QueryData, _internal_metadata_),
  ~0u,  // no _extensions_
  ~0u,  // no _oneof_case_
  ~0u,  // no _weak_field_map_
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::exec::shared::QueryData, query_id_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::exec::shared::QueryData, row_count_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::exec::shared::QueryData, def_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::exec::shared::QueryData, affected_rows_count_),
  0,
  2,
  1,
  3,
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::exec::shared::QueryInfo, _has_bits_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::exec::shared::QueryInfo, _internal_metadata_),
  ~0u,  // no _extensions_
  ~0u,  // no _oneof_case_
  ~0u,  // no _weak_field_map_
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::exec::shared::QueryInfo, query_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::exec::shared::QueryInfo, start_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::exec::shared::QueryInfo, state_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::exec::shared::QueryInfo, user_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::exec::shared::QueryInfo, foreman_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::exec::shared::QueryInfo, options_json_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::exec::shared::QueryInfo, total_cost_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::exec::shared::QueryInfo, queue_name_),
  0,
  5,
  7,
  1,
  4,
  2,
  6,
  3,
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::exec::shared::QueryProfile, _has_bits_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::exec::shared::QueryProfile, _internal_metadata_),
  ~0u,  // no _extensions_
  ~0u,  // no _oneof_case_
  ~0u,  // no _weak_field_map_
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::exec::shared::QueryProfile, id_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::exec::shared::QueryProfile, type_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::exec::shared::QueryProfile, start_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::exec::shared::QueryProfile, end_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::exec::shared::QueryProfile, query_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::exec::shared::QueryProfile, plan_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::exec::shared::QueryProfile, foreman_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::exec::shared::QueryProfile, state_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::exec::shared::QueryProfile, total_fragments_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::exec::shared::QueryProfile, finished_fragments_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::exec::shared::QueryProfile, fragment_profile_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::exec::shared::QueryProfile, user_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::exec::shared::QueryProfile, error_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::exec::shared::QueryProfile, verboseerror_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::exec::shared::QueryProfile, error_id_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::exec::shared::QueryProfile, error_node_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::exec::shared::QueryProfile, options_json_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::exec::shared::QueryProfile, planend_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::exec::shared::QueryProfile, queuewaitend_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::exec::shared::QueryProfile, total_cost_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::exec::shared::QueryProfile, queue_name_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::exec::shared::QueryProfile, queryid_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::exec::shared::QueryProfile, autolimit_),
  10,
  21,
  12,
  13,
  0,
  1,
  11,
  14,
  15,
  16,
  ~0u,
  2,
  3,
  4,
  5,
  6,
  7,
  18,
  19,
  20,
  8,
  9,
  17,
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::exec::shared::MajorFragmentProfile, _has_bits_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::exec::shared::MajorFragmentProfile, _internal_metadata_),
  ~0u,  // no _extensions_
  ~0u,  // no _oneof_case_
  ~0u,  // no _weak_field_map_
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::exec::shared::MajorFragmentProfile, major_fragment_id_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::exec::shared::MajorFragmentProfile, minor_fragment_profile_),
  0,
  ~0u,
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::exec::shared::MinorFragmentProfile, _has_bits_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::exec::shared::MinorFragmentProfile, _internal_metadata_),
  ~0u,  // no _extensions_
  ~0u,  // no _oneof_case_
  ~0u,  // no _weak_field_map_
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::exec::shared::MinorFragmentProfile, state_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::exec::shared::MinorFragmentProfile, error_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::exec::shared::MinorFragmentProfile, minor_fragment_id_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::exec::shared::MinorFragmentProfile, operator_profile_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::exec::shared::MinorFragmentProfile, start_time_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::exec::shared::MinorFragmentProfile, end_time_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::exec::shared::MinorFragmentProfile, memory_used_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::exec::shared::MinorFragmentProfile, max_memory_used_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::exec::shared::MinorFragmentProfile, endpoint_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::exec::shared::MinorFragmentProfile, last_update_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::exec::shared::MinorFragmentProfile, last_progress_),
  2,
  0,
  3,
  ~0u,
  4,
  5,
  6,
  7,
  1,
  8,
  9,
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::exec::shared::OperatorProfile, _has_bits_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::exec::shared::OperatorProfile, _internal_metadata_),
  ~0u,  // no _extensions_
  ~0u,  // no _oneof_case_
  ~0u,  // no _weak_field_map_
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::exec::shared::OperatorProfile, input_profile_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::exec::shared::OperatorProfile, operator_id_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::exec::shared::OperatorProfile, operator_type_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::exec::shared::OperatorProfile, setup_nanos_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::exec::shared::OperatorProfile, process_nanos_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::exec::shared::OperatorProfile, peak_local_memory_allocated_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::exec::shared::OperatorProfile, metric_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::exec::shared::OperatorProfile, wait_nanos_),
  ~0u,
  0,
  1,
  2,
  3,
  4,
  ~0u,
  5,
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::exec::shared::StreamProfile, _has_bits_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::exec::shared::StreamProfile, _internal_metadata_),
  ~0u,  // no _extensions_
  ~0u,  // no _oneof_case_
  ~0u,  // no _weak_field_map_
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::exec::shared::StreamProfile, records_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::exec::shared::StreamProfile, batches_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::exec::shared::StreamProfile, schemas_),
  0,
  1,
  2,
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::exec::shared::MetricValue, _has_bits_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::exec::shared::MetricValue, _internal_metadata_),
  ~0u,  // no _extensions_
  ~0u,  // no _oneof_case_
  ~0u,  // no _weak_field_map_
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::exec::shared::MetricValue, metric_id_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::exec::shared::MetricValue, long_value_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::exec::shared::MetricValue, double_value_),
  2,
  0,
  1,
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::exec::shared::Registry, _has_bits_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::exec::shared::Registry, _internal_metadata_),
  ~0u,  // no _extensions_
  ~0u,  // no _oneof_case_
  ~0u,  // no _weak_field_map_
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::exec::shared::Registry, jar_),
  ~0u,
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::exec::shared::Jar, _has_bits_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::exec::shared::Jar, _internal_metadata_),
  ~0u,  // no _extensions_
  ~0u,  // no _oneof_case_
  ~0u,  // no _weak_field_map_
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::exec::shared::Jar, name_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::exec::shared::Jar, function_signature_),
  0,
  ~0u,
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::exec::shared::SaslMessage, _has_bits_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::exec::shared::SaslMessage, _internal_metadata_),
  ~0u,  // no _extensions_
  ~0u,  // no _oneof_case_
  ~0u,  // no _weak_field_map_
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::exec::shared::SaslMessage, mechanism_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::exec::shared::SaslMessage, data_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::exec::shared::SaslMessage, status_),
  0,
  1,
  2,
};
static const ::google::protobuf::internal::MigrationSchema schemas[] GOOGLE_PROTOBUF_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = {
  { 0, 6, sizeof(::exec::shared::UserCredentials)},
  { 7, 14, sizeof(::exec::shared::QueryId)},
  { 16, 27, sizeof(::exec::shared::DrillPBError)},
  { 33, 42, sizeof(::exec::shared::ExceptionWrapper)},
  { 46, 56, sizeof(::exec::shared::StackTraceElementWrapper)},
  { 61, 70, sizeof(::exec::shared::ParsingError)},
  { 74, 83, sizeof(::exec::shared::RecordBatchDef)},
  { 87, 95, sizeof(::exec::shared::NamePart)},
  { 98, 109, sizeof(::exec::shared::SerializedField)},
  { 115, 122, sizeof(::exec::shared::NodeStatus)},
  { 124, 132, sizeof(::exec::shared::QueryResult)},
  { 135, 144, sizeof(::exec::shared::QueryData)},
  { 148, 161, sizeof(::exec::shared::QueryInfo)},
  { 169, 197, sizeof(::exec::shared::QueryProfile)},
  { 220, 227, sizeof(::exec::shared::MajorFragmentProfile)},
  { 229, 245, sizeof(::exec::shared::MinorFragmentProfile)},
  { 256, 269, sizeof(::exec::shared::OperatorProfile)},
  { 277, 285, sizeof(::exec::shared::StreamProfile)},
  { 288, 296, sizeof(::exec::shared::MetricValue)},
  { 299, 305, sizeof(::exec::shared::Registry)},
  { 306, 313, sizeof(::exec::shared::Jar)},
  { 315, 323, sizeof(::exec::shared::SaslMessage)},
};

static ::google::protobuf::Message const * const file_default_instances[] = {
  reinterpret_cast<const ::google::protobuf::Message*>(&::exec::shared::_UserCredentials_default_instance_),
  reinterpret_cast<const ::google::protobuf::Message*>(&::exec::shared::_QueryId_default_instance_),
  reinterpret_cast<const ::google::protobuf::Message*>(&::exec::shared::_DrillPBError_default_instance_),
  reinterpret_cast<const ::google::protobuf::Message*>(&::exec::shared::_ExceptionWrapper_default_instance_),
  reinterpret_cast<const ::google::protobuf::Message*>(&::exec::shared::_StackTraceElementWrapper_default_instance_),
  reinterpret_cast<const ::google::protobuf::Message*>(&::exec::shared::_ParsingError_default_instance_),
  reinterpret_cast<const ::google::protobuf::Message*>(&::exec::shared::_RecordBatchDef_default_instance_),
  reinterpret_cast<const ::google::protobuf::Message*>(&::exec::shared::_NamePart_default_instance_),
  reinterpret_cast<const ::google::protobuf::Message*>(&::exec::shared::_SerializedField_default_instance_),
  reinterpret_cast<const ::google::protobuf::Message*>(&::exec::shared::_NodeStatus_default_instance_),
  reinterpret_cast<const ::google::protobuf::Message*>(&::exec::shared::_QueryResult_default_instance_),
  reinterpret_cast<const ::google::protobuf::Message*>(&::exec::shared::_QueryData_default_instance_),
  reinterpret_cast<const ::google::protobuf::Message*>(&::exec::shared::_QueryInfo_default_instance_),
  reinterpret_cast<const ::google::protobuf::Message*>(&::exec::shared::_QueryProfile_default_instance_),
  reinterpret_cast<const ::google::protobuf::Message*>(&::exec::shared::_MajorFragmentProfile_default_instance_),
  reinterpret_cast<const ::google::protobuf::Message*>(&::exec::shared::_MinorFragmentProfile_default_instance_),
  reinterpret_cast<const ::google::protobuf::Message*>(&::exec::shared::_OperatorProfile_default_instance_),
  reinterpret_cast<const ::google::protobuf::Message*>(&::exec::shared::_StreamProfile_default_instance_),
  reinterpret_cast<const ::google::protobuf::Message*>(&::exec::shared::_MetricValue_default_instance_),
  reinterpret_cast<const ::google::protobuf::Message*>(&::exec::shared::_Registry_default_instance_),
  reinterpret_cast<const ::google::protobuf::Message*>(&::exec::shared::_Jar_default_instance_),
  reinterpret_cast<const ::google::protobuf::Message*>(&::exec::shared::_SaslMessage_default_instance_),
};

void protobuf_AssignDescriptors() {
  AddDescriptors();
  AssignDescriptors(
      "UserBitShared.proto", schemas, file_default_instances, TableStruct::offsets,
      file_level_metadata, file_level_enum_descriptors, NULL);
}

void protobuf_AssignDescriptorsOnce() {
  static ::google::protobuf::internal::once_flag once;
  ::google::protobuf::internal::call_once(once, protobuf_AssignDescriptors);
}

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

void AddDescriptorsImpl() {
  InitDefaults();
  static const char descriptor[] GOOGLE_PROTOBUF_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = {
      "\n\023UserBitShared.proto\022\013exec.shared\032\013Type"
      "s.proto\032\022Coordination.proto\032\017SchemaDef.p"
      "roto\"$\n\017UserCredentials\022\021\n\tuser_name\030\001 \001"
      "(\t\"\'\n\007QueryId\022\r\n\005part1\030\001 \001(\020\022\r\n\005part2\030\002 "
      "\001(\020\"\355\003\n\014DrillPBError\022\020\n\010error_id\030\001 \001(\t\022("
      "\n\010endpoint\030\002 \001(\0132\026.exec.DrillbitEndpoint"
      "\0227\n\nerror_type\030\003 \001(\0162#.exec.shared.Drill"
      "PBError.ErrorType\022\017\n\007message\030\004 \001(\t\0220\n\tex"
      "ception\030\005 \001(\0132\035.exec.shared.ExceptionWra"
      "pper\0220\n\rparsing_error\030\006 \003(\0132\031.exec.share"
      "d.ParsingError\"\362\001\n\tErrorType\022\016\n\nCONNECTI"
      "ON\020\000\022\r\n\tDATA_READ\020\001\022\016\n\nDATA_WRITE\020\002\022\014\n\010F"
      "UNCTION\020\003\022\t\n\005PARSE\020\004\022\016\n\nPERMISSION\020\005\022\010\n\004"
      "PLAN\020\006\022\014\n\010RESOURCE\020\007\022\n\n\006SYSTEM\020\010\022\031\n\025UNSU"
      "PPORTED_OPERATION\020\t\022\016\n\nVALIDATION\020\n\022\023\n\017E"
      "XECUTION_ERROR\020\013\022\022\n\016INTERNAL_ERROR\020\014\022\025\n\021"
      "UNSPECIFIED_ERROR\020\r\"\246\001\n\020ExceptionWrapper"
      "\022\027\n\017exception_class\030\001 \001(\t\022\017\n\007message\030\002 \001"
      "(\t\022:\n\013stack_trace\030\003 \003(\0132%.exec.shared.St"
      "ackTraceElementWrapper\022,\n\005cause\030\004 \001(\0132\035."
      "exec.shared.ExceptionWrapper\"\205\001\n\030StackTr"
      "aceElementWrapper\022\022\n\nclass_name\030\001 \001(\t\022\021\n"
      "\tfile_name\030\002 \001(\t\022\023\n\013line_number\030\003 \001(\005\022\023\n"
      "\013method_name\030\004 \001(\t\022\030\n\020is_native_method\030\005"
      " \001(\010\"\\\n\014ParsingError\022\024\n\014start_column\030\002 \001"
      "(\005\022\021\n\tstart_row\030\003 \001(\005\022\022\n\nend_column\030\004 \001("
      "\005\022\017\n\007end_row\030\005 \001(\005\"\233\001\n\016RecordBatchDef\022\024\n"
      "\014record_count\030\001 \001(\005\022+\n\005field\030\002 \003(\0132\034.exe"
      "c.shared.SerializedField\022)\n!carries_two_"
      "byte_selection_vector\030\003 \001(\010\022\033\n\023affected_"
      "rows_count\030\004 \001(\005\"\205\001\n\010NamePart\022(\n\004type\030\001 "
      "\001(\0162\032.exec.shared.NamePart.Type\022\014\n\004name\030"
      "\002 \001(\t\022$\n\005child\030\003 \001(\0132\025.exec.shared.NameP"
      "art\"\033\n\004Type\022\010\n\004NAME\020\000\022\t\n\005ARRAY\020\001\"\324\001\n\017Ser"
      "ializedField\022%\n\nmajor_type\030\001 \001(\0132\021.commo"
      "n.MajorType\022(\n\tname_part\030\002 \001(\0132\025.exec.sh"
      "ared.NamePart\022+\n\005child\030\003 \003(\0132\034.exec.shar"
      "ed.SerializedField\022\023\n\013value_count\030\004 \001(\005\022"
      "\027\n\017var_byte_length\030\005 \001(\005\022\025\n\rbuffer_lengt"
      "h\030\007 \001(\005\"7\n\nNodeStatus\022\017\n\007node_id\030\001 \001(\005\022\030"
      "\n\020memory_footprint\030\002 \001(\003\"\263\002\n\013QueryResult"
      "\0228\n\013query_state\030\001 \001(\0162#.exec.shared.Quer"
      "yResult.QueryState\022&\n\010query_id\030\002 \001(\0132\024.e"
      "xec.shared.QueryId\022(\n\005error\030\003 \003(\0132\031.exec"
      ".shared.DrillPBError\"\227\001\n\nQueryState\022\014\n\010S"
      "TARTING\020\000\022\013\n\007RUNNING\020\001\022\r\n\tCOMPLETED\020\002\022\014\n"
      "\010CANCELED\020\003\022\n\n\006FAILED\020\004\022\032\n\026CANCELLATION_"
      "REQUESTED\020\005\022\014\n\010ENQUEUED\020\006\022\r\n\tPREPARING\020\007"
      "\022\014\n\010PLANNING\020\010\"\215\001\n\tQueryData\022&\n\010query_id"
      "\030\001 \001(\0132\024.exec.shared.QueryId\022\021\n\trow_coun"
      "t\030\002 \001(\005\022(\n\003def\030\003 \001(\0132\033.exec.shared.Recor"
      "dBatchDef\022\033\n\023affected_rows_count\030\004 \001(\005\"\330"
      "\001\n\tQueryInfo\022\r\n\005query\030\001 \001(\t\022\r\n\005start\030\002 \001"
      "(\003\0222\n\005state\030\003 \001(\0162#.exec.shared.QueryRes"
      "ult.QueryState\022\017\n\004user\030\004 \001(\t:\001-\022\'\n\007forem"
      "an\030\005 \001(\0132\026.exec.DrillbitEndpoint\022\024\n\014opti"
      "ons_json\030\006 \001(\t\022\022\n\ntotal_cost\030\007 \001(\001\022\025\n\nqu"
      "eue_name\030\010 \001(\t:\001-\"\306\004\n\014QueryProfile\022 \n\002id"
      "\030\001 \001(\0132\024.exec.shared.QueryId\022$\n\004type\030\002 \001"
      "(\0162\026.exec.shared.QueryType\022\r\n\005start\030\003 \001("
      "\003\022\013\n\003end\030\004 \001(\003\022\r\n\005query\030\005 \001(\t\022\014\n\004plan\030\006 "
      "\001(\t\022\'\n\007foreman\030\007 \001(\0132\026.exec.DrillbitEndp"
      "oint\0222\n\005state\030\010 \001(\0162#.exec.shared.QueryR"
      "esult.QueryState\022\027\n\017total_fragments\030\t \001("
      "\005\022\032\n\022finished_fragments\030\n \001(\005\022;\n\020fragmen"
      "t_profile\030\013 \003(\0132!.exec.shared.MajorFragm"
      "entProfile\022\017\n\004user\030\014 \001(\t:\001-\022\r\n\005error\030\r \001"
      "(\t\022\024\n\014verboseError\030\016 \001(\t\022\020\n\010error_id\030\017 \001"
      "(\t\022\022\n\nerror_node\030\020 \001(\t\022\024\n\014options_json\030\021"
      " \001(\t\022\017\n\007planEnd\030\022 \001(\003\022\024\n\014queueWaitEnd\030\023 "
      "\001(\003\022\022\n\ntotal_cost\030\024 \001(\001\022\025\n\nqueue_name\030\025 "
      "\001(\t:\001-\022\017\n\007queryId\030\026 \001(\t\022\021\n\tautoLimit\030\027 \001"
      "(\005\"t\n\024MajorFragmentProfile\022\031\n\021major_frag"
      "ment_id\030\001 \001(\005\022A\n\026minor_fragment_profile\030"
      "\002 \003(\0132!.exec.shared.MinorFragmentProfile"
      "\"\350\002\n\024MinorFragmentProfile\022)\n\005state\030\001 \001(\016"
      "2\032.exec.shared.FragmentState\022(\n\005error\030\002 "
      "\001(\0132\031.exec.shared.DrillPBError\022\031\n\021minor_"
      "fragment_id\030\003 \001(\005\0226\n\020operator_profile\030\004 "
      "\003(\0132\034.exec.shared.OperatorProfile\022\022\n\nsta"
      "rt_time\030\005 \001(\003\022\020\n\010end_time\030\006 \001(\003\022\023\n\013memor"
      "y_used\030\007 \001(\003\022\027\n\017max_memory_used\030\010 \001(\003\022(\n"
      "\010endpoint\030\t \001(\0132\026.exec.DrillbitEndpoint\022"
      "\023\n\013last_update\030\n \001(\003\022\025\n\rlast_progress\030\013 "
      "\001(\003\"\377\001\n\017OperatorProfile\0221\n\rinput_profile"
      "\030\001 \003(\0132\032.exec.shared.StreamProfile\022\023\n\013op"
      "erator_id\030\003 \001(\005\022\025\n\roperator_type\030\004 \001(\005\022\023"
      "\n\013setup_nanos\030\005 \001(\003\022\025\n\rprocess_nanos\030\006 \001"
      "(\003\022#\n\033peak_local_memory_allocated\030\007 \001(\003\022"
      "(\n\006metric\030\010 \003(\0132\030.exec.shared.MetricValu"
      "e\022\022\n\nwait_nanos\030\t \001(\003\"B\n\rStreamProfile\022\017"
      "\n\007records\030\001 \001(\003\022\017\n\007batches\030\002 \001(\003\022\017\n\007sche"
      "mas\030\003 \001(\003\"J\n\013MetricValue\022\021\n\tmetric_id\030\001 "
      "\001(\005\022\022\n\nlong_value\030\002 \001(\003\022\024\n\014double_value\030"
      "\003 \001(\001\")\n\010Registry\022\035\n\003jar\030\001 \003(\0132\020.exec.sh"
      "ared.Jar\"/\n\003Jar\022\014\n\004name\030\001 \001(\t\022\032\n\022functio"
      "n_signature\030\002 \003(\t\"W\n\013SaslMessage\022\021\n\tmech"
      "anism\030\001 \001(\t\022\014\n\004data\030\002 \001(\014\022\'\n\006status\030\003 \001("
      "\0162\027.exec.shared.SaslStatus*5\n\nRpcChannel"
      "\022\017\n\013BIT_CONTROL\020\000\022\014\n\010BIT_DATA\020\001\022\010\n\004USER\020"
      "\002*V\n\tQueryType\022\007\n\003SQL\020\001\022\013\n\007LOGICAL\020\002\022\014\n\010"
      "PHYSICAL\020\003\022\r\n\tEXECUTION\020\004\022\026\n\022PREPARED_ST"
      "ATEMENT\020\005*\207\001\n\rFragmentState\022\013\n\007SENDING\020\000"
      "\022\027\n\023AWAITING_ALLOCATION\020\001\022\013\n\007RUNNING\020\002\022\014"
      "\n\010FINISHED\020\003\022\r\n\tCANCELLED\020\004\022\n\n\006FAILED\020\005\022"
      "\032\n\026CANCELLATION_REQUESTED\020\006*\344\n\n\020CoreOper"
      "atorType\022\021\n\rSINGLE_SENDER\020\000\022\024\n\020BROADCAST"
      "_SENDER\020\001\022\n\n\006FILTER\020\002\022\022\n\016HASH_AGGREGATE\020"
      "\003\022\r\n\tHASH_JOIN\020\004\022\016\n\nMERGE_JOIN\020\005\022\031\n\025HASH"
      "_PARTITION_SENDER\020\006\022\t\n\005LIMIT\020\007\022\024\n\020MERGIN"
      "G_RECEIVER\020\010\022\034\n\030ORDERED_PARTITION_SENDER"
      "\020\t\022\013\n\007PROJECT\020\n\022\026\n\022UNORDERED_RECEIVER\020\013\022"
      "\032\n\026RANGE_PARTITION_SENDER\020\014\022\n\n\006SCREEN\020\r\022"
      "\034\n\030SELECTION_VECTOR_REMOVER\020\016\022\027\n\023STREAMI"
      "NG_AGGREGATE\020\017\022\016\n\nTOP_N_SORT\020\020\022\021\n\rEXTERN"
      "AL_SORT\020\021\022\t\n\005TRACE\020\022\022\t\n\005UNION\020\023\022\014\n\010OLD_S"
      "ORT\020\024\022\032\n\026PARQUET_ROW_GROUP_SCAN\020\025\022\021\n\rHIV"
      "E_SUB_SCAN\020\026\022\025\n\021SYSTEM_TABLE_SCAN\020\027\022\021\n\rM"
      "OCK_SUB_SCAN\020\030\022\022\n\016PARQUET_WRITER\020\031\022\023\n\017DI"
      "RECT_SUB_SCAN\020\032\022\017\n\013TEXT_WRITER\020\033\022\021\n\rTEXT"
      "_SUB_SCAN\020\034\022\021\n\rJSON_SUB_SCAN\020\035\022\030\n\024INFO_S"
      "CHEMA_SUB_SCAN\020\036\022\023\n\017COMPLEX_TO_JSON\020\037\022\025\n"
      "\021PRODUCER_CONSUMER\020 \022\022\n\016HBASE_SUB_SCAN\020!"
      "\022\n\n\006WINDOW\020\"\022\024\n\020NESTED_LOOP_JOIN\020#\022\021\n\rAV"
      "RO_SUB_SCAN\020$\022\021\n\rPCAP_SUB_SCAN\020%\022\022\n\016KAFK"
      "A_SUB_SCAN\020&\022\021\n\rKUDU_SUB_SCAN\020\'\022\013\n\007FLATT"
      "EN\020(\022\020\n\014LATERAL_JOIN\020)\022\n\n\006UNNEST\020*\022,\n(HI"
      "VE_DRILL_NATIVE_PARQUET_ROW_GROUP_SCAN\020+"
      "\022\r\n\tJDBC_SCAN\020,\022\022\n\016REGEX_SUB_SCAN\020-\022\023\n\017M"
      "APRDB_SUB_SCAN\020.\022\022\n\016MONGO_SUB_SCAN\020/\022\017\n\013"
      "KUDU_WRITER\0200\022\026\n\022OPEN_TSDB_SUB_SCAN\0201\022\017\n"
      "\013JSON_WRITER\0202\022\026\n\022HTPPD_LOG_SUB_SCAN\0203\022\022"
      "\n\016IMAGE_SUB_SCAN\0204\022\025\n\021SEQUENCE_SUB_SCAN\020"
      "5\022\023\n\017PARTITION_LIMIT\0206\022\023\n\017PCAPNG_SUB_SCA"
      "N\0207\022\022\n\016RUNTIME_FILTER\0208\022\017\n\013ROWKEY_JOIN\0209"
      "\022\023\n\017SYSLOG_SUB_SCAN\020:\022\030\n\024STATISTICS_AGGR"
      "EGATE\020;\022\020\n\014UNPIVOT_MAPS\020<\022\024\n\020STATISTICS_"
      "MERGE\020=\022\021\n\rLTSV_SUB_SCAN\020>\022\021\n\rHDF5_SUB_S"
      "CAN\020\?\022\022\n\016EXCEL_SUB_SCAN\020@\022\020\n\014SHP_SUB_SCA"
      "N\020A\022\024\n\020METADATA_HANDLER\020B\022\027\n\023METADATA_CO"
      "NTROLLER\020C*g\n\nSaslStatus\022\020\n\014SASL_UNKNOWN"
      "\020\000\022\016\n\nSASL_START\020\001\022\024\n\020SASL_IN_PROGRESS\020\002"
      "\022\020\n\014SASL_SUCCESS\020\003\022\017\n\013SASL_FAILED\020\004B.\n\033o"
      "rg.apache.drill.exec.protoB\rUserBitShare"
      "dH\001"
  };
  ::google::protobuf::DescriptorPool::InternalAddGeneratedFile(
      descriptor, 5763);
  ::google::protobuf::MessageFactory::InternalRegisterGeneratedFile(
    "UserBitShared.proto", &protobuf_RegisterTypes);
  ::protobuf_Types_2eproto::AddDescriptors();
  ::protobuf_Coordination_2eproto::AddDescriptors();
  ::protobuf_SchemaDef_2eproto::AddDescriptors();
}

void AddDescriptors() {
  static ::google::protobuf::internal::once_flag once;
  ::google::protobuf::internal::call_once(once, AddDescriptorsImpl);
}
// Force AddDescriptors() to be called at dynamic initialization time.
struct StaticDescriptorInitializer {
  StaticDescriptorInitializer() {
    AddDescriptors();
  }
} static_descriptor_initializer;
}  // namespace protobuf_UserBitShared_2eproto
namespace exec {
namespace shared {
const ::google::protobuf::EnumDescriptor* DrillPBError_ErrorType_descriptor() {
  protobuf_UserBitShared_2eproto::protobuf_AssignDescriptorsOnce();
  return protobuf_UserBitShared_2eproto::file_level_enum_descriptors[0];
}
bool DrillPBError_ErrorType_IsValid(int value) {
  switch (value) {
    case 0:
    case 1:
    case 2:
    case 3:
    case 4:
    case 5:
    case 6:
    case 7:
    case 8:
    case 9:
    case 10:
    case 11:
    case 12:
    case 13:
      return true;
    default:
      return false;
  }
}

#if !defined(_MSC_VER) || _MSC_VER >= 1900
const DrillPBError_ErrorType DrillPBError::CONNECTION;
const DrillPBError_ErrorType DrillPBError::DATA_READ;
const DrillPBError_ErrorType DrillPBError::DATA_WRITE;
const DrillPBError_ErrorType DrillPBError::FUNCTION;
const DrillPBError_ErrorType DrillPBError::PARSE;
const DrillPBError_ErrorType DrillPBError::PERMISSION;
const DrillPBError_ErrorType DrillPBError::PLAN;
const DrillPBError_ErrorType DrillPBError::RESOURCE;
const DrillPBError_ErrorType DrillPBError::SYSTEM;
const DrillPBError_ErrorType DrillPBError::UNSUPPORTED_OPERATION;
const DrillPBError_ErrorType DrillPBError::VALIDATION;
const DrillPBError_ErrorType DrillPBError::EXECUTION_ERROR;
const DrillPBError_ErrorType DrillPBError::INTERNAL_ERROR;
const DrillPBError_ErrorType DrillPBError::UNSPECIFIED_ERROR;
const DrillPBError_ErrorType DrillPBError::ErrorType_MIN;
const DrillPBError_ErrorType DrillPBError::ErrorType_MAX;
const int DrillPBError::ErrorType_ARRAYSIZE;
#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
const ::google::protobuf::EnumDescriptor* NamePart_Type_descriptor() {
  protobuf_UserBitShared_2eproto::protobuf_AssignDescriptorsOnce();
  return protobuf_UserBitShared_2eproto::file_level_enum_descriptors[1];
}
bool NamePart_Type_IsValid(int value) {
  switch (value) {
    case 0:
    case 1:
      return true;
    default:
      return false;
  }
}

#if !defined(_MSC_VER) || _MSC_VER >= 1900
const NamePart_Type NamePart::NAME;
const NamePart_Type NamePart::ARRAY;
const NamePart_Type NamePart::Type_MIN;
const NamePart_Type NamePart::Type_MAX;
const int NamePart::Type_ARRAYSIZE;
#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
const ::google::protobuf::EnumDescriptor* QueryResult_QueryState_descriptor() {
  protobuf_UserBitShared_2eproto::protobuf_AssignDescriptorsOnce();
  return protobuf_UserBitShared_2eproto::file_level_enum_descriptors[2];
}
bool QueryResult_QueryState_IsValid(int value) {
  switch (value) {
    case 0:
    case 1:
    case 2:
    case 3:
    case 4:
    case 5:
    case 6:
    case 7:
    case 8:
      return true;
    default:
      return false;
  }
}

#if !defined(_MSC_VER) || _MSC_VER >= 1900
const QueryResult_QueryState QueryResult::STARTING;
const QueryResult_QueryState QueryResult::RUNNING;
const QueryResult_QueryState QueryResult::COMPLETED;
const QueryResult_QueryState QueryResult::CANCELED;
const QueryResult_QueryState QueryResult::FAILED;
const QueryResult_QueryState QueryResult::CANCELLATION_REQUESTED;
const QueryResult_QueryState QueryResult::ENQUEUED;
const QueryResult_QueryState QueryResult::PREPARING;
const QueryResult_QueryState QueryResult::PLANNING;
const QueryResult_QueryState QueryResult::QueryState_MIN;
const QueryResult_QueryState QueryResult::QueryState_MAX;
const int QueryResult::QueryState_ARRAYSIZE;
#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
const ::google::protobuf::EnumDescriptor* RpcChannel_descriptor() {
  protobuf_UserBitShared_2eproto::protobuf_AssignDescriptorsOnce();
  return protobuf_UserBitShared_2eproto::file_level_enum_descriptors[3];
}
bool RpcChannel_IsValid(int value) {
  switch (value) {
    case 0:
    case 1:
    case 2:
      return true;
    default:
      return false;
  }
}

const ::google::protobuf::EnumDescriptor* QueryType_descriptor() {
  protobuf_UserBitShared_2eproto::protobuf_AssignDescriptorsOnce();
  return protobuf_UserBitShared_2eproto::file_level_enum_descriptors[4];
}
bool QueryType_IsValid(int value) {
  switch (value) {
    case 1:
    case 2:
    case 3:
    case 4:
    case 5:
      return true;
    default:
      return false;
  }
}

const ::google::protobuf::EnumDescriptor* FragmentState_descriptor() {
  protobuf_UserBitShared_2eproto::protobuf_AssignDescriptorsOnce();
  return protobuf_UserBitShared_2eproto::file_level_enum_descriptors[5];
}
bool FragmentState_IsValid(int value) {
  switch (value) {
    case 0:
    case 1:
    case 2:
    case 3:
    case 4:
    case 5:
    case 6:
      return true;
    default:
      return false;
  }
}

const ::google::protobuf::EnumDescriptor* CoreOperatorType_descriptor() {
  protobuf_UserBitShared_2eproto::protobuf_AssignDescriptorsOnce();
  return protobuf_UserBitShared_2eproto::file_level_enum_descriptors[6];
}
bool CoreOperatorType_IsValid(int value) {
  switch (value) {
    case 0:
    case 1:
    case 2:
    case 3:
    case 4:
    case 5:
    case 6:
    case 7:
    case 8:
    case 9:
    case 10:
    case 11:
    case 12:
    case 13:
    case 14:
    case 15:
    case 16:
    case 17:
    case 18:
    case 19:
    case 20:
    case 21:
    case 22:
    case 23:
    case 24:
    case 25:
    case 26:
    case 27:
    case 28:
    case 29:
    case 30:
    case 31:
    case 32:
    case 33:
    case 34:
    case 35:
    case 36:
    case 37:
    case 38:
    case 39:
    case 40:
    case 41:
    case 42:
    case 43:
    case 44:
    case 45:
    case 46:
    case 47:
    case 48:
    case 49:
    case 50:
    case 51:
    case 52:
    case 53:
    case 54:
    case 55:
    case 56:
    case 57:
    case 58:
    case 59:
    case 60:
    case 61:
    case 62:
    case 63:
    case 64:
    case 65:
    case 66:
    case 67:
      return true;
    default:
      return false;
  }
}

const ::google::protobuf::EnumDescriptor* SaslStatus_descriptor() {
  protobuf_UserBitShared_2eproto::protobuf_AssignDescriptorsOnce();
  return protobuf_UserBitShared_2eproto::file_level_enum_descriptors[7];
}
bool SaslStatus_IsValid(int value) {
  switch (value) {
    case 0:
    case 1:
    case 2:
    case 3:
    case 4:
      return true;
    default:
      return false;
  }
}


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

void UserCredentials::InitAsDefaultInstance() {
}
#if !defined(_MSC_VER) || _MSC_VER >= 1900
const int UserCredentials::kUserNameFieldNumber;
#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900

UserCredentials::UserCredentials()
  : ::google::protobuf::Message(), _internal_metadata_(NULL) {
  ::google::protobuf::internal::InitSCC(
      &protobuf_UserBitShared_2eproto::scc_info_UserCredentials.base);
  SharedCtor();
  // @@protoc_insertion_point(constructor:exec.shared.UserCredentials)
}
UserCredentials::UserCredentials(const UserCredentials& from)
  : ::google::protobuf::Message(),
      _internal_metadata_(NULL),
      _has_bits_(from._has_bits_) {
  _internal_metadata_.MergeFrom(from._internal_metadata_);
  user_name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  if (from.has_user_name()) {
    user_name_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.user_name_);
  }
  // @@protoc_insertion_point(copy_constructor:exec.shared.UserCredentials)
}

void UserCredentials::SharedCtor() {
  user_name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}

UserCredentials::~UserCredentials() {
  // @@protoc_insertion_point(destructor:exec.shared.UserCredentials)
  SharedDtor();
}

void UserCredentials::SharedDtor() {
  user_name_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}

void UserCredentials::SetCachedSize(int size) const {
  _cached_size_.Set(size);
}
const ::google::protobuf::Descriptor* UserCredentials::descriptor() {
  ::protobuf_UserBitShared_2eproto::protobuf_AssignDescriptorsOnce();
  return ::protobuf_UserBitShared_2eproto::file_level_metadata[kIndexInFileMessages].descriptor;
}

const UserCredentials& UserCredentials::default_instance() {
  ::google::protobuf::internal::InitSCC(&protobuf_UserBitShared_2eproto::scc_info_UserCredentials.base);
  return *internal_default_instance();
}


void UserCredentials::Clear() {
// @@protoc_insertion_point(message_clear_start:exec.shared.UserCredentials)
  ::google::protobuf::uint32 cached_has_bits = 0;
  // Prevent compiler warnings about cached_has_bits being unused
  (void) cached_has_bits;

  cached_has_bits = _has_bits_[0];
  if (cached_has_bits & 0x00000001u) {
    user_name_.ClearNonDefaultToEmptyNoArena();
  }
  _has_bits_.Clear();
  _internal_metadata_.Clear();
}

bool UserCredentials::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:exec.shared.UserCredentials)
  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)) {
      // optional string user_name = 1;
      case 1: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(10u /* 10 & 0xFF */)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                input, this->mutable_user_name()));
          ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
            this->user_name().data(), static_cast<int>(this->user_name().length()),
            ::google::protobuf::internal::WireFormat::PARSE,
            "exec.shared.UserCredentials.user_name");
        } else {
          goto handle_unusual;
        }
        break;
      }

      default: {
      handle_unusual:
        if (tag == 0) {
          goto success;
        }
        DO_(::google::protobuf::internal::WireFormat::SkipField(
              input, tag, _internal_metadata_.mutable_unknown_fields()));
        break;
      }
    }
  }
success:
  // @@protoc_insertion_point(parse_success:exec.shared.UserCredentials)
  return true;
failure:
  // @@protoc_insertion_point(parse_failure:exec.shared.UserCredentials)
  return false;
#undef DO_
}

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

  cached_has_bits = _has_bits_[0];
  // optional string user_name = 1;
  if (cached_has_bits & 0x00000001u) {
    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
      this->user_name().data(), static_cast<int>(this->user_name().length()),
      ::google::protobuf::internal::WireFormat::SERIALIZE,
      "exec.shared.UserCredentials.user_name");
    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
      1, this->user_name(), output);
  }

  if (_internal_metadata_.have_unknown_fields()) {
    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
        _internal_metadata_.unknown_fields(), output);
  }
  // @@protoc_insertion_point(serialize_end:exec.shared.UserCredentials)
}

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

  cached_has_bits = _has_bits_[0];
  // optional string user_name = 1;
  if (cached_has_bits & 0x00000001u) {
    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
      this->user_name().data(), static_cast<int>(this->user_name().length()),
      ::google::protobuf::internal::WireFormat::SERIALIZE,
      "exec.shared.UserCredentials.user_name");
    target =
      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
        1, this->user_name(), target);
  }

  if (_internal_metadata_.have_unknown_fields()) {
    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
        _internal_metadata_.unknown_fields(), target);
  }
  // @@protoc_insertion_point(serialize_to_array_end:exec.shared.UserCredentials)
  return target;
}

size_t UserCredentials::ByteSizeLong() const {
// @@protoc_insertion_point(message_byte_size_start:exec.shared.UserCredentials)
  size_t total_size = 0;

  if (_internal_metadata_.have_unknown_fields()) {
    total_size +=
      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
        _internal_metadata_.unknown_fields());
  }
  // optional string user_name = 1;
  if (has_user_name()) {
    total_size += 1 +
      ::google::protobuf::internal::WireFormatLite::StringSize(
        this->user_name());
  }

  int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
  SetCachedSize(cached_size);
  return total_size;
}

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

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

  if (from.has_user_name()) {
    set_has_user_name();
    user_name_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.user_name_);
  }
}

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

void UserCredentials::CopyFrom(const UserCredentials& from) {
// @@protoc_insertion_point(class_specific_copy_from_start:exec.shared.UserCredentials)
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

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

void UserCredentials::Swap(UserCredentials* other) {
  if (other == this) return;
  InternalSwap(other);
}
void UserCredentials::InternalSwap(UserCredentials* other) {
  using std::swap;
  user_name_.Swap(&other->user_name_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
    GetArenaNoVirtual());
  swap(_has_bits_[0], other->_has_bits_[0]);
  _internal_metadata_.Swap(&other->_internal_metadata_);
}

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


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

void QueryId::InitAsDefaultInstance() {
}
#if !defined(_MSC_VER) || _MSC_VER >= 1900
const int QueryId::kPart1FieldNumber;
const int QueryId::kPart2FieldNumber;
#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900

QueryId::QueryId()
  : ::google::protobuf::Message(), _internal_metadata_(NULL) {
  ::google::protobuf::internal::InitSCC(
      &protobuf_UserBitShared_2eproto::scc_info_QueryId.base);
  SharedCtor();
  // @@protoc_insertion_point(constructor:exec.shared.QueryId)
}
QueryId::QueryId(const QueryId& from)
  : ::google::protobuf::Message(),
      _internal_metadata_(NULL),
      _has_bits_(from._has_bits_) {
  _internal_metadata_.MergeFrom(from._internal_metadata_);
  ::memcpy(&part1_, &from.part1_,
    static_cast<size_t>(reinterpret_cast<char*>(&part2_) -
    reinterpret_cast<char*>(&part1_)) + sizeof(part2_));
  // @@protoc_insertion_point(copy_constructor:exec.shared.QueryId)
}

void QueryId::SharedCtor() {
  ::memset(&part1_, 0, static_cast<size_t>(
      reinterpret_cast<char*>(&part2_) -
      reinterpret_cast<char*>(&part1_)) + sizeof(part2_));
}

QueryId::~QueryId() {
  // @@protoc_insertion_point(destructor:exec.shared.QueryId)
  SharedDtor();
}

void QueryId::SharedDtor() {
}

void QueryId::SetCachedSize(int size) const {
  _cached_size_.Set(size);
}
const ::google::protobuf::Descriptor* QueryId::descriptor() {
  ::protobuf_UserBitShared_2eproto::protobuf_AssignDescriptorsOnce();
  return ::protobuf_UserBitShared_2eproto::file_level_metadata[kIndexInFileMessages].descriptor;
}

const QueryId& QueryId::default_instance() {
  ::google::protobuf::internal::InitSCC(&protobuf_UserBitShared_2eproto::scc_info_QueryId.base);
  return *internal_default_instance();
}


void QueryId::Clear() {
// @@protoc_insertion_point(message_clear_start:exec.shared.QueryId)
  ::google::protobuf::uint32 cached_has_bits = 0;
  // Prevent compiler warnings about cached_has_bits being unused
  (void) cached_has_bits;

  cached_has_bits = _has_bits_[0];
  if (cached_has_bits & 3u) {
    ::memset(&part1_, 0, static_cast<size_t>(
        reinterpret_cast<char*>(&part2_) -
        reinterpret_cast<char*>(&part1_)) + sizeof(part2_));
  }
  _has_bits_.Clear();
  _internal_metadata_.Clear();
}

bool QueryId::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:exec.shared.QueryId)
  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)) {
      // optional sfixed64 part1 = 1;
      case 1: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(9u /* 9 & 0xFF */)) {
          set_has_part1();
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   ::google::protobuf::int64, ::google::protobuf::internal::WireFormatLite::TYPE_SFIXED64>(
                 input, &part1_)));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // optional sfixed64 part2 = 2;
      case 2: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(17u /* 17 & 0xFF */)) {
          set_has_part2();
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   ::google::protobuf::int64, ::google::protobuf::internal::WireFormatLite::TYPE_SFIXED64>(
                 input, &part2_)));
        } else {
          goto handle_unusual;
        }
        break;
      }

      default: {
      handle_unusual:
        if (tag == 0) {
          goto success;
        }
        DO_(::google::protobuf::internal::WireFormat::SkipField(
              input, tag, _internal_metadata_.mutable_unknown_fields()));
        break;
      }
    }
  }
success:
  // @@protoc_insertion_point(parse_success:exec.shared.QueryId)
  return true;
failure:
  // @@protoc_insertion_point(parse_failure:exec.shared.QueryId)
  return false;
#undef DO_
}

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

  cached_has_bits = _has_bits_[0];
  // optional sfixed64 part1 = 1;
  if (cached_has_bits & 0x00000001u) {
    ::google::protobuf::internal::WireFormatLite::WriteSFixed64(1, this->part1(), output);
  }

  // optional sfixed64 part2 = 2;
  if (cached_has_bits & 0x00000002u) {
    ::google::protobuf::internal::WireFormatLite::WriteSFixed64(2, this->part2(), output);
  }

  if (_internal_metadata_.have_unknown_fields()) {
    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
        _internal_metadata_.unknown_fields(), output);
  }
  // @@protoc_insertion_point(serialize_end:exec.shared.QueryId)
}

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

  cached_has_bits = _has_bits_[0];
  // optional sfixed64 part1 = 1;
  if (cached_has_bits & 0x00000001u) {
    target = ::google::protobuf::internal::WireFormatLite::WriteSFixed64ToArray(1, this->part1(), target);
  }

  // optional sfixed64 part2 = 2;
  if (cached_has_bits & 0x00000002u) {
    target = ::google::protobuf::internal::WireFormatLite::WriteSFixed64ToArray(2, this->part2(), target);
  }

  if (_internal_metadata_.have_unknown_fields()) {
    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
        _internal_metadata_.unknown_fields(), target);
  }
  // @@protoc_insertion_point(serialize_to_array_end:exec.shared.QueryId)
  return target;
}

size_t QueryId::ByteSizeLong() const {
// @@protoc_insertion_point(message_byte_size_start:exec.shared.QueryId)
  size_t total_size = 0;

  if (_internal_metadata_.have_unknown_fields()) {
    total_size +=
      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
        _internal_metadata_.unknown_fields());
  }
  if (_has_bits_[0 / 32] & 3u) {
    // optional sfixed64 part1 = 1;
    if (has_part1()) {
      total_size += 1 + 8;
    }

    // optional sfixed64 part2 = 2;
    if (has_part2()) {
      total_size += 1 + 8;
    }

  }
  int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
  SetCachedSize(cached_size);
  return total_size;
}

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

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

  cached_has_bits = from._has_bits_[0];
  if (cached_has_bits & 3u) {
    if (cached_has_bits & 0x00000001u) {
      part1_ = from.part1_;
    }
    if (cached_has_bits & 0x00000002u) {
      part2_ = from.part2_;
    }
    _has_bits_[0] |= cached_has_bits;
  }
}

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

void QueryId::CopyFrom(const QueryId& from) {
// @@protoc_insertion_point(class_specific_copy_from_start:exec.shared.QueryId)
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

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

void QueryId::Swap(QueryId* other) {
  if (other == this) return;
  InternalSwap(other);
}
void QueryId::InternalSwap(QueryId* other) {
  using std::swap;
  swap(part1_, other->part1_);
  swap(part2_, other->part2_);
  swap(_has_bits_[0], other->_has_bits_[0]);
  _internal_metadata_.Swap(&other->_internal_metadata_);
}

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


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

void DrillPBError::InitAsDefaultInstance() {
  ::exec::shared::_DrillPBError_default_instance_._instance.get_mutable()->endpoint_ = const_cast< ::exec::DrillbitEndpoint*>(
      ::exec::DrillbitEndpoint::internal_default_instance());
  ::exec::shared::_DrillPBError_default_instance_._instance.get_mutable()->exception_ = const_cast< ::exec::shared::ExceptionWrapper*>(
      ::exec::shared::ExceptionWrapper::internal_default_instance());
}
void DrillPBError::clear_endpoint() {
  if (endpoint_ != NULL) endpoint_->Clear();
  clear_has_endpoint();
}
#if !defined(_MSC_VER) || _MSC_VER >= 1900
const int DrillPBError::kErrorIdFieldNumber;
const int DrillPBError::kEndpointFieldNumber;
const int DrillPBError::kErrorTypeFieldNumber;
const int DrillPBError::kMessageFieldNumber;
const int DrillPBError::kExceptionFieldNumber;
const int DrillPBError::kParsingErrorFieldNumber;
#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900

DrillPBError::DrillPBError()
  : ::google::protobuf::Message(), _internal_metadata_(NULL) {
  ::google::protobuf::internal::InitSCC(
      &protobuf_UserBitShared_2eproto::scc_info_DrillPBError.base);
  SharedCtor();
  // @@protoc_insertion_point(constructor:exec.shared.DrillPBError)
}
DrillPBError::DrillPBError(const DrillPBError& from)
  : ::google::protobuf::Message(),
      _internal_metadata_(NULL),
      _has_bits_(from._has_bits_),
      parsing_error_(from.parsing_error_) {
  _internal_metadata_.MergeFrom(from._internal_metadata_);
  error_id_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  if (from.has_error_id()) {
    error_id_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.error_id_);
  }
  message_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  if (from.has_message()) {
    message_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.message_);
  }
  if (from.has_endpoint()) {
    endpoint_ = new ::exec::DrillbitEndpoint(*from.endpoint_);
  } else {
    endpoint_ = NULL;
  }
  if (from.has_exception()) {
    exception_ = new ::exec::shared::ExceptionWrapper(*from.exception_);
  } else {
    exception_ = NULL;
  }
  error_type_ = from.error_type_;
  // @@protoc_insertion_point(copy_constructor:exec.shared.DrillPBError)
}

void DrillPBError::SharedCtor() {
  error_id_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  message_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  ::memset(&endpoint_, 0, static_cast<size_t>(
      reinterpret_cast<char*>(&error_type_) -
      reinterpret_cast<char*>(&endpoint_)) + sizeof(error_type_));
}

DrillPBError::~DrillPBError() {
  // @@protoc_insertion_point(destructor:exec.shared.DrillPBError)
  SharedDtor();
}

void DrillPBError::SharedDtor() {
  error_id_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  message_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  if (this != internal_default_instance()) delete endpoint_;
  if (this != internal_default_instance()) delete exception_;
}

void DrillPBError::SetCachedSize(int size) const {
  _cached_size_.Set(size);
}
const ::google::protobuf::Descriptor* DrillPBError::descriptor() {
  ::protobuf_UserBitShared_2eproto::protobuf_AssignDescriptorsOnce();
  return ::protobuf_UserBitShared_2eproto::file_level_metadata[kIndexInFileMessages].descriptor;
}

const DrillPBError& DrillPBError::default_instance() {
  ::google::protobuf::internal::InitSCC(&protobuf_UserBitShared_2eproto::scc_info_DrillPBError.base);
  return *internal_default_instance();
}


void DrillPBError::Clear() {
// @@protoc_insertion_point(message_clear_start:exec.shared.DrillPBError)
  ::google::protobuf::uint32 cached_has_bits = 0;
  // Prevent compiler warnings about cached_has_bits being unused
  (void) cached_has_bits;

  parsing_error_.Clear();
  cached_has_bits = _has_bits_[0];
  if (cached_has_bits & 15u) {
    if (cached_has_bits & 0x00000001u) {
      error_id_.ClearNonDefaultToEmptyNoArena();
    }
    if (cached_has_bits & 0x00000002u) {
      message_.ClearNonDefaultToEmptyNoArena();
    }
    if (cached_has_bits & 0x00000004u) {
      GOOGLE_DCHECK(endpoint_ != NULL);
      endpoint_->Clear();
    }
    if (cached_has_bits & 0x00000008u) {
      GOOGLE_DCHECK(exception_ != NULL);
      exception_->Clear();
    }
  }
  error_type_ = 0;
  _has_bits_.Clear();
  _internal_metadata_.Clear();
}

bool DrillPBError::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:exec.shared.DrillPBError)
  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)) {
      // optional string error_id = 1;
      case 1: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(10u /* 10 & 0xFF */)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                input, this->mutable_error_id()));
          ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
            this->error_id().data(), static_cast<int>(this->error_id().length()),
            ::google::protobuf::internal::WireFormat::PARSE,
            "exec.shared.DrillPBError.error_id");
        } else {
          goto handle_unusual;
        }
        break;
      }

      // optional .exec.DrillbitEndpoint endpoint = 2;
      case 2: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(18u /* 18 & 0xFF */)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
               input, mutable_endpoint()));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // optional .exec.shared.DrillPBError.ErrorType error_type = 3;
      case 3: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(24u /* 24 & 0xFF */)) {
          int value;
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
                 input, &value)));
          if (::exec::shared::DrillPBError_ErrorType_IsValid(value)) {
            set_error_type(static_cast< ::exec::shared::DrillPBError_ErrorType >(value));
          } else {
            mutable_unknown_fields()->AddVarint(
                3, static_cast< ::google::protobuf::uint64>(value));
          }
        } else {
          goto handle_unusual;
        }
        break;
      }

      // optional string message = 4;
      case 4: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(34u /* 34 & 0xFF */)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                input, this->mutable_message()));
          ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
            this->message().data(), static_cast<int>(this->message().length()),
            ::google::protobuf::internal::WireFormat::PARSE,
            "exec.shared.DrillPBError.message");
        } else {
          goto handle_unusual;
        }
        break;
      }

      // optional .exec.shared.ExceptionWrapper exception = 5;
      case 5: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(42u /* 42 & 0xFF */)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
               input, mutable_exception()));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // repeated .exec.shared.ParsingError parsing_error = 6;
      case 6: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(50u /* 50 & 0xFF */)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
                input, add_parsing_error()));
        } else {
          goto handle_unusual;
        }
        break;
      }

      default: {
      handle_unusual:
        if (tag == 0) {
          goto success;
        }
        DO_(::google::protobuf::internal::WireFormat::SkipField(
              input, tag, _internal_metadata_.mutable_unknown_fields()));
        break;
      }
    }
  }
success:
  // @@protoc_insertion_point(parse_success:exec.shared.DrillPBError)
  return true;
failure:
  // @@protoc_insertion_point(parse_failure:exec.shared.DrillPBError)
  return false;
#undef DO_
}

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

  cached_has_bits = _has_bits_[0];
  // optional string error_id = 1;
  if (cached_has_bits & 0x00000001u) {
    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
      this->error_id().data(), static_cast<int>(this->error_id().length()),
      ::google::protobuf::internal::WireFormat::SERIALIZE,
      "exec.shared.DrillPBError.error_id");
    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
      1, this->error_id(), output);
  }

  // optional .exec.DrillbitEndpoint endpoint = 2;
  if (cached_has_bits & 0x00000004u) {
    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
      2, this->_internal_endpoint(), output);
  }

  // optional .exec.shared.DrillPBError.ErrorType error_type = 3;
  if (cached_has_bits & 0x00000010u) {
    ::google::protobuf::internal::WireFormatLite::WriteEnum(
      3, this->error_type(), output);
  }

  // optional string message = 4;
  if (cached_has_bits & 0x00000002u) {
    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
      this->message().data(), static_cast<int>(this->message().length()),
      ::google::protobuf::internal::WireFormat::SERIALIZE,
      "exec.shared.DrillPBError.message");
    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
      4, this->message(), output);
  }

  // optional .exec.shared.ExceptionWrapper exception = 5;
  if (cached_has_bits & 0x00000008u) {
    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
      5, this->_internal_exception(), output);
  }

  // repeated .exec.shared.ParsingError parsing_error = 6;
  for (unsigned int i = 0,
      n = static_cast<unsigned int>(this->parsing_error_size()); i < n; i++) {
    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
      6,
      this->parsing_error(static_cast<int>(i)),
      output);
  }

  if (_internal_metadata_.have_unknown_fields()) {
    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
        _internal_metadata_.unknown_fields(), output);
  }
  // @@protoc_insertion_point(serialize_end:exec.shared.DrillPBError)
}

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

  cached_has_bits = _has_bits_[0];
  // optional string error_id = 1;
  if (cached_has_bits & 0x00000001u) {
    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
      this->error_id().data(), static_cast<int>(this->error_id().length()),
      ::google::protobuf::internal::WireFormat::SERIALIZE,
      "exec.shared.DrillPBError.error_id");
    target =
      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
        1, this->error_id(), target);
  }

  // optional .exec.DrillbitEndpoint endpoint = 2;
  if (cached_has_bits & 0x00000004u) {
    target = ::google::protobuf::internal::WireFormatLite::
      InternalWriteMessageToArray(
        2, this->_internal_endpoint(), deterministic, target);
  }

  // optional .exec.shared.DrillPBError.ErrorType error_type = 3;
  if (cached_has_bits & 0x00000010u) {
    target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
      3, this->error_type(), target);
  }

  // optional string message = 4;
  if (cached_has_bits & 0x00000002u) {
    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
      this->message().data(), static_cast<int>(this->message().length()),
      ::google::protobuf::internal::WireFormat::SERIALIZE,
      "exec.shared.DrillPBError.message");
    target =
      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
        4, this->message(), target);
  }

  // optional .exec.shared.ExceptionWrapper exception = 5;
  if (cached_has_bits & 0x00000008u) {
    target = ::google::protobuf::internal::WireFormatLite::
      InternalWriteMessageToArray(
        5, this->_internal_exception(), deterministic, target);
  }

  // repeated .exec.shared.ParsingError parsing_error = 6;
  for (unsigned int i = 0,
      n = static_cast<unsigned int>(this->parsing_error_size()); i < n; i++) {
    target = ::google::protobuf::internal::WireFormatLite::
      InternalWriteMessageToArray(
        6, this->parsing_error(static_cast<int>(i)), deterministic, target);
  }

  if (_internal_metadata_.have_unknown_fields()) {
    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
        _internal_metadata_.unknown_fields(), target);
  }
  // @@protoc_insertion_point(serialize_to_array_end:exec.shared.DrillPBError)
  return target;
}

size_t DrillPBError::ByteSizeLong() const {
// @@protoc_insertion_point(message_byte_size_start:exec.shared.DrillPBError)
  size_t total_size = 0;

  if (_internal_metadata_.have_unknown_fields()) {
    total_size +=
      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
        _internal_metadata_.unknown_fields());
  }
  // repeated .exec.shared.ParsingError parsing_error = 6;
  {
    unsigned int count = static_cast<unsigned int>(this->parsing_error_size());
    total_size += 1UL * count;
    for (unsigned int i = 0; i < count; i++) {
      total_size +=
        ::google::protobuf::internal::WireFormatLite::MessageSize(
          this->parsing_error(static_cast<int>(i)));
    }
  }

  if (_has_bits_[0 / 32] & 31u) {
    // optional string error_id = 1;
    if (has_error_id()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::StringSize(
          this->error_id());
    }

    // optional string message = 4;
    if (has_message()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::StringSize(
          this->message());
    }

    // optional .exec.DrillbitEndpoint endpoint = 2;
    if (has_endpoint()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::MessageSize(
          *endpoint_);
    }

    // optional .exec.shared.ExceptionWrapper exception = 5;
    if (has_exception()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::MessageSize(
          *exception_);
    }

    // optional .exec.shared.DrillPBError.ErrorType error_type = 3;
    if (has_error_type()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::EnumSize(this->error_type());
    }

  }
  int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
  SetCachedSize(cached_size);
  return total_size;
}

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

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

  parsing_error_.MergeFrom(from.parsing_error_);
  cached_has_bits = from._has_bits_[0];
  if (cached_has_bits & 31u) {
    if (cached_has_bits & 0x00000001u) {
      set_has_error_id();
      error_id_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.error_id_);
    }
    if (cached_has_bits & 0x00000002u) {
      set_has_message();
      message_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.message_);
    }
    if (cached_has_bits & 0x00000004u) {
      mutable_endpoint()->::exec::DrillbitEndpoint::MergeFrom(from.endpoint());
    }
    if (cached_has_bits & 0x00000008u) {
      mutable_exception()->::exec::shared::ExceptionWrapper::MergeFrom(from.exception());
    }
    if (cached_has_bits & 0x00000010u) {
      error_type_ = from.error_type_;
    }
    _has_bits_[0] |= cached_has_bits;
  }
}

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

void DrillPBError::CopyFrom(const DrillPBError& from) {
// @@protoc_insertion_point(class_specific_copy_from_start:exec.shared.DrillPBError)
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

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

void DrillPBError::Swap(DrillPBError* other) {
  if (other == this) return;
  InternalSwap(other);
}
void DrillPBError::InternalSwap(DrillPBError* other) {
  using std::swap;
  CastToBase(&parsing_error_)->InternalSwap(CastToBase(&other->parsing_error_));
  error_id_.Swap(&other->error_id_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
    GetArenaNoVirtual());
  message_.Swap(&other->message_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
    GetArenaNoVirtual());
  swap(endpoint_, other->endpoint_);
  swap(exception_, other->exception_);
  swap(error_type_, other->error_type_);
  swap(_has_bits_[0], other->_has_bits_[0]);
  _internal_metadata_.Swap(&other->_internal_metadata_);
}

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


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

void ExceptionWrapper::InitAsDefaultInstance() {
  ::exec::shared::_ExceptionWrapper_default_instance_._instance.get_mutable()->cause_ = const_cast< ::exec::shared::ExceptionWrapper*>(
      ::exec::shared::ExceptionWrapper::internal_default_instance());
}
#if !defined(_MSC_VER) || _MSC_VER >= 1900
const int ExceptionWrapper::kExceptionClassFieldNumber;
const int ExceptionWrapper::kMessageFieldNumber;
const int ExceptionWrapper::kStackTraceFieldNumber;
const int ExceptionWrapper::kCauseFieldNumber;
#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900

ExceptionWrapper::ExceptionWrapper()
  : ::google::protobuf::Message(), _internal_metadata_(NULL) {
  ::google::protobuf::internal::InitSCC(
      &protobuf_UserBitShared_2eproto::scc_info_ExceptionWrapper.base);
  SharedCtor();
  // @@protoc_insertion_point(constructor:exec.shared.ExceptionWrapper)
}
ExceptionWrapper::ExceptionWrapper(const ExceptionWrapper& from)
  : ::google::protobuf::Message(),
      _internal_metadata_(NULL),
      _has_bits_(from._has_bits_),
      stack_trace_(from.stack_trace_) {
  _internal_metadata_.MergeFrom(from._internal_metadata_);
  exception_class_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  if (from.has_exception_class()) {
    exception_class_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.exception_class_);
  }
  message_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  if (from.has_message()) {
    message_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.message_);
  }
  if (from.has_cause()) {
    cause_ = new ::exec::shared::ExceptionWrapper(*from.cause_);
  } else {
    cause_ = NULL;
  }
  // @@protoc_insertion_point(copy_constructor:exec.shared.ExceptionWrapper)
}

void ExceptionWrapper::SharedCtor() {
  exception_class_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  message_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  cause_ = NULL;
}

ExceptionWrapper::~ExceptionWrapper() {
  // @@protoc_insertion_point(destructor:exec.shared.ExceptionWrapper)
  SharedDtor();
}

void ExceptionWrapper::SharedDtor() {
  exception_class_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  message_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  if (this != internal_default_instance()) delete cause_;
}

void ExceptionWrapper::SetCachedSize(int size) const {
  _cached_size_.Set(size);
}
const ::google::protobuf::Descriptor* ExceptionWrapper::descriptor() {
  ::protobuf_UserBitShared_2eproto::protobuf_AssignDescriptorsOnce();
  return ::protobuf_UserBitShared_2eproto::file_level_metadata[kIndexInFileMessages].descriptor;
}

const ExceptionWrapper& ExceptionWrapper::default_instance() {
  ::google::protobuf::internal::InitSCC(&protobuf_UserBitShared_2eproto::scc_info_ExceptionWrapper.base);
  return *internal_default_instance();
}


void ExceptionWrapper::Clear() {
// @@protoc_insertion_point(message_clear_start:exec.shared.ExceptionWrapper)
  ::google::protobuf::uint32 cached_has_bits = 0;
  // Prevent compiler warnings about cached_has_bits being unused
  (void) cached_has_bits;

  stack_trace_.Clear();
  cached_has_bits = _has_bits_[0];
  if (cached_has_bits & 7u) {
    if (cached_has_bits & 0x00000001u) {
      exception_class_.ClearNonDefaultToEmptyNoArena();
    }
    if (cached_has_bits & 0x00000002u) {
      message_.ClearNonDefaultToEmptyNoArena();
    }
    if (cached_has_bits & 0x00000004u) {
      GOOGLE_DCHECK(cause_ != NULL);
      cause_->Clear();
    }
  }
  _has_bits_.Clear();
  _internal_metadata_.Clear();
}

bool ExceptionWrapper::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:exec.shared.ExceptionWrapper)
  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)) {
      // optional string exception_class = 1;
      case 1: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(10u /* 10 & 0xFF */)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                input, this->mutable_exception_class()));
          ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
            this->exception_class().data(), static_cast<int>(this->exception_class().length()),
            ::google::protobuf::internal::WireFormat::PARSE,
            "exec.shared.ExceptionWrapper.exception_class");
        } else {
          goto handle_unusual;
        }
        break;
      }

      // optional string message = 2;
      case 2: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(18u /* 18 & 0xFF */)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                input, this->mutable_message()));
          ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
            this->message().data(), static_cast<int>(this->message().length()),
            ::google::protobuf::internal::WireFormat::PARSE,
            "exec.shared.ExceptionWrapper.message");
        } else {
          goto handle_unusual;
        }
        break;
      }

      // repeated .exec.shared.StackTraceElementWrapper stack_trace = 3;
      case 3: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(26u /* 26 & 0xFF */)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
                input, add_stack_trace()));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // optional .exec.shared.ExceptionWrapper cause = 4;
      case 4: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(34u /* 34 & 0xFF */)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
               input, mutable_cause()));
        } else {
          goto handle_unusual;
        }
        break;
      }

      default: {
      handle_unusual:
        if (tag == 0) {
          goto success;
        }
        DO_(::google::protobuf::internal::WireFormat::SkipField(
              input, tag, _internal_metadata_.mutable_unknown_fields()));
        break;
      }
    }
  }
success:
  // @@protoc_insertion_point(parse_success:exec.shared.ExceptionWrapper)
  return true;
failure:
  // @@protoc_insertion_point(parse_failure:exec.shared.ExceptionWrapper)
  return false;
#undef DO_
}

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

  cached_has_bits = _has_bits_[0];
  // optional string exception_class = 1;
  if (cached_has_bits & 0x00000001u) {
    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
      this->exception_class().data(), static_cast<int>(this->exception_class().length()),
      ::google::protobuf::internal::WireFormat::SERIALIZE,
      "exec.shared.ExceptionWrapper.exception_class");
    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
      1, this->exception_class(), output);
  }

  // optional string message = 2;
  if (cached_has_bits & 0x00000002u) {
    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
      this->message().data(), static_cast<int>(this->message().length()),
      ::google::protobuf::internal::WireFormat::SERIALIZE,
      "exec.shared.ExceptionWrapper.message");
    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
      2, this->message(), output);
  }

  // repeated .exec.shared.StackTraceElementWrapper stack_trace = 3;
  for (unsigned int i = 0,
      n = static_cast<unsigned int>(this->stack_trace_size()); i < n; i++) {
    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
      3,
      this->stack_trace(static_cast<int>(i)),
      output);
  }

  // optional .exec.shared.ExceptionWrapper cause = 4;
  if (cached_has_bits & 0x00000004u) {
    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
      4, this->_internal_cause(), output);
  }

  if (_internal_metadata_.have_unknown_fields()) {
    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
        _internal_metadata_.unknown_fields(), output);
  }
  // @@protoc_insertion_point(serialize_end:exec.shared.ExceptionWrapper)
}

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

  cached_has_bits = _has_bits_[0];
  // optional string exception_class = 1;
  if (cached_has_bits & 0x00000001u) {
    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
      this->exception_class().data(), static_cast<int>(this->exception_class().length()),
      ::google::protobuf::internal::WireFormat::SERIALIZE,
      "exec.shared.ExceptionWrapper.exception_class");
    target =
      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
        1, this->exception_class(), target);
  }

  // optional string message = 2;
  if (cached_has_bits & 0x00000002u) {
    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
      this->message().data(), static_cast<int>(this->message().length()),
      ::google::protobuf::internal::WireFormat::SERIALIZE,
      "exec.shared.ExceptionWrapper.message");
    target =
      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
        2, this->message(), target);
  }

  // repeated .exec.shared.StackTraceElementWrapper stack_trace = 3;
  for (unsigned int i = 0,
      n = static_cast<unsigned int>(this->stack_trace_size()); i < n; i++) {
    target = ::google::protobuf::internal::WireFormatLite::
      InternalWriteMessageToArray(
        3, this->stack_trace(static_cast<int>(i)), deterministic, target);
  }

  // optional .exec.shared.ExceptionWrapper cause = 4;
  if (cached_has_bits & 0x00000004u) {
    target = ::google::protobuf::internal::WireFormatLite::
      InternalWriteMessageToArray(
        4, this->_internal_cause(), deterministic, target);
  }

  if (_internal_metadata_.have_unknown_fields()) {
    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
        _internal_metadata_.unknown_fields(), target);
  }
  // @@protoc_insertion_point(serialize_to_array_end:exec.shared.ExceptionWrapper)
  return target;
}

size_t ExceptionWrapper::ByteSizeLong() const {
// @@protoc_insertion_point(message_byte_size_start:exec.shared.ExceptionWrapper)
  size_t total_size = 0;

  if (_internal_metadata_.have_unknown_fields()) {
    total_size +=
      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
        _internal_metadata_.unknown_fields());
  }
  // repeated .exec.shared.StackTraceElementWrapper stack_trace = 3;
  {
    unsigned int count = static_cast<unsigned int>(this->stack_trace_size());
    total_size += 1UL * count;
    for (unsigned int i = 0; i < count; i++) {
      total_size +=
        ::google::protobuf::internal::WireFormatLite::MessageSize(
          this->stack_trace(static_cast<int>(i)));
    }
  }

  if (_has_bits_[0 / 32] & 7u) {
    // optional string exception_class = 1;
    if (has_exception_class()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::StringSize(
          this->exception_class());
    }

    // optional string message = 2;
    if (has_message()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::StringSize(
          this->message());
    }

    // optional .exec.shared.ExceptionWrapper cause = 4;
    if (has_cause()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::MessageSize(
          *cause_);
    }

  }
  int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
  SetCachedSize(cached_size);
  return total_size;
}

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

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

  stack_trace_.MergeFrom(from.stack_trace_);
  cached_has_bits = from._has_bits_[0];
  if (cached_has_bits & 7u) {
    if (cached_has_bits & 0x00000001u) {
      set_has_exception_class();
      exception_class_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.exception_class_);
    }
    if (cached_has_bits & 0x00000002u) {
      set_has_message();
      message_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.message_);
    }
    if (cached_has_bits & 0x00000004u) {
      mutable_cause()->::exec::shared::ExceptionWrapper::MergeFrom(from.cause());
    }
  }
}

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

void ExceptionWrapper::CopyFrom(const ExceptionWrapper& from) {
// @@protoc_insertion_point(class_specific_copy_from_start:exec.shared.ExceptionWrapper)
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

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

void ExceptionWrapper::Swap(ExceptionWrapper* other) {
  if (other == this) return;
  InternalSwap(other);
}
void ExceptionWrapper::InternalSwap(ExceptionWrapper* other) {
  using std::swap;
  CastToBase(&stack_trace_)->InternalSwap(CastToBase(&other->stack_trace_));
  exception_class_.Swap(&other->exception_class_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
    GetArenaNoVirtual());
  message_.Swap(&other->message_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
    GetArenaNoVirtual());
  swap(cause_, other->cause_);
  swap(_has_bits_[0], other->_has_bits_[0]);
  _internal_metadata_.Swap(&other->_internal_metadata_);
}

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


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

void StackTraceElementWrapper::InitAsDefaultInstance() {
}
#if !defined(_MSC_VER) || _MSC_VER >= 1900
const int StackTraceElementWrapper::kClassNameFieldNumber;
const int StackTraceElementWrapper::kFileNameFieldNumber;
const int StackTraceElementWrapper::kLineNumberFieldNumber;
const int StackTraceElementWrapper::kMethodNameFieldNumber;
const int StackTraceElementWrapper::kIsNativeMethodFieldNumber;
#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900

StackTraceElementWrapper::StackTraceElementWrapper()
  : ::google::protobuf::Message(), _internal_metadata_(NULL) {
  ::google::protobuf::internal::InitSCC(
      &protobuf_UserBitShared_2eproto::scc_info_StackTraceElementWrapper.base);
  SharedCtor();
  // @@protoc_insertion_point(constructor:exec.shared.StackTraceElementWrapper)
}
StackTraceElementWrapper::StackTraceElementWrapper(const StackTraceElementWrapper& from)
  : ::google::protobuf::Message(),
      _internal_metadata_(NULL),
      _has_bits_(from._has_bits_) {
  _internal_metadata_.MergeFrom(from._internal_metadata_);
  class_name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  if (from.has_class_name()) {
    class_name_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.class_name_);
  }
  file_name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  if (from.has_file_name()) {
    file_name_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.file_name_);
  }
  method_name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  if (from.has_method_name()) {
    method_name_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.method_name_);
  }
  ::memcpy(&line_number_, &from.line_number_,
    static_cast<size_t>(reinterpret_cast<char*>(&is_native_method_) -
    reinterpret_cast<char*>(&line_number_)) + sizeof(is_native_method_));
  // @@protoc_insertion_point(copy_constructor:exec.shared.StackTraceElementWrapper)
}

void StackTraceElementWrapper::SharedCtor() {
  class_name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  file_name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  method_name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  ::memset(&line_number_, 0, static_cast<size_t>(
      reinterpret_cast<char*>(&is_native_method_) -
      reinterpret_cast<char*>(&line_number_)) + sizeof(is_native_method_));
}

StackTraceElementWrapper::~StackTraceElementWrapper() {
  // @@protoc_insertion_point(destructor:exec.shared.StackTraceElementWrapper)
  SharedDtor();
}

void StackTraceElementWrapper::SharedDtor() {
  class_name_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  file_name_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  method_name_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}

void StackTraceElementWrapper::SetCachedSize(int size) const {
  _cached_size_.Set(size);
}
const ::google::protobuf::Descriptor* StackTraceElementWrapper::descriptor() {
  ::protobuf_UserBitShared_2eproto::protobuf_AssignDescriptorsOnce();
  return ::protobuf_UserBitShared_2eproto::file_level_metadata[kIndexInFileMessages].descriptor;
}

const StackTraceElementWrapper& StackTraceElementWrapper::default_instance() {
  ::google::protobuf::internal::InitSCC(&protobuf_UserBitShared_2eproto::scc_info_StackTraceElementWrapper.base);
  return *internal_default_instance();
}


void StackTraceElementWrapper::Clear() {
// @@protoc_insertion_point(message_clear_start:exec.shared.StackTraceElementWrapper)
  ::google::protobuf::uint32 cached_has_bits = 0;
  // Prevent compiler warnings about cached_has_bits being unused
  (void) cached_has_bits;

  cached_has_bits = _has_bits_[0];
  if (cached_has_bits & 7u) {
    if (cached_has_bits & 0x00000001u) {
      class_name_.ClearNonDefaultToEmptyNoArena();
    }
    if (cached_has_bits & 0x00000002u) {
      file_name_.ClearNonDefaultToEmptyNoArena();
    }
    if (cached_has_bits & 0x00000004u) {
      method_name_.ClearNonDefaultToEmptyNoArena();
    }
  }
  if (cached_has_bits & 24u) {
    ::memset(&line_number_, 0, static_cast<size_t>(
        reinterpret_cast<char*>(&is_native_method_) -
        reinterpret_cast<char*>(&line_number_)) + sizeof(is_native_method_));
  }
  _has_bits_.Clear();
  _internal_metadata_.Clear();
}

bool StackTraceElementWrapper::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:exec.shared.StackTraceElementWrapper)
  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)) {
      // optional string class_name = 1;
      case 1: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(10u /* 10 & 0xFF */)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                input, this->mutable_class_name()));
          ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
            this->class_name().data(), static_cast<int>(this->class_name().length()),
            ::google::protobuf::internal::WireFormat::PARSE,
            "exec.shared.StackTraceElementWrapper.class_name");
        } else {
          goto handle_unusual;
        }
        break;
      }

      // optional string file_name = 2;
      case 2: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(18u /* 18 & 0xFF */)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                input, this->mutable_file_name()));
          ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
            this->file_name().data(), static_cast<int>(this->file_name().length()),
            ::google::protobuf::internal::WireFormat::PARSE,
            "exec.shared.StackTraceElementWrapper.file_name");
        } else {
          goto handle_unusual;
        }
        break;
      }

      // optional int32 line_number = 3;
      case 3: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(24u /* 24 & 0xFF */)) {
          set_has_line_number();
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
                 input, &line_number_)));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // optional string method_name = 4;
      case 4: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(34u /* 34 & 0xFF */)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                input, this->mutable_method_name()));
          ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
            this->method_name().data(), static_cast<int>(this->method_name().length()),
            ::google::protobuf::internal::WireFormat::PARSE,
            "exec.shared.StackTraceElementWrapper.method_name");
        } else {
          goto handle_unusual;
        }
        break;
      }

      // optional bool is_native_method = 5;
      case 5: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(40u /* 40 & 0xFF */)) {
          set_has_is_native_method();
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
                 input, &is_native_method_)));
        } else {
          goto handle_unusual;
        }
        break;
      }

      default: {
      handle_unusual:
        if (tag == 0) {
          goto success;
        }
        DO_(::google::protobuf::internal::WireFormat::SkipField(
              input, tag, _internal_metadata_.mutable_unknown_fields()));
        break;
      }
    }
  }
success:
  // @@protoc_insertion_point(parse_success:exec.shared.StackTraceElementWrapper)
  return true;
failure:
  // @@protoc_insertion_point(parse_failure:exec.shared.StackTraceElementWrapper)
  return false;
#undef DO_
}

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

  cached_has_bits = _has_bits_[0];
  // optional string class_name = 1;
  if (cached_has_bits & 0x00000001u) {
    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
      this->class_name().data(), static_cast<int>(this->class_name().length()),
      ::google::protobuf::internal::WireFormat::SERIALIZE,
      "exec.shared.StackTraceElementWrapper.class_name");
    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
      1, this->class_name(), output);
  }

  // optional string file_name = 2;
  if (cached_has_bits & 0x00000002u) {
    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
      this->file_name().data(), static_cast<int>(this->file_name().length()),
      ::google::protobuf::internal::WireFormat::SERIALIZE,
      "exec.shared.StackTraceElementWrapper.file_name");
    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
      2, this->file_name(), output);
  }

  // optional int32 line_number = 3;
  if (cached_has_bits & 0x00000008u) {
    ::google::protobuf::internal::WireFormatLite::WriteInt32(3, this->line_number(), output);
  }

  // optional string method_name = 4;
  if (cached_has_bits & 0x00000004u) {
    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
      this->method_name().data(), static_cast<int>(this->method_name().length()),
      ::google::protobuf::internal::WireFormat::SERIALIZE,
      "exec.shared.StackTraceElementWrapper.method_name");
    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
      4, this->method_name(), output);
  }

  // optional bool is_native_method = 5;
  if (cached_has_bits & 0x00000010u) {
    ::google::protobuf::internal::WireFormatLite::WriteBool(5, this->is_native_method(), output);
  }

  if (_internal_metadata_.have_unknown_fields()) {
    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
        _internal_metadata_.unknown_fields(), output);
  }
  // @@protoc_insertion_point(serialize_end:exec.shared.StackTraceElementWrapper)
}

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

  cached_has_bits = _has_bits_[0];
  // optional string class_name = 1;
  if (cached_has_bits & 0x00000001u) {
    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
      this->class_name().data(), static_cast<int>(this->class_name().length()),
      ::google::protobuf::internal::WireFormat::SERIALIZE,
      "exec.shared.StackTraceElementWrapper.class_name");
    target =
      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
        1, this->class_name(), target);
  }

  // optional string file_name = 2;
  if (cached_has_bits & 0x00000002u) {
    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
      this->file_name().data(), static_cast<int>(this->file_name().length()),
      ::google::protobuf::internal::WireFormat::SERIALIZE,
      "exec.shared.StackTraceElementWrapper.file_name");
    target =
      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
        2, this->file_name(), target);
  }

  // optional int32 line_number = 3;
  if (cached_has_bits & 0x00000008u) {
    target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(3, this->line_number(), target);
  }

  // optional string method_name = 4;
  if (cached_has_bits & 0x00000004u) {
    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
      this->method_name().data(), static_cast<int>(this->method_name().length()),
      ::google::protobuf::internal::WireFormat::SERIALIZE,
      "exec.shared.StackTraceElementWrapper.method_name");
    target =
      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
        4, this->method_name(), target);
  }

  // optional bool is_native_method = 5;
  if (cached_has_bits & 0x00000010u) {
    target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(5, this->is_native_method(), target);
  }

  if (_internal_metadata_.have_unknown_fields()) {
    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
        _internal_metadata_.unknown_fields(), target);
  }
  // @@protoc_insertion_point(serialize_to_array_end:exec.shared.StackTraceElementWrapper)
  return target;
}

size_t StackTraceElementWrapper::ByteSizeLong() const {
// @@protoc_insertion_point(message_byte_size_start:exec.shared.StackTraceElementWrapper)
  size_t total_size = 0;

  if (_internal_metadata_.have_unknown_fields()) {
    total_size +=
      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
        _internal_metadata_.unknown_fields());
  }
  if (_has_bits_[0 / 32] & 31u) {
    // optional string class_name = 1;
    if (has_class_name()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::StringSize(
          this->class_name());
    }

    // optional string file_name = 2;
    if (has_file_name()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::StringSize(
          this->file_name());
    }

    // optional string method_name = 4;
    if (has_method_name()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::StringSize(
          this->method_name());
    }

    // optional int32 line_number = 3;
    if (has_line_number()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::Int32Size(
          this->line_number());
    }

    // optional bool is_native_method = 5;
    if (has_is_native_method()) {
      total_size += 1 + 1;
    }

  }
  int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
  SetCachedSize(cached_size);
  return total_size;
}

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

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

  cached_has_bits = from._has_bits_[0];
  if (cached_has_bits & 31u) {
    if (cached_has_bits & 0x00000001u) {
      set_has_class_name();
      class_name_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.class_name_);
    }
    if (cached_has_bits & 0x00000002u) {
      set_has_file_name();
      file_name_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.file_name_);
    }
    if (cached_has_bits & 0x00000004u) {
      set_has_method_name();
      method_name_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.method_name_);
    }
    if (cached_has_bits & 0x00000008u) {
      line_number_ = from.line_number_;
    }
    if (cached_has_bits & 0x00000010u) {
      is_native_method_ = from.is_native_method_;
    }
    _has_bits_[0] |= cached_has_bits;
  }
}

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

void StackTraceElementWrapper::CopyFrom(const StackTraceElementWrapper& from) {
// @@protoc_insertion_point(class_specific_copy_from_start:exec.shared.StackTraceElementWrapper)
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

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

void StackTraceElementWrapper::Swap(StackTraceElementWrapper* other) {
  if (other == this) return;
  InternalSwap(other);
}
void StackTraceElementWrapper::InternalSwap(StackTraceElementWrapper* other) {
  using std::swap;
  class_name_.Swap(&other->class_name_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
    GetArenaNoVirtual());
  file_name_.Swap(&other->file_name_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
    GetArenaNoVirtual());
  method_name_.Swap(&other->method_name_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
    GetArenaNoVirtual());
  swap(line_number_, other->line_number_);
  swap(is_native_method_, other->is_native_method_);
  swap(_has_bits_[0], other->_has_bits_[0]);
  _internal_metadata_.Swap(&other->_internal_metadata_);
}

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


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

void ParsingError::InitAsDefaultInstance() {
}
#if !defined(_MSC_VER) || _MSC_VER >= 1900
const int ParsingError::kStartColumnFieldNumber;
const int ParsingError::kStartRowFieldNumber;
const int ParsingError::kEndColumnFieldNumber;
const int ParsingError::kEndRowFieldNumber;
#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900

ParsingError::ParsingError()
  : ::google::protobuf::Message(), _internal_metadata_(NULL) {
  ::google::protobuf::internal::InitSCC(
      &protobuf_UserBitShared_2eproto::scc_info_ParsingError.base);
  SharedCtor();
  // @@protoc_insertion_point(constructor:exec.shared.ParsingError)
}
ParsingError::ParsingError(const ParsingError& from)
  : ::google::protobuf::Message(),
      _internal_metadata_(NULL),
      _has_bits_(from._has_bits_) {
  _internal_metadata_.MergeFrom(from._internal_metadata_);
  ::memcpy(&start_column_, &from.start_column_,
    static_cast<size_t>(reinterpret_cast<char*>(&end_row_) -
    reinterpret_cast<char*>(&start_column_)) + sizeof(end_row_));
  // @@protoc_insertion_point(copy_constructor:exec.shared.ParsingError)
}

void ParsingError::SharedCtor() {
  ::memset(&start_column_, 0, static_cast<size_t>(
      reinterpret_cast<char*>(&end_row_) -
      reinterpret_cast<char*>(&start_column_)) + sizeof(end_row_));
}

ParsingError::~ParsingError() {
  // @@protoc_insertion_point(destructor:exec.shared.ParsingError)
  SharedDtor();
}

void ParsingError::SharedDtor() {
}

void ParsingError::SetCachedSize(int size) const {
  _cached_size_.Set(size);
}
const ::google::protobuf::Descriptor* ParsingError::descriptor() {
  ::protobuf_UserBitShared_2eproto::protobuf_AssignDescriptorsOnce();
  return ::protobuf_UserBitShared_2eproto::file_level_metadata[kIndexInFileMessages].descriptor;
}

const ParsingError& ParsingError::default_instance() {
  ::google::protobuf::internal::InitSCC(&protobuf_UserBitShared_2eproto::scc_info_ParsingError.base);
  return *internal_default_instance();
}


void ParsingError::Clear() {
// @@protoc_insertion_point(message_clear_start:exec.shared.ParsingError)
  ::google::protobuf::uint32 cached_has_bits = 0;
  // Prevent compiler warnings about cached_has_bits being unused
  (void) cached_has_bits;

  cached_has_bits = _has_bits_[0];
  if (cached_has_bits & 15u) {
    ::memset(&start_column_, 0, static_cast<size_t>(
        reinterpret_cast<char*>(&end_row_) -
        reinterpret_cast<char*>(&start_column_)) + sizeof(end_row_));
  }
  _has_bits_.Clear();
  _internal_metadata_.Clear();
}

bool ParsingError::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:exec.shared.ParsingError)
  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)) {
      // optional int32 start_column = 2;
      case 2: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(16u /* 16 & 0xFF */)) {
          set_has_start_column();
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
                 input, &start_column_)));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // optional int32 start_row = 3;
      case 3: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(24u /* 24 & 0xFF */)) {
          set_has_start_row();
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
                 input, &start_row_)));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // optional int32 end_column = 4;
      case 4: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(32u /* 32 & 0xFF */)) {
          set_has_end_column();
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
                 input, &end_column_)));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // optional int32 end_row = 5;
      case 5: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(40u /* 40 & 0xFF */)) {
          set_has_end_row();
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
                 input, &end_row_)));
        } else {
          goto handle_unusual;
        }
        break;
      }

      default: {
      handle_unusual:
        if (tag == 0) {
          goto success;
        }
        DO_(::google::protobuf::internal::WireFormat::SkipField(
              input, tag, _internal_metadata_.mutable_unknown_fields()));
        break;
      }
    }
  }
success:
  // @@protoc_insertion_point(parse_success:exec.shared.ParsingError)
  return true;
failure:
  // @@protoc_insertion_point(parse_failure:exec.shared.ParsingError)
  return false;
#undef DO_
}

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

  cached_has_bits = _has_bits_[0];
  // optional int32 start_column = 2;
  if (cached_has_bits & 0x00000001u) {
    ::google::protobuf::internal::WireFormatLite::WriteInt32(2, this->start_column(), output);
  }

  // optional int32 start_row = 3;
  if (cached_has_bits & 0x00000002u) {
    ::google::protobuf::internal::WireFormatLite::WriteInt32(3, this->start_row(), output);
  }

  // optional int32 end_column = 4;
  if (cached_has_bits & 0x00000004u) {
    ::google::protobuf::internal::WireFormatLite::WriteInt32(4, this->end_column(), output);
  }

  // optional int32 end_row = 5;
  if (cached_has_bits & 0x00000008u) {
    ::google::protobuf::internal::WireFormatLite::WriteInt32(5, this->end_row(), output);
  }

  if (_internal_metadata_.have_unknown_fields()) {
    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
        _internal_metadata_.unknown_fields(), output);
  }
  // @@protoc_insertion_point(serialize_end:exec.shared.ParsingError)
}

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

  cached_has_bits = _has_bits_[0];
  // optional int32 start_column = 2;
  if (cached_has_bits & 0x00000001u) {
    target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(2, this->start_column(), target);
  }

  // optional int32 start_row = 3;
  if (cached_has_bits & 0x00000002u) {
    target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(3, this->start_row(), target);
  }

  // optional int32 end_column = 4;
  if (cached_has_bits & 0x00000004u) {
    target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(4, this->end_column(), target);
  }

  // optional int32 end_row = 5;
  if (cached_has_bits & 0x00000008u) {
    target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(5, this->end_row(), target);
  }

  if (_internal_metadata_.have_unknown_fields()) {
    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
        _internal_metadata_.unknown_fields(), target);
  }
  // @@protoc_insertion_point(serialize_to_array_end:exec.shared.ParsingError)
  return target;
}

size_t ParsingError::ByteSizeLong() const {
// @@protoc_insertion_point(message_byte_size_start:exec.shared.ParsingError)
  size_t total_size = 0;

  if (_internal_metadata_.have_unknown_fields()) {
    total_size +=
      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
        _internal_metadata_.unknown_fields());
  }
  if (_has_bits_[0 / 32] & 15u) {
    // optional int32 start_column = 2;
    if (has_start_column()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::Int32Size(
          this->start_column());
    }

    // optional int32 start_row = 3;
    if (has_start_row()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::Int32Size(
          this->start_row());
    }

    // optional int32 end_column = 4;
    if (has_end_column()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::Int32Size(
          this->end_column());
    }

    // optional int32 end_row = 5;
    if (has_end_row()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::Int32Size(
          this->end_row());
    }

  }
  int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
  SetCachedSize(cached_size);
  return total_size;
}

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

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

  cached_has_bits = from._has_bits_[0];
  if (cached_has_bits & 15u) {
    if (cached_has_bits & 0x00000001u) {
      start_column_ = from.start_column_;
    }
    if (cached_has_bits & 0x00000002u) {
      start_row_ = from.start_row_;
    }
    if (cached_has_bits & 0x00000004u) {
      end_column_ = from.end_column_;
    }
    if (cached_has_bits & 0x00000008u) {
      end_row_ = from.end_row_;
    }
    _has_bits_[0] |= cached_has_bits;
  }
}

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

void ParsingError::CopyFrom(const ParsingError& from) {
// @@protoc_insertion_point(class_specific_copy_from_start:exec.shared.ParsingError)
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

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

void ParsingError::Swap(ParsingError* other) {
  if (other == this) return;
  InternalSwap(other);
}
void ParsingError::InternalSwap(ParsingError* other) {
  using std::swap;
  swap(start_column_, other->start_column_);
  swap(start_row_, other->start_row_);
  swap(end_column_, other->end_column_);
  swap(end_row_, other->end_row_);
  swap(_has_bits_[0], other->_has_bits_[0]);
  _internal_metadata_.Swap(&other->_internal_metadata_);
}

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


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

void RecordBatchDef::InitAsDefaultInstance() {
}
#if !defined(_MSC_VER) || _MSC_VER >= 1900
const int RecordBatchDef::kRecordCountFieldNumber;
const int RecordBatchDef::kFieldFieldNumber;
const int RecordBatchDef::kCarriesTwoByteSelectionVectorFieldNumber;
const int RecordBatchDef::kAffectedRowsCountFieldNumber;
#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900

RecordBatchDef::RecordBatchDef()
  : ::google::protobuf::Message(), _internal_metadata_(NULL) {
  ::google::protobuf::internal::InitSCC(
      &protobuf_UserBitShared_2eproto::scc_info_RecordBatchDef.base);
  SharedCtor();
  // @@protoc_insertion_point(constructor:exec.shared.RecordBatchDef)
}
RecordBatchDef::RecordBatchDef(const RecordBatchDef& from)
  : ::google::protobuf::Message(),
      _internal_metadata_(NULL),
      _has_bits_(from._has_bits_),
      field_(from.field_) {
  _internal_metadata_.MergeFrom(from._internal_metadata_);
  ::memcpy(&record_count_, &from.record_count_,
    static_cast<size_t>(reinterpret_cast<char*>(&affected_rows_count_) -
    reinterpret_cast<char*>(&record_count_)) + sizeof(affected_rows_count_));
  // @@protoc_insertion_point(copy_constructor:exec.shared.RecordBatchDef)
}

void RecordBatchDef::SharedCtor() {
  ::memset(&record_count_, 0, static_cast<size_t>(
      reinterpret_cast<char*>(&affected_rows_count_) -
      reinterpret_cast<char*>(&record_count_)) + sizeof(affected_rows_count_));
}

RecordBatchDef::~RecordBatchDef() {
  // @@protoc_insertion_point(destructor:exec.shared.RecordBatchDef)
  SharedDtor();
}

void RecordBatchDef::SharedDtor() {
}

void RecordBatchDef::SetCachedSize(int size) const {
  _cached_size_.Set(size);
}
const ::google::protobuf::Descriptor* RecordBatchDef::descriptor() {
  ::protobuf_UserBitShared_2eproto::protobuf_AssignDescriptorsOnce();
  return ::protobuf_UserBitShared_2eproto::file_level_metadata[kIndexInFileMessages].descriptor;
}

const RecordBatchDef& RecordBatchDef::default_instance() {
  ::google::protobuf::internal::InitSCC(&protobuf_UserBitShared_2eproto::scc_info_RecordBatchDef.base);
  return *internal_default_instance();
}


void RecordBatchDef::Clear() {
// @@protoc_insertion_point(message_clear_start:exec.shared.RecordBatchDef)
  ::google::protobuf::uint32 cached_has_bits = 0;
  // Prevent compiler warnings about cached_has_bits being unused
  (void) cached_has_bits;

  field_.Clear();
  cached_has_bits = _has_bits_[0];
  if (cached_has_bits & 7u) {
    ::memset(&record_count_, 0, static_cast<size_t>(
        reinterpret_cast<char*>(&affected_rows_count_) -
        reinterpret_cast<char*>(&record_count_)) + sizeof(affected_rows_count_));
  }
  _has_bits_.Clear();
  _internal_metadata_.Clear();
}

bool RecordBatchDef::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:exec.shared.RecordBatchDef)
  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)) {
      // optional int32 record_count = 1;
      case 1: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(8u /* 8 & 0xFF */)) {
          set_has_record_count();
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
                 input, &record_count_)));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // repeated .exec.shared.SerializedField field = 2;
      case 2: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(18u /* 18 & 0xFF */)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
                input, add_field()));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // optional bool carries_two_byte_selection_vector = 3;
      case 3: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(24u /* 24 & 0xFF */)) {
          set_has_carries_two_byte_selection_vector();
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
                 input, &carries_two_byte_selection_vector_)));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // optional int32 affected_rows_count = 4;
      case 4: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(32u /* 32 & 0xFF */)) {
          set_has_affected_rows_count();
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
                 input, &affected_rows_count_)));
        } else {
          goto handle_unusual;
        }
        break;
      }

      default: {
      handle_unusual:
        if (tag == 0) {
          goto success;
        }
        DO_(::google::protobuf::internal::WireFormat::SkipField(
              input, tag, _internal_metadata_.mutable_unknown_fields()));
        break;
      }
    }
  }
success:
  // @@protoc_insertion_point(parse_success:exec.shared.RecordBatchDef)
  return true;
failure:
  // @@protoc_insertion_point(parse_failure:exec.shared.RecordBatchDef)
  return false;
#undef DO_
}

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

  cached_has_bits = _has_bits_[0];
  // optional int32 record_count = 1;
  if (cached_has_bits & 0x00000001u) {
    ::google::protobuf::internal::WireFormatLite::WriteInt32(1, this->record_count(), output);
  }

  // repeated .exec.shared.SerializedField field = 2;
  for (unsigned int i = 0,
      n = static_cast<unsigned int>(this->field_size()); i < n; i++) {
    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
      2,
      this->field(static_cast<int>(i)),
      output);
  }

  // optional bool carries_two_byte_selection_vector = 3;
  if (cached_has_bits & 0x00000002u) {
    ::google::protobuf::internal::WireFormatLite::WriteBool(3, this->carries_two_byte_selection_vector(), output);
  }

  // optional int32 affected_rows_count = 4;
  if (cached_has_bits & 0x00000004u) {
    ::google::protobuf::internal::WireFormatLite::WriteInt32(4, this->affected_rows_count(), output);
  }

  if (_internal_metadata_.have_unknown_fields()) {
    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
        _internal_metadata_.unknown_fields(), output);
  }
  // @@protoc_insertion_point(serialize_end:exec.shared.RecordBatchDef)
}

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

  cached_has_bits = _has_bits_[0];
  // optional int32 record_count = 1;
  if (cached_has_bits & 0x00000001u) {
    target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(1, this->record_count(), target);
  }

  // repeated .exec.shared.SerializedField field = 2;
  for (unsigned int i = 0,
      n = static_cast<unsigned int>(this->field_size()); i < n; i++) {
    target = ::google::protobuf::internal::WireFormatLite::
      InternalWriteMessageToArray(
        2, this->field(static_cast<int>(i)), deterministic, target);
  }

  // optional bool carries_two_byte_selection_vector = 3;
  if (cached_has_bits & 0x00000002u) {
    target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(3, this->carries_two_byte_selection_vector(), target);
  }

  // optional int32 affected_rows_count = 4;
  if (cached_has_bits & 0x00000004u) {
    target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(4, this->affected_rows_count(), target);
  }

  if (_internal_metadata_.have_unknown_fields()) {
    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
        _internal_metadata_.unknown_fields(), target);
  }
  // @@protoc_insertion_point(serialize_to_array_end:exec.shared.RecordBatchDef)
  return target;
}

size_t RecordBatchDef::ByteSizeLong() const {
// @@protoc_insertion_point(message_byte_size_start:exec.shared.RecordBatchDef)
  size_t total_size = 0;

  if (_internal_metadata_.have_unknown_fields()) {
    total_size +=
      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
        _internal_metadata_.unknown_fields());
  }
  // repeated .exec.shared.SerializedField field = 2;
  {
    unsigned int count = static_cast<unsigned int>(this->field_size());
    total_size += 1UL * count;
    for (unsigned int i = 0; i < count; i++) {
      total_size +=
        ::google::protobuf::internal::WireFormatLite::MessageSize(
          this->field(static_cast<int>(i)));
    }
  }

  if (_has_bits_[0 / 32] & 7u) {
    // optional int32 record_count = 1;
    if (has_record_count()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::Int32Size(
          this->record_count());
    }

    // optional bool carries_two_byte_selection_vector = 3;
    if (has_carries_two_byte_selection_vector()) {
      total_size += 1 + 1;
    }

    // optional int32 affected_rows_count = 4;
    if (has_affected_rows_count()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::Int32Size(
          this->affected_rows_count());
    }

  }
  int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
  SetCachedSize(cached_size);
  return total_size;
}

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

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

  field_.MergeFrom(from.field_);
  cached_has_bits = from._has_bits_[0];
  if (cached_has_bits & 7u) {
    if (cached_has_bits & 0x00000001u) {
      record_count_ = from.record_count_;
    }
    if (cached_has_bits & 0x00000002u) {
      carries_two_byte_selection_vector_ = from.carries_two_byte_selection_vector_;
    }
    if (cached_has_bits & 0x00000004u) {
      affected_rows_count_ = from.affected_rows_count_;
    }
    _has_bits_[0] |= cached_has_bits;
  }
}

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

void RecordBatchDef::CopyFrom(const RecordBatchDef& from) {
// @@protoc_insertion_point(class_specific_copy_from_start:exec.shared.RecordBatchDef)
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

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

void RecordBatchDef::Swap(RecordBatchDef* other) {
  if (other == this) return;
  InternalSwap(other);
}
void RecordBatchDef::InternalSwap(RecordBatchDef* other) {
  using std::swap;
  CastToBase(&field_)->InternalSwap(CastToBase(&other->field_));
  swap(record_count_, other->record_count_);
  swap(carries_two_byte_selection_vector_, other->carries_two_byte_selection_vector_);
  swap(affected_rows_count_, other->affected_rows_count_);
  swap(_has_bits_[0], other->_has_bits_[0]);
  _internal_metadata_.Swap(&other->_internal_metadata_);
}

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


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

void NamePart::InitAsDefaultInstance() {
  ::exec::shared::_NamePart_default_instance_._instance.get_mutable()->child_ = const_cast< ::exec::shared::NamePart*>(
      ::exec::shared::NamePart::internal_default_instance());
}
#if !defined(_MSC_VER) || _MSC_VER >= 1900
const int NamePart::kTypeFieldNumber;
const int NamePart::kNameFieldNumber;
const int NamePart::kChildFieldNumber;
#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900

NamePart::NamePart()
  : ::google::protobuf::Message(), _internal_metadata_(NULL) {
  ::google::protobuf::internal::InitSCC(
      &protobuf_UserBitShared_2eproto::scc_info_NamePart.base);
  SharedCtor();
  // @@protoc_insertion_point(constructor:exec.shared.NamePart)
}
NamePart::NamePart(const NamePart& from)
  : ::google::protobuf::Message(),
      _internal_metadata_(NULL),
      _has_bits_(from._has_bits_) {
  _internal_metadata_.MergeFrom(from._internal_metadata_);
  name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  if (from.has_name()) {
    name_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.name_);
  }
  if (from.has_child()) {
    child_ = new ::exec::shared::NamePart(*from.child_);
  } else {
    child_ = NULL;
  }
  type_ = from.type_;
  // @@protoc_insertion_point(copy_constructor:exec.shared.NamePart)
}

void NamePart::SharedCtor() {
  name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  ::memset(&child_, 0, static_cast<size_t>(
      reinterpret_cast<char*>(&type_) -
      reinterpret_cast<char*>(&child_)) + sizeof(type_));
}

NamePart::~NamePart() {
  // @@protoc_insertion_point(destructor:exec.shared.NamePart)
  SharedDtor();
}

void NamePart::SharedDtor() {
  name_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  if (this != internal_default_instance()) delete child_;
}

void NamePart::SetCachedSize(int size) const {
  _cached_size_.Set(size);
}
const ::google::protobuf::Descriptor* NamePart::descriptor() {
  ::protobuf_UserBitShared_2eproto::protobuf_AssignDescriptorsOnce();
  return ::protobuf_UserBitShared_2eproto::file_level_metadata[kIndexInFileMessages].descriptor;
}

const NamePart& NamePart::default_instance() {
  ::google::protobuf::internal::InitSCC(&protobuf_UserBitShared_2eproto::scc_info_NamePart.base);
  return *internal_default_instance();
}


void NamePart::Clear() {
// @@protoc_insertion_point(message_clear_start:exec.shared.NamePart)
  ::google::protobuf::uint32 cached_has_bits = 0;
  // Prevent compiler warnings about cached_has_bits being unused
  (void) cached_has_bits;

  cached_has_bits = _has_bits_[0];
  if (cached_has_bits & 3u) {
    if (cached_has_bits & 0x00000001u) {
      name_.ClearNonDefaultToEmptyNoArena();
    }
    if (cached_has_bits & 0x00000002u) {
      GOOGLE_DCHECK(child_ != NULL);
      child_->Clear();
    }
  }
  type_ = 0;
  _has_bits_.Clear();
  _internal_metadata_.Clear();
}

bool NamePart::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:exec.shared.NamePart)
  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)) {
      // optional .exec.shared.NamePart.Type type = 1;
      case 1: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(8u /* 8 & 0xFF */)) {
          int value;
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
                 input, &value)));
          if (::exec::shared::NamePart_Type_IsValid(value)) {
            set_type(static_cast< ::exec::shared::NamePart_Type >(value));
          } else {
            mutable_unknown_fields()->AddVarint(
                1, static_cast< ::google::protobuf::uint64>(value));
          }
        } else {
          goto handle_unusual;
        }
        break;
      }

      // optional string name = 2;
      case 2: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(18u /* 18 & 0xFF */)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                input, this->mutable_name()));
          ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
            this->name().data(), static_cast<int>(this->name().length()),
            ::google::protobuf::internal::WireFormat::PARSE,
            "exec.shared.NamePart.name");
        } else {
          goto handle_unusual;
        }
        break;
      }

      // optional .exec.shared.NamePart child = 3;
      case 3: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(26u /* 26 & 0xFF */)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
               input, mutable_child()));
        } else {
          goto handle_unusual;
        }
        break;
      }

      default: {
      handle_unusual:
        if (tag == 0) {
          goto success;
        }
        DO_(::google::protobuf::internal::WireFormat::SkipField(
              input, tag, _internal_metadata_.mutable_unknown_fields()));
        break;
      }
    }
  }
success:
  // @@protoc_insertion_point(parse_success:exec.shared.NamePart)
  return true;
failure:
  // @@protoc_insertion_point(parse_failure:exec.shared.NamePart)
  return false;
#undef DO_
}

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

  cached_has_bits = _has_bits_[0];
  // optional .exec.shared.NamePart.Type type = 1;
  if (cached_has_bits & 0x00000004u) {
    ::google::protobuf::internal::WireFormatLite::WriteEnum(
      1, this->type(), output);
  }

  // optional string name = 2;
  if (cached_has_bits & 0x00000001u) {
    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
      this->name().data(), static_cast<int>(this->name().length()),
      ::google::protobuf::internal::WireFormat::SERIALIZE,
      "exec.shared.NamePart.name");
    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
      2, this->name(), output);
  }

  // optional .exec.shared.NamePart child = 3;
  if (cached_has_bits & 0x00000002u) {
    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
      3, this->_internal_child(), output);
  }

  if (_internal_metadata_.have_unknown_fields()) {
    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
        _internal_metadata_.unknown_fields(), output);
  }
  // @@protoc_insertion_point(serialize_end:exec.shared.NamePart)
}

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

  cached_has_bits = _has_bits_[0];
  // optional .exec.shared.NamePart.Type type = 1;
  if (cached_has_bits & 0x00000004u) {
    target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
      1, this->type(), target);
  }

  // optional string name = 2;
  if (cached_has_bits & 0x00000001u) {
    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
      this->name().data(), static_cast<int>(this->name().length()),
      ::google::protobuf::internal::WireFormat::SERIALIZE,
      "exec.shared.NamePart.name");
    target =
      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
        2, this->name(), target);
  }

  // optional .exec.shared.NamePart child = 3;
  if (cached_has_bits & 0x00000002u) {
    target = ::google::protobuf::internal::WireFormatLite::
      InternalWriteMessageToArray(
        3, this->_internal_child(), deterministic, target);
  }

  if (_internal_metadata_.have_unknown_fields()) {
    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
        _internal_metadata_.unknown_fields(), target);
  }
  // @@protoc_insertion_point(serialize_to_array_end:exec.shared.NamePart)
  return target;
}

size_t NamePart::ByteSizeLong() const {
// @@protoc_insertion_point(message_byte_size_start:exec.shared.NamePart)
  size_t total_size = 0;

  if (_internal_metadata_.have_unknown_fields()) {
    total_size +=
      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
        _internal_metadata_.unknown_fields());
  }
  if (_has_bits_[0 / 32] & 7u) {
    // optional string name = 2;
    if (has_name()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::StringSize(
          this->name());
    }

    // optional .exec.shared.NamePart child = 3;
    if (has_child()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::MessageSize(
          *child_);
    }

    // optional .exec.shared.NamePart.Type type = 1;
    if (has_type()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::EnumSize(this->type());
    }

  }
  int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
  SetCachedSize(cached_size);
  return total_size;
}

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

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

  cached_has_bits = from._has_bits_[0];
  if (cached_has_bits & 7u) {
    if (cached_has_bits & 0x00000001u) {
      set_has_name();
      name_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.name_);
    }
    if (cached_has_bits & 0x00000002u) {
      mutable_child()->::exec::shared::NamePart::MergeFrom(from.child());
    }
    if (cached_has_bits & 0x00000004u) {
      type_ = from.type_;
    }
    _has_bits_[0] |= cached_has_bits;
  }
}

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

void NamePart::CopyFrom(const NamePart& from) {
// @@protoc_insertion_point(class_specific_copy_from_start:exec.shared.NamePart)
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

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

void NamePart::Swap(NamePart* other) {
  if (other == this) return;
  InternalSwap(other);
}
void NamePart::InternalSwap(NamePart* other) {
  using std::swap;
  name_.Swap(&other->name_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
    GetArenaNoVirtual());
  swap(child_, other->child_);
  swap(type_, other->type_);
  swap(_has_bits_[0], other->_has_bits_[0]);
  _internal_metadata_.Swap(&other->_internal_metadata_);
}

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


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

void SerializedField::InitAsDefaultInstance() {
  ::exec::shared::_SerializedField_default_instance_._instance.get_mutable()->major_type_ = const_cast< ::common::MajorType*>(
      ::common::MajorType::internal_default_instance());
  ::exec::shared::_SerializedField_default_instance_._instance.get_mutable()->name_part_ = const_cast< ::exec::shared::NamePart*>(
      ::exec::shared::NamePart::internal_default_instance());
}
void SerializedField::clear_major_type() {
  if (major_type_ != NULL) major_type_->Clear();
  clear_has_major_type();
}
#if !defined(_MSC_VER) || _MSC_VER >= 1900
const int SerializedField::kMajorTypeFieldNumber;
const int SerializedField::kNamePartFieldNumber;
const int SerializedField::kChildFieldNumber;
const int SerializedField::kValueCountFieldNumber;
const int SerializedField::kVarByteLengthFieldNumber;
const int SerializedField::kBufferLengthFieldNumber;
#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900

SerializedField::SerializedField()
  : ::google::protobuf::Message(), _internal_metadata_(NULL) {
  ::google::protobuf::internal::InitSCC(
      &protobuf_UserBitShared_2eproto::scc_info_SerializedField.base);
  SharedCtor();
  // @@protoc_insertion_point(constructor:exec.shared.SerializedField)
}
SerializedField::SerializedField(const SerializedField& from)
  : ::google::protobuf::Message(),
      _internal_metadata_(NULL),
      _has_bits_(from._has_bits_),
      child_(from.child_) {
  _internal_metadata_.MergeFrom(from._internal_metadata_);
  if (from.has_major_type()) {
    major_type_ = new ::common::MajorType(*from.major_type_);
  } else {
    major_type_ = NULL;
  }
  if (from.has_name_part()) {
    name_part_ = new ::exec::shared::NamePart(*from.name_part_);
  } else {
    name_part_ = NULL;
  }
  ::memcpy(&value_count_, &from.value_count_,
    static_cast<size_t>(reinterpret_cast<char*>(&buffer_length_) -
    reinterpret_cast<char*>(&value_count_)) + sizeof(buffer_length_));
  // @@protoc_insertion_point(copy_constructor:exec.shared.SerializedField)
}

void SerializedField::SharedCtor() {
  ::memset(&major_type_, 0, static_cast<size_t>(
      reinterpret_cast<char*>(&buffer_length_) -
      reinterpret_cast<char*>(&major_type_)) + sizeof(buffer_length_));
}

SerializedField::~SerializedField() {
  // @@protoc_insertion_point(destructor:exec.shared.SerializedField)
  SharedDtor();
}

void SerializedField::SharedDtor() {
  if (this != internal_default_instance()) delete major_type_;
  if (this != internal_default_instance()) delete name_part_;
}

void SerializedField::SetCachedSize(int size) const {
  _cached_size_.Set(size);
}
const ::google::protobuf::Descriptor* SerializedField::descriptor() {
  ::protobuf_UserBitShared_2eproto::protobuf_AssignDescriptorsOnce();
  return ::protobuf_UserBitShared_2eproto::file_level_metadata[kIndexInFileMessages].descriptor;
}

const SerializedField& SerializedField::default_instance() {
  ::google::protobuf::internal::InitSCC(&protobuf_UserBitShared_2eproto::scc_info_SerializedField.base);
  return *internal_default_instance();
}


void SerializedField::Clear() {
// @@protoc_insertion_point(message_clear_start:exec.shared.SerializedField)
  ::google::protobuf::uint32 cached_has_bits = 0;
  // Prevent compiler warnings about cached_has_bits being unused
  (void) cached_has_bits;

  child_.Clear();
  cached_has_bits = _has_bits_[0];
  if (cached_has_bits & 3u) {
    if (cached_has_bits & 0x00000001u) {
      GOOGLE_DCHECK(major_type_ != NULL);
      major_type_->Clear();
    }
    if (cached_has_bits & 0x00000002u) {
      GOOGLE_DCHECK(name_part_ != NULL);
      name_part_->Clear();
    }
  }
  if (cached_has_bits & 28u) {
    ::memset(&value_count_, 0, static_cast<size_t>(
        reinterpret_cast<char*>(&buffer_length_) -
        reinterpret_cast<char*>(&value_count_)) + sizeof(buffer_length_));
  }
  _has_bits_.Clear();
  _internal_metadata_.Clear();
}

bool SerializedField::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:exec.shared.SerializedField)
  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)) {
      // optional .common.MajorType major_type = 1;
      case 1: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(10u /* 10 & 0xFF */)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
               input, mutable_major_type()));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // optional .exec.shared.NamePart name_part = 2;
      case 2: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(18u /* 18 & 0xFF */)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
               input, mutable_name_part()));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // repeated .exec.shared.SerializedField child = 3;
      case 3: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(26u /* 26 & 0xFF */)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
                input, add_child()));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // optional int32 value_count = 4;
      case 4: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(32u /* 32 & 0xFF */)) {
          set_has_value_count();
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
                 input, &value_count_)));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // optional int32 var_byte_length = 5;
      case 5: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(40u /* 40 & 0xFF */)) {
          set_has_var_byte_length();
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
                 input, &var_byte_length_)));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // optional int32 buffer_length = 7;
      case 7: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(56u /* 56 & 0xFF */)) {
          set_has_buffer_length();
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
                 input, &buffer_length_)));
        } else {
          goto handle_unusual;
        }
        break;
      }

      default: {
      handle_unusual:
        if (tag == 0) {
          goto success;
        }
        DO_(::google::protobuf::internal::WireFormat::SkipField(
              input, tag, _internal_metadata_.mutable_unknown_fields()));
        break;
      }
    }
  }
success:
  // @@protoc_insertion_point(parse_success:exec.shared.SerializedField)
  return true;
failure:
  // @@protoc_insertion_point(parse_failure:exec.shared.SerializedField)
  return false;
#undef DO_
}

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

  cached_has_bits = _has_bits_[0];
  // optional .common.MajorType major_type = 1;
  if (cached_has_bits & 0x00000001u) {
    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
      1, this->_internal_major_type(), output);
  }

  // optional .exec.shared.NamePart name_part = 2;
  if (cached_has_bits & 0x00000002u) {
    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
      2, this->_internal_name_part(), output);
  }

  // repeated .exec.shared.SerializedField child = 3;
  for (unsigned int i = 0,
      n = static_cast<unsigned int>(this->child_size()); i < n; i++) {
    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
      3,
      this->child(static_cast<int>(i)),
      output);
  }

  // optional int32 value_count = 4;
  if (cached_has_bits & 0x00000004u) {
    ::google::protobuf::internal::WireFormatLite::WriteInt32(4, this->value_count(), output);
  }

  // optional int32 var_byte_length = 5;
  if (cached_has_bits & 0x00000008u) {
    ::google::protobuf::internal::WireFormatLite::WriteInt32(5, this->var_byte_length(), output);
  }

  // optional int32 buffer_length = 7;
  if (cached_has_bits & 0x00000010u) {
    ::google::protobuf::internal::WireFormatLite::WriteInt32(7, this->buffer_length(), output);
  }

  if (_internal_metadata_.have_unknown_fields()) {
    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
        _internal_metadata_.unknown_fields(), output);
  }
  // @@protoc_insertion_point(serialize_end:exec.shared.SerializedField)
}

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

  cached_has_bits = _has_bits_[0];
  // optional .common.MajorType major_type = 1;
  if (cached_has_bits & 0x00000001u) {
    target = ::google::protobuf::internal::WireFormatLite::
      InternalWriteMessageToArray(
        1, this->_internal_major_type(), deterministic, target);
  }

  // optional .exec.shared.NamePart name_part = 2;
  if (cached_has_bits & 0x00000002u) {
    target = ::google::protobuf::internal::WireFormatLite::
      InternalWriteMessageToArray(
        2, this->_internal_name_part(), deterministic, target);
  }

  // repeated .exec.shared.SerializedField child = 3;
  for (unsigned int i = 0,
      n = static_cast<unsigned int>(this->child_size()); i < n; i++) {
    target = ::google::protobuf::internal::WireFormatLite::
      InternalWriteMessageToArray(
        3, this->child(static_cast<int>(i)), deterministic, target);
  }

  // optional int32 value_count = 4;
  if (cached_has_bits & 0x00000004u) {
    target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(4, this->value_count(), target);
  }

  // optional int32 var_byte_length = 5;
  if (cached_has_bits & 0x00000008u) {
    target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(5, this->var_byte_length(), target);
  }

  // optional int32 buffer_length = 7;
  if (cached_has_bits & 0x00000010u) {
    target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(7, this->buffer_length(), target);
  }

  if (_internal_metadata_.have_unknown_fields()) {
    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
        _internal_metadata_.unknown_fields(), target);
  }
  // @@protoc_insertion_point(serialize_to_array_end:exec.shared.SerializedField)
  return target;
}

size_t SerializedField::ByteSizeLong() const {
// @@protoc_insertion_point(message_byte_size_start:exec.shared.SerializedField)
  size_t total_size = 0;

  if (_internal_metadata_.have_unknown_fields()) {
    total_size +=
      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
        _internal_metadata_.unknown_fields());
  }
  // repeated .exec.shared.SerializedField child = 3;
  {
    unsigned int count = static_cast<unsigned int>(this->child_size());
    total_size += 1UL * count;
    for (unsigned int i = 0; i < count; i++) {
      total_size +=
        ::google::protobuf::internal::WireFormatLite::MessageSize(
          this->child(static_cast<int>(i)));
    }
  }

  if (_has_bits_[0 / 32] & 31u) {
    // optional .common.MajorType major_type = 1;
    if (has_major_type()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::MessageSize(
          *major_type_);
    }

    // optional .exec.shared.NamePart name_part = 2;
    if (has_name_part()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::MessageSize(
          *name_part_);
    }

    // optional int32 value_count = 4;
    if (has_value_count()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::Int32Size(
          this->value_count());
    }

    // optional int32 var_byte_length = 5;
    if (has_var_byte_length()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::Int32Size(
          this->var_byte_length());
    }

    // optional int32 buffer_length = 7;
    if (has_buffer_length()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::Int32Size(
          this->buffer_length());
    }

  }
  int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
  SetCachedSize(cached_size);
  return total_size;
}

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

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

  child_.MergeFrom(from.child_);
  cached_has_bits = from._has_bits_[0];
  if (cached_has_bits & 31u) {
    if (cached_has_bits & 0x00000001u) {
      mutable_major_type()->::common::MajorType::MergeFrom(from.major_type());
    }
    if (cached_has_bits & 0x00000002u) {
      mutable_name_part()->::exec::shared::NamePart::MergeFrom(from.name_part());
    }
    if (cached_has_bits & 0x00000004u) {
      value_count_ = from.value_count_;
    }
    if (cached_has_bits & 0x00000008u) {
      var_byte_length_ = from.var_byte_length_;
    }
    if (cached_has_bits & 0x00000010u) {
      buffer_length_ = from.buffer_length_;
    }
    _has_bits_[0] |= cached_has_bits;
  }
}

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

void SerializedField::CopyFrom(const SerializedField& from) {
// @@protoc_insertion_point(class_specific_copy_from_start:exec.shared.SerializedField)
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

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

void SerializedField::Swap(SerializedField* other) {
  if (other == this) return;
  InternalSwap(other);
}
void SerializedField::InternalSwap(SerializedField* other) {
  using std::swap;
  CastToBase(&child_)->InternalSwap(CastToBase(&other->child_));
  swap(major_type_, other->major_type_);
  swap(name_part_, other->name_part_);
  swap(value_count_, other->value_count_);
  swap(var_byte_length_, other->var_byte_length_);
  swap(buffer_length_, other->buffer_length_);
  swap(_has_bits_[0], other->_has_bits_[0]);
  _internal_metadata_.Swap(&other->_internal_metadata_);
}

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


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

void NodeStatus::InitAsDefaultInstance() {
}
#if !defined(_MSC_VER) || _MSC_VER >= 1900
const int NodeStatus::kNodeIdFieldNumber;
const int NodeStatus::kMemoryFootprintFieldNumber;
#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900

NodeStatus::NodeStatus()
  : ::google::protobuf::Message(), _internal_metadata_(NULL) {
  ::google::protobuf::internal::InitSCC(
      &protobuf_UserBitShared_2eproto::scc_info_NodeStatus.base);
  SharedCtor();
  // @@protoc_insertion_point(constructor:exec.shared.NodeStatus)
}
NodeStatus::NodeStatus(const NodeStatus& from)
  : ::google::protobuf::Message(),
      _internal_metadata_(NULL),
      _has_bits_(from._has_bits_) {
  _internal_metadata_.MergeFrom(from._internal_metadata_);
  ::memcpy(&memory_footprint_, &from.memory_footprint_,
    static_cast<size_t>(reinterpret_cast<char*>(&node_id_) -
    reinterpret_cast<char*>(&memory_footprint_)) + sizeof(node_id_));
  // @@protoc_insertion_point(copy_constructor:exec.shared.NodeStatus)
}

void NodeStatus::SharedCtor() {
  ::memset(&memory_footprint_, 0, static_cast<size_t>(
      reinterpret_cast<char*>(&node_id_) -
      reinterpret_cast<char*>(&memory_footprint_)) + sizeof(node_id_));
}

NodeStatus::~NodeStatus() {
  // @@protoc_insertion_point(destructor:exec.shared.NodeStatus)
  SharedDtor();
}

void NodeStatus::SharedDtor() {
}

void NodeStatus::SetCachedSize(int size) const {
  _cached_size_.Set(size);
}
const ::google::protobuf::Descriptor* NodeStatus::descriptor() {
  ::protobuf_UserBitShared_2eproto::protobuf_AssignDescriptorsOnce();
  return ::protobuf_UserBitShared_2eproto::file_level_metadata[kIndexInFileMessages].descriptor;
}

const NodeStatus& NodeStatus::default_instance() {
  ::google::protobuf::internal::InitSCC(&protobuf_UserBitShared_2eproto::scc_info_NodeStatus.base);
  return *internal_default_instance();
}


void NodeStatus::Clear() {
// @@protoc_insertion_point(message_clear_start:exec.shared.NodeStatus)
  ::google::protobuf::uint32 cached_has_bits = 0;
  // Prevent compiler warnings about cached_has_bits being unused
  (void) cached_has_bits;

  cached_has_bits = _has_bits_[0];
  if (cached_has_bits & 3u) {
    ::memset(&memory_footprint_, 0, static_cast<size_t>(
        reinterpret_cast<char*>(&node_id_) -
        reinterpret_cast<char*>(&memory_footprint_)) + sizeof(node_id_));
  }
  _has_bits_.Clear();
  _internal_metadata_.Clear();
}

bool NodeStatus::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:exec.shared.NodeStatus)
  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)) {
      // optional int32 node_id = 1;
      case 1: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(8u /* 8 & 0xFF */)) {
          set_has_node_id();
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
                 input, &node_id_)));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // optional int64 memory_footprint = 2;
      case 2: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(16u /* 16 & 0xFF */)) {
          set_has_memory_footprint();
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   ::google::protobuf::int64, ::google::protobuf::internal::WireFormatLite::TYPE_INT64>(
                 input, &memory_footprint_)));
        } else {
          goto handle_unusual;
        }
        break;
      }

      default: {
      handle_unusual:
        if (tag == 0) {
          goto success;
        }
        DO_(::google::protobuf::internal::WireFormat::SkipField(
              input, tag, _internal_metadata_.mutable_unknown_fields()));
        break;
      }
    }
  }
success:
  // @@protoc_insertion_point(parse_success:exec.shared.NodeStatus)
  return true;
failure:
  // @@protoc_insertion_point(parse_failure:exec.shared.NodeStatus)
  return false;
#undef DO_
}

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

  cached_has_bits = _has_bits_[0];
  // optional int32 node_id = 1;
  if (cached_has_bits & 0x00000002u) {
    ::google::protobuf::internal::WireFormatLite::WriteInt32(1, this->node_id(), output);
  }

  // optional int64 memory_footprint = 2;
  if (cached_has_bits & 0x00000001u) {
    ::google::protobuf::internal::WireFormatLite::WriteInt64(2, this->memory_footprint(), output);
  }

  if (_internal_metadata_.have_unknown_fields()) {
    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
        _internal_metadata_.unknown_fields(), output);
  }
  // @@protoc_insertion_point(serialize_end:exec.shared.NodeStatus)
}

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

  cached_has_bits = _has_bits_[0];
  // optional int32 node_id = 1;
  if (cached_has_bits & 0x00000002u) {
    target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(1, this->node_id(), target);
  }

  // optional int64 memory_footprint = 2;
  if (cached_has_bits & 0x00000001u) {
    target = ::google::protobuf::internal::WireFormatLite::WriteInt64ToArray(2, this->memory_footprint(), target);
  }

  if (_internal_metadata_.have_unknown_fields()) {
    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
        _internal_metadata_.unknown_fields(), target);
  }
  // @@protoc_insertion_point(serialize_to_array_end:exec.shared.NodeStatus)
  return target;
}

size_t NodeStatus::ByteSizeLong() const {
// @@protoc_insertion_point(message_byte_size_start:exec.shared.NodeStatus)
  size_t total_size = 0;

  if (_internal_metadata_.have_unknown_fields()) {
    total_size +=
      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
        _internal_metadata_.unknown_fields());
  }
  if (_has_bits_[0 / 32] & 3u) {
    // optional int64 memory_footprint = 2;
    if (has_memory_footprint()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::Int64Size(
          this->memory_footprint());
    }

    // optional int32 node_id = 1;
    if (has_node_id()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::Int32Size(
          this->node_id());
    }

  }
  int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
  SetCachedSize(cached_size);
  return total_size;
}

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

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

  cached_has_bits = from._has_bits_[0];
  if (cached_has_bits & 3u) {
    if (cached_has_bits & 0x00000001u) {
      memory_footprint_ = from.memory_footprint_;
    }
    if (cached_has_bits & 0x00000002u) {
      node_id_ = from.node_id_;
    }
    _has_bits_[0] |= cached_has_bits;
  }
}

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

void NodeStatus::CopyFrom(const NodeStatus& from) {
// @@protoc_insertion_point(class_specific_copy_from_start:exec.shared.NodeStatus)
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

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

void NodeStatus::Swap(NodeStatus* other) {
  if (other == this) return;
  InternalSwap(other);
}
void NodeStatus::InternalSwap(NodeStatus* other) {
  using std::swap;
  swap(memory_footprint_, other->memory_footprint_);
  swap(node_id_, other->node_id_);
  swap(_has_bits_[0], other->_has_bits_[0]);
  _internal_metadata_.Swap(&other->_internal_metadata_);
}

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


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

void QueryResult::InitAsDefaultInstance() {
  ::exec::shared::_QueryResult_default_instance_._instance.get_mutable()->query_id_ = const_cast< ::exec::shared::QueryId*>(
      ::exec::shared::QueryId::internal_default_instance());
}
#if !defined(_MSC_VER) || _MSC_VER >= 1900
const int QueryResult::kQueryStateFieldNumber;
const int QueryResult::kQueryIdFieldNumber;
const int QueryResult::kErrorFieldNumber;
#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900

QueryResult::QueryResult()
  : ::google::protobuf::Message(), _internal_metadata_(NULL) {
  ::google::protobuf::internal::InitSCC(
      &protobuf_UserBitShared_2eproto::scc_info_QueryResult.base);
  SharedCtor();
  // @@protoc_insertion_point(constructor:exec.shared.QueryResult)
}
QueryResult::QueryResult(const QueryResult& from)
  : ::google::protobuf::Message(),
      _internal_metadata_(NULL),
      _has_bits_(from._has_bits_),
      error_(from.error_) {
  _internal_metadata_.MergeFrom(from._internal_metadata_);
  if (from.has_query_id()) {
    query_id_ = new ::exec::shared::QueryId(*from.query_id_);
  } else {
    query_id_ = NULL;
  }
  query_state_ = from.query_state_;
  // @@protoc_insertion_point(copy_constructor:exec.shared.QueryResult)
}

void QueryResult::SharedCtor() {
  ::memset(&query_id_, 0, static_cast<size_t>(
      reinterpret_cast<char*>(&query_state_) -
      reinterpret_cast<char*>(&query_id_)) + sizeof(query_state_));
}

QueryResult::~QueryResult() {
  // @@protoc_insertion_point(destructor:exec.shared.QueryResult)
  SharedDtor();
}

void QueryResult::SharedDtor() {
  if (this != internal_default_instance()) delete query_id_;
}

void QueryResult::SetCachedSize(int size) const {
  _cached_size_.Set(size);
}
const ::google::protobuf::Descriptor* QueryResult::descriptor() {
  ::protobuf_UserBitShared_2eproto::protobuf_AssignDescriptorsOnce();
  return ::protobuf_UserBitShared_2eproto::file_level_metadata[kIndexInFileMessages].descriptor;
}

const QueryResult& QueryResult::default_instance() {
  ::google::protobuf::internal::InitSCC(&protobuf_UserBitShared_2eproto::scc_info_QueryResult.base);
  return *internal_default_instance();
}


void QueryResult::Clear() {
// @@protoc_insertion_point(message_clear_start:exec.shared.QueryResult)
  ::google::protobuf::uint32 cached_has_bits = 0;
  // Prevent compiler warnings about cached_has_bits being unused
  (void) cached_has_bits;

  error_.Clear();
  cached_has_bits = _has_bits_[0];
  if (cached_has_bits & 0x00000001u) {
    GOOGLE_DCHECK(query_id_ != NULL);
    query_id_->Clear();
  }
  query_state_ = 0;
  _has_bits_.Clear();
  _internal_metadata_.Clear();
}

bool QueryResult::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:exec.shared.QueryResult)
  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)) {
      // optional .exec.shared.QueryResult.QueryState query_state = 1;
      case 1: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(8u /* 8 & 0xFF */)) {
          int value;
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
                 input, &value)));
          if (::exec::shared::QueryResult_QueryState_IsValid(value)) {
            set_query_state(static_cast< ::exec::shared::QueryResult_QueryState >(value));
          } else {
            mutable_unknown_fields()->AddVarint(
                1, static_cast< ::google::protobuf::uint64>(value));
          }
        } else {
          goto handle_unusual;
        }
        break;
      }

      // optional .exec.shared.QueryId query_id = 2;
      case 2: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(18u /* 18 & 0xFF */)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
               input, mutable_query_id()));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // repeated .exec.shared.DrillPBError error = 3;
      case 3: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(26u /* 26 & 0xFF */)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
                input, add_error()));
        } else {
          goto handle_unusual;
        }
        break;
      }

      default: {
      handle_unusual:
        if (tag == 0) {
          goto success;
        }
        DO_(::google::protobuf::internal::WireFormat::SkipField(
              input, tag, _internal_metadata_.mutable_unknown_fields()));
        break;
      }
    }
  }
success:
  // @@protoc_insertion_point(parse_success:exec.shared.QueryResult)
  return true;
failure:
  // @@protoc_insertion_point(parse_failure:exec.shared.QueryResult)
  return false;
#undef DO_
}

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

  cached_has_bits = _has_bits_[0];
  // optional .exec.shared.QueryResult.QueryState query_state = 1;
  if (cached_has_bits & 0x00000002u) {
    ::google::protobuf::internal::WireFormatLite::WriteEnum(
      1, this->query_state(), output);
  }

  // optional .exec.shared.QueryId query_id = 2;
  if (cached_has_bits & 0x00000001u) {
    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
      2, this->_internal_query_id(), output);
  }

  // repeated .exec.shared.DrillPBError error = 3;
  for (unsigned int i = 0,
      n = static_cast<unsigned int>(this->error_size()); i < n; i++) {
    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
      3,
      this->error(static_cast<int>(i)),
      output);
  }

  if (_internal_metadata_.have_unknown_fields()) {
    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
        _internal_metadata_.unknown_fields(), output);
  }
  // @@protoc_insertion_point(serialize_end:exec.shared.QueryResult)
}

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

  cached_has_bits = _has_bits_[0];
  // optional .exec.shared.QueryResult.QueryState query_state = 1;
  if (cached_has_bits & 0x00000002u) {
    target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
      1, this->query_state(), target);
  }

  // optional .exec.shared.QueryId query_id = 2;
  if (cached_has_bits & 0x00000001u) {
    target = ::google::protobuf::internal::WireFormatLite::
      InternalWriteMessageToArray(
        2, this->_internal_query_id(), deterministic, target);
  }

  // repeated .exec.shared.DrillPBError error = 3;
  for (unsigned int i = 0,
      n = static_cast<unsigned int>(this->error_size()); i < n; i++) {
    target = ::google::protobuf::internal::WireFormatLite::
      InternalWriteMessageToArray(
        3, this->error(static_cast<int>(i)), deterministic, target);
  }

  if (_internal_metadata_.have_unknown_fields()) {
    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
        _internal_metadata_.unknown_fields(), target);
  }
  // @@protoc_insertion_point(serialize_to_array_end:exec.shared.QueryResult)
  return target;
}

size_t QueryResult::ByteSizeLong() const {
// @@protoc_insertion_point(message_byte_size_start:exec.shared.QueryResult)
  size_t total_size = 0;

  if (_internal_metadata_.have_unknown_fields()) {
    total_size +=
      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
        _internal_metadata_.unknown_fields());
  }
  // repeated .exec.shared.DrillPBError error = 3;
  {
    unsigned int count = static_cast<unsigned int>(this->error_size());
    total_size += 1UL * count;
    for (unsigned int i = 0; i < count; i++) {
      total_size +=
        ::google::protobuf::internal::WireFormatLite::MessageSize(
          this->error(static_cast<int>(i)));
    }
  }

  if (_has_bits_[0 / 32] & 3u) {
    // optional .exec.shared.QueryId query_id = 2;
    if (has_query_id()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::MessageSize(
          *query_id_);
    }

    // optional .exec.shared.QueryResult.QueryState query_state = 1;
    if (has_query_state()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::EnumSize(this->query_state());
    }

  }
  int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
  SetCachedSize(cached_size);
  return total_size;
}

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

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

  error_.MergeFrom(from.error_);
  cached_has_bits = from._has_bits_[0];
  if (cached_has_bits & 3u) {
    if (cached_has_bits & 0x00000001u) {
      mutable_query_id()->::exec::shared::QueryId::MergeFrom(from.query_id());
    }
    if (cached_has_bits & 0x00000002u) {
      query_state_ = from.query_state_;
    }
    _has_bits_[0] |= cached_has_bits;
  }
}

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

void QueryResult::CopyFrom(const QueryResult& from) {
// @@protoc_insertion_point(class_specific_copy_from_start:exec.shared.QueryResult)
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

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

void QueryResult::Swap(QueryResult* other) {
  if (other == this) return;
  InternalSwap(other);
}
void QueryResult::InternalSwap(QueryResult* other) {
  using std::swap;
  CastToBase(&error_)->InternalSwap(CastToBase(&other->error_));
  swap(query_id_, other->query_id_);
  swap(query_state_, other->query_state_);
  swap(_has_bits_[0], other->_has_bits_[0]);
  _internal_metadata_.Swap(&other->_internal_metadata_);
}

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


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

void QueryData::InitAsDefaultInstance() {
  ::exec::shared::_QueryData_default_instance_._instance.get_mutable()->query_id_ = const_cast< ::exec::shared::QueryId*>(
      ::exec::shared::QueryId::internal_default_instance());
  ::exec::shared::_QueryData_default_instance_._instance.get_mutable()->def_ = const_cast< ::exec::shared::RecordBatchDef*>(
      ::exec::shared::RecordBatchDef::internal_default_instance());
}
#if !defined(_MSC_VER) || _MSC_VER >= 1900
const int QueryData::kQueryIdFieldNumber;
const int QueryData::kRowCountFieldNumber;
const int QueryData::kDefFieldNumber;
const int QueryData::kAffectedRowsCountFieldNumber;
#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900

QueryData::QueryData()
  : ::google::protobuf::Message(), _internal_metadata_(NULL) {
  ::google::protobuf::internal::InitSCC(
      &protobuf_UserBitShared_2eproto::scc_info_QueryData.base);
  SharedCtor();
  // @@protoc_insertion_point(constructor:exec.shared.QueryData)
}
QueryData::QueryData(const QueryData& from)
  : ::google::protobuf::Message(),
      _internal_metadata_(NULL),
      _has_bits_(from._has_bits_) {
  _internal_metadata_.MergeFrom(from._internal_metadata_);
  if (from.has_query_id()) {
    query_id_ = new ::exec::shared::QueryId(*from.query_id_);
  } else {
    query_id_ = NULL;
  }
  if (from.has_def()) {
    def_ = new ::exec::shared::RecordBatchDef(*from.def_);
  } else {
    def_ = NULL;
  }
  ::memcpy(&row_count_, &from.row_count_,
    static_cast<size_t>(reinterpret_cast<char*>(&affected_rows_count_) -
    reinterpret_cast<char*>(&row_count_)) + sizeof(affected_rows_count_));
  // @@protoc_insertion_point(copy_constructor:exec.shared.QueryData)
}

void QueryData::SharedCtor() {
  ::memset(&query_id_, 0, static_cast<size_t>(
      reinterpret_cast<char*>(&affected_rows_count_) -
      reinterpret_cast<char*>(&query_id_)) + sizeof(affected_rows_count_));
}

QueryData::~QueryData() {
  // @@protoc_insertion_point(destructor:exec.shared.QueryData)
  SharedDtor();
}

void QueryData::SharedDtor() {
  if (this != internal_default_instance()) delete query_id_;
  if (this != internal_default_instance()) delete def_;
}

void QueryData::SetCachedSize(int size) const {
  _cached_size_.Set(size);
}
const ::google::protobuf::Descriptor* QueryData::descriptor() {
  ::protobuf_UserBitShared_2eproto::protobuf_AssignDescriptorsOnce();
  return ::protobuf_UserBitShared_2eproto::file_level_metadata[kIndexInFileMessages].descriptor;
}

const QueryData& QueryData::default_instance() {
  ::google::protobuf::internal::InitSCC(&protobuf_UserBitShared_2eproto::scc_info_QueryData.base);
  return *internal_default_instance();
}


void QueryData::Clear() {
// @@protoc_insertion_point(message_clear_start:exec.shared.QueryData)
  ::google::protobuf::uint32 cached_has_bits = 0;
  // Prevent compiler warnings about cached_has_bits being unused
  (void) cached_has_bits;

  cached_has_bits = _has_bits_[0];
  if (cached_has_bits & 3u) {
    if (cached_has_bits & 0x00000001u) {
      GOOGLE_DCHECK(query_id_ != NULL);
      query_id_->Clear();
    }
    if (cached_has_bits & 0x00000002u) {
      GOOGLE_DCHECK(def_ != NULL);
      def_->Clear();
    }
  }
  if (cached_has_bits & 12u) {
    ::memset(&row_count_, 0, static_cast<size_t>(
        reinterpret_cast<char*>(&affected_rows_count_) -
        reinterpret_cast<char*>(&row_count_)) + sizeof(affected_rows_count_));
  }
  _has_bits_.Clear();
  _internal_metadata_.Clear();
}

bool QueryData::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:exec.shared.QueryData)
  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)) {
      // optional .exec.shared.QueryId query_id = 1;
      case 1: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(10u /* 10 & 0xFF */)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
               input, mutable_query_id()));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // optional int32 row_count = 2;
      case 2: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(16u /* 16 & 0xFF */)) {
          set_has_row_count();
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
                 input, &row_count_)));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // optional .exec.shared.RecordBatchDef def = 3;
      case 3: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(26u /* 26 & 0xFF */)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
               input, mutable_def()));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // optional int32 affected_rows_count = 4;
      case 4: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(32u /* 32 & 0xFF */)) {
          set_has_affected_rows_count();
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
                 input, &affected_rows_count_)));
        } else {
          goto handle_unusual;
        }
        break;
      }

      default: {
      handle_unusual:
        if (tag == 0) {
          goto success;
        }
        DO_(::google::protobuf::internal::WireFormat::SkipField(
              input, tag, _internal_metadata_.mutable_unknown_fields()));
        break;
      }
    }
  }
success:
  // @@protoc_insertion_point(parse_success:exec.shared.QueryData)
  return true;
failure:
  // @@protoc_insertion_point(parse_failure:exec.shared.QueryData)
  return false;
#undef DO_
}

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

  cached_has_bits = _has_bits_[0];
  // optional .exec.shared.QueryId query_id = 1;
  if (cached_has_bits & 0x00000001u) {
    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
      1, this->_internal_query_id(), output);
  }

  // optional int32 row_count = 2;
  if (cached_has_bits & 0x00000004u) {
    ::google::protobuf::internal::WireFormatLite::WriteInt32(2, this->row_count(), output);
  }

  // optional .exec.shared.RecordBatchDef def = 3;
  if (cached_has_bits & 0x00000002u) {
    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
      3, this->_internal_def(), output);
  }

  // optional int32 affected_rows_count = 4;
  if (cached_has_bits & 0x00000008u) {
    ::google::protobuf::internal::WireFormatLite::WriteInt32(4, this->affected_rows_count(), output);
  }

  if (_internal_metadata_.have_unknown_fields()) {
    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
        _internal_metadata_.unknown_fields(), output);
  }
  // @@protoc_insertion_point(serialize_end:exec.shared.QueryData)
}

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

  cached_has_bits = _has_bits_[0];
  // optional .exec.shared.QueryId query_id = 1;
  if (cached_has_bits & 0x00000001u) {
    target = ::google::protobuf::internal::WireFormatLite::
      InternalWriteMessageToArray(
        1, this->_internal_query_id(), deterministic, target);
  }

  // optional int32 row_count = 2;
  if (cached_has_bits & 0x00000004u) {
    target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(2, this->row_count(), target);
  }

  // optional .exec.shared.RecordBatchDef def = 3;
  if (cached_has_bits & 0x00000002u) {
    target = ::google::protobuf::internal::WireFormatLite::
      InternalWriteMessageToArray(
        3, this->_internal_def(), deterministic, target);
  }

  // optional int32 affected_rows_count = 4;
  if (cached_has_bits & 0x00000008u) {
    target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(4, this->affected_rows_count(), target);
  }

  if (_internal_metadata_.have_unknown_fields()) {
    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
        _internal_metadata_.unknown_fields(), target);
  }
  // @@protoc_insertion_point(serialize_to_array_end:exec.shared.QueryData)
  return target;
}

size_t QueryData::ByteSizeLong() const {
// @@protoc_insertion_point(message_byte_size_start:exec.shared.QueryData)
  size_t total_size = 0;

  if (_internal_metadata_.have_unknown_fields()) {
    total_size +=
      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
        _internal_metadata_.unknown_fields());
  }
  if (_has_bits_[0 / 32] & 15u) {
    // optional .exec.shared.QueryId query_id = 1;
    if (has_query_id()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::MessageSize(
          *query_id_);
    }

    // optional .exec.shared.RecordBatchDef def = 3;
    if (has_def()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::MessageSize(
          *def_);
    }

    // optional int32 row_count = 2;
    if (has_row_count()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::Int32Size(
          this->row_count());
    }

    // optional int32 affected_rows_count = 4;
    if (has_affected_rows_count()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::Int32Size(
          this->affected_rows_count());
    }

  }
  int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
  SetCachedSize(cached_size);
  return total_size;
}

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

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

  cached_has_bits = from._has_bits_[0];
  if (cached_has_bits & 15u) {
    if (cached_has_bits & 0x00000001u) {
      mutable_query_id()->::exec::shared::QueryId::MergeFrom(from.query_id());
    }
    if (cached_has_bits & 0x00000002u) {
      mutable_def()->::exec::shared::RecordBatchDef::MergeFrom(from.def());
    }
    if (cached_has_bits & 0x00000004u) {
      row_count_ = from.row_count_;
    }
    if (cached_has_bits & 0x00000008u) {
      affected_rows_count_ = from.affected_rows_count_;
    }
    _has_bits_[0] |= cached_has_bits;
  }
}

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

void QueryData::CopyFrom(const QueryData& from) {
// @@protoc_insertion_point(class_specific_copy_from_start:exec.shared.QueryData)
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

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

void QueryData::Swap(QueryData* other) {
  if (other == this) return;
  InternalSwap(other);
}
void QueryData::InternalSwap(QueryData* other) {
  using std::swap;
  swap(query_id_, other->query_id_);
  swap(def_, other->def_);
  swap(row_count_, other->row_count_);
  swap(affected_rows_count_, other->affected_rows_count_);
  swap(_has_bits_[0], other->_has_bits_[0]);
  _internal_metadata_.Swap(&other->_internal_metadata_);
}

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


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

void QueryInfo::InitAsDefaultInstance() {
  ::exec::shared::_QueryInfo_default_instance_._instance.get_mutable()->foreman_ = const_cast< ::exec::DrillbitEndpoint*>(
      ::exec::DrillbitEndpoint::internal_default_instance());
}
::google::protobuf::internal::ExplicitlyConstructed<::std::string> QueryInfo::_i_give_permission_to_break_this_code_default_user_;
void QueryInfo::clear_foreman() {
  if (foreman_ != NULL) foreman_->Clear();
  clear_has_foreman();
}
::google::protobuf::internal::ExplicitlyConstructed<::std::string> QueryInfo::_i_give_permission_to_break_this_code_default_queue_name_;
#if !defined(_MSC_VER) || _MSC_VER >= 1900
const int QueryInfo::kQueryFieldNumber;
const int QueryInfo::kStartFieldNumber;
const int QueryInfo::kStateFieldNumber;
const int QueryInfo::kUserFieldNumber;
const int QueryInfo::kForemanFieldNumber;
const int QueryInfo::kOptionsJsonFieldNumber;
const int QueryInfo::kTotalCostFieldNumber;
const int QueryInfo::kQueueNameFieldNumber;
#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900

QueryInfo::QueryInfo()
  : ::google::protobuf::Message(), _internal_metadata_(NULL) {
  ::google::protobuf::internal::InitSCC(
      &protobuf_UserBitShared_2eproto::scc_info_QueryInfo.base);
  SharedCtor();
  // @@protoc_insertion_point(constructor:exec.shared.QueryInfo)
}
QueryInfo::QueryInfo(const QueryInfo& from)
  : ::google::protobuf::Message(),
      _internal_metadata_(NULL),
      _has_bits_(from._has_bits_) {
  _internal_metadata_.MergeFrom(from._internal_metadata_);
  query_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  if (from.has_query()) {
    query_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.query_);
  }
  user_.UnsafeSetDefault(&::exec::shared::QueryInfo::_i_give_permission_to_break_this_code_default_user_.get());
  if (from.has_user()) {
    user_.AssignWithDefault(&::exec::shared::QueryInfo::_i_give_permission_to_break_this_code_default_user_.get(), from.user_);
  }
  options_json_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  if (from.has_options_json()) {
    options_json_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.options_json_);
  }
  queue_name_.UnsafeSetDefault(&::exec::shared::QueryInfo::_i_give_permission_to_break_this_code_default_queue_name_.get());
  if (from.has_queue_name()) {
    queue_name_.AssignWithDefault(&::exec::shared::QueryInfo::_i_give_permission_to_break_this_code_default_queue_name_.get(), from.queue_name_);
  }
  if (from.has_foreman()) {
    foreman_ = new ::exec::DrillbitEndpoint(*from.foreman_);
  } else {
    foreman_ = NULL;
  }
  ::memcpy(&start_, &from.start_,
    static_cast<size_t>(reinterpret_cast<char*>(&state_) -
    reinterpret_cast<char*>(&start_)) + sizeof(state_));
  // @@protoc_insertion_point(copy_constructor:exec.shared.QueryInfo)
}

void QueryInfo::SharedCtor() {
  query_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  user_.UnsafeSetDefault(&::exec::shared::QueryInfo::_i_give_permission_to_break_this_code_default_user_.get());
  options_json_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  queue_name_.UnsafeSetDefault(&::exec::shared::QueryInfo::_i_give_permission_to_break_this_code_default_queue_name_.get());
  ::memset(&foreman_, 0, static_cast<size_t>(
      reinterpret_cast<char*>(&state_) -
      reinterpret_cast<char*>(&foreman_)) + sizeof(state_));
}

QueryInfo::~QueryInfo() {
  // @@protoc_insertion_point(destructor:exec.shared.QueryInfo)
  SharedDtor();
}

void QueryInfo::SharedDtor() {
  query_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  user_.DestroyNoArena(&::exec::shared::QueryInfo::_i_give_permission_to_break_this_code_default_user_.get());
  options_json_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  queue_name_.DestroyNoArena(&::exec::shared::QueryInfo::_i_give_permission_to_break_this_code_default_queue_name_.get());
  if (this != internal_default_instance()) delete foreman_;
}

void QueryInfo::SetCachedSize(int size) const {
  _cached_size_.Set(size);
}
const ::google::protobuf::Descriptor* QueryInfo::descriptor() {
  ::protobuf_UserBitShared_2eproto::protobuf_AssignDescriptorsOnce();
  return ::protobuf_UserBitShared_2eproto::file_level_metadata[kIndexInFileMessages].descriptor;
}

const QueryInfo& QueryInfo::default_instance() {
  ::google::protobuf::internal::InitSCC(&protobuf_UserBitShared_2eproto::scc_info_QueryInfo.base);
  return *internal_default_instance();
}


void QueryInfo::Clear() {
// @@protoc_insertion_point(message_clear_start:exec.shared.QueryInfo)
  ::google::protobuf::uint32 cached_has_bits = 0;
  // Prevent compiler warnings about cached_has_bits being unused
  (void) cached_has_bits;

  cached_has_bits = _has_bits_[0];
  if (cached_has_bits & 31u) {
    if (cached_has_bits & 0x00000001u) {
      query_.ClearNonDefaultToEmptyNoArena();
    }
    if (cached_has_bits & 0x00000002u) {
      user_.UnsafeMutablePointer()->assign(*&::exec::shared::QueryInfo::_i_give_permission_to_break_this_code_default_user_.get());
    }
    if (cached_has_bits & 0x00000004u) {
      options_json_.ClearNonDefaultToEmptyNoArena();
    }
    if (cached_has_bits & 0x00000008u) {
      queue_name_.UnsafeMutablePointer()->assign(*&::exec::shared::QueryInfo::_i_give_permission_to_break_this_code_default_queue_name_.get());
    }
    if (cached_has_bits & 0x00000010u) {
      GOOGLE_DCHECK(foreman_ != NULL);
      foreman_->Clear();
    }
  }
  if (cached_has_bits & 224u) {
    ::memset(&start_, 0, static_cast<size_t>(
        reinterpret_cast<char*>(&state_) -
        reinterpret_cast<char*>(&start_)) + sizeof(state_));
  }
  _has_bits_.Clear();
  _internal_metadata_.Clear();
}

bool QueryInfo::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:exec.shared.QueryInfo)
  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)) {
      // optional string query = 1;
      case 1: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(10u /* 10 & 0xFF */)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                input, this->mutable_query()));
          ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
            this->query().data(), static_cast<int>(this->query().length()),
            ::google::protobuf::internal::WireFormat::PARSE,
            "exec.shared.QueryInfo.query");
        } else {
          goto handle_unusual;
        }
        break;
      }

      // optional int64 start = 2;
      case 2: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(16u /* 16 & 0xFF */)) {
          set_has_start();
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   ::google::protobuf::int64, ::google::protobuf::internal::WireFormatLite::TYPE_INT64>(
                 input, &start_)));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // optional .exec.shared.QueryResult.QueryState state = 3;
      case 3: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(24u /* 24 & 0xFF */)) {
          int value;
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
                 input, &value)));
          if (::exec::shared::QueryResult_QueryState_IsValid(value)) {
            set_state(static_cast< ::exec::shared::QueryResult_QueryState >(value));
          } else {
            mutable_unknown_fields()->AddVarint(
                3, static_cast< ::google::protobuf::uint64>(value));
          }
        } else {
          goto handle_unusual;
        }
        break;
      }

      // optional string user = 4 [default = "-"];
      case 4: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(34u /* 34 & 0xFF */)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                input, this->mutable_user()));
          ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
            this->user().data(), static_cast<int>(this->user().length()),
            ::google::protobuf::internal::WireFormat::PARSE,
            "exec.shared.QueryInfo.user");
        } else {
          goto handle_unusual;
        }
        break;
      }

      // optional .exec.DrillbitEndpoint foreman = 5;
      case 5: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(42u /* 42 & 0xFF */)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
               input, mutable_foreman()));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // optional string options_json = 6;
      case 6: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(50u /* 50 & 0xFF */)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                input, this->mutable_options_json()));
          ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
            this->options_json().data(), static_cast<int>(this->options_json().length()),
            ::google::protobuf::internal::WireFormat::PARSE,
            "exec.shared.QueryInfo.options_json");
        } else {
          goto handle_unusual;
        }
        break;
      }

      // optional double total_cost = 7;
      case 7: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(57u /* 57 & 0xFF */)) {
          set_has_total_cost();
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   double, ::google::protobuf::internal::WireFormatLite::TYPE_DOUBLE>(
                 input, &total_cost_)));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // optional string queue_name = 8 [default = "-"];
      case 8: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(66u /* 66 & 0xFF */)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                input, this->mutable_queue_name()));
          ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
            this->queue_name().data(), static_cast<int>(this->queue_name().length()),
            ::google::protobuf::internal::WireFormat::PARSE,
            "exec.shared.QueryInfo.queue_name");
        } else {
          goto handle_unusual;
        }
        break;
      }

      default: {
      handle_unusual:
        if (tag == 0) {
          goto success;
        }
        DO_(::google::protobuf::internal::WireFormat::SkipField(
              input, tag, _internal_metadata_.mutable_unknown_fields()));
        break;
      }
    }
  }
success:
  // @@protoc_insertion_point(parse_success:exec.shared.QueryInfo)
  return true;
failure:
  // @@protoc_insertion_point(parse_failure:exec.shared.QueryInfo)
  return false;
#undef DO_
}

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

  cached_has_bits = _has_bits_[0];
  // optional string query = 1;
  if (cached_has_bits & 0x00000001u) {
    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
      this->query().data(), static_cast<int>(this->query().length()),
      ::google::protobuf::internal::WireFormat::SERIALIZE,
      "exec.shared.QueryInfo.query");
    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
      1, this->query(), output);
  }

  // optional int64 start = 2;
  if (cached_has_bits & 0x00000020u) {
    ::google::protobuf::internal::WireFormatLite::WriteInt64(2, this->start(), output);
  }

  // optional .exec.shared.QueryResult.QueryState state = 3;
  if (cached_has_bits & 0x00000080u) {
    ::google::protobuf::internal::WireFormatLite::WriteEnum(
      3, this->state(), output);
  }

  // optional string user = 4 [default = "-"];
  if (cached_has_bits & 0x00000002u) {
    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
      this->user().data(), static_cast<int>(this->user().length()),
      ::google::protobuf::internal::WireFormat::SERIALIZE,
      "exec.shared.QueryInfo.user");
    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
      4, this->user(), output);
  }

  // optional .exec.DrillbitEndpoint foreman = 5;
  if (cached_has_bits & 0x00000010u) {
    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
      5, this->_internal_foreman(), output);
  }

  // optional string options_json = 6;
  if (cached_has_bits & 0x00000004u) {
    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
      this->options_json().data(), static_cast<int>(this->options_json().length()),
      ::google::protobuf::internal::WireFormat::SERIALIZE,
      "exec.shared.QueryInfo.options_json");
    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
      6, this->options_json(), output);
  }

  // optional double total_cost = 7;
  if (cached_has_bits & 0x00000040u) {
    ::google::protobuf::internal::WireFormatLite::WriteDouble(7, this->total_cost(), output);
  }

  // optional string queue_name = 8 [default = "-"];
  if (cached_has_bits & 0x00000008u) {
    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
      this->queue_name().data(), static_cast<int>(this->queue_name().length()),
      ::google::protobuf::internal::WireFormat::SERIALIZE,
      "exec.shared.QueryInfo.queue_name");
    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
      8, this->queue_name(), output);
  }

  if (_internal_metadata_.have_unknown_fields()) {
    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
        _internal_metadata_.unknown_fields(), output);
  }
  // @@protoc_insertion_point(serialize_end:exec.shared.QueryInfo)
}

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

  cached_has_bits = _has_bits_[0];
  // optional string query = 1;
  if (cached_has_bits & 0x00000001u) {
    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
      this->query().data(), static_cast<int>(this->query().length()),
      ::google::protobuf::internal::WireFormat::SERIALIZE,
      "exec.shared.QueryInfo.query");
    target =
      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
        1, this->query(), target);
  }

  // optional int64 start = 2;
  if (cached_has_bits & 0x00000020u) {
    target = ::google::protobuf::internal::WireFormatLite::WriteInt64ToArray(2, this->start(), target);
  }

  // optional .exec.shared.QueryResult.QueryState state = 3;
  if (cached_has_bits & 0x00000080u) {
    target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
      3, this->state(), target);
  }

  // optional string user = 4 [default = "-"];
  if (cached_has_bits & 0x00000002u) {
    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
      this->user().data(), static_cast<int>(this->user().length()),
      ::google::protobuf::internal::WireFormat::SERIALIZE,
      "exec.shared.QueryInfo.user");
    target =
      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
        4, this->user(), target);
  }

  // optional .exec.DrillbitEndpoint foreman = 5;
  if (cached_has_bits & 0x00000010u) {
    target = ::google::protobuf::internal::WireFormatLite::
      InternalWriteMessageToArray(
        5, this->_internal_foreman(), deterministic, target);
  }

  // optional string options_json = 6;
  if (cached_has_bits & 0x00000004u) {
    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
      this->options_json().data(), static_cast<int>(this->options_json().length()),
      ::google::protobuf::internal::WireFormat::SERIALIZE,
      "exec.shared.QueryInfo.options_json");
    target =
      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
        6, this->options_json(), target);
  }

  // optional double total_cost = 7;
  if (cached_has_bits & 0x00000040u) {
    target = ::google::protobuf::internal::WireFormatLite::WriteDoubleToArray(7, this->total_cost(), target);
  }

  // optional string queue_name = 8 [default = "-"];
  if (cached_has_bits & 0x00000008u) {
    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
      this->queue_name().data(), static_cast<int>(this->queue_name().length()),
      ::google::protobuf::internal::WireFormat::SERIALIZE,
      "exec.shared.QueryInfo.queue_name");
    target =
      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
        8, this->queue_name(), target);
  }

  if (_internal_metadata_.have_unknown_fields()) {
    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
        _internal_metadata_.unknown_fields(), target);
  }
  // @@protoc_insertion_point(serialize_to_array_end:exec.shared.QueryInfo)
  return target;
}

size_t QueryInfo::ByteSizeLong() const {
// @@protoc_insertion_point(message_byte_size_start:exec.shared.QueryInfo)
  size_t total_size = 0;

  if (_internal_metadata_.have_unknown_fields()) {
    total_size +=
      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
        _internal_metadata_.unknown_fields());
  }
  if (_has_bits_[0 / 32] & 255u) {
    // optional string query = 1;
    if (has_query()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::StringSize(
          this->query());
    }

    // optional string user = 4 [default = "-"];
    if (has_user()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::StringSize(
          this->user());
    }

    // optional string options_json = 6;
    if (has_options_json()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::StringSize(
          this->options_json());
    }

    // optional string queue_name = 8 [default = "-"];
    if (has_queue_name()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::StringSize(
          this->queue_name());
    }

    // optional .exec.DrillbitEndpoint foreman = 5;
    if (has_foreman()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::MessageSize(
          *foreman_);
    }

    // optional int64 start = 2;
    if (has_start()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::Int64Size(
          this->start());
    }

    // optional double total_cost = 7;
    if (has_total_cost()) {
      total_size += 1 + 8;
    }

    // optional .exec.shared.QueryResult.QueryState state = 3;
    if (has_state()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::EnumSize(this->state());
    }

  }
  int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
  SetCachedSize(cached_size);
  return total_size;
}

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

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

  cached_has_bits = from._has_bits_[0];
  if (cached_has_bits & 255u) {
    if (cached_has_bits & 0x00000001u) {
      set_has_query();
      query_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.query_);
    }
    if (cached_has_bits & 0x00000002u) {
      set_has_user();
      user_.AssignWithDefault(&::exec::shared::QueryInfo::_i_give_permission_to_break_this_code_default_user_.get(), from.user_);
    }
    if (cached_has_bits & 0x00000004u) {
      set_has_options_json();
      options_json_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.options_json_);
    }
    if (cached_has_bits & 0x00000008u) {
      set_has_queue_name();
      queue_name_.AssignWithDefault(&::exec::shared::QueryInfo::_i_give_permission_to_break_this_code_default_queue_name_.get(), from.queue_name_);
    }
    if (cached_has_bits & 0x00000010u) {
      mutable_foreman()->::exec::DrillbitEndpoint::MergeFrom(from.foreman());
    }
    if (cached_has_bits & 0x00000020u) {
      start_ = from.start_;
    }
    if (cached_has_bits & 0x00000040u) {
      total_cost_ = from.total_cost_;
    }
    if (cached_has_bits & 0x00000080u) {
      state_ = from.state_;
    }
    _has_bits_[0] |= cached_has_bits;
  }
}

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

void QueryInfo::CopyFrom(const QueryInfo& from) {
// @@protoc_insertion_point(class_specific_copy_from_start:exec.shared.QueryInfo)
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

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

void QueryInfo::Swap(QueryInfo* other) {
  if (other == this) return;
  InternalSwap(other);
}
void QueryInfo::InternalSwap(QueryInfo* other) {
  using std::swap;
  query_.Swap(&other->query_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
    GetArenaNoVirtual());
  user_.Swap(&other->user_, &::exec::shared::QueryInfo::_i_give_permission_to_break_this_code_default_user_.get(),
    GetArenaNoVirtual());
  options_json_.Swap(&other->options_json_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
    GetArenaNoVirtual());
  queue_name_.Swap(&other->queue_name_, &::exec::shared::QueryInfo::_i_give_permission_to_break_this_code_default_queue_name_.get(),
    GetArenaNoVirtual());
  swap(foreman_, other->foreman_);
  swap(start_, other->start_);
  swap(total_cost_, other->total_cost_);
  swap(state_, other->state_);
  swap(_has_bits_[0], other->_has_bits_[0]);
  _internal_metadata_.Swap(&other->_internal_metadata_);
}

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


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

void QueryProfile::InitAsDefaultInstance() {
  ::exec::shared::_QueryProfile_default_instance_._instance.get_mutable()->id_ = const_cast< ::exec::shared::QueryId*>(
      ::exec::shared::QueryId::internal_default_instance());
  ::exec::shared::_QueryProfile_default_instance_._instance.get_mutable()->foreman_ = const_cast< ::exec::DrillbitEndpoint*>(
      ::exec::DrillbitEndpoint::internal_default_instance());
}
void QueryProfile::clear_foreman() {
  if (foreman_ != NULL) foreman_->Clear();
  clear_has_foreman();
}
::google::protobuf::internal::ExplicitlyConstructed<::std::string> QueryProfile::_i_give_permission_to_break_this_code_default_user_;
::google::protobuf::internal::ExplicitlyConstructed<::std::string> QueryProfile::_i_give_permission_to_break_this_code_default_queue_name_;
#if !defined(_MSC_VER) || _MSC_VER >= 1900
const int QueryProfile::kIdFieldNumber;
const int QueryProfile::kTypeFieldNumber;
const int QueryProfile::kStartFieldNumber;
const int QueryProfile::kEndFieldNumber;
const int QueryProfile::kQueryFieldNumber;
const int QueryProfile::kPlanFieldNumber;
const int QueryProfile::kForemanFieldNumber;
const int QueryProfile::kStateFieldNumber;
const int QueryProfile::kTotalFragmentsFieldNumber;
const int QueryProfile::kFinishedFragmentsFieldNumber;
const int QueryProfile::kFragmentProfileFieldNumber;
const int QueryProfile::kUserFieldNumber;
const int QueryProfile::kErrorFieldNumber;
const int QueryProfile::kVerboseErrorFieldNumber;
const int QueryProfile::kErrorIdFieldNumber;
const int QueryProfile::kErrorNodeFieldNumber;
const int QueryProfile::kOptionsJsonFieldNumber;
const int QueryProfile::kPlanEndFieldNumber;
const int QueryProfile::kQueueWaitEndFieldNumber;
const int QueryProfile::kTotalCostFieldNumber;
const int QueryProfile::kQueueNameFieldNumber;
const int QueryProfile::kQueryIdFieldNumber;
const int QueryProfile::kAutoLimitFieldNumber;
#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900

QueryProfile::QueryProfile()
  : ::google::protobuf::Message(), _internal_metadata_(NULL) {
  ::google::protobuf::internal::InitSCC(
      &protobuf_UserBitShared_2eproto::scc_info_QueryProfile.base);
  SharedCtor();
  // @@protoc_insertion_point(constructor:exec.shared.QueryProfile)
}
QueryProfile::QueryProfile(const QueryProfile& from)
  : ::google::protobuf::Message(),
      _internal_metadata_(NULL),
      _has_bits_(from._has_bits_),
      fragment_profile_(from.fragment_profile_) {
  _internal_metadata_.MergeFrom(from._internal_metadata_);
  query_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  if (from.has_query()) {
    query_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.query_);
  }
  plan_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  if (from.has_plan()) {
    plan_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.plan_);
  }
  user_.UnsafeSetDefault(&::exec::shared::QueryProfile::_i_give_permission_to_break_this_code_default_user_.get());
  if (from.has_user()) {
    user_.AssignWithDefault(&::exec::shared::QueryProfile::_i_give_permission_to_break_this_code_default_user_.get(), from.user_);
  }
  error_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  if (from.has_error()) {
    error_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.error_);
  }
  verboseerror_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  if (from.has_verboseerror()) {
    verboseerror_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.verboseerror_);
  }
  error_id_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  if (from.has_error_id()) {
    error_id_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.error_id_);
  }
  error_node_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  if (from.has_error_node()) {
    error_node_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.error_node_);
  }
  options_json_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  if (from.has_options_json()) {
    options_json_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.options_json_);
  }
  queue_name_.UnsafeSetDefault(&::exec::shared::QueryProfile::_i_give_permission_to_break_this_code_default_queue_name_.get());
  if (from.has_queue_name()) {
    queue_name_.AssignWithDefault(&::exec::shared::QueryProfile::_i_give_permission_to_break_this_code_default_queue_name_.get(), from.queue_name_);
  }
  queryid_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  if (from.has_queryid()) {
    queryid_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.queryid_);
  }
  if (from.has_id()) {
    id_ = new ::exec::shared::QueryId(*from.id_);
  } else {
    id_ = NULL;
  }
  if (from.has_foreman()) {
    foreman_ = new ::exec::DrillbitEndpoint(*from.foreman_);
  } else {
    foreman_ = NULL;
  }
  ::memcpy(&start_, &from.start_,
    static_cast<size_t>(reinterpret_cast<char*>(&type_) -
    reinterpret_cast<char*>(&start_)) + sizeof(type_));
  // @@protoc_insertion_point(copy_constructor:exec.shared.QueryProfile)
}

void QueryProfile::SharedCtor() {
  query_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  plan_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  user_.UnsafeSetDefault(&::exec::shared::QueryProfile::_i_give_permission_to_break_this_code_default_user_.get());
  error_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  verboseerror_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  error_id_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  error_node_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  options_json_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  queue_name_.UnsafeSetDefault(&::exec::shared::QueryProfile::_i_give_permission_to_break_this_code_default_queue_name_.get());
  queryid_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  ::memset(&id_, 0, static_cast<size_t>(
      reinterpret_cast<char*>(&total_cost_) -
      reinterpret_cast<char*>(&id_)) + sizeof(total_cost_));
  type_ = 1;
}

QueryProfile::~QueryProfile() {
  // @@protoc_insertion_point(destructor:exec.shared.QueryProfile)
  SharedDtor();
}

void QueryProfile::SharedDtor() {
  query_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  plan_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  user_.DestroyNoArena(&::exec::shared::QueryProfile::_i_give_permission_to_break_this_code_default_user_.get());
  error_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  verboseerror_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  error_id_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  error_node_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  options_json_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  queue_name_.DestroyNoArena(&::exec::shared::QueryProfile::_i_give_permission_to_break_this_code_default_queue_name_.get());
  queryid_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  if (this != internal_default_instance()) delete id_;
  if (this != internal_default_instance()) delete foreman_;
}

void QueryProfile::SetCachedSize(int size) const {
  _cached_size_.Set(size);
}
const ::google::protobuf::Descriptor* QueryProfile::descriptor() {
  ::protobuf_UserBitShared_2eproto::protobuf_AssignDescriptorsOnce();
  return ::protobuf_UserBitShared_2eproto::file_level_metadata[kIndexInFileMessages].descriptor;
}

const QueryProfile& QueryProfile::default_instance() {
  ::google::protobuf::internal::InitSCC(&protobuf_UserBitShared_2eproto::scc_info_QueryProfile.base);
  return *internal_default_instance();
}


void QueryProfile::Clear() {
// @@protoc_insertion_point(message_clear_start:exec.shared.QueryProfile)
  ::google::protobuf::uint32 cached_has_bits = 0;
  // Prevent compiler warnings about cached_has_bits being unused
  (void) cached_has_bits;

  fragment_profile_.Clear();
  cached_has_bits = _has_bits_[0];
  if (cached_has_bits & 255u) {
    if (cached_has_bits & 0x00000001u) {
      query_.ClearNonDefaultToEmptyNoArena();
    }
    if (cached_has_bits & 0x00000002u) {
      plan_.ClearNonDefaultToEmptyNoArena();
    }
    if (cached_has_bits & 0x00000004u) {
      user_.UnsafeMutablePointer()->assign(*&::exec::shared::QueryProfile::_i_give_permission_to_break_this_code_default_user_.get());
    }
    if (cached_has_bits & 0x00000008u) {
      error_.ClearNonDefaultToEmptyNoArena();
    }
    if (cached_has_bits & 0x00000010u) {
      verboseerror_.ClearNonDefaultToEmptyNoArena();
    }
    if (cached_has_bits & 0x00000020u) {
      error_id_.ClearNonDefaultToEmptyNoArena();
    }
    if (cached_has_bits & 0x00000040u) {
      error_node_.ClearNonDefaultToEmptyNoArena();
    }
    if (cached_has_bits & 0x00000080u) {
      options_json_.ClearNonDefaultToEmptyNoArena();
    }
  }
  if (cached_has_bits & 3840u) {
    if (cached_has_bits & 0x00000100u) {
      queue_name_.UnsafeMutablePointer()->assign(*&::exec::shared::QueryProfile::_i_give_permission_to_break_this_code_default_queue_name_.get());
    }
    if (cached_has_bits & 0x00000200u) {
      queryid_.ClearNonDefaultToEmptyNoArena();
    }
    if (cached_has_bits & 0x00000400u) {
      GOOGLE_DCHECK(id_ != NULL);
      id_->Clear();
    }
    if (cached_has_bits & 0x00000800u) {
      GOOGLE_DCHECK(foreman_ != NULL);
      foreman_->Clear();
    }
  }
  if (cached_has_bits & 61440u) {
    ::memset(&start_, 0, static_cast<size_t>(
        reinterpret_cast<char*>(&total_fragments_) -
        reinterpret_cast<char*>(&start_)) + sizeof(total_fragments_));
  }
  if (cached_has_bits & 4128768u) {
    ::memset(&finished_fragments_, 0, static_cast<size_t>(
        reinterpret_cast<char*>(&total_cost_) -
        reinterpret_cast<char*>(&finished_fragments_)) + sizeof(total_cost_));
    type_ = 1;
  }
  _has_bits_.Clear();
  _internal_metadata_.Clear();
}

bool QueryProfile::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:exec.shared.QueryProfile)
  for (;;) {
    ::std::pair<::google::protobuf::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(16383u);
    tag = p.first;
    if (!p.second) goto handle_unusual;
    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
      // optional .exec.shared.QueryId id = 1;
      case 1: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(10u /* 10 & 0xFF */)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
               input, mutable_id()));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // optional .exec.shared.QueryType type = 2;
      case 2: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(16u /* 16 & 0xFF */)) {
          int value;
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
                 input, &value)));
          if (::exec::shared::QueryType_IsValid(value)) {
            set_type(static_cast< ::exec::shared::QueryType >(value));
          } else {
            mutable_unknown_fields()->AddVarint(
                2, static_cast< ::google::protobuf::uint64>(value));
          }
        } else {
          goto handle_unusual;
        }
        break;
      }

      // optional int64 start = 3;
      case 3: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(24u /* 24 & 0xFF */)) {
          set_has_start();
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   ::google::protobuf::int64, ::google::protobuf::internal::WireFormatLite::TYPE_INT64>(
                 input, &start_)));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // optional int64 end = 4;
      case 4: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(32u /* 32 & 0xFF */)) {
          set_has_end();
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   ::google::protobuf::int64, ::google::protobuf::internal::WireFormatLite::TYPE_INT64>(
                 input, &end_)));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // optional string query = 5;
      case 5: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(42u /* 42 & 0xFF */)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                input, this->mutable_query()));
          ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
            this->query().data(), static_cast<int>(this->query().length()),
            ::google::protobuf::internal::WireFormat::PARSE,
            "exec.shared.QueryProfile.query");
        } else {
          goto handle_unusual;
        }
        break;
      }

      // optional string plan = 6;
      case 6: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(50u /* 50 & 0xFF */)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                input, this->mutable_plan()));
          ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
            this->plan().data(), static_cast<int>(this->plan().length()),
            ::google::protobuf::internal::WireFormat::PARSE,
            "exec.shared.QueryProfile.plan");
        } else {
          goto handle_unusual;
        }
        break;
      }

      // optional .exec.DrillbitEndpoint foreman = 7;
      case 7: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(58u /* 58 & 0xFF */)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
               input, mutable_foreman()));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // optional .exec.shared.QueryResult.QueryState state = 8;
      case 8: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(64u /* 64 & 0xFF */)) {
          int value;
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
                 input, &value)));
          if (::exec::shared::QueryResult_QueryState_IsValid(value)) {
            set_state(static_cast< ::exec::shared::QueryResult_QueryState >(value));
          } else {
            mutable_unknown_fields()->AddVarint(
                8, static_cast< ::google::protobuf::uint64>(value));
          }
        } else {
          goto handle_unusual;
        }
        break;
      }

      // optional int32 total_fragments = 9;
      case 9: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(72u /* 72 & 0xFF */)) {
          set_has_total_fragments();
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
                 input, &total_fragments_)));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // optional int32 finished_fragments = 10;
      case 10: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(80u /* 80 & 0xFF */)) {
          set_has_finished_fragments();
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
                 input, &finished_fragments_)));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // repeated .exec.shared.MajorFragmentProfile fragment_profile = 11;
      case 11: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(90u /* 90 & 0xFF */)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
                input, add_fragment_profile()));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // optional string user = 12 [default = "-"];
      case 12: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(98u /* 98 & 0xFF */)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                input, this->mutable_user()));
          ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
            this->user().data(), static_cast<int>(this->user().length()),
            ::google::protobuf::internal::WireFormat::PARSE,
            "exec.shared.QueryProfile.user");
        } else {
          goto handle_unusual;
        }
        break;
      }

      // optional string error = 13;
      case 13: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(106u /* 106 & 0xFF */)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                input, this->mutable_error()));
          ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
            this->error().data(), static_cast<int>(this->error().length()),
            ::google::protobuf::internal::WireFormat::PARSE,
            "exec.shared.QueryProfile.error");
        } else {
          goto handle_unusual;
        }
        break;
      }

      // optional string verboseError = 14;
      case 14: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(114u /* 114 & 0xFF */)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                input, this->mutable_verboseerror()));
          ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
            this->verboseerror().data(), static_cast<int>(this->verboseerror().length()),
            ::google::protobuf::internal::WireFormat::PARSE,
            "exec.shared.QueryProfile.verboseError");
        } else {
          goto handle_unusual;
        }
        break;
      }

      // optional string error_id = 15;
      case 15: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(122u /* 122 & 0xFF */)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                input, this->mutable_error_id()));
          ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
            this->error_id().data(), static_cast<int>(this->error_id().length()),
            ::google::protobuf::internal::WireFormat::PARSE,
            "exec.shared.QueryProfile.error_id");
        } else {
          goto handle_unusual;
        }
        break;
      }

      // optional string error_node = 16;
      case 16: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(130u /* 130 & 0xFF */)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                input, this->mutable_error_node()));
          ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
            this->error_node().data(), static_cast<int>(this->error_node().length()),
            ::google::protobuf::internal::WireFormat::PARSE,
            "exec.shared.QueryProfile.error_node");
        } else {
          goto handle_unusual;
        }
        break;
      }

      // optional string options_json = 17;
      case 17: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(138u /* 138 & 0xFF */)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                input, this->mutable_options_json()));
          ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
            this->options_json().data(), static_cast<int>(this->options_json().length()),
            ::google::protobuf::internal::WireFormat::PARSE,
            "exec.shared.QueryProfile.options_json");
        } else {
          goto handle_unusual;
        }
        break;
      }

      // optional int64 planEnd = 18;
      case 18: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(144u /* 144 & 0xFF */)) {
          set_has_planend();
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   ::google::protobuf::int64, ::google::protobuf::internal::WireFormatLite::TYPE_INT64>(
                 input, &planend_)));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // optional int64 queueWaitEnd = 19;
      case 19: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(152u /* 152 & 0xFF */)) {
          set_has_queuewaitend();
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   ::google::protobuf::int64, ::google::protobuf::internal::WireFormatLite::TYPE_INT64>(
                 input, &queuewaitend_)));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // optional double total_cost = 20;
      case 20: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(161u /* 161 & 0xFF */)) {
          set_has_total_cost();
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   double, ::google::protobuf::internal::WireFormatLite::TYPE_DOUBLE>(
                 input, &total_cost_)));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // optional string queue_name = 21 [default = "-"];
      case 21: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(170u /* 170 & 0xFF */)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                input, this->mutable_queue_name()));
          ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
            this->queue_name().data(), static_cast<int>(this->queue_name().length()),
            ::google::protobuf::internal::WireFormat::PARSE,
            "exec.shared.QueryProfile.queue_name");
        } else {
          goto handle_unusual;
        }
        break;
      }

      // optional string queryId = 22;
      case 22: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(178u /* 178 & 0xFF */)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                input, this->mutable_queryid()));
          ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
            this->queryid().data(), static_cast<int>(this->queryid().length()),
            ::google::protobuf::internal::WireFormat::PARSE,
            "exec.shared.QueryProfile.queryId");
        } else {
          goto handle_unusual;
        }
        break;
      }

      // optional int32 autoLimit = 23;
      case 23: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(184u /* 184 & 0xFF */)) {
          set_has_autolimit();
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
                 input, &autolimit_)));
        } else {
          goto handle_unusual;
        }
        break;
      }

      default: {
      handle_unusual:
        if (tag == 0) {
          goto success;
        }
        DO_(::google::protobuf::internal::WireFormat::SkipField(
              input, tag, _internal_metadata_.mutable_unknown_fields()));
        break;
      }
    }
  }
success:
  // @@protoc_insertion_point(parse_success:exec.shared.QueryProfile)
  return true;
failure:
  // @@protoc_insertion_point(parse_failure:exec.shared.QueryProfile)
  return false;
#undef DO_
}

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

  cached_has_bits = _has_bits_[0];
  // optional .exec.shared.QueryId id = 1;
  if (cached_has_bits & 0x00000400u) {
    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
      1, this->_internal_id(), output);
  }

  // optional .exec.shared.QueryType type = 2;
  if (cached_has_bits & 0x00200000u) {
    ::google::protobuf::internal::WireFormatLite::WriteEnum(
      2, this->type(), output);
  }

  // optional int64 start = 3;
  if (cached_has_bits & 0x00001000u) {
    ::google::protobuf::internal::WireFormatLite::WriteInt64(3, this->start(), output);
  }

  // optional int64 end = 4;
  if (cached_has_bits & 0x00002000u) {
    ::google::protobuf::internal::WireFormatLite::WriteInt64(4, this->end(), output);
  }

  // optional string query = 5;
  if (cached_has_bits & 0x00000001u) {
    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
      this->query().data(), static_cast<int>(this->query().length()),
      ::google::protobuf::internal::WireFormat::SERIALIZE,
      "exec.shared.QueryProfile.query");
    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
      5, this->query(), output);
  }

  // optional string plan = 6;
  if (cached_has_bits & 0x00000002u) {
    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
      this->plan().data(), static_cast<int>(this->plan().length()),
      ::google::protobuf::internal::WireFormat::SERIALIZE,
      "exec.shared.QueryProfile.plan");
    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
      6, this->plan(), output);
  }

  // optional .exec.DrillbitEndpoint foreman = 7;
  if (cached_has_bits & 0x00000800u) {
    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
      7, this->_internal_foreman(), output);
  }

  // optional .exec.shared.QueryResult.QueryState state = 8;
  if (cached_has_bits & 0x00004000u) {
    ::google::protobuf::internal::WireFormatLite::WriteEnum(
      8, this->state(), output);
  }

  // optional int32 total_fragments = 9;
  if (cached_has_bits & 0x00008000u) {
    ::google::protobuf::internal::WireFormatLite::WriteInt32(9, this->total_fragments(), output);
  }

  // optional int32 finished_fragments = 10;
  if (cached_has_bits & 0x00010000u) {
    ::google::protobuf::internal::WireFormatLite::WriteInt32(10, this->finished_fragments(), output);
  }

  // repeated .exec.shared.MajorFragmentProfile fragment_profile = 11;
  for (unsigned int i = 0,
      n = static_cast<unsigned int>(this->fragment_profile_size()); i < n; i++) {
    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
      11,
      this->fragment_profile(static_cast<int>(i)),
      output);
  }

  // optional string user = 12 [default = "-"];
  if (cached_has_bits & 0x00000004u) {
    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
      this->user().data(), static_cast<int>(this->user().length()),
      ::google::protobuf::internal::WireFormat::SERIALIZE,
      "exec.shared.QueryProfile.user");
    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
      12, this->user(), output);
  }

  // optional string error = 13;
  if (cached_has_bits & 0x00000008u) {
    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
      this->error().data(), static_cast<int>(this->error().length()),
      ::google::protobuf::internal::WireFormat::SERIALIZE,
      "exec.shared.QueryProfile.error");
    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
      13, this->error(), output);
  }

  // optional string verboseError = 14;
  if (cached_has_bits & 0x00000010u) {
    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
      this->verboseerror().data(), static_cast<int>(this->verboseerror().length()),
      ::google::protobuf::internal::WireFormat::SERIALIZE,
      "exec.shared.QueryProfile.verboseError");
    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
      14, this->verboseerror(), output);
  }

  // optional string error_id = 15;
  if (cached_has_bits & 0x00000020u) {
    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
      this->error_id().data(), static_cast<int>(this->error_id().length()),
      ::google::protobuf::internal::WireFormat::SERIALIZE,
      "exec.shared.QueryProfile.error_id");
    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
      15, this->error_id(), output);
  }

  // optional string error_node = 16;
  if (cached_has_bits & 0x00000040u) {
    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
      this->error_node().data(), static_cast<int>(this->error_node().length()),
      ::google::protobuf::internal::WireFormat::SERIALIZE,
      "exec.shared.QueryProfile.error_node");
    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
      16, this->error_node(), output);
  }

  // optional string options_json = 17;
  if (cached_has_bits & 0x00000080u) {
    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
      this->options_json().data(), static_cast<int>(this->options_json().length()),
      ::google::protobuf::internal::WireFormat::SERIALIZE,
      "exec.shared.QueryProfile.options_json");
    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
      17, this->options_json(), output);
  }

  // optional int64 planEnd = 18;
  if (cached_has_bits & 0x00040000u) {
    ::google::protobuf::internal::WireFormatLite::WriteInt64(18, this->planend(), output);
  }

  // optional int64 queueWaitEnd = 19;
  if (cached_has_bits & 0x00080000u) {
    ::google::protobuf::internal::WireFormatLite::WriteInt64(19, this->queuewaitend(), output);
  }

  // optional double total_cost = 20;
  if (cached_has_bits & 0x00100000u) {
    ::google::protobuf::internal::WireFormatLite::WriteDouble(20, this->total_cost(), output);
  }

  // optional string queue_name = 21 [default = "-"];
  if (cached_has_bits & 0x00000100u) {
    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
      this->queue_name().data(), static_cast<int>(this->queue_name().length()),
      ::google::protobuf::internal::WireFormat::SERIALIZE,
      "exec.shared.QueryProfile.queue_name");
    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
      21, this->queue_name(), output);
  }

  // optional string queryId = 22;
  if (cached_has_bits & 0x00000200u) {
    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
      this->queryid().data(), static_cast<int>(this->queryid().length()),
      ::google::protobuf::internal::WireFormat::SERIALIZE,
      "exec.shared.QueryProfile.queryId");
    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
      22, this->queryid(), output);
  }

  // optional int32 autoLimit = 23;
  if (cached_has_bits & 0x00020000u) {
    ::google::protobuf::internal::WireFormatLite::WriteInt32(23, this->autolimit(), output);
  }

  if (_internal_metadata_.have_unknown_fields()) {
    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
        _internal_metadata_.unknown_fields(), output);
  }
  // @@protoc_insertion_point(serialize_end:exec.shared.QueryProfile)
}

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

  cached_has_bits = _has_bits_[0];
  // optional .exec.shared.QueryId id = 1;
  if (cached_has_bits & 0x00000400u) {
    target = ::google::protobuf::internal::WireFormatLite::
      InternalWriteMessageToArray(
        1, this->_internal_id(), deterministic, target);
  }

  // optional .exec.shared.QueryType type = 2;
  if (cached_has_bits & 0x00200000u) {
    target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
      2, this->type(), target);
  }

  // optional int64 start = 3;
  if (cached_has_bits & 0x00001000u) {
    target = ::google::protobuf::internal::WireFormatLite::WriteInt64ToArray(3, this->start(), target);
  }

  // optional int64 end = 4;
  if (cached_has_bits & 0x00002000u) {
    target = ::google::protobuf::internal::WireFormatLite::WriteInt64ToArray(4, this->end(), target);
  }

  // optional string query = 5;
  if (cached_has_bits & 0x00000001u) {
    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
      this->query().data(), static_cast<int>(this->query().length()),
      ::google::protobuf::internal::WireFormat::SERIALIZE,
      "exec.shared.QueryProfile.query");
    target =
      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
        5, this->query(), target);
  }

  // optional string plan = 6;
  if (cached_has_bits & 0x00000002u) {
    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
      this->plan().data(), static_cast<int>(this->plan().length()),
      ::google::protobuf::internal::WireFormat::SERIALIZE,
      "exec.shared.QueryProfile.plan");
    target =
      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
        6, this->plan(), target);
  }

  // optional .exec.DrillbitEndpoint foreman = 7;
  if (cached_has_bits & 0x00000800u) {
    target = ::google::protobuf::internal::WireFormatLite::
      InternalWriteMessageToArray(
        7, this->_internal_foreman(), deterministic, target);
  }

  // optional .exec.shared.QueryResult.QueryState state = 8;
  if (cached_has_bits & 0x00004000u) {
    target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
      8, this->state(), target);
  }

  // optional int32 total_fragments = 9;
  if (cached_has_bits & 0x00008000u) {
    target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(9, this->total_fragments(), target);
  }

  // optional int32 finished_fragments = 10;
  if (cached_has_bits & 0x00010000u) {
    target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(10, this->finished_fragments(), target);
  }

  // repeated .exec.shared.MajorFragmentProfile fragment_profile = 11;
  for (unsigned int i = 0,
      n = static_cast<unsigned int>(this->fragment_profile_size()); i < n; i++) {
    target = ::google::protobuf::internal::WireFormatLite::
      InternalWriteMessageToArray(
        11, this->fragment_profile(static_cast<int>(i)), deterministic, target);
  }

  // optional string user = 12 [default = "-"];
  if (cached_has_bits & 0x00000004u) {
    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
      this->user().data(), static_cast<int>(this->user().length()),
      ::google::protobuf::internal::WireFormat::SERIALIZE,
      "exec.shared.QueryProfile.user");
    target =
      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
        12, this->user(), target);
  }

  // optional string error = 13;
  if (cached_has_bits & 0x00000008u) {
    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
      this->error().data(), static_cast<int>(this->error().length()),
      ::google::protobuf::internal::WireFormat::SERIALIZE,
      "exec.shared.QueryProfile.error");
    target =
      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
        13, this->error(), target);
  }

  // optional string verboseError = 14;
  if (cached_has_bits & 0x00000010u) {
    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
      this->verboseerror().data(), static_cast<int>(this->verboseerror().length()),
      ::google::protobuf::internal::WireFormat::SERIALIZE,
      "exec.shared.QueryProfile.verboseError");
    target =
      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
        14, this->verboseerror(), target);
  }

  // optional string error_id = 15;
  if (cached_has_bits & 0x00000020u) {
    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
      this->error_id().data(), static_cast<int>(this->error_id().length()),
      ::google::protobuf::internal::WireFormat::SERIALIZE,
      "exec.shared.QueryProfile.error_id");
    target =
      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
        15, this->error_id(), target);
  }

  // optional string error_node = 16;
  if (cached_has_bits & 0x00000040u) {
    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
      this->error_node().data(), static_cast<int>(this->error_node().length()),
      ::google::protobuf::internal::WireFormat::SERIALIZE,
      "exec.shared.QueryProfile.error_node");
    target =
      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
        16, this->error_node(), target);
  }

  // optional string options_json = 17;
  if (cached_has_bits & 0x00000080u) {
    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
      this->options_json().data(), static_cast<int>(this->options_json().length()),
      ::google::protobuf::internal::WireFormat::SERIALIZE,
      "exec.shared.QueryProfile.options_json");
    target =
      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
        17, this->options_json(), target);
  }

  // optional int64 planEnd = 18;
  if (cached_has_bits & 0x00040000u) {
    target = ::google::protobuf::internal::WireFormatLite::WriteInt64ToArray(18, this->planend(), target);
  }

  // optional int64 queueWaitEnd = 19;
  if (cached_has_bits & 0x00080000u) {
    target = ::google::protobuf::internal::WireFormatLite::WriteInt64ToArray(19, this->queuewaitend(), target);
  }

  // optional double total_cost = 20;
  if (cached_has_bits & 0x00100000u) {
    target = ::google::protobuf::internal::WireFormatLite::WriteDoubleToArray(20, this->total_cost(), target);
  }

  // optional string queue_name = 21 [default = "-"];
  if (cached_has_bits & 0x00000100u) {
    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
      this->queue_name().data(), static_cast<int>(this->queue_name().length()),
      ::google::protobuf::internal::WireFormat::SERIALIZE,
      "exec.shared.QueryProfile.queue_name");
    target =
      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
        21, this->queue_name(), target);
  }

  // optional string queryId = 22;
  if (cached_has_bits & 0x00000200u) {
    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
      this->queryid().data(), static_cast<int>(this->queryid().length()),
      ::google::protobuf::internal::WireFormat::SERIALIZE,
      "exec.shared.QueryProfile.queryId");
    target =
      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
        22, this->queryid(), target);
  }

  // optional int32 autoLimit = 23;
  if (cached_has_bits & 0x00020000u) {
    target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(23, this->autolimit(), target);
  }

  if (_internal_metadata_.have_unknown_fields()) {
    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
        _internal_metadata_.unknown_fields(), target);
  }
  // @@protoc_insertion_point(serialize_to_array_end:exec.shared.QueryProfile)
  return target;
}

size_t QueryProfile::ByteSizeLong() const {
// @@protoc_insertion_point(message_byte_size_start:exec.shared.QueryProfile)
  size_t total_size = 0;

  if (_internal_metadata_.have_unknown_fields()) {
    total_size +=
      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
        _internal_metadata_.unknown_fields());
  }
  // repeated .exec.shared.MajorFragmentProfile fragment_profile = 11;
  {
    unsigned int count = static_cast<unsigned int>(this->fragment_profile_size());
    total_size += 1UL * count;
    for (unsigned int i = 0; i < count; i++) {
      total_size +=
        ::google::protobuf::internal::WireFormatLite::MessageSize(
          this->fragment_profile(static_cast<int>(i)));
    }
  }

  if (_has_bits_[0 / 32] & 255u) {
    // optional string query = 5;
    if (has_query()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::StringSize(
          this->query());
    }

    // optional string plan = 6;
    if (has_plan()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::StringSize(
          this->plan());
    }

    // optional string user = 12 [default = "-"];
    if (has_user()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::StringSize(
          this->user());
    }

    // optional string error = 13;
    if (has_error()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::StringSize(
          this->error());
    }

    // optional string verboseError = 14;
    if (has_verboseerror()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::StringSize(
          this->verboseerror());
    }

    // optional string error_id = 15;
    if (has_error_id()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::StringSize(
          this->error_id());
    }

    // optional string error_node = 16;
    if (has_error_node()) {
      total_size += 2 +
        ::google::protobuf::internal::WireFormatLite::StringSize(
          this->error_node());
    }

    // optional string options_json = 17;
    if (has_options_json()) {
      total_size += 2 +
        ::google::protobuf::internal::WireFormatLite::StringSize(
          this->options_json());
    }

  }
  if (_has_bits_[8 / 32] & 65280u) {
    // optional string queue_name = 21 [default = "-"];
    if (has_queue_name()) {
      total_size += 2 +
        ::google::protobuf::internal::WireFormatLite::StringSize(
          this->queue_name());
    }

    // optional string queryId = 22;
    if (has_queryid()) {
      total_size += 2 +
        ::google::protobuf::internal::WireFormatLite::StringSize(
          this->queryid());
    }

    // optional .exec.shared.QueryId id = 1;
    if (has_id()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::MessageSize(
          *id_);
    }

    // optional .exec.DrillbitEndpoint foreman = 7;
    if (has_foreman()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::MessageSize(
          *foreman_);
    }

    // optional int64 start = 3;
    if (has_start()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::Int64Size(
          this->start());
    }

    // optional int64 end = 4;
    if (has_end()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::Int64Size(
          this->end());
    }

    // optional .exec.shared.QueryResult.QueryState state = 8;
    if (has_state()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::EnumSize(this->state());
    }

    // optional int32 total_fragments = 9;
    if (has_total_fragments()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::Int32Size(
          this->total_fragments());
    }

  }
  if (_has_bits_[16 / 32] & 4128768u) {
    // optional int32 finished_fragments = 10;
    if (has_finished_fragments()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::Int32Size(
          this->finished_fragments());
    }

    // optional int32 autoLimit = 23;
    if (has_autolimit()) {
      total_size += 2 +
        ::google::protobuf::internal::WireFormatLite::Int32Size(
          this->autolimit());
    }

    // optional int64 planEnd = 18;
    if (has_planend()) {
      total_size += 2 +
        ::google::protobuf::internal::WireFormatLite::Int64Size(
          this->planend());
    }

    // optional int64 queueWaitEnd = 19;
    if (has_queuewaitend()) {
      total_size += 2 +
        ::google::protobuf::internal::WireFormatLite::Int64Size(
          this->queuewaitend());
    }

    // optional double total_cost = 20;
    if (has_total_cost()) {
      total_size += 2 + 8;
    }

    // optional .exec.shared.QueryType type = 2;
    if (has_type()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::EnumSize(this->type());
    }

  }
  int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
  SetCachedSize(cached_size);
  return total_size;
}

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

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

  fragment_profile_.MergeFrom(from.fragment_profile_);
  cached_has_bits = from._has_bits_[0];
  if (cached_has_bits & 255u) {
    if (cached_has_bits & 0x00000001u) {
      set_has_query();
      query_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.query_);
    }
    if (cached_has_bits & 0x00000002u) {
      set_has_plan();
      plan_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.plan_);
    }
    if (cached_has_bits & 0x00000004u) {
      set_has_user();
      user_.AssignWithDefault(&::exec::shared::QueryProfile::_i_give_permission_to_break_this_code_default_user_.get(), from.user_);
    }
    if (cached_has_bits & 0x00000008u) {
      set_has_error();
      error_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.error_);
    }
    if (cached_has_bits & 0x00000010u) {
      set_has_verboseerror();
      verboseerror_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.verboseerror_);
    }
    if (cached_has_bits & 0x00000020u) {
      set_has_error_id();
      error_id_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.error_id_);
    }
    if (cached_has_bits & 0x00000040u) {
      set_has_error_node();
      error_node_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.error_node_);
    }
    if (cached_has_bits & 0x00000080u) {
      set_has_options_json();
      options_json_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.options_json_);
    }
  }
  if (cached_has_bits & 65280u) {
    if (cached_has_bits & 0x00000100u) {
      set_has_queue_name();
      queue_name_.AssignWithDefault(&::exec::shared::QueryProfile::_i_give_permission_to_break_this_code_default_queue_name_.get(), from.queue_name_);
    }
    if (cached_has_bits & 0x00000200u) {
      set_has_queryid();
      queryid_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.queryid_);
    }
    if (cached_has_bits & 0x00000400u) {
      mutable_id()->::exec::shared::QueryId::MergeFrom(from.id());
    }
    if (cached_has_bits & 0x00000800u) {
      mutable_foreman()->::exec::DrillbitEndpoint::MergeFrom(from.foreman());
    }
    if (cached_has_bits & 0x00001000u) {
      start_ = from.start_;
    }
    if (cached_has_bits & 0x00002000u) {
      end_ = from.end_;
    }
    if (cached_has_bits & 0x00004000u) {
      state_ = from.state_;
    }
    if (cached_has_bits & 0x00008000u) {
      total_fragments_ = from.total_fragments_;
    }
    _has_bits_[0] |= cached_has_bits;
  }
  if (cached_has_bits & 4128768u) {
    if (cached_has_bits & 0x00010000u) {
      finished_fragments_ = from.finished_fragments_;
    }
    if (cached_has_bits & 0x00020000u) {
      autolimit_ = from.autolimit_;
    }
    if (cached_has_bits & 0x00040000u) {
      planend_ = from.planend_;
    }
    if (cached_has_bits & 0x00080000u) {
      queuewaitend_ = from.queuewaitend_;
    }
    if (cached_has_bits & 0x00100000u) {
      total_cost_ = from.total_cost_;
    }
    if (cached_has_bits & 0x00200000u) {
      type_ = from.type_;
    }
    _has_bits_[0] |= cached_has_bits;
  }
}

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

void QueryProfile::CopyFrom(const QueryProfile& from) {
// @@protoc_insertion_point(class_specific_copy_from_start:exec.shared.QueryProfile)
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

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

void QueryProfile::Swap(QueryProfile* other) {
  if (other == this) return;
  InternalSwap(other);
}
void QueryProfile::InternalSwap(QueryProfile* other) {
  using std::swap;
  CastToBase(&fragment_profile_)->InternalSwap(CastToBase(&other->fragment_profile_));
  query_.Swap(&other->query_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
    GetArenaNoVirtual());
  plan_.Swap(&other->plan_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
    GetArenaNoVirtual());
  user_.Swap(&other->user_, &::exec::shared::QueryProfile::_i_give_permission_to_break_this_code_default_user_.get(),
    GetArenaNoVirtual());
  error_.Swap(&other->error_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
    GetArenaNoVirtual());
  verboseerror_.Swap(&other->verboseerror_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
    GetArenaNoVirtual());
  error_id_.Swap(&other->error_id_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
    GetArenaNoVirtual());
  error_node_.Swap(&other->error_node_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
    GetArenaNoVirtual());
  options_json_.Swap(&other->options_json_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
    GetArenaNoVirtual());
  queue_name_.Swap(&other->queue_name_, &::exec::shared::QueryProfile::_i_give_permission_to_break_this_code_default_queue_name_.get(),
    GetArenaNoVirtual());
  queryid_.Swap(&other->queryid_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
    GetArenaNoVirtual());
  swap(id_, other->id_);
  swap(foreman_, other->foreman_);
  swap(start_, other->start_);
  swap(end_, other->end_);
  swap(state_, other->state_);
  swap(total_fragments_, other->total_fragments_);
  swap(finished_fragments_, other->finished_fragments_);
  swap(autolimit_, other->autolimit_);
  swap(planend_, other->planend_);
  swap(queuewaitend_, other->queuewaitend_);
  swap(total_cost_, other->total_cost_);
  swap(type_, other->type_);
  swap(_has_bits_[0], other->_has_bits_[0]);
  _internal_metadata_.Swap(&other->_internal_metadata_);
}

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


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

void MajorFragmentProfile::InitAsDefaultInstance() {
}
#if !defined(_MSC_VER) || _MSC_VER >= 1900
const int MajorFragmentProfile::kMajorFragmentIdFieldNumber;
const int MajorFragmentProfile::kMinorFragmentProfileFieldNumber;
#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900

MajorFragmentProfile::MajorFragmentProfile()
  : ::google::protobuf::Message(), _internal_metadata_(NULL) {
  ::google::protobuf::internal::InitSCC(
      &protobuf_UserBitShared_2eproto::scc_info_MajorFragmentProfile.base);
  SharedCtor();
  // @@protoc_insertion_point(constructor:exec.shared.MajorFragmentProfile)
}
MajorFragmentProfile::MajorFragmentProfile(const MajorFragmentProfile& from)
  : ::google::protobuf::Message(),
      _internal_metadata_(NULL),
      _has_bits_(from._has_bits_),
      minor_fragment_profile_(from.minor_fragment_profile_) {
  _internal_metadata_.MergeFrom(from._internal_metadata_);
  major_fragment_id_ = from.major_fragment_id_;
  // @@protoc_insertion_point(copy_constructor:exec.shared.MajorFragmentProfile)
}

void MajorFragmentProfile::SharedCtor() {
  major_fragment_id_ = 0;
}

MajorFragmentProfile::~MajorFragmentProfile() {
  // @@protoc_insertion_point(destructor:exec.shared.MajorFragmentProfile)
  SharedDtor();
}

void MajorFragmentProfile::SharedDtor() {
}

void MajorFragmentProfile::SetCachedSize(int size) const {
  _cached_size_.Set(size);
}
const ::google::protobuf::Descriptor* MajorFragmentProfile::descriptor() {
  ::protobuf_UserBitShared_2eproto::protobuf_AssignDescriptorsOnce();
  return ::protobuf_UserBitShared_2eproto::file_level_metadata[kIndexInFileMessages].descriptor;
}

const MajorFragmentProfile& MajorFragmentProfile::default_instance() {
  ::google::protobuf::internal::InitSCC(&protobuf_UserBitShared_2eproto::scc_info_MajorFragmentProfile.base);
  return *internal_default_instance();
}


void MajorFragmentProfile::Clear() {
// @@protoc_insertion_point(message_clear_start:exec.shared.MajorFragmentProfile)
  ::google::protobuf::uint32 cached_has_bits = 0;
  // Prevent compiler warnings about cached_has_bits being unused
  (void) cached_has_bits;

  minor_fragment_profile_.Clear();
  major_fragment_id_ = 0;
  _has_bits_.Clear();
  _internal_metadata_.Clear();
}

bool MajorFragmentProfile::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:exec.shared.MajorFragmentProfile)
  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)) {
      // optional int32 major_fragment_id = 1;
      case 1: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(8u /* 8 & 0xFF */)) {
          set_has_major_fragment_id();
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
                 input, &major_fragment_id_)));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // repeated .exec.shared.MinorFragmentProfile minor_fragment_profile = 2;
      case 2: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(18u /* 18 & 0xFF */)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
                input, add_minor_fragment_profile()));
        } else {
          goto handle_unusual;
        }
        break;
      }

      default: {
      handle_unusual:
        if (tag == 0) {
          goto success;
        }
        DO_(::google::protobuf::internal::WireFormat::SkipField(
              input, tag, _internal_metadata_.mutable_unknown_fields()));
        break;
      }
    }
  }
success:
  // @@protoc_insertion_point(parse_success:exec.shared.MajorFragmentProfile)
  return true;
failure:
  // @@protoc_insertion_point(parse_failure:exec.shared.MajorFragmentProfile)
  return false;
#undef DO_
}

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

  cached_has_bits = _has_bits_[0];
  // optional int32 major_fragment_id = 1;
  if (cached_has_bits & 0x00000001u) {
    ::google::protobuf::internal::WireFormatLite::WriteInt32(1, this->major_fragment_id(), output);
  }

  // repeated .exec.shared.MinorFragmentProfile minor_fragment_profile = 2;
  for (unsigned int i = 0,
      n = static_cast<unsigned int>(this->minor_fragment_profile_size()); i < n; i++) {
    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
      2,
      this->minor_fragment_profile(static_cast<int>(i)),
      output);
  }

  if (_internal_metadata_.have_unknown_fields()) {
    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
        _internal_metadata_.unknown_fields(), output);
  }
  // @@protoc_insertion_point(serialize_end:exec.shared.MajorFragmentProfile)
}

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

  cached_has_bits = _has_bits_[0];
  // optional int32 major_fragment_id = 1;
  if (cached_has_bits & 0x00000001u) {
    target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(1, this->major_fragment_id(), target);
  }

  // repeated .exec.shared.MinorFragmentProfile minor_fragment_profile = 2;
  for (unsigned int i = 0,
      n = static_cast<unsigned int>(this->minor_fragment_profile_size()); i < n; i++) {
    target = ::google::protobuf::internal::WireFormatLite::
      InternalWriteMessageToArray(
        2, this->minor_fragment_profile(static_cast<int>(i)), deterministic, target);
  }

  if (_internal_metadata_.have_unknown_fields()) {
    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
        _internal_metadata_.unknown_fields(), target);
  }
  // @@protoc_insertion_point(serialize_to_array_end:exec.shared.MajorFragmentProfile)
  return target;
}

size_t MajorFragmentProfile::ByteSizeLong() const {
// @@protoc_insertion_point(message_byte_size_start:exec.shared.MajorFragmentProfile)
  size_t total_size = 0;

  if (_internal_metadata_.have_unknown_fields()) {
    total_size +=
      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
        _internal_metadata_.unknown_fields());
  }
  // repeated .exec.shared.MinorFragmentProfile minor_fragment_profile = 2;
  {
    unsigned int count = static_cast<unsigned int>(this->minor_fragment_profile_size());
    total_size += 1UL * count;
    for (unsigned int i = 0; i < count; i++) {
      total_size +=
        ::google::protobuf::internal::WireFormatLite::MessageSize(
          this->minor_fragment_profile(static_cast<int>(i)));
    }
  }

  // optional int32 major_fragment_id = 1;
  if (has_major_fragment_id()) {
    total_size += 1 +
      ::google::protobuf::internal::WireFormatLite::Int32Size(
        this->major_fragment_id());
  }

  int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
  SetCachedSize(cached_size);
  return total_size;
}

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

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

  minor_fragment_profile_.MergeFrom(from.minor_fragment_profile_);
  if (from.has_major_fragment_id()) {
    set_major_fragment_id(from.major_fragment_id());
  }
}

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

void MajorFragmentProfile::CopyFrom(const MajorFragmentProfile& from) {
// @@protoc_insertion_point(class_specific_copy_from_start:exec.shared.MajorFragmentProfile)
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

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

void MajorFragmentProfile::Swap(MajorFragmentProfile* other) {
  if (other == this) return;
  InternalSwap(other);
}
void MajorFragmentProfile::InternalSwap(MajorFragmentProfile* other) {
  using std::swap;
  CastToBase(&minor_fragment_profile_)->InternalSwap(CastToBase(&other->minor_fragment_profile_));
  swap(major_fragment_id_, other->major_fragment_id_);
  swap(_has_bits_[0], other->_has_bits_[0]);
  _internal_metadata_.Swap(&other->_internal_metadata_);
}

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


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

void MinorFragmentProfile::InitAsDefaultInstance() {
  ::exec::shared::_MinorFragmentProfile_default_instance_._instance.get_mutable()->error_ = const_cast< ::exec::shared::DrillPBError*>(
      ::exec::shared::DrillPBError::internal_default_instance());
  ::exec::shared::_MinorFragmentProfile_default_instance_._instance.get_mutable()->endpoint_ = const_cast< ::exec::DrillbitEndpoint*>(
      ::exec::DrillbitEndpoint::internal_default_instance());
}
void MinorFragmentProfile::clear_endpoint() {
  if (endpoint_ != NULL) endpoint_->Clear();
  clear_has_endpoint();
}
#if !defined(_MSC_VER) || _MSC_VER >= 1900
const int MinorFragmentProfile::kStateFieldNumber;
const int MinorFragmentProfile::kErrorFieldNumber;
const int MinorFragmentProfile::kMinorFragmentIdFieldNumber;
const int MinorFragmentProfile::kOperatorProfileFieldNumber;
const int MinorFragmentProfile::kStartTimeFieldNumber;
const int MinorFragmentProfile::kEndTimeFieldNumber;
const int MinorFragmentProfile::kMemoryUsedFieldNumber;
const int MinorFragmentProfile::kMaxMemoryUsedFieldNumber;
const int MinorFragmentProfile::kEndpointFieldNumber;
const int MinorFragmentProfile::kLastUpdateFieldNumber;
const int MinorFragmentProfile::kLastProgressFieldNumber;
#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900

MinorFragmentProfile::MinorFragmentProfile()
  : ::google::protobuf::Message(), _internal_metadata_(NULL) {
  ::google::protobuf::internal::InitSCC(
      &protobuf_UserBitShared_2eproto::scc_info_MinorFragmentProfile.base);
  SharedCtor();
  // @@protoc_insertion_point(constructor:exec.shared.MinorFragmentProfile)
}
MinorFragmentProfile::MinorFragmentProfile(const MinorFragmentProfile& from)
  : ::google::protobuf::Message(),
      _internal_metadata_(NULL),
      _has_bits_(from._has_bits_),
      operator_profile_(from.operator_profile_) {
  _internal_metadata_.MergeFrom(from._internal_metadata_);
  if (from.has_error()) {
    error_ = new ::exec::shared::DrillPBError(*from.error_);
  } else {
    error_ = NULL;
  }
  if (from.has_endpoint()) {
    endpoint_ = new ::exec::DrillbitEndpoint(*from.endpoint_);
  } else {
    endpoint_ = NULL;
  }
  ::memcpy(&state_, &from.state_,
    static_cast<size_t>(reinterpret_cast<char*>(&last_progress_) -
    reinterpret_cast<char*>(&state_)) + sizeof(last_progress_));
  // @@protoc_insertion_point(copy_constructor:exec.shared.MinorFragmentProfile)
}

void MinorFragmentProfile::SharedCtor() {
  ::memset(&error_, 0, static_cast<size_t>(
      reinterpret_cast<char*>(&last_progress_) -
      reinterpret_cast<char*>(&error_)) + sizeof(last_progress_));
}

MinorFragmentProfile::~MinorFragmentProfile() {
  // @@protoc_insertion_point(destructor:exec.shared.MinorFragmentProfile)
  SharedDtor();
}

void MinorFragmentProfile::SharedDtor() {
  if (this != internal_default_instance()) delete error_;
  if (this != internal_default_instance()) delete endpoint_;
}

void MinorFragmentProfile::SetCachedSize(int size) const {
  _cached_size_.Set(size);
}
const ::google::protobuf::Descriptor* MinorFragmentProfile::descriptor() {
  ::protobuf_UserBitShared_2eproto::protobuf_AssignDescriptorsOnce();
  return ::protobuf_UserBitShared_2eproto::file_level_metadata[kIndexInFileMessages].descriptor;
}

const MinorFragmentProfile& MinorFragmentProfile::default_instance() {
  ::google::protobuf::internal::InitSCC(&protobuf_UserBitShared_2eproto::scc_info_MinorFragmentProfile.base);
  return *internal_default_instance();
}


void MinorFragmentProfile::Clear() {
// @@protoc_insertion_point(message_clear_start:exec.shared.MinorFragmentProfile)
  ::google::protobuf::uint32 cached_has_bits = 0;
  // Prevent compiler warnings about cached_has_bits being unused
  (void) cached_has_bits;

  operator_profile_.Clear();
  cached_has_bits = _has_bits_[0];
  if (cached_has_bits & 3u) {
    if (cached_has_bits & 0x00000001u) {
      GOOGLE_DCHECK(error_ != NULL);
      error_->Clear();
    }
    if (cached_has_bits & 0x00000002u) {
      GOOGLE_DCHECK(endpoint_ != NULL);
      endpoint_->Clear();
    }
  }
  if (cached_has_bits & 252u) {
    ::memset(&state_, 0, static_cast<size_t>(
        reinterpret_cast<char*>(&max_memory_used_) -
        reinterpret_cast<char*>(&state_)) + sizeof(max_memory_used_));
  }
  if (cached_has_bits & 768u) {
    ::memset(&last_update_, 0, static_cast<size_t>(
        reinterpret_cast<char*>(&last_progress_) -
        reinterpret_cast<char*>(&last_update_)) + sizeof(last_progress_));
  }
  _has_bits_.Clear();
  _internal_metadata_.Clear();
}

bool MinorFragmentProfile::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:exec.shared.MinorFragmentProfile)
  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)) {
      // optional .exec.shared.FragmentState state = 1;
      case 1: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(8u /* 8 & 0xFF */)) {
          int value;
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
                 input, &value)));
          if (::exec::shared::FragmentState_IsValid(value)) {
            set_state(static_cast< ::exec::shared::FragmentState >(value));
          } else {
            mutable_unknown_fields()->AddVarint(
                1, static_cast< ::google::protobuf::uint64>(value));
          }
        } else {
          goto handle_unusual;
        }
        break;
      }

      // optional .exec.shared.DrillPBError error = 2;
      case 2: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(18u /* 18 & 0xFF */)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
               input, mutable_error()));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // optional int32 minor_fragment_id = 3;
      case 3: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(24u /* 24 & 0xFF */)) {
          set_has_minor_fragment_id();
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
                 input, &minor_fragment_id_)));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // repeated .exec.shared.OperatorProfile operator_profile = 4;
      case 4: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(34u /* 34 & 0xFF */)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
                input, add_operator_profile()));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // optional int64 start_time = 5;
      case 5: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(40u /* 40 & 0xFF */)) {
          set_has_start_time();
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   ::google::protobuf::int64, ::google::protobuf::internal::WireFormatLite::TYPE_INT64>(
                 input, &start_time_)));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // optional int64 end_time = 6;
      case 6: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(48u /* 48 & 0xFF */)) {
          set_has_end_time();
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   ::google::protobuf::int64, ::google::protobuf::internal::WireFormatLite::TYPE_INT64>(
                 input, &end_time_)));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // optional int64 memory_used = 7;
      case 7: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(56u /* 56 & 0xFF */)) {
          set_has_memory_used();
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   ::google::protobuf::int64, ::google::protobuf::internal::WireFormatLite::TYPE_INT64>(
                 input, &memory_used_)));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // optional int64 max_memory_used = 8;
      case 8: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(64u /* 64 & 0xFF */)) {
          set_has_max_memory_used();
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   ::google::protobuf::int64, ::google::protobuf::internal::WireFormatLite::TYPE_INT64>(
                 input, &max_memory_used_)));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // optional .exec.DrillbitEndpoint endpoint = 9;
      case 9: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(74u /* 74 & 0xFF */)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
               input, mutable_endpoint()));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // optional int64 last_update = 10;
      case 10: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(80u /* 80 & 0xFF */)) {
          set_has_last_update();
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   ::google::protobuf::int64, ::google::protobuf::internal::WireFormatLite::TYPE_INT64>(
                 input, &last_update_)));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // optional int64 last_progress = 11;
      case 11: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(88u /* 88 & 0xFF */)) {
          set_has_last_progress();
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   ::google::protobuf::int64, ::google::protobuf::internal::WireFormatLite::TYPE_INT64>(
                 input, &last_progress_)));
        } else {
          goto handle_unusual;
        }
        break;
      }

      default: {
      handle_unusual:
        if (tag == 0) {
          goto success;
        }
        DO_(::google::protobuf::internal::WireFormat::SkipField(
              input, tag, _internal_metadata_.mutable_unknown_fields()));
        break;
      }
    }
  }
success:
  // @@protoc_insertion_point(parse_success:exec.shared.MinorFragmentProfile)
  return true;
failure:
  // @@protoc_insertion_point(parse_failure:exec.shared.MinorFragmentProfile)
  return false;
#undef DO_
}

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

  cached_has_bits = _has_bits_[0];
  // optional .exec.shared.FragmentState state = 1;
  if (cached_has_bits & 0x00000004u) {
    ::google::protobuf::internal::WireFormatLite::WriteEnum(
      1, this->state(), output);
  }

  // optional .exec.shared.DrillPBError error = 2;
  if (cached_has_bits & 0x00000001u) {
    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
      2, this->_internal_error(), output);
  }

  // optional int32 minor_fragment_id = 3;
  if (cached_has_bits & 0x00000008u) {
    ::google::protobuf::internal::WireFormatLite::WriteInt32(3, this->minor_fragment_id(), output);
  }

  // repeated .exec.shared.OperatorProfile operator_profile = 4;
  for (unsigned int i = 0,
      n = static_cast<unsigned int>(this->operator_profile_size()); i < n; i++) {
    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
      4,
      this->operator_profile(static_cast<int>(i)),
      output);
  }

  // optional int64 start_time = 5;
  if (cached_has_bits & 0x00000010u) {
    ::google::protobuf::internal::WireFormatLite::WriteInt64(5, this->start_time(), output);
  }

  // optional int64 end_time = 6;
  if (cached_has_bits & 0x00000020u) {
    ::google::protobuf::internal::WireFormatLite::WriteInt64(6, this->end_time(), output);
  }

  // optional int64 memory_used = 7;
  if (cached_has_bits & 0x00000040u) {
    ::google::protobuf::internal::WireFormatLite::WriteInt64(7, this->memory_used(), output);
  }

  // optional int64 max_memory_used = 8;
  if (cached_has_bits & 0x00000080u) {
    ::google::protobuf::internal::WireFormatLite::WriteInt64(8, this->max_memory_used(), output);
  }

  // optional .exec.DrillbitEndpoint endpoint = 9;
  if (cached_has_bits & 0x00000002u) {
    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
      9, this->_internal_endpoint(), output);
  }

  // optional int64 last_update = 10;
  if (cached_has_bits & 0x00000100u) {
    ::google::protobuf::internal::WireFormatLite::WriteInt64(10, this->last_update(), output);
  }

  // optional int64 last_progress = 11;
  if (cached_has_bits & 0x00000200u) {
    ::google::protobuf::internal::WireFormatLite::WriteInt64(11, this->last_progress(), output);
  }

  if (_internal_metadata_.have_unknown_fields()) {
    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
        _internal_metadata_.unknown_fields(), output);
  }
  // @@protoc_insertion_point(serialize_end:exec.shared.MinorFragmentProfile)
}

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

  cached_has_bits = _has_bits_[0];
  // optional .exec.shared.FragmentState state = 1;
  if (cached_has_bits & 0x00000004u) {
    target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
      1, this->state(), target);
  }

  // optional .exec.shared.DrillPBError error = 2;
  if (cached_has_bits & 0x00000001u) {
    target = ::google::protobuf::internal::WireFormatLite::
      InternalWriteMessageToArray(
        2, this->_internal_error(), deterministic, target);
  }

  // optional int32 minor_fragment_id = 3;
  if (cached_has_bits & 0x00000008u) {
    target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(3, this->minor_fragment_id(), target);
  }

  // repeated .exec.shared.OperatorProfile operator_profile = 4;
  for (unsigned int i = 0,
      n = static_cast<unsigned int>(this->operator_profile_size()); i < n; i++) {
    target = ::google::protobuf::internal::WireFormatLite::
      InternalWriteMessageToArray(
        4, this->operator_profile(static_cast<int>(i)), deterministic, target);
  }

  // optional int64 start_time = 5;
  if (cached_has_bits & 0x00000010u) {
    target = ::google::protobuf::internal::WireFormatLite::WriteInt64ToArray(5, this->start_time(), target);
  }

  // optional int64 end_time = 6;
  if (cached_has_bits & 0x00000020u) {
    target = ::google::protobuf::internal::WireFormatLite::WriteInt64ToArray(6, this->end_time(), target);
  }

  // optional int64 memory_used = 7;
  if (cached_has_bits & 0x00000040u) {
    target = ::google::protobuf::internal::WireFormatLite::WriteInt64ToArray(7, this->memory_used(), target);
  }

  // optional int64 max_memory_used = 8;
  if (cached_has_bits & 0x00000080u) {
    target = ::google::protobuf::internal::WireFormatLite::WriteInt64ToArray(8, this->max_memory_used(), target);
  }

  // optional .exec.DrillbitEndpoint endpoint = 9;
  if (cached_has_bits & 0x00000002u) {
    target = ::google::protobuf::internal::WireFormatLite::
      InternalWriteMessageToArray(
        9, this->_internal_endpoint(), deterministic, target);
  }

  // optional int64 last_update = 10;
  if (cached_has_bits & 0x00000100u) {
    target = ::google::protobuf::internal::WireFormatLite::WriteInt64ToArray(10, this->last_update(), target);
  }

  // optional int64 last_progress = 11;
  if (cached_has_bits & 0x00000200u) {
    target = ::google::protobuf::internal::WireFormatLite::WriteInt64ToArray(11, this->last_progress(), target);
  }

  if (_internal_metadata_.have_unknown_fields()) {
    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
        _internal_metadata_.unknown_fields(), target);
  }
  // @@protoc_insertion_point(serialize_to_array_end:exec.shared.MinorFragmentProfile)
  return target;
}

size_t MinorFragmentProfile::ByteSizeLong() const {
// @@protoc_insertion_point(message_byte_size_start:exec.shared.MinorFragmentProfile)
  size_t total_size = 0;

  if (_internal_metadata_.have_unknown_fields()) {
    total_size +=
      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
        _internal_metadata_.unknown_fields());
  }
  // repeated .exec.shared.OperatorProfile operator_profile = 4;
  {
    unsigned int count = static_cast<unsigned int>(this->operator_profile_size());
    total_size += 1UL * count;
    for (unsigned int i = 0; i < count; i++) {
      total_size +=
        ::google::protobuf::internal::WireFormatLite::MessageSize(
          this->operator_profile(static_cast<int>(i)));
    }
  }

  if (_has_bits_[0 / 32] & 255u) {
    // optional .exec.shared.DrillPBError error = 2;
    if (has_error()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::MessageSize(
          *error_);
    }

    // optional .exec.DrillbitEndpoint endpoint = 9;
    if (has_endpoint()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::MessageSize(
          *endpoint_);
    }

    // optional .exec.shared.FragmentState state = 1;
    if (has_state()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::EnumSize(this->state());
    }

    // optional int32 minor_fragment_id = 3;
    if (has_minor_fragment_id()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::Int32Size(
          this->minor_fragment_id());
    }

    // optional int64 start_time = 5;
    if (has_start_time()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::Int64Size(
          this->start_time());
    }

    // optional int64 end_time = 6;
    if (has_end_time()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::Int64Size(
          this->end_time());
    }

    // optional int64 memory_used = 7;
    if (has_memory_used()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::Int64Size(
          this->memory_used());
    }

    // optional int64 max_memory_used = 8;
    if (has_max_memory_used()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::Int64Size(
          this->max_memory_used());
    }

  }
  if (_has_bits_[8 / 32] & 768u) {
    // optional int64 last_update = 10;
    if (has_last_update()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::Int64Size(
          this->last_update());
    }

    // optional int64 last_progress = 11;
    if (has_last_progress()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::Int64Size(
          this->last_progress());
    }

  }
  int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
  SetCachedSize(cached_size);
  return total_size;
}

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

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

  operator_profile_.MergeFrom(from.operator_profile_);
  cached_has_bits = from._has_bits_[0];
  if (cached_has_bits & 255u) {
    if (cached_has_bits & 0x00000001u) {
      mutable_error()->::exec::shared::DrillPBError::MergeFrom(from.error());
    }
    if (cached_has_bits & 0x00000002u) {
      mutable_endpoint()->::exec::DrillbitEndpoint::MergeFrom(from.endpoint());
    }
    if (cached_has_bits & 0x00000004u) {
      state_ = from.state_;
    }
    if (cached_has_bits & 0x00000008u) {
      minor_fragment_id_ = from.minor_fragment_id_;
    }
    if (cached_has_bits & 0x00000010u) {
      start_time_ = from.start_time_;
    }
    if (cached_has_bits & 0x00000020u) {
      end_time_ = from.end_time_;
    }
    if (cached_has_bits & 0x00000040u) {
      memory_used_ = from.memory_used_;
    }
    if (cached_has_bits & 0x00000080u) {
      max_memory_used_ = from.max_memory_used_;
    }
    _has_bits_[0] |= cached_has_bits;
  }
  if (cached_has_bits & 768u) {
    if (cached_has_bits & 0x00000100u) {
      last_update_ = from.last_update_;
    }
    if (cached_has_bits & 0x00000200u) {
      last_progress_ = from.last_progress_;
    }
    _has_bits_[0] |= cached_has_bits;
  }
}

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

void MinorFragmentProfile::CopyFrom(const MinorFragmentProfile& from) {
// @@protoc_insertion_point(class_specific_copy_from_start:exec.shared.MinorFragmentProfile)
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

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

void MinorFragmentProfile::Swap(MinorFragmentProfile* other) {
  if (other == this) return;
  InternalSwap(other);
}
void MinorFragmentProfile::InternalSwap(MinorFragmentProfile* other) {
  using std::swap;
  CastToBase(&operator_profile_)->InternalSwap(CastToBase(&other->operator_profile_));
  swap(error_, other->error_);
  swap(endpoint_, other->endpoint_);
  swap(state_, other->state_);
  swap(minor_fragment_id_, other->minor_fragment_id_);
  swap(start_time_, other->start_time_);
  swap(end_time_, other->end_time_);
  swap(memory_used_, other->memory_used_);
  swap(max_memory_used_, other->max_memory_used_);
  swap(last_update_, other->last_update_);
  swap(last_progress_, other->last_progress_);
  swap(_has_bits_[0], other->_has_bits_[0]);
  _internal_metadata_.Swap(&other->_internal_metadata_);
}

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


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

void OperatorProfile::InitAsDefaultInstance() {
}
#if !defined(_MSC_VER) || _MSC_VER >= 1900
const int OperatorProfile::kInputProfileFieldNumber;
const int OperatorProfile::kOperatorIdFieldNumber;
const int OperatorProfile::kOperatorTypeFieldNumber;
const int OperatorProfile::kSetupNanosFieldNumber;
const int OperatorProfile::kProcessNanosFieldNumber;
const int OperatorProfile::kPeakLocalMemoryAllocatedFieldNumber;
const int OperatorProfile::kMetricFieldNumber;
const int OperatorProfile::kWaitNanosFieldNumber;
#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900

OperatorProfile::OperatorProfile()
  : ::google::protobuf::Message(), _internal_metadata_(NULL) {
  ::google::protobuf::internal::InitSCC(
      &protobuf_UserBitShared_2eproto::scc_info_OperatorProfile.base);
  SharedCtor();
  // @@protoc_insertion_point(constructor:exec.shared.OperatorProfile)
}
OperatorProfile::OperatorProfile(const OperatorProfile& from)
  : ::google::protobuf::Message(),
      _internal_metadata_(NULL),
      _has_bits_(from._has_bits_),
      input_profile_(from.input_profile_),
      metric_(from.metric_) {
  _internal_metadata_.MergeFrom(from._internal_metadata_);
  ::memcpy(&operator_id_, &from.operator_id_,
    static_cast<size_t>(reinterpret_cast<char*>(&wait_nanos_) -
    reinterpret_cast<char*>(&operator_id_)) + sizeof(wait_nanos_));
  // @@protoc_insertion_point(copy_constructor:exec.shared.OperatorProfile)
}

void OperatorProfile::SharedCtor() {
  ::memset(&operator_id_, 0, static_cast<size_t>(
      reinterpret_cast<char*>(&wait_nanos_) -
      reinterpret_cast<char*>(&operator_id_)) + sizeof(wait_nanos_));
}

OperatorProfile::~OperatorProfile() {
  // @@protoc_insertion_point(destructor:exec.shared.OperatorProfile)
  SharedDtor();
}

void OperatorProfile::SharedDtor() {
}

void OperatorProfile::SetCachedSize(int size) const {
  _cached_size_.Set(size);
}
const ::google::protobuf::Descriptor* OperatorProfile::descriptor() {
  ::protobuf_UserBitShared_2eproto::protobuf_AssignDescriptorsOnce();
  return ::protobuf_UserBitShared_2eproto::file_level_metadata[kIndexInFileMessages].descriptor;
}

const OperatorProfile& OperatorProfile::default_instance() {
  ::google::protobuf::internal::InitSCC(&protobuf_UserBitShared_2eproto::scc_info_OperatorProfile.base);
  return *internal_default_instance();
}


void OperatorProfile::Clear() {
// @@protoc_insertion_point(message_clear_start:exec.shared.OperatorProfile)
  ::google::protobuf::uint32 cached_has_bits = 0;
  // Prevent compiler warnings about cached_has_bits being unused
  (void) cached_has_bits;

  input_profile_.Clear();
  metric_.Clear();
  cached_has_bits = _has_bits_[0];
  if (cached_has_bits & 63u) {
    ::memset(&operator_id_, 0, static_cast<size_t>(
        reinterpret_cast<char*>(&wait_nanos_) -
        reinterpret_cast<char*>(&operator_id_)) + sizeof(wait_nanos_));
  }
  _has_bits_.Clear();
  _internal_metadata_.Clear();
}

bool OperatorProfile::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:exec.shared.OperatorProfile)
  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 .exec.shared.StreamProfile input_profile = 1;
      case 1: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(10u /* 10 & 0xFF */)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
                input, add_input_profile()));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // optional int32 operator_id = 3;
      case 3: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(24u /* 24 & 0xFF */)) {
          set_has_operator_id();
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
                 input, &operator_id_)));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // optional int32 operator_type = 4;
      case 4: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(32u /* 32 & 0xFF */)) {
          set_has_operator_type();
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
                 input, &operator_type_)));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // optional int64 setup_nanos = 5;
      case 5: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(40u /* 40 & 0xFF */)) {
          set_has_setup_nanos();
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   ::google::protobuf::int64, ::google::protobuf::internal::WireFormatLite::TYPE_INT64>(
                 input, &setup_nanos_)));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // optional int64 process_nanos = 6;
      case 6: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(48u /* 48 & 0xFF */)) {
          set_has_process_nanos();
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   ::google::protobuf::int64, ::google::protobuf::internal::WireFormatLite::TYPE_INT64>(
                 input, &process_nanos_)));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // optional int64 peak_local_memory_allocated = 7;
      case 7: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(56u /* 56 & 0xFF */)) {
          set_has_peak_local_memory_allocated();
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   ::google::protobuf::int64, ::google::protobuf::internal::WireFormatLite::TYPE_INT64>(
                 input, &peak_local_memory_allocated_)));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // repeated .exec.shared.MetricValue metric = 8;
      case 8: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(66u /* 66 & 0xFF */)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
                input, add_metric()));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // optional int64 wait_nanos = 9;
      case 9: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(72u /* 72 & 0xFF */)) {
          set_has_wait_nanos();
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   ::google::protobuf::int64, ::google::protobuf::internal::WireFormatLite::TYPE_INT64>(
                 input, &wait_nanos_)));
        } else {
          goto handle_unusual;
        }
        break;
      }

      default: {
      handle_unusual:
        if (tag == 0) {
          goto success;
        }
        DO_(::google::protobuf::internal::WireFormat::SkipField(
              input, tag, _internal_metadata_.mutable_unknown_fields()));
        break;
      }
    }
  }
success:
  // @@protoc_insertion_point(parse_success:exec.shared.OperatorProfile)
  return true;
failure:
  // @@protoc_insertion_point(parse_failure:exec.shared.OperatorProfile)
  return false;
#undef DO_
}

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

  // repeated .exec.shared.StreamProfile input_profile = 1;
  for (unsigned int i = 0,
      n = static_cast<unsigned int>(this->input_profile_size()); i < n; i++) {
    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
      1,
      this->input_profile(static_cast<int>(i)),
      output);
  }

  cached_has_bits = _has_bits_[0];
  // optional int32 operator_id = 3;
  if (cached_has_bits & 0x00000001u) {
    ::google::protobuf::internal::WireFormatLite::WriteInt32(3, this->operator_id(), output);
  }

  // optional int32 operator_type = 4;
  if (cached_has_bits & 0x00000002u) {
    ::google::protobuf::internal::WireFormatLite::WriteInt32(4, this->operator_type(), output);
  }

  // optional int64 setup_nanos = 5;
  if (cached_has_bits & 0x00000004u) {
    ::google::protobuf::internal::WireFormatLite::WriteInt64(5, this->setup_nanos(), output);
  }

  // optional int64 process_nanos = 6;
  if (cached_has_bits & 0x00000008u) {
    ::google::protobuf::internal::WireFormatLite::WriteInt64(6, this->process_nanos(), output);
  }

  // optional int64 peak_local_memory_allocated = 7;
  if (cached_has_bits & 0x00000010u) {
    ::google::protobuf::internal::WireFormatLite::WriteInt64(7, this->peak_local_memory_allocated(), output);
  }

  // repeated .exec.shared.MetricValue metric = 8;
  for (unsigned int i = 0,
      n = static_cast<unsigned int>(this->metric_size()); i < n; i++) {
    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
      8,
      this->metric(static_cast<int>(i)),
      output);
  }

  // optional int64 wait_nanos = 9;
  if (cached_has_bits & 0x00000020u) {
    ::google::protobuf::internal::WireFormatLite::WriteInt64(9, this->wait_nanos(), output);
  }

  if (_internal_metadata_.have_unknown_fields()) {
    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
        _internal_metadata_.unknown_fields(), output);
  }
  // @@protoc_insertion_point(serialize_end:exec.shared.OperatorProfile)
}

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

  // repeated .exec.shared.StreamProfile input_profile = 1;
  for (unsigned int i = 0,
      n = static_cast<unsigned int>(this->input_profile_size()); i < n; i++) {
    target = ::google::protobuf::internal::WireFormatLite::
      InternalWriteMessageToArray(
        1, this->input_profile(static_cast<int>(i)), deterministic, target);
  }

  cached_has_bits = _has_bits_[0];
  // optional int32 operator_id = 3;
  if (cached_has_bits & 0x00000001u) {
    target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(3, this->operator_id(), target);
  }

  // optional int32 operator_type = 4;
  if (cached_has_bits & 0x00000002u) {
    target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(4, this->operator_type(), target);
  }

  // optional int64 setup_nanos = 5;
  if (cached_has_bits & 0x00000004u) {
    target = ::google::protobuf::internal::WireFormatLite::WriteInt64ToArray(5, this->setup_nanos(), target);
  }

  // optional int64 process_nanos = 6;
  if (cached_has_bits & 0x00000008u) {
    target = ::google::protobuf::internal::WireFormatLite::WriteInt64ToArray(6, this->process_nanos(), target);
  }

  // optional int64 peak_local_memory_allocated = 7;
  if (cached_has_bits & 0x00000010u) {
    target = ::google::protobuf::internal::WireFormatLite::WriteInt64ToArray(7, this->peak_local_memory_allocated(), target);
  }

  // repeated .exec.shared.MetricValue metric = 8;
  for (unsigned int i = 0,
      n = static_cast<unsigned int>(this->metric_size()); i < n; i++) {
    target = ::google::protobuf::internal::WireFormatLite::
      InternalWriteMessageToArray(
        8, this->metric(static_cast<int>(i)), deterministic, target);
  }

  // optional int64 wait_nanos = 9;
  if (cached_has_bits & 0x00000020u) {
    target = ::google::protobuf::internal::WireFormatLite::WriteInt64ToArray(9, this->wait_nanos(), target);
  }

  if (_internal_metadata_.have_unknown_fields()) {
    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
        _internal_metadata_.unknown_fields(), target);
  }
  // @@protoc_insertion_point(serialize_to_array_end:exec.shared.OperatorProfile)
  return target;
}

size_t OperatorProfile::ByteSizeLong() const {
// @@protoc_insertion_point(message_byte_size_start:exec.shared.OperatorProfile)
  size_t total_size = 0;

  if (_internal_metadata_.have_unknown_fields()) {
    total_size +=
      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
        _internal_metadata_.unknown_fields());
  }
  // repeated .exec.shared.StreamProfile input_profile = 1;
  {
    unsigned int count = static_cast<unsigned int>(this->input_profile_size());
    total_size += 1UL * count;
    for (unsigned int i = 0; i < count; i++) {
      total_size +=
        ::google::protobuf::internal::WireFormatLite::MessageSize(
          this->input_profile(static_cast<int>(i)));
    }
  }

  // repeated .exec.shared.MetricValue metric = 8;
  {
    unsigned int count = static_cast<unsigned int>(this->metric_size());
    total_size += 1UL * count;
    for (unsigned int i = 0; i < count; i++) {
      total_size +=
        ::google::protobuf::internal::WireFormatLite::MessageSize(
          this->metric(static_cast<int>(i)));
    }
  }

  if (_has_bits_[0 / 32] & 63u) {
    // optional int32 operator_id = 3;
    if (has_operator_id()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::Int32Size(
          this->operator_id());
    }

    // optional int32 operator_type = 4;
    if (has_operator_type()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::Int32Size(
          this->operator_type());
    }

    // optional int64 setup_nanos = 5;
    if (has_setup_nanos()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::Int64Size(
          this->setup_nanos());
    }

    // optional int64 process_nanos = 6;
    if (has_process_nanos()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::Int64Size(
          this->process_nanos());
    }

    // optional int64 peak_local_memory_allocated = 7;
    if (has_peak_local_memory_allocated()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::Int64Size(
          this->peak_local_memory_allocated());
    }

    // optional int64 wait_nanos = 9;
    if (has_wait_nanos()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::Int64Size(
          this->wait_nanos());
    }

  }
  int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
  SetCachedSize(cached_size);
  return total_size;
}

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

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

  input_profile_.MergeFrom(from.input_profile_);
  metric_.MergeFrom(from.metric_);
  cached_has_bits = from._has_bits_[0];
  if (cached_has_bits & 63u) {
    if (cached_has_bits & 0x00000001u) {
      operator_id_ = from.operator_id_;
    }
    if (cached_has_bits & 0x00000002u) {
      operator_type_ = from.operator_type_;
    }
    if (cached_has_bits & 0x00000004u) {
      setup_nanos_ = from.setup_nanos_;
    }
    if (cached_has_bits & 0x00000008u) {
      process_nanos_ = from.process_nanos_;
    }
    if (cached_has_bits & 0x00000010u) {
      peak_local_memory_allocated_ = from.peak_local_memory_allocated_;
    }
    if (cached_has_bits & 0x00000020u) {
      wait_nanos_ = from.wait_nanos_;
    }
    _has_bits_[0] |= cached_has_bits;
  }
}

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

void OperatorProfile::CopyFrom(const OperatorProfile& from) {
// @@protoc_insertion_point(class_specific_copy_from_start:exec.shared.OperatorProfile)
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

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

void OperatorProfile::Swap(OperatorProfile* other) {
  if (other == this) return;
  InternalSwap(other);
}
void OperatorProfile::InternalSwap(OperatorProfile* other) {
  using std::swap;
  CastToBase(&input_profile_)->InternalSwap(CastToBase(&other->input_profile_));
  CastToBase(&metric_)->InternalSwap(CastToBase(&other->metric_));
  swap(operator_id_, other->operator_id_);
  swap(operator_type_, other->operator_type_);
  swap(setup_nanos_, other->setup_nanos_);
  swap(process_nanos_, other->process_nanos_);
  swap(peak_local_memory_allocated_, other->peak_local_memory_allocated_);
  swap(wait_nanos_, other->wait_nanos_);
  swap(_has_bits_[0], other->_has_bits_[0]);
  _internal_metadata_.Swap(&other->_internal_metadata_);
}

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


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

void StreamProfile::InitAsDefaultInstance() {
}
#if !defined(_MSC_VER) || _MSC_VER >= 1900
const int StreamProfile::kRecordsFieldNumber;
const int StreamProfile::kBatchesFieldNumber;
const int StreamProfile::kSchemasFieldNumber;
#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900

StreamProfile::StreamProfile()
  : ::google::protobuf::Message(), _internal_metadata_(NULL) {
  ::google::protobuf::internal::InitSCC(
      &protobuf_UserBitShared_2eproto::scc_info_StreamProfile.base);
  SharedCtor();
  // @@protoc_insertion_point(constructor:exec.shared.StreamProfile)
}
StreamProfile::StreamProfile(const StreamProfile& from)
  : ::google::protobuf::Message(),
      _internal_metadata_(NULL),
      _has_bits_(from._has_bits_) {
  _internal_metadata_.MergeFrom(from._internal_metadata_);
  ::memcpy(&records_, &from.records_,
    static_cast<size_t>(reinterpret_cast<char*>(&schemas_) -
    reinterpret_cast<char*>(&records_)) + sizeof(schemas_));
  // @@protoc_insertion_point(copy_constructor:exec.shared.StreamProfile)
}

void StreamProfile::SharedCtor() {
  ::memset(&records_, 0, static_cast<size_t>(
      reinterpret_cast<char*>(&schemas_) -
      reinterpret_cast<char*>(&records_)) + sizeof(schemas_));
}

StreamProfile::~StreamProfile() {
  // @@protoc_insertion_point(destructor:exec.shared.StreamProfile)
  SharedDtor();
}

void StreamProfile::SharedDtor() {
}

void StreamProfile::SetCachedSize(int size) const {
  _cached_size_.Set(size);
}
const ::google::protobuf::Descriptor* StreamProfile::descriptor() {
  ::protobuf_UserBitShared_2eproto::protobuf_AssignDescriptorsOnce();
  return ::protobuf_UserBitShared_2eproto::file_level_metadata[kIndexInFileMessages].descriptor;
}

const StreamProfile& StreamProfile::default_instance() {
  ::google::protobuf::internal::InitSCC(&protobuf_UserBitShared_2eproto::scc_info_StreamProfile.base);
  return *internal_default_instance();
}


void StreamProfile::Clear() {
// @@protoc_insertion_point(message_clear_start:exec.shared.StreamProfile)
  ::google::protobuf::uint32 cached_has_bits = 0;
  // Prevent compiler warnings about cached_has_bits being unused
  (void) cached_has_bits;

  cached_has_bits = _has_bits_[0];
  if (cached_has_bits & 7u) {
    ::memset(&records_, 0, static_cast<size_t>(
        reinterpret_cast<char*>(&schemas_) -
        reinterpret_cast<char*>(&records_)) + sizeof(schemas_));
  }
  _has_bits_.Clear();
  _internal_metadata_.Clear();
}

bool StreamProfile::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:exec.shared.StreamProfile)
  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)) {
      // optional int64 records = 1;
      case 1: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(8u /* 8 & 0xFF */)) {
          set_has_records();
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   ::google::protobuf::int64, ::google::protobuf::internal::WireFormatLite::TYPE_INT64>(
                 input, &records_)));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // optional int64 batches = 2;
      case 2: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(16u /* 16 & 0xFF */)) {
          set_has_batches();
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   ::google::protobuf::int64, ::google::protobuf::internal::WireFormatLite::TYPE_INT64>(
                 input, &batches_)));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // optional int64 schemas = 3;
      case 3: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(24u /* 24 & 0xFF */)) {
          set_has_schemas();
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   ::google::protobuf::int64, ::google::protobuf::internal::WireFormatLite::TYPE_INT64>(
                 input, &schemas_)));
        } else {
          goto handle_unusual;
        }
        break;
      }

      default: {
      handle_unusual:
        if (tag == 0) {
          goto success;
        }
        DO_(::google::protobuf::internal::WireFormat::SkipField(
              input, tag, _internal_metadata_.mutable_unknown_fields()));
        break;
      }
    }
  }
success:
  // @@protoc_insertion_point(parse_success:exec.shared.StreamProfile)
  return true;
failure:
  // @@protoc_insertion_point(parse_failure:exec.shared.StreamProfile)
  return false;
#undef DO_
}

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

  cached_has_bits = _has_bits_[0];
  // optional int64 records = 1;
  if (cached_has_bits & 0x00000001u) {
    ::google::protobuf::internal::WireFormatLite::WriteInt64(1, this->records(), output);
  }

  // optional int64 batches = 2;
  if (cached_has_bits & 0x00000002u) {
    ::google::protobuf::internal::WireFormatLite::WriteInt64(2, this->batches(), output);
  }

  // optional int64 schemas = 3;
  if (cached_has_bits & 0x00000004u) {
    ::google::protobuf::internal::WireFormatLite::WriteInt64(3, this->schemas(), output);
  }

  if (_internal_metadata_.have_unknown_fields()) {
    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
        _internal_metadata_.unknown_fields(), output);
  }
  // @@protoc_insertion_point(serialize_end:exec.shared.StreamProfile)
}

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

  cached_has_bits = _has_bits_[0];
  // optional int64 records = 1;
  if (cached_has_bits & 0x00000001u) {
    target = ::google::protobuf::internal::WireFormatLite::WriteInt64ToArray(1, this->records(), target);
  }

  // optional int64 batches = 2;
  if (cached_has_bits & 0x00000002u) {
    target = ::google::protobuf::internal::WireFormatLite::WriteInt64ToArray(2, this->batches(), target);
  }

  // optional int64 schemas = 3;
  if (cached_has_bits & 0x00000004u) {
    target = ::google::protobuf::internal::WireFormatLite::WriteInt64ToArray(3, this->schemas(), target);
  }

  if (_internal_metadata_.have_unknown_fields()) {
    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
        _internal_metadata_.unknown_fields(), target);
  }
  // @@protoc_insertion_point(serialize_to_array_end:exec.shared.StreamProfile)
  return target;
}

size_t StreamProfile::ByteSizeLong() const {
// @@protoc_insertion_point(message_byte_size_start:exec.shared.StreamProfile)
  size_t total_size = 0;

  if (_internal_metadata_.have_unknown_fields()) {
    total_size +=
      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
        _internal_metadata_.unknown_fields());
  }
  if (_has_bits_[0 / 32] & 7u) {
    // optional int64 records = 1;
    if (has_records()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::Int64Size(
          this->records());
    }

    // optional int64 batches = 2;
    if (has_batches()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::Int64Size(
          this->batches());
    }

    // optional int64 schemas = 3;
    if (has_schemas()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::Int64Size(
          this->schemas());
    }

  }
  int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
  SetCachedSize(cached_size);
  return total_size;
}

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

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

  cached_has_bits = from._has_bits_[0];
  if (cached_has_bits & 7u) {
    if (cached_has_bits & 0x00000001u) {
      records_ = from.records_;
    }
    if (cached_has_bits & 0x00000002u) {
      batches_ = from.batches_;
    }
    if (cached_has_bits & 0x00000004u) {
      schemas_ = from.schemas_;
    }
    _has_bits_[0] |= cached_has_bits;
  }
}

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

void StreamProfile::CopyFrom(const StreamProfile& from) {
// @@protoc_insertion_point(class_specific_copy_from_start:exec.shared.StreamProfile)
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

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

void StreamProfile::Swap(StreamProfile* other) {
  if (other == this) return;
  InternalSwap(other);
}
void StreamProfile::InternalSwap(StreamProfile* other) {
  using std::swap;
  swap(records_, other->records_);
  swap(batches_, other->batches_);
  swap(schemas_, other->schemas_);
  swap(_has_bits_[0], other->_has_bits_[0]);
  _internal_metadata_.Swap(&other->_internal_metadata_);
}

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


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

void MetricValue::InitAsDefaultInstance() {
}
#if !defined(_MSC_VER) || _MSC_VER >= 1900
const int MetricValue::kMetricIdFieldNumber;
const int MetricValue::kLongValueFieldNumber;
const int MetricValue::kDoubleValueFieldNumber;
#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900

MetricValue::MetricValue()
  : ::google::protobuf::Message(), _internal_metadata_(NULL) {
  ::google::protobuf::internal::InitSCC(
      &protobuf_UserBitShared_2eproto::scc_info_MetricValue.base);
  SharedCtor();
  // @@protoc_insertion_point(constructor:exec.shared.MetricValue)
}
MetricValue::MetricValue(const MetricValue& from)
  : ::google::protobuf::Message(),
      _internal_metadata_(NULL),
      _has_bits_(from._has_bits_) {
  _internal_metadata_.MergeFrom(from._internal_metadata_);
  ::memcpy(&long_value_, &from.long_value_,
    static_cast<size_t>(reinterpret_cast<char*>(&metric_id_) -
    reinterpret_cast<char*>(&long_value_)) + sizeof(metric_id_));
  // @@protoc_insertion_point(copy_constructor:exec.shared.MetricValue)
}

void MetricValue::SharedCtor() {
  ::memset(&long_value_, 0, static_cast<size_t>(
      reinterpret_cast<char*>(&metric_id_) -
      reinterpret_cast<char*>(&long_value_)) + sizeof(metric_id_));
}

MetricValue::~MetricValue() {
  // @@protoc_insertion_point(destructor:exec.shared.MetricValue)
  SharedDtor();
}

void MetricValue::SharedDtor() {
}

void MetricValue::SetCachedSize(int size) const {
  _cached_size_.Set(size);
}
const ::google::protobuf::Descriptor* MetricValue::descriptor() {
  ::protobuf_UserBitShared_2eproto::protobuf_AssignDescriptorsOnce();
  return ::protobuf_UserBitShared_2eproto::file_level_metadata[kIndexInFileMessages].descriptor;
}

const MetricValue& MetricValue::default_instance() {
  ::google::protobuf::internal::InitSCC(&protobuf_UserBitShared_2eproto::scc_info_MetricValue.base);
  return *internal_default_instance();
}


void MetricValue::Clear() {
// @@protoc_insertion_point(message_clear_start:exec.shared.MetricValue)
  ::google::protobuf::uint32 cached_has_bits = 0;
  // Prevent compiler warnings about cached_has_bits being unused
  (void) cached_has_bits;

  cached_has_bits = _has_bits_[0];
  if (cached_has_bits & 7u) {
    ::memset(&long_value_, 0, static_cast<size_t>(
        reinterpret_cast<char*>(&metric_id_) -
        reinterpret_cast<char*>(&long_value_)) + sizeof(metric_id_));
  }
  _has_bits_.Clear();
  _internal_metadata_.Clear();
}

bool MetricValue::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:exec.shared.MetricValue)
  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)) {
      // optional int32 metric_id = 1;
      case 1: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(8u /* 8 & 0xFF */)) {
          set_has_metric_id();
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
                 input, &metric_id_)));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // optional int64 long_value = 2;
      case 2: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(16u /* 16 & 0xFF */)) {
          set_has_long_value();
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   ::google::protobuf::int64, ::google::protobuf::internal::WireFormatLite::TYPE_INT64>(
                 input, &long_value_)));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // optional double double_value = 3;
      case 3: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(25u /* 25 & 0xFF */)) {
          set_has_double_value();
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   double, ::google::protobuf::internal::WireFormatLite::TYPE_DOUBLE>(
                 input, &double_value_)));
        } else {
          goto handle_unusual;
        }
        break;
      }

      default: {
      handle_unusual:
        if (tag == 0) {
          goto success;
        }
        DO_(::google::protobuf::internal::WireFormat::SkipField(
              input, tag, _internal_metadata_.mutable_unknown_fields()));
        break;
      }
    }
  }
success:
  // @@protoc_insertion_point(parse_success:exec.shared.MetricValue)
  return true;
failure:
  // @@protoc_insertion_point(parse_failure:exec.shared.MetricValue)
  return false;
#undef DO_
}

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

  cached_has_bits = _has_bits_[0];
  // optional int32 metric_id = 1;
  if (cached_has_bits & 0x00000004u) {
    ::google::protobuf::internal::WireFormatLite::WriteInt32(1, this->metric_id(), output);
  }

  // optional int64 long_value = 2;
  if (cached_has_bits & 0x00000001u) {
    ::google::protobuf::internal::WireFormatLite::WriteInt64(2, this->long_value(), output);
  }

  // optional double double_value = 3;
  if (cached_has_bits & 0x00000002u) {
    ::google::protobuf::internal::WireFormatLite::WriteDouble(3, this->double_value(), output);
  }

  if (_internal_metadata_.have_unknown_fields()) {
    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
        _internal_metadata_.unknown_fields(), output);
  }
  // @@protoc_insertion_point(serialize_end:exec.shared.MetricValue)
}

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

  cached_has_bits = _has_bits_[0];
  // optional int32 metric_id = 1;
  if (cached_has_bits & 0x00000004u) {
    target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(1, this->metric_id(), target);
  }

  // optional int64 long_value = 2;
  if (cached_has_bits & 0x00000001u) {
    target = ::google::protobuf::internal::WireFormatLite::WriteInt64ToArray(2, this->long_value(), target);
  }

  // optional double double_value = 3;
  if (cached_has_bits & 0x00000002u) {
    target = ::google::protobuf::internal::WireFormatLite::WriteDoubleToArray(3, this->double_value(), target);
  }

  if (_internal_metadata_.have_unknown_fields()) {
    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
        _internal_metadata_.unknown_fields(), target);
  }
  // @@protoc_insertion_point(serialize_to_array_end:exec.shared.MetricValue)
  return target;
}

size_t MetricValue::ByteSizeLong() const {
// @@protoc_insertion_point(message_byte_size_start:exec.shared.MetricValue)
  size_t total_size = 0;

  if (_internal_metadata_.have_unknown_fields()) {
    total_size +=
      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
        _internal_metadata_.unknown_fields());
  }
  if (_has_bits_[0 / 32] & 7u) {
    // optional int64 long_value = 2;
    if (has_long_value()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::Int64Size(
          this->long_value());
    }

    // optional double double_value = 3;
    if (has_double_value()) {
      total_size += 1 + 8;
    }

    // optional int32 metric_id = 1;
    if (has_metric_id()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::Int32Size(
          this->metric_id());
    }

  }
  int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
  SetCachedSize(cached_size);
  return total_size;
}

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

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

  cached_has_bits = from._has_bits_[0];
  if (cached_has_bits & 7u) {
    if (cached_has_bits & 0x00000001u) {
      long_value_ = from.long_value_;
    }
    if (cached_has_bits & 0x00000002u) {
      double_value_ = from.double_value_;
    }
    if (cached_has_bits & 0x00000004u) {
      metric_id_ = from.metric_id_;
    }
    _has_bits_[0] |= cached_has_bits;
  }
}

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

void MetricValue::CopyFrom(const MetricValue& from) {
// @@protoc_insertion_point(class_specific_copy_from_start:exec.shared.MetricValue)
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

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

void MetricValue::Swap(MetricValue* other) {
  if (other == this) return;
  InternalSwap(other);
}
void MetricValue::InternalSwap(MetricValue* other) {
  using std::swap;
  swap(long_value_, other->long_value_);
  swap(double_value_, other->double_value_);
  swap(metric_id_, other->metric_id_);
  swap(_has_bits_[0], other->_has_bits_[0]);
  _internal_metadata_.Swap(&other->_internal_metadata_);
}

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


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

void Registry::InitAsDefaultInstance() {
}
#if !defined(_MSC_VER) || _MSC_VER >= 1900
const int Registry::kJarFieldNumber;
#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900

Registry::Registry()
  : ::google::protobuf::Message(), _internal_metadata_(NULL) {
  ::google::protobuf::internal::InitSCC(
      &protobuf_UserBitShared_2eproto::scc_info_Registry.base);
  SharedCtor();
  // @@protoc_insertion_point(constructor:exec.shared.Registry)
}
Registry::Registry(const Registry& from)
  : ::google::protobuf::Message(),
      _internal_metadata_(NULL),
      _has_bits_(from._has_bits_),
      jar_(from.jar_) {
  _internal_metadata_.MergeFrom(from._internal_metadata_);
  // @@protoc_insertion_point(copy_constructor:exec.shared.Registry)
}

void Registry::SharedCtor() {
}

Registry::~Registry() {
  // @@protoc_insertion_point(destructor:exec.shared.Registry)
  SharedDtor();
}

void Registry::SharedDtor() {
}

void Registry::SetCachedSize(int size) const {
  _cached_size_.Set(size);
}
const ::google::protobuf::Descriptor* Registry::descriptor() {
  ::protobuf_UserBitShared_2eproto::protobuf_AssignDescriptorsOnce();
  return ::protobuf_UserBitShared_2eproto::file_level_metadata[kIndexInFileMessages].descriptor;
}

const Registry& Registry::default_instance() {
  ::google::protobuf::internal::InitSCC(&protobuf_UserBitShared_2eproto::scc_info_Registry.base);
  return *internal_default_instance();
}


void Registry::Clear() {
// @@protoc_insertion_point(message_clear_start:exec.shared.Registry)
  ::google::protobuf::uint32 cached_has_bits = 0;
  // Prevent compiler warnings about cached_has_bits being unused
  (void) cached_has_bits;

  jar_.Clear();
  _has_bits_.Clear();
  _internal_metadata_.Clear();
}

bool Registry::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:exec.shared.Registry)
  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 .exec.shared.Jar jar = 1;
      case 1: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(10u /* 10 & 0xFF */)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
                input, add_jar()));
        } else {
          goto handle_unusual;
        }
        break;
      }

      default: {
      handle_unusual:
        if (tag == 0) {
          goto success;
        }
        DO_(::google::protobuf::internal::WireFormat::SkipField(
              input, tag, _internal_metadata_.mutable_unknown_fields()));
        break;
      }
    }
  }
success:
  // @@protoc_insertion_point(parse_success:exec.shared.Registry)
  return true;
failure:
  // @@protoc_insertion_point(parse_failure:exec.shared.Registry)
  return false;
#undef DO_
}

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

  // repeated .exec.shared.Jar jar = 1;
  for (unsigned int i = 0,
      n = static_cast<unsigned int>(this->jar_size()); i < n; i++) {
    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
      1,
      this->jar(static_cast<int>(i)),
      output);
  }

  if (_internal_metadata_.have_unknown_fields()) {
    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
        _internal_metadata_.unknown_fields(), output);
  }
  // @@protoc_insertion_point(serialize_end:exec.shared.Registry)
}

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

  // repeated .exec.shared.Jar jar = 1;
  for (unsigned int i = 0,
      n = static_cast<unsigned int>(this->jar_size()); i < n; i++) {
    target = ::google::protobuf::internal::WireFormatLite::
      InternalWriteMessageToArray(
        1, this->jar(static_cast<int>(i)), deterministic, target);
  }

  if (_internal_metadata_.have_unknown_fields()) {
    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
        _internal_metadata_.unknown_fields(), target);
  }
  // @@protoc_insertion_point(serialize_to_array_end:exec.shared.Registry)
  return target;
}

size_t Registry::ByteSizeLong() const {
// @@protoc_insertion_point(message_byte_size_start:exec.shared.Registry)
  size_t total_size = 0;

  if (_internal_metadata_.have_unknown_fields()) {
    total_size +=
      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
        _internal_metadata_.unknown_fields());
  }
  // repeated .exec.shared.Jar jar = 1;
  {
    unsigned int count = static_cast<unsigned int>(this->jar_size());
    total_size += 1UL * count;
    for (unsigned int i = 0; i < count; i++) {
      total_size +=
        ::google::protobuf::internal::WireFormatLite::MessageSize(
          this->jar(static_cast<int>(i)));
    }
  }

  int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
  SetCachedSize(cached_size);
  return total_size;
}

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

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

  jar_.MergeFrom(from.jar_);
}

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

void Registry::CopyFrom(const Registry& from) {
// @@protoc_insertion_point(class_specific_copy_from_start:exec.shared.Registry)
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

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

void Registry::Swap(Registry* other) {
  if (other == this) return;
  InternalSwap(other);
}
void Registry::InternalSwap(Registry* other) {
  using std::swap;
  CastToBase(&jar_)->InternalSwap(CastToBase(&other->jar_));
  swap(_has_bits_[0], other->_has_bits_[0]);
  _internal_metadata_.Swap(&other->_internal_metadata_);
}

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


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

void Jar::InitAsDefaultInstance() {
}
#if !defined(_MSC_VER) || _MSC_VER >= 1900
const int Jar::kNameFieldNumber;
const int Jar::kFunctionSignatureFieldNumber;
#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900

Jar::Jar()
  : ::google::protobuf::Message(), _internal_metadata_(NULL) {
  ::google::protobuf::internal::InitSCC(
      &protobuf_UserBitShared_2eproto::scc_info_Jar.base);
  SharedCtor();
  // @@protoc_insertion_point(constructor:exec.shared.Jar)
}
Jar::Jar(const Jar& from)
  : ::google::protobuf::Message(),
      _internal_metadata_(NULL),
      _has_bits_(from._has_bits_),
      function_signature_(from.function_signature_) {
  _internal_metadata_.MergeFrom(from._internal_metadata_);
  name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  if (from.has_name()) {
    name_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.name_);
  }
  // @@protoc_insertion_point(copy_constructor:exec.shared.Jar)
}

void Jar::SharedCtor() {
  name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}

Jar::~Jar() {
  // @@protoc_insertion_point(destructor:exec.shared.Jar)
  SharedDtor();
}

void Jar::SharedDtor() {
  name_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}

void Jar::SetCachedSize(int size) const {
  _cached_size_.Set(size);
}
const ::google::protobuf::Descriptor* Jar::descriptor() {
  ::protobuf_UserBitShared_2eproto::protobuf_AssignDescriptorsOnce();
  return ::protobuf_UserBitShared_2eproto::file_level_metadata[kIndexInFileMessages].descriptor;
}

const Jar& Jar::default_instance() {
  ::google::protobuf::internal::InitSCC(&protobuf_UserBitShared_2eproto::scc_info_Jar.base);
  return *internal_default_instance();
}


void Jar::Clear() {
// @@protoc_insertion_point(message_clear_start:exec.shared.Jar)
  ::google::protobuf::uint32 cached_has_bits = 0;
  // Prevent compiler warnings about cached_has_bits being unused
  (void) cached_has_bits;

  function_signature_.Clear();
  cached_has_bits = _has_bits_[0];
  if (cached_has_bits & 0x00000001u) {
    name_.ClearNonDefaultToEmptyNoArena();
  }
  _has_bits_.Clear();
  _internal_metadata_.Clear();
}

bool Jar::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:exec.shared.Jar)
  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)) {
      // optional string name = 1;
      case 1: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(10u /* 10 & 0xFF */)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                input, this->mutable_name()));
          ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
            this->name().data(), static_cast<int>(this->name().length()),
            ::google::protobuf::internal::WireFormat::PARSE,
            "exec.shared.Jar.name");
        } else {
          goto handle_unusual;
        }
        break;
      }

      // repeated string function_signature = 2;
      case 2: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(18u /* 18 & 0xFF */)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                input, this->add_function_signature()));
          ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
            this->function_signature(this->function_signature_size() - 1).data(),
            static_cast<int>(this->function_signature(this->function_signature_size() - 1).length()),
            ::google::protobuf::internal::WireFormat::PARSE,
            "exec.shared.Jar.function_signature");
        } else {
          goto handle_unusual;
        }
        break;
      }

      default: {
      handle_unusual:
        if (tag == 0) {
          goto success;
        }
        DO_(::google::protobuf::internal::WireFormat::SkipField(
              input, tag, _internal_metadata_.mutable_unknown_fields()));
        break;
      }
    }
  }
success:
  // @@protoc_insertion_point(parse_success:exec.shared.Jar)
  return true;
failure:
  // @@protoc_insertion_point(parse_failure:exec.shared.Jar)
  return false;
#undef DO_
}

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

  cached_has_bits = _has_bits_[0];
  // optional string name = 1;
  if (cached_has_bits & 0x00000001u) {
    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
      this->name().data(), static_cast<int>(this->name().length()),
      ::google::protobuf::internal::WireFormat::SERIALIZE,
      "exec.shared.Jar.name");
    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
      1, this->name(), output);
  }

  // repeated string function_signature = 2;
  for (int i = 0, n = this->function_signature_size(); i < n; i++) {
    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
      this->function_signature(i).data(), static_cast<int>(this->function_signature(i).length()),
      ::google::protobuf::internal::WireFormat::SERIALIZE,
      "exec.shared.Jar.function_signature");
    ::google::protobuf::internal::WireFormatLite::WriteString(
      2, this->function_signature(i), output);
  }

  if (_internal_metadata_.have_unknown_fields()) {
    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
        _internal_metadata_.unknown_fields(), output);
  }
  // @@protoc_insertion_point(serialize_end:exec.shared.Jar)
}

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

  cached_has_bits = _has_bits_[0];
  // optional string name = 1;
  if (cached_has_bits & 0x00000001u) {
    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
      this->name().data(), static_cast<int>(this->name().length()),
      ::google::protobuf::internal::WireFormat::SERIALIZE,
      "exec.shared.Jar.name");
    target =
      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
        1, this->name(), target);
  }

  // repeated string function_signature = 2;
  for (int i = 0, n = this->function_signature_size(); i < n; i++) {
    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
      this->function_signature(i).data(), static_cast<int>(this->function_signature(i).length()),
      ::google::protobuf::internal::WireFormat::SERIALIZE,
      "exec.shared.Jar.function_signature");
    target = ::google::protobuf::internal::WireFormatLite::
      WriteStringToArray(2, this->function_signature(i), target);
  }

  if (_internal_metadata_.have_unknown_fields()) {
    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
        _internal_metadata_.unknown_fields(), target);
  }
  // @@protoc_insertion_point(serialize_to_array_end:exec.shared.Jar)
  return target;
}

size_t Jar::ByteSizeLong() const {
// @@protoc_insertion_point(message_byte_size_start:exec.shared.Jar)
  size_t total_size = 0;

  if (_internal_metadata_.have_unknown_fields()) {
    total_size +=
      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
        _internal_metadata_.unknown_fields());
  }
  // repeated string function_signature = 2;
  total_size += 1 *
      ::google::protobuf::internal::FromIntSize(this->function_signature_size());
  for (int i = 0, n = this->function_signature_size(); i < n; i++) {
    total_size += ::google::protobuf::internal::WireFormatLite::StringSize(
      this->function_signature(i));
  }

  // optional string name = 1;
  if (has_name()) {
    total_size += 1 +
      ::google::protobuf::internal::WireFormatLite::StringSize(
        this->name());
  }

  int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
  SetCachedSize(cached_size);
  return total_size;
}

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

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

  function_signature_.MergeFrom(from.function_signature_);
  if (from.has_name()) {
    set_has_name();
    name_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.name_);
  }
}

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

void Jar::CopyFrom(const Jar& from) {
// @@protoc_insertion_point(class_specific_copy_from_start:exec.shared.Jar)
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

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

void Jar::Swap(Jar* other) {
  if (other == this) return;
  InternalSwap(other);
}
void Jar::InternalSwap(Jar* other) {
  using std::swap;
  function_signature_.InternalSwap(CastToBase(&other->function_signature_));
  name_.Swap(&other->name_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
    GetArenaNoVirtual());
  swap(_has_bits_[0], other->_has_bits_[0]);
  _internal_metadata_.Swap(&other->_internal_metadata_);
}

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


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

void SaslMessage::InitAsDefaultInstance() {
}
#if !defined(_MSC_VER) || _MSC_VER >= 1900
const int SaslMessage::kMechanismFieldNumber;
const int SaslMessage::kDataFieldNumber;
const int SaslMessage::kStatusFieldNumber;
#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900

SaslMessage::SaslMessage()
  : ::google::protobuf::Message(), _internal_metadata_(NULL) {
  ::google::protobuf::internal::InitSCC(
      &protobuf_UserBitShared_2eproto::scc_info_SaslMessage.base);
  SharedCtor();
  // @@protoc_insertion_point(constructor:exec.shared.SaslMessage)
}
SaslMessage::SaslMessage(const SaslMessage& from)
  : ::google::protobuf::Message(),
      _internal_metadata_(NULL),
      _has_bits_(from._has_bits_) {
  _internal_metadata_.MergeFrom(from._internal_metadata_);
  mechanism_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  if (from.has_mechanism()) {
    mechanism_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.mechanism_);
  }
  data_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  if (from.has_data()) {
    data_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.data_);
  }
  status_ = from.status_;
  // @@protoc_insertion_point(copy_constructor:exec.shared.SaslMessage)
}

void SaslMessage::SharedCtor() {
  mechanism_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  data_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  status_ = 0;
}

SaslMessage::~SaslMessage() {
  // @@protoc_insertion_point(destructor:exec.shared.SaslMessage)
  SharedDtor();
}

void SaslMessage::SharedDtor() {
  mechanism_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  data_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}

void SaslMessage::SetCachedSize(int size) const {
  _cached_size_.Set(size);
}
const ::google::protobuf::Descriptor* SaslMessage::descriptor() {
  ::protobuf_UserBitShared_2eproto::protobuf_AssignDescriptorsOnce();
  return ::protobuf_UserBitShared_2eproto::file_level_metadata[kIndexInFileMessages].descriptor;
}

const SaslMessage& SaslMessage::default_instance() {
  ::google::protobuf::internal::InitSCC(&protobuf_UserBitShared_2eproto::scc_info_SaslMessage.base);
  return *internal_default_instance();
}


void SaslMessage::Clear() {
// @@protoc_insertion_point(message_clear_start:exec.shared.SaslMessage)
  ::google::protobuf::uint32 cached_has_bits = 0;
  // Prevent compiler warnings about cached_has_bits being unused
  (void) cached_has_bits;

  cached_has_bits = _has_bits_[0];
  if (cached_has_bits & 3u) {
    if (cached_has_bits & 0x00000001u) {
      mechanism_.ClearNonDefaultToEmptyNoArena();
    }
    if (cached_has_bits & 0x00000002u) {
      data_.ClearNonDefaultToEmptyNoArena();
    }
  }
  status_ = 0;
  _has_bits_.Clear();
  _internal_metadata_.Clear();
}

bool SaslMessage::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:exec.shared.SaslMessage)
  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)) {
      // optional string mechanism = 1;
      case 1: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(10u /* 10 & 0xFF */)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                input, this->mutable_mechanism()));
          ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
            this->mechanism().data(), static_cast<int>(this->mechanism().length()),
            ::google::protobuf::internal::WireFormat::PARSE,
            "exec.shared.SaslMessage.mechanism");
        } else {
          goto handle_unusual;
        }
        break;
      }

      // optional bytes data = 2;
      case 2: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(18u /* 18 & 0xFF */)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadBytes(
                input, this->mutable_data()));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // optional .exec.shared.SaslStatus status = 3;
      case 3: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(24u /* 24 & 0xFF */)) {
          int value;
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
                 input, &value)));
          if (::exec::shared::SaslStatus_IsValid(value)) {
            set_status(static_cast< ::exec::shared::SaslStatus >(value));
          } else {
            mutable_unknown_fields()->AddVarint(
                3, static_cast< ::google::protobuf::uint64>(value));
          }
        } else {
          goto handle_unusual;
        }
        break;
      }

      default: {
      handle_unusual:
        if (tag == 0) {
          goto success;
        }
        DO_(::google::protobuf::internal::WireFormat::SkipField(
              input, tag, _internal_metadata_.mutable_unknown_fields()));
        break;
      }
    }
  }
success:
  // @@protoc_insertion_point(parse_success:exec.shared.SaslMessage)
  return true;
failure:
  // @@protoc_insertion_point(parse_failure:exec.shared.SaslMessage)
  return false;
#undef DO_
}

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

  cached_has_bits = _has_bits_[0];
  // optional string mechanism = 1;
  if (cached_has_bits & 0x00000001u) {
    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
      this->mechanism().data(), static_cast<int>(this->mechanism().length()),
      ::google::protobuf::internal::WireFormat::SERIALIZE,
      "exec.shared.SaslMessage.mechanism");
    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
      1, this->mechanism(), output);
  }

  // optional bytes data = 2;
  if (cached_has_bits & 0x00000002u) {
    ::google::protobuf::internal::WireFormatLite::WriteBytesMaybeAliased(
      2, this->data(), output);
  }

  // optional .exec.shared.SaslStatus status = 3;
  if (cached_has_bits & 0x00000004u) {
    ::google::protobuf::internal::WireFormatLite::WriteEnum(
      3, this->status(), output);
  }

  if (_internal_metadata_.have_unknown_fields()) {
    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
        _internal_metadata_.unknown_fields(), output);
  }
  // @@protoc_insertion_point(serialize_end:exec.shared.SaslMessage)
}

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

  cached_has_bits = _has_bits_[0];
  // optional string mechanism = 1;
  if (cached_has_bits & 0x00000001u) {
    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
      this->mechanism().data(), static_cast<int>(this->mechanism().length()),
      ::google::protobuf::internal::WireFormat::SERIALIZE,
      "exec.shared.SaslMessage.mechanism");
    target =
      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
        1, this->mechanism(), target);
  }

  // optional bytes data = 2;
  if (cached_has_bits & 0x00000002u) {
    target =
      ::google::protobuf::internal::WireFormatLite::WriteBytesToArray(
        2, this->data(), target);
  }

  // optional .exec.shared.SaslStatus status = 3;
  if (cached_has_bits & 0x00000004u) {
    target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
      3, this->status(), target);
  }

  if (_internal_metadata_.have_unknown_fields()) {
    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
        _internal_metadata_.unknown_fields(), target);
  }
  // @@protoc_insertion_point(serialize_to_array_end:exec.shared.SaslMessage)
  return target;
}

size_t SaslMessage::ByteSizeLong() const {
// @@protoc_insertion_point(message_byte_size_start:exec.shared.SaslMessage)
  size_t total_size = 0;

  if (_internal_metadata_.have_unknown_fields()) {
    total_size +=
      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
        _internal_metadata_.unknown_fields());
  }
  if (_has_bits_[0 / 32] & 7u) {
    // optional string mechanism = 1;
    if (has_mechanism()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::StringSize(
          this->mechanism());
    }

    // optional bytes data = 2;
    if (has_data()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::BytesSize(
          this->data());
    }

    // optional .exec.shared.SaslStatus status = 3;
    if (has_status()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::EnumSize(this->status());
    }

  }
  int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
  SetCachedSize(cached_size);
  return total_size;
}

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

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

  cached_has_bits = from._has_bits_[0];
  if (cached_has_bits & 7u) {
    if (cached_has_bits & 0x00000001u) {
      set_has_mechanism();
      mechanism_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.mechanism_);
    }
    if (cached_has_bits & 0x00000002u) {
      set_has_data();
      data_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.data_);
    }
    if (cached_has_bits & 0x00000004u) {
      status_ = from.status_;
    }
    _has_bits_[0] |= cached_has_bits;
  }
}

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

void SaslMessage::CopyFrom(const SaslMessage& from) {
// @@protoc_insertion_point(class_specific_copy_from_start:exec.shared.SaslMessage)
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

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

void SaslMessage::Swap(SaslMessage* other) {
  if (other == this) return;
  InternalSwap(other);
}
void SaslMessage::InternalSwap(SaslMessage* other) {
  using std::swap;
  mechanism_.Swap(&other->mechanism_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
    GetArenaNoVirtual());
  data_.Swap(&other->data_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
    GetArenaNoVirtual());
  swap(status_, other->status_);
  swap(_has_bits_[0], other->_has_bits_[0]);
  _internal_metadata_.Swap(&other->_internal_metadata_);
}

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


// @@protoc_insertion_point(namespace_scope)
}  // namespace shared
}  // namespace exec
namespace google {
namespace protobuf {
template<> GOOGLE_PROTOBUF_ATTRIBUTE_NOINLINE ::exec::shared::UserCredentials* Arena::CreateMaybeMessage< ::exec::shared::UserCredentials >(Arena* arena) {
  return Arena::CreateInternal< ::exec::shared::UserCredentials >(arena);
}
template<> GOOGLE_PROTOBUF_ATTRIBUTE_NOINLINE ::exec::shared::QueryId* Arena::CreateMaybeMessage< ::exec::shared::QueryId >(Arena* arena) {
  return Arena::CreateInternal< ::exec::shared::QueryId >(arena);
}
template<> GOOGLE_PROTOBUF_ATTRIBUTE_NOINLINE ::exec::shared::DrillPBError* Arena::CreateMaybeMessage< ::exec::shared::DrillPBError >(Arena* arena) {
  return Arena::CreateInternal< ::exec::shared::DrillPBError >(arena);
}
template<> GOOGLE_PROTOBUF_ATTRIBUTE_NOINLINE ::exec::shared::ExceptionWrapper* Arena::CreateMaybeMessage< ::exec::shared::ExceptionWrapper >(Arena* arena) {
  return Arena::CreateInternal< ::exec::shared::ExceptionWrapper >(arena);
}
template<> GOOGLE_PROTOBUF_ATTRIBUTE_NOINLINE ::exec::shared::StackTraceElementWrapper* Arena::CreateMaybeMessage< ::exec::shared::StackTraceElementWrapper >(Arena* arena) {
  return Arena::CreateInternal< ::exec::shared::StackTraceElementWrapper >(arena);
}
template<> GOOGLE_PROTOBUF_ATTRIBUTE_NOINLINE ::exec::shared::ParsingError* Arena::CreateMaybeMessage< ::exec::shared::ParsingError >(Arena* arena) {
  return Arena::CreateInternal< ::exec::shared::ParsingError >(arena);
}
template<> GOOGLE_PROTOBUF_ATTRIBUTE_NOINLINE ::exec::shared::RecordBatchDef* Arena::CreateMaybeMessage< ::exec::shared::RecordBatchDef >(Arena* arena) {
  return Arena::CreateInternal< ::exec::shared::RecordBatchDef >(arena);
}
template<> GOOGLE_PROTOBUF_ATTRIBUTE_NOINLINE ::exec::shared::NamePart* Arena::CreateMaybeMessage< ::exec::shared::NamePart >(Arena* arena) {
  return Arena::CreateInternal< ::exec::shared::NamePart >(arena);
}
template<> GOOGLE_PROTOBUF_ATTRIBUTE_NOINLINE ::exec::shared::SerializedField* Arena::CreateMaybeMessage< ::exec::shared::SerializedField >(Arena* arena) {
  return Arena::CreateInternal< ::exec::shared::SerializedField >(arena);
}
template<> GOOGLE_PROTOBUF_ATTRIBUTE_NOINLINE ::exec::shared::NodeStatus* Arena::CreateMaybeMessage< ::exec::shared::NodeStatus >(Arena* arena) {
  return Arena::CreateInternal< ::exec::shared::NodeStatus >(arena);
}
template<> GOOGLE_PROTOBUF_ATTRIBUTE_NOINLINE ::exec::shared::QueryResult* Arena::CreateMaybeMessage< ::exec::shared::QueryResult >(Arena* arena) {
  return Arena::CreateInternal< ::exec::shared::QueryResult >(arena);
}
template<> GOOGLE_PROTOBUF_ATTRIBUTE_NOINLINE ::exec::shared::QueryData* Arena::CreateMaybeMessage< ::exec::shared::QueryData >(Arena* arena) {
  return Arena::CreateInternal< ::exec::shared::QueryData >(arena);
}
template<> GOOGLE_PROTOBUF_ATTRIBUTE_NOINLINE ::exec::shared::QueryInfo* Arena::CreateMaybeMessage< ::exec::shared::QueryInfo >(Arena* arena) {
  return Arena::CreateInternal< ::exec::shared::QueryInfo >(arena);
}
template<> GOOGLE_PROTOBUF_ATTRIBUTE_NOINLINE ::exec::shared::QueryProfile* Arena::CreateMaybeMessage< ::exec::shared::QueryProfile >(Arena* arena) {
  return Arena::CreateInternal< ::exec::shared::QueryProfile >(arena);
}
template<> GOOGLE_PROTOBUF_ATTRIBUTE_NOINLINE ::exec::shared::MajorFragmentProfile* Arena::CreateMaybeMessage< ::exec::shared::MajorFragmentProfile >(Arena* arena) {
  return Arena::CreateInternal< ::exec::shared::MajorFragmentProfile >(arena);
}
template<> GOOGLE_PROTOBUF_ATTRIBUTE_NOINLINE ::exec::shared::MinorFragmentProfile* Arena::CreateMaybeMessage< ::exec::shared::MinorFragmentProfile >(Arena* arena) {
  return Arena::CreateInternal< ::exec::shared::MinorFragmentProfile >(arena);
}
template<> GOOGLE_PROTOBUF_ATTRIBUTE_NOINLINE ::exec::shared::OperatorProfile* Arena::CreateMaybeMessage< ::exec::shared::OperatorProfile >(Arena* arena) {
  return Arena::CreateInternal< ::exec::shared::OperatorProfile >(arena);
}
template<> GOOGLE_PROTOBUF_ATTRIBUTE_NOINLINE ::exec::shared::StreamProfile* Arena::CreateMaybeMessage< ::exec::shared::StreamProfile >(Arena* arena) {
  return Arena::CreateInternal< ::exec::shared::StreamProfile >(arena);
}
template<> GOOGLE_PROTOBUF_ATTRIBUTE_NOINLINE ::exec::shared::MetricValue* Arena::CreateMaybeMessage< ::exec::shared::MetricValue >(Arena* arena) {
  return Arena::CreateInternal< ::exec::shared::MetricValue >(arena);
}
template<> GOOGLE_PROTOBUF_ATTRIBUTE_NOINLINE ::exec::shared::Registry* Arena::CreateMaybeMessage< ::exec::shared::Registry >(Arena* arena) {
  return Arena::CreateInternal< ::exec::shared::Registry >(arena);
}
template<> GOOGLE_PROTOBUF_ATTRIBUTE_NOINLINE ::exec::shared::Jar* Arena::CreateMaybeMessage< ::exec::shared::Jar >(Arena* arena) {
  return Arena::CreateInternal< ::exec::shared::Jar >(arena);
}
template<> GOOGLE_PROTOBUF_ATTRIBUTE_NOINLINE ::exec::shared::SaslMessage* Arena::CreateMaybeMessage< ::exec::shared::SaslMessage >(Arena* arena) {
  return Arena::CreateInternal< ::exec::shared::SaslMessage >(arena);
}
}  // namespace protobuf
}  // namespace google

// @@protoc_insertion_point(global_scope)
