// 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*\367\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\022\021\n\rHTTP_SUB_SCAN\020F*g\n\nSaslSta"
      "tus\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\033org.apache.drill.exec."
      "protoB\rUserBitSharedH\001"
  };
  ::google::protobuf::DescriptorPool::InternalAddGeneratedFile(
      descriptor, 5782);
  ::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:
    case 70:
      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)
