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

#ifndef GOOGLE_PROTOBUF_INCLUDED_BitControl_2eproto
#define GOOGLE_PROTOBUF_INCLUDED_BitControl_2eproto

#include <limits>
#include <string>

#include <google/protobuf/port_def.inc>
#if PROTOBUF_VERSION < 3016000
#error This file was generated by a newer version of protoc which is
#error incompatible with your Protocol Buffer headers. Please update
#error your headers.
#endif
#if 3016003 < PROTOBUF_MIN_PROTOC_VERSION
#error This file was generated by an older version of protoc which is
#error incompatible with your Protocol Buffer headers. Please
#error regenerate this file with a newer version of protoc.
#endif

#include <google/protobuf/port_undef.inc>
#include <google/protobuf/io/coded_stream.h>
#include <google/protobuf/arena.h>
#include <google/protobuf/arenastring.h>
#include <google/protobuf/generated_message_table_driven.h>
#include <google/protobuf/generated_message_util.h>
#include <google/protobuf/metadata_lite.h>
#include <google/protobuf/generated_message_reflection.h>
#include <google/protobuf/message.h>
#include <google/protobuf/repeated_field.h>  // IWYU pragma: export
#include <google/protobuf/extension_set.h>  // IWYU pragma: export
#include <google/protobuf/generated_enum_reflection.h>
#include <google/protobuf/unknown_field_set.h>
#include "ExecutionProtos.pb.h"
#include "Coordination.pb.h"
#include "UserBitShared.pb.h"
// @@protoc_insertion_point(includes)
#include <google/protobuf/port_def.inc>
#define PROTOBUF_INTERNAL_EXPORT_BitControl_2eproto
PROTOBUF_NAMESPACE_OPEN
namespace internal {
class AnyMetadata;
}  // namespace internal
PROTOBUF_NAMESPACE_CLOSE

// Internal implementation detail -- do not use these members.
struct TableStruct_BitControl_2eproto {
  static const ::PROTOBUF_NAMESPACE_ID::internal::ParseTableField entries[]
    PROTOBUF_SECTION_VARIABLE(protodesc_cold);
  static const ::PROTOBUF_NAMESPACE_ID::internal::AuxiliaryParseTableField aux[]
    PROTOBUF_SECTION_VARIABLE(protodesc_cold);
  static const ::PROTOBUF_NAMESPACE_ID::internal::ParseTable schema[10]
    PROTOBUF_SECTION_VARIABLE(protodesc_cold);
  static const ::PROTOBUF_NAMESPACE_ID::internal::FieldMetadata field_metadata[];
  static const ::PROTOBUF_NAMESPACE_ID::internal::SerializationTable serialization_table[];
  static const ::PROTOBUF_NAMESPACE_ID::uint32 offsets[];
};
extern const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable descriptor_table_BitControl_2eproto;
namespace exec {
namespace bit {
namespace control {
class BitControlHandshake;
struct BitControlHandshakeDefaultTypeInternal;
extern BitControlHandshakeDefaultTypeInternal _BitControlHandshake_default_instance_;
class BitStatus;
struct BitStatusDefaultTypeInternal;
extern BitStatusDefaultTypeInternal _BitStatus_default_instance_;
class Collector;
struct CollectorDefaultTypeInternal;
extern CollectorDefaultTypeInternal _Collector_default_instance_;
class CustomMessage;
struct CustomMessageDefaultTypeInternal;
extern CustomMessageDefaultTypeInternal _CustomMessage_default_instance_;
class FinishedReceiver;
struct FinishedReceiverDefaultTypeInternal;
extern FinishedReceiverDefaultTypeInternal _FinishedReceiver_default_instance_;
class FragmentStatus;
struct FragmentStatusDefaultTypeInternal;
extern FragmentStatusDefaultTypeInternal _FragmentStatus_default_instance_;
class InitializeFragments;
struct InitializeFragmentsDefaultTypeInternal;
extern InitializeFragmentsDefaultTypeInternal _InitializeFragments_default_instance_;
class PlanFragment;
struct PlanFragmentDefaultTypeInternal;
extern PlanFragmentDefaultTypeInternal _PlanFragment_default_instance_;
class QueryContextInformation;
struct QueryContextInformationDefaultTypeInternal;
extern QueryContextInformationDefaultTypeInternal _QueryContextInformation_default_instance_;
class WorkQueueStatus;
struct WorkQueueStatusDefaultTypeInternal;
extern WorkQueueStatusDefaultTypeInternal _WorkQueueStatus_default_instance_;
}  // namespace control
}  // namespace bit
}  // namespace exec
PROTOBUF_NAMESPACE_OPEN
template<> ::exec::bit::control::BitControlHandshake* Arena::CreateMaybeMessage<::exec::bit::control::BitControlHandshake>(Arena*);
template<> ::exec::bit::control::BitStatus* Arena::CreateMaybeMessage<::exec::bit::control::BitStatus>(Arena*);
template<> ::exec::bit::control::Collector* Arena::CreateMaybeMessage<::exec::bit::control::Collector>(Arena*);
template<> ::exec::bit::control::CustomMessage* Arena::CreateMaybeMessage<::exec::bit::control::CustomMessage>(Arena*);
template<> ::exec::bit::control::FinishedReceiver* Arena::CreateMaybeMessage<::exec::bit::control::FinishedReceiver>(Arena*);
template<> ::exec::bit::control::FragmentStatus* Arena::CreateMaybeMessage<::exec::bit::control::FragmentStatus>(Arena*);
template<> ::exec::bit::control::InitializeFragments* Arena::CreateMaybeMessage<::exec::bit::control::InitializeFragments>(Arena*);
template<> ::exec::bit::control::PlanFragment* Arena::CreateMaybeMessage<::exec::bit::control::PlanFragment>(Arena*);
template<> ::exec::bit::control::QueryContextInformation* Arena::CreateMaybeMessage<::exec::bit::control::QueryContextInformation>(Arena*);
template<> ::exec::bit::control::WorkQueueStatus* Arena::CreateMaybeMessage<::exec::bit::control::WorkQueueStatus>(Arena*);
PROTOBUF_NAMESPACE_CLOSE
namespace exec {
namespace bit {
namespace control {

enum RpcType : int {
  HANDSHAKE = 0,
  ACK = 1,
  GOODBYE = 2,
  REQ_INITIALIZE_FRAGMENTS = 3,
  REQ_CANCEL_FRAGMENT = 6,
  REQ_RECEIVER_FINISHED = 7,
  REQ_FRAGMENT_STATUS = 8,
  REQ_BIT_STATUS = 9,
  REQ_QUERY_STATUS = 10,
  REQ_QUERY_CANCEL = 15,
  REQ_UNPAUSE_FRAGMENT = 16,
  REQ_CUSTOM = 17,
  RESP_FRAGMENT_HANDLE = 11,
  RESP_FRAGMENT_STATUS = 12,
  RESP_BIT_STATUS = 13,
  RESP_QUERY_STATUS = 14,
  RESP_CUSTOM = 18,
  SASL_MESSAGE = 19
};
bool RpcType_IsValid(int value);
constexpr RpcType RpcType_MIN = HANDSHAKE;
constexpr RpcType RpcType_MAX = SASL_MESSAGE;
constexpr int RpcType_ARRAYSIZE = RpcType_MAX + 1;

const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor* RpcType_descriptor();
template<typename T>
inline const std::string& RpcType_Name(T enum_t_value) {
  static_assert(::std::is_same<T, RpcType>::value ||
    ::std::is_integral<T>::value,
    "Incorrect type passed to function RpcType_Name.");
  return ::PROTOBUF_NAMESPACE_ID::internal::NameOfEnum(
    RpcType_descriptor(), enum_t_value);
}
inline bool RpcType_Parse(
    ::PROTOBUF_NAMESPACE_ID::ConstStringParam name, RpcType* value) {
  return ::PROTOBUF_NAMESPACE_ID::internal::ParseNamedEnum<RpcType>(
    RpcType_descriptor(), name, value);
}
// ===================================================================

class BitControlHandshake PROTOBUF_FINAL :
    public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:exec.bit.control.BitControlHandshake) */ {
 public:
  inline BitControlHandshake() : BitControlHandshake(nullptr) {}
  ~BitControlHandshake() override;
  explicit constexpr BitControlHandshake(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);

  BitControlHandshake(const BitControlHandshake& from);
  BitControlHandshake(BitControlHandshake&& from) noexcept
    : BitControlHandshake() {
    *this = ::std::move(from);
  }

  inline BitControlHandshake& operator=(const BitControlHandshake& from) {
    CopyFrom(from);
    return *this;
  }
  inline BitControlHandshake& operator=(BitControlHandshake&& from) noexcept {
    if (GetArena() == from.GetArena()) {
      if (this != &from) InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }

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

  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() {
    return GetDescriptor();
  }
  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() {
    return default_instance().GetMetadata().descriptor;
  }
  static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() {
    return default_instance().GetMetadata().reflection;
  }
  static const BitControlHandshake& default_instance() {
    return *internal_default_instance();
  }
  static inline const BitControlHandshake* internal_default_instance() {
    return reinterpret_cast<const BitControlHandshake*>(
               &_BitControlHandshake_default_instance_);
  }
  static constexpr int kIndexInFileMessages =
    0;

  friend void swap(BitControlHandshake& a, BitControlHandshake& b) {
    a.Swap(&b);
  }
  inline void Swap(BitControlHandshake* other) {
    if (other == this) return;
    if (GetArena() == other->GetArena()) {
      InternalSwap(other);
    } else {
      ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);
    }
  }
  void UnsafeArenaSwap(BitControlHandshake* other) {
    if (other == this) return;
    GOOGLE_DCHECK(GetArena() == other->GetArena());
    InternalSwap(other);
  }

  // implements Message ----------------------------------------------

  inline BitControlHandshake* New() const final {
    return CreateMaybeMessage<BitControlHandshake>(nullptr);
  }

  BitControlHandshake* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final {
    return CreateMaybeMessage<BitControlHandshake>(arena);
  }
  void CopyFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
  void MergeFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
  void CopyFrom(const BitControlHandshake& from);
  void MergeFrom(const BitControlHandshake& from);
  PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
  bool IsInitialized() const final;

  size_t ByteSizeLong() const final;
  const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
  ::PROTOBUF_NAMESPACE_ID::uint8* _InternalSerialize(
      ::PROTOBUF_NAMESPACE_ID::uint8* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
  int GetCachedSize() const final { return _cached_size_.Get(); }

  private:
  inline void SharedCtor();
  inline void SharedDtor();
  void SetCachedSize(int size) const final;
  void InternalSwap(BitControlHandshake* other);
  friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
  static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
    return "exec.bit.control.BitControlHandshake";
  }
  protected:
  explicit BitControlHandshake(::PROTOBUF_NAMESPACE_ID::Arena* arena);
  private:
  static void ArenaDtor(void* object);
  inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena);
  public:

  ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final;

  // nested types ----------------------------------------------------

  // accessors -------------------------------------------------------

  enum : int {
    kAuthenticationMechanismsFieldNumber = 4,
    kEndpointFieldNumber = 3,
    kRpcVersionFieldNumber = 1,
    kChannelFieldNumber = 2,
  };
  // repeated string authenticationMechanisms = 4;
  int authenticationmechanisms_size() const;
  private:
  int _internal_authenticationmechanisms_size() const;
  public:
  void clear_authenticationmechanisms();
  const std::string& authenticationmechanisms(int index) const;
  std::string* mutable_authenticationmechanisms(int index);
  void set_authenticationmechanisms(int index, const std::string& value);
  void set_authenticationmechanisms(int index, std::string&& value);
  void set_authenticationmechanisms(int index, const char* value);
  void set_authenticationmechanisms(int index, const char* value, size_t size);
  std::string* add_authenticationmechanisms();
  void add_authenticationmechanisms(const std::string& value);
  void add_authenticationmechanisms(std::string&& value);
  void add_authenticationmechanisms(const char* value);
  void add_authenticationmechanisms(const char* value, size_t size);
  const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField<std::string>& authenticationmechanisms() const;
  ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField<std::string>* mutable_authenticationmechanisms();
  private:
  const std::string& _internal_authenticationmechanisms(int index) const;
  std::string* _internal_add_authenticationmechanisms();
  public:

  // optional .exec.DrillbitEndpoint endpoint = 3;
  bool has_endpoint() const;
  private:
  bool _internal_has_endpoint() const;
  public:
  void clear_endpoint();
  const ::exec::DrillbitEndpoint& endpoint() const;
  ::exec::DrillbitEndpoint* release_endpoint();
  ::exec::DrillbitEndpoint* mutable_endpoint();
  void set_allocated_endpoint(::exec::DrillbitEndpoint* endpoint);
  private:
  const ::exec::DrillbitEndpoint& _internal_endpoint() const;
  ::exec::DrillbitEndpoint* _internal_mutable_endpoint();
  public:
  void unsafe_arena_set_allocated_endpoint(
      ::exec::DrillbitEndpoint* endpoint);
  ::exec::DrillbitEndpoint* unsafe_arena_release_endpoint();

  // optional int32 rpc_version = 1;
  bool has_rpc_version() const;
  private:
  bool _internal_has_rpc_version() const;
  public:
  void clear_rpc_version();
  ::PROTOBUF_NAMESPACE_ID::int32 rpc_version() const;
  void set_rpc_version(::PROTOBUF_NAMESPACE_ID::int32 value);
  private:
  ::PROTOBUF_NAMESPACE_ID::int32 _internal_rpc_version() const;
  void _internal_set_rpc_version(::PROTOBUF_NAMESPACE_ID::int32 value);
  public:

  // optional .exec.shared.RpcChannel channel = 2 [default = BIT_CONTROL];
  bool has_channel() const;
  private:
  bool _internal_has_channel() const;
  public:
  void clear_channel();
  ::exec::shared::RpcChannel channel() const;
  void set_channel(::exec::shared::RpcChannel value);
  private:
  ::exec::shared::RpcChannel _internal_channel() const;
  void _internal_set_channel(::exec::shared::RpcChannel value);
  public:

  // @@protoc_insertion_point(class_scope:exec.bit.control.BitControlHandshake)
 private:
  class _Internal;

  template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper;
  typedef void InternalArenaConstructable_;
  typedef void DestructorSkippable_;
  ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_;
  mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
  ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField<std::string> authenticationmechanisms_;
  ::exec::DrillbitEndpoint* endpoint_;
  ::PROTOBUF_NAMESPACE_ID::int32 rpc_version_;
  int channel_;
  friend struct ::TableStruct_BitControl_2eproto;
};
// -------------------------------------------------------------------

class BitStatus PROTOBUF_FINAL :
    public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:exec.bit.control.BitStatus) */ {
 public:
  inline BitStatus() : BitStatus(nullptr) {}
  ~BitStatus() override;
  explicit constexpr BitStatus(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);

  BitStatus(const BitStatus& from);
  BitStatus(BitStatus&& from) noexcept
    : BitStatus() {
    *this = ::std::move(from);
  }

  inline BitStatus& operator=(const BitStatus& from) {
    CopyFrom(from);
    return *this;
  }
  inline BitStatus& operator=(BitStatus&& from) noexcept {
    if (GetArena() == from.GetArena()) {
      if (this != &from) InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }

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

  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() {
    return GetDescriptor();
  }
  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() {
    return default_instance().GetMetadata().descriptor;
  }
  static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() {
    return default_instance().GetMetadata().reflection;
  }
  static const BitStatus& default_instance() {
    return *internal_default_instance();
  }
  static inline const BitStatus* internal_default_instance() {
    return reinterpret_cast<const BitStatus*>(
               &_BitStatus_default_instance_);
  }
  static constexpr int kIndexInFileMessages =
    1;

  friend void swap(BitStatus& a, BitStatus& b) {
    a.Swap(&b);
  }
  inline void Swap(BitStatus* other) {
    if (other == this) return;
    if (GetArena() == other->GetArena()) {
      InternalSwap(other);
    } else {
      ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);
    }
  }
  void UnsafeArenaSwap(BitStatus* other) {
    if (other == this) return;
    GOOGLE_DCHECK(GetArena() == other->GetArena());
    InternalSwap(other);
  }

  // implements Message ----------------------------------------------

  inline BitStatus* New() const final {
    return CreateMaybeMessage<BitStatus>(nullptr);
  }

  BitStatus* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final {
    return CreateMaybeMessage<BitStatus>(arena);
  }
  void CopyFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
  void MergeFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
  void CopyFrom(const BitStatus& from);
  void MergeFrom(const BitStatus& from);
  PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
  bool IsInitialized() const final;

  size_t ByteSizeLong() const final;
  const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
  ::PROTOBUF_NAMESPACE_ID::uint8* _InternalSerialize(
      ::PROTOBUF_NAMESPACE_ID::uint8* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
  int GetCachedSize() const final { return _cached_size_.Get(); }

  private:
  inline void SharedCtor();
  inline void SharedDtor();
  void SetCachedSize(int size) const final;
  void InternalSwap(BitStatus* other);
  friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
  static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
    return "exec.bit.control.BitStatus";
  }
  protected:
  explicit BitStatus(::PROTOBUF_NAMESPACE_ID::Arena* arena);
  private:
  static void ArenaDtor(void* object);
  inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena);
  public:

  ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final;

  // nested types ----------------------------------------------------

  // accessors -------------------------------------------------------

  enum : int {
    kFragmentStatusFieldNumber = 1,
  };
  // repeated .exec.bit.control.FragmentStatus fragment_status = 1;
  int fragment_status_size() const;
  private:
  int _internal_fragment_status_size() const;
  public:
  void clear_fragment_status();
  ::exec::bit::control::FragmentStatus* mutable_fragment_status(int index);
  ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::exec::bit::control::FragmentStatus >*
      mutable_fragment_status();
  private:
  const ::exec::bit::control::FragmentStatus& _internal_fragment_status(int index) const;
  ::exec::bit::control::FragmentStatus* _internal_add_fragment_status();
  public:
  const ::exec::bit::control::FragmentStatus& fragment_status(int index) const;
  ::exec::bit::control::FragmentStatus* add_fragment_status();
  const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::exec::bit::control::FragmentStatus >&
      fragment_status() const;

  // @@protoc_insertion_point(class_scope:exec.bit.control.BitStatus)
 private:
  class _Internal;

  template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper;
  typedef void InternalArenaConstructable_;
  typedef void DestructorSkippable_;
  ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::exec::bit::control::FragmentStatus > fragment_status_;
  mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
  friend struct ::TableStruct_BitControl_2eproto;
};
// -------------------------------------------------------------------

class FragmentStatus PROTOBUF_FINAL :
    public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:exec.bit.control.FragmentStatus) */ {
 public:
  inline FragmentStatus() : FragmentStatus(nullptr) {}
  ~FragmentStatus() override;
  explicit constexpr FragmentStatus(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);

  FragmentStatus(const FragmentStatus& from);
  FragmentStatus(FragmentStatus&& from) noexcept
    : FragmentStatus() {
    *this = ::std::move(from);
  }

  inline FragmentStatus& operator=(const FragmentStatus& from) {
    CopyFrom(from);
    return *this;
  }
  inline FragmentStatus& operator=(FragmentStatus&& from) noexcept {
    if (GetArena() == from.GetArena()) {
      if (this != &from) InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }

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

  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() {
    return GetDescriptor();
  }
  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() {
    return default_instance().GetMetadata().descriptor;
  }
  static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() {
    return default_instance().GetMetadata().reflection;
  }
  static const FragmentStatus& default_instance() {
    return *internal_default_instance();
  }
  static inline const FragmentStatus* internal_default_instance() {
    return reinterpret_cast<const FragmentStatus*>(
               &_FragmentStatus_default_instance_);
  }
  static constexpr int kIndexInFileMessages =
    2;

  friend void swap(FragmentStatus& a, FragmentStatus& b) {
    a.Swap(&b);
  }
  inline void Swap(FragmentStatus* other) {
    if (other == this) return;
    if (GetArena() == other->GetArena()) {
      InternalSwap(other);
    } else {
      ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);
    }
  }
  void UnsafeArenaSwap(FragmentStatus* other) {
    if (other == this) return;
    GOOGLE_DCHECK(GetArena() == other->GetArena());
    InternalSwap(other);
  }

  // implements Message ----------------------------------------------

  inline FragmentStatus* New() const final {
    return CreateMaybeMessage<FragmentStatus>(nullptr);
  }

  FragmentStatus* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final {
    return CreateMaybeMessage<FragmentStatus>(arena);
  }
  void CopyFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
  void MergeFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
  void CopyFrom(const FragmentStatus& from);
  void MergeFrom(const FragmentStatus& from);
  PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
  bool IsInitialized() const final;

  size_t ByteSizeLong() const final;
  const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
  ::PROTOBUF_NAMESPACE_ID::uint8* _InternalSerialize(
      ::PROTOBUF_NAMESPACE_ID::uint8* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
  int GetCachedSize() const final { return _cached_size_.Get(); }

  private:
  inline void SharedCtor();
  inline void SharedDtor();
  void SetCachedSize(int size) const final;
  void InternalSwap(FragmentStatus* other);
  friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
  static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
    return "exec.bit.control.FragmentStatus";
  }
  protected:
  explicit FragmentStatus(::PROTOBUF_NAMESPACE_ID::Arena* arena);
  private:
  static void ArenaDtor(void* object);
  inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena);
  public:

  ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final;

  // nested types ----------------------------------------------------

  // accessors -------------------------------------------------------

  enum : int {
    kProfileFieldNumber = 1,
    kHandleFieldNumber = 2,
  };
  // optional .exec.shared.MinorFragmentProfile profile = 1;
  bool has_profile() const;
  private:
  bool _internal_has_profile() const;
  public:
  void clear_profile();
  const ::exec::shared::MinorFragmentProfile& profile() const;
  ::exec::shared::MinorFragmentProfile* release_profile();
  ::exec::shared::MinorFragmentProfile* mutable_profile();
  void set_allocated_profile(::exec::shared::MinorFragmentProfile* profile);
  private:
  const ::exec::shared::MinorFragmentProfile& _internal_profile() const;
  ::exec::shared::MinorFragmentProfile* _internal_mutable_profile();
  public:
  void unsafe_arena_set_allocated_profile(
      ::exec::shared::MinorFragmentProfile* profile);
  ::exec::shared::MinorFragmentProfile* unsafe_arena_release_profile();

  // optional .exec.bit.FragmentHandle handle = 2;
  bool has_handle() const;
  private:
  bool _internal_has_handle() const;
  public:
  void clear_handle();
  const ::exec::bit::FragmentHandle& handle() const;
  ::exec::bit::FragmentHandle* release_handle();
  ::exec::bit::FragmentHandle* mutable_handle();
  void set_allocated_handle(::exec::bit::FragmentHandle* handle);
  private:
  const ::exec::bit::FragmentHandle& _internal_handle() const;
  ::exec::bit::FragmentHandle* _internal_mutable_handle();
  public:
  void unsafe_arena_set_allocated_handle(
      ::exec::bit::FragmentHandle* handle);
  ::exec::bit::FragmentHandle* unsafe_arena_release_handle();

  // @@protoc_insertion_point(class_scope:exec.bit.control.FragmentStatus)
 private:
  class _Internal;

  template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper;
  typedef void InternalArenaConstructable_;
  typedef void DestructorSkippable_;
  ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_;
  mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
  ::exec::shared::MinorFragmentProfile* profile_;
  ::exec::bit::FragmentHandle* handle_;
  friend struct ::TableStruct_BitControl_2eproto;
};
// -------------------------------------------------------------------

class InitializeFragments PROTOBUF_FINAL :
    public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:exec.bit.control.InitializeFragments) */ {
 public:
  inline InitializeFragments() : InitializeFragments(nullptr) {}
  ~InitializeFragments() override;
  explicit constexpr InitializeFragments(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);

  InitializeFragments(const InitializeFragments& from);
  InitializeFragments(InitializeFragments&& from) noexcept
    : InitializeFragments() {
    *this = ::std::move(from);
  }

  inline InitializeFragments& operator=(const InitializeFragments& from) {
    CopyFrom(from);
    return *this;
  }
  inline InitializeFragments& operator=(InitializeFragments&& from) noexcept {
    if (GetArena() == from.GetArena()) {
      if (this != &from) InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }

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

  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() {
    return GetDescriptor();
  }
  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() {
    return default_instance().GetMetadata().descriptor;
  }
  static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() {
    return default_instance().GetMetadata().reflection;
  }
  static const InitializeFragments& default_instance() {
    return *internal_default_instance();
  }
  static inline const InitializeFragments* internal_default_instance() {
    return reinterpret_cast<const InitializeFragments*>(
               &_InitializeFragments_default_instance_);
  }
  static constexpr int kIndexInFileMessages =
    3;

  friend void swap(InitializeFragments& a, InitializeFragments& b) {
    a.Swap(&b);
  }
  inline void Swap(InitializeFragments* other) {
    if (other == this) return;
    if (GetArena() == other->GetArena()) {
      InternalSwap(other);
    } else {
      ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);
    }
  }
  void UnsafeArenaSwap(InitializeFragments* other) {
    if (other == this) return;
    GOOGLE_DCHECK(GetArena() == other->GetArena());
    InternalSwap(other);
  }

  // implements Message ----------------------------------------------

  inline InitializeFragments* New() const final {
    return CreateMaybeMessage<InitializeFragments>(nullptr);
  }

  InitializeFragments* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final {
    return CreateMaybeMessage<InitializeFragments>(arena);
  }
  void CopyFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
  void MergeFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
  void CopyFrom(const InitializeFragments& from);
  void MergeFrom(const InitializeFragments& from);
  PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
  bool IsInitialized() const final;

  size_t ByteSizeLong() const final;
  const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
  ::PROTOBUF_NAMESPACE_ID::uint8* _InternalSerialize(
      ::PROTOBUF_NAMESPACE_ID::uint8* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
  int GetCachedSize() const final { return _cached_size_.Get(); }

  private:
  inline void SharedCtor();
  inline void SharedDtor();
  void SetCachedSize(int size) const final;
  void InternalSwap(InitializeFragments* other);
  friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
  static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
    return "exec.bit.control.InitializeFragments";
  }
  protected:
  explicit InitializeFragments(::PROTOBUF_NAMESPACE_ID::Arena* arena);
  private:
  static void ArenaDtor(void* object);
  inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena);
  public:

  ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final;

  // nested types ----------------------------------------------------

  // accessors -------------------------------------------------------

  enum : int {
    kFragmentFieldNumber = 1,
  };
  // repeated .exec.bit.control.PlanFragment fragment = 1;
  int fragment_size() const;
  private:
  int _internal_fragment_size() const;
  public:
  void clear_fragment();
  ::exec::bit::control::PlanFragment* mutable_fragment(int index);
  ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::exec::bit::control::PlanFragment >*
      mutable_fragment();
  private:
  const ::exec::bit::control::PlanFragment& _internal_fragment(int index) const;
  ::exec::bit::control::PlanFragment* _internal_add_fragment();
  public:
  const ::exec::bit::control::PlanFragment& fragment(int index) const;
  ::exec::bit::control::PlanFragment* add_fragment();
  const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::exec::bit::control::PlanFragment >&
      fragment() const;

  // @@protoc_insertion_point(class_scope:exec.bit.control.InitializeFragments)
 private:
  class _Internal;

  template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper;
  typedef void InternalArenaConstructable_;
  typedef void DestructorSkippable_;
  ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::exec::bit::control::PlanFragment > fragment_;
  mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
  friend struct ::TableStruct_BitControl_2eproto;
};
// -------------------------------------------------------------------

class CustomMessage PROTOBUF_FINAL :
    public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:exec.bit.control.CustomMessage) */ {
 public:
  inline CustomMessage() : CustomMessage(nullptr) {}
  ~CustomMessage() override;
  explicit constexpr CustomMessage(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);

  CustomMessage(const CustomMessage& from);
  CustomMessage(CustomMessage&& from) noexcept
    : CustomMessage() {
    *this = ::std::move(from);
  }

  inline CustomMessage& operator=(const CustomMessage& from) {
    CopyFrom(from);
    return *this;
  }
  inline CustomMessage& operator=(CustomMessage&& from) noexcept {
    if (GetArena() == from.GetArena()) {
      if (this != &from) InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }

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

  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() {
    return GetDescriptor();
  }
  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() {
    return default_instance().GetMetadata().descriptor;
  }
  static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() {
    return default_instance().GetMetadata().reflection;
  }
  static const CustomMessage& default_instance() {
    return *internal_default_instance();
  }
  static inline const CustomMessage* internal_default_instance() {
    return reinterpret_cast<const CustomMessage*>(
               &_CustomMessage_default_instance_);
  }
  static constexpr int kIndexInFileMessages =
    4;

  friend void swap(CustomMessage& a, CustomMessage& b) {
    a.Swap(&b);
  }
  inline void Swap(CustomMessage* other) {
    if (other == this) return;
    if (GetArena() == other->GetArena()) {
      InternalSwap(other);
    } else {
      ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);
    }
  }
  void UnsafeArenaSwap(CustomMessage* other) {
    if (other == this) return;
    GOOGLE_DCHECK(GetArena() == other->GetArena());
    InternalSwap(other);
  }

  // implements Message ----------------------------------------------

  inline CustomMessage* New() const final {
    return CreateMaybeMessage<CustomMessage>(nullptr);
  }

  CustomMessage* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final {
    return CreateMaybeMessage<CustomMessage>(arena);
  }
  void CopyFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
  void MergeFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
  void CopyFrom(const CustomMessage& from);
  void MergeFrom(const CustomMessage& from);
  PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
  bool IsInitialized() const final;

  size_t ByteSizeLong() const final;
  const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
  ::PROTOBUF_NAMESPACE_ID::uint8* _InternalSerialize(
      ::PROTOBUF_NAMESPACE_ID::uint8* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
  int GetCachedSize() const final { return _cached_size_.Get(); }

  private:
  inline void SharedCtor();
  inline void SharedDtor();
  void SetCachedSize(int size) const final;
  void InternalSwap(CustomMessage* other);
  friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
  static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
    return "exec.bit.control.CustomMessage";
  }
  protected:
  explicit CustomMessage(::PROTOBUF_NAMESPACE_ID::Arena* arena);
  private:
  static void ArenaDtor(void* object);
  inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena);
  public:

  ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final;

  // nested types ----------------------------------------------------

  // accessors -------------------------------------------------------

  enum : int {
    kMessageFieldNumber = 2,
    kTypeFieldNumber = 1,
  };
  // optional bytes message = 2;
  bool has_message() const;
  private:
  bool _internal_has_message() const;
  public:
  void clear_message();
  const std::string& message() const;
  template <typename ArgT0 = const std::string&, typename... ArgT>
  void set_message(ArgT0&& arg0, ArgT... args);
  std::string* mutable_message();
  std::string* release_message();
  void set_allocated_message(std::string* message);
  private:
  const std::string& _internal_message() const;
  void _internal_set_message(const std::string& value);
  std::string* _internal_mutable_message();
  public:

  // optional int32 type = 1;
  bool has_type() const;
  private:
  bool _internal_has_type() const;
  public:
  void clear_type();
  ::PROTOBUF_NAMESPACE_ID::int32 type() const;
  void set_type(::PROTOBUF_NAMESPACE_ID::int32 value);
  private:
  ::PROTOBUF_NAMESPACE_ID::int32 _internal_type() const;
  void _internal_set_type(::PROTOBUF_NAMESPACE_ID::int32 value);
  public:

  // @@protoc_insertion_point(class_scope:exec.bit.control.CustomMessage)
 private:
  class _Internal;

  template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper;
  typedef void InternalArenaConstructable_;
  typedef void DestructorSkippable_;
  ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_;
  mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
  ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr message_;
  ::PROTOBUF_NAMESPACE_ID::int32 type_;
  friend struct ::TableStruct_BitControl_2eproto;
};
// -------------------------------------------------------------------

class PlanFragment PROTOBUF_FINAL :
    public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:exec.bit.control.PlanFragment) */ {
 public:
  inline PlanFragment() : PlanFragment(nullptr) {}
  ~PlanFragment() override;
  explicit constexpr PlanFragment(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);

  PlanFragment(const PlanFragment& from);
  PlanFragment(PlanFragment&& from) noexcept
    : PlanFragment() {
    *this = ::std::move(from);
  }

  inline PlanFragment& operator=(const PlanFragment& from) {
    CopyFrom(from);
    return *this;
  }
  inline PlanFragment& operator=(PlanFragment&& from) noexcept {
    if (GetArena() == from.GetArena()) {
      if (this != &from) InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }

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

  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() {
    return GetDescriptor();
  }
  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() {
    return default_instance().GetMetadata().descriptor;
  }
  static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() {
    return default_instance().GetMetadata().reflection;
  }
  static const PlanFragment& default_instance() {
    return *internal_default_instance();
  }
  static inline const PlanFragment* internal_default_instance() {
    return reinterpret_cast<const PlanFragment*>(
               &_PlanFragment_default_instance_);
  }
  static constexpr int kIndexInFileMessages =
    5;

  friend void swap(PlanFragment& a, PlanFragment& b) {
    a.Swap(&b);
  }
  inline void Swap(PlanFragment* other) {
    if (other == this) return;
    if (GetArena() == other->GetArena()) {
      InternalSwap(other);
    } else {
      ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);
    }
  }
  void UnsafeArenaSwap(PlanFragment* other) {
    if (other == this) return;
    GOOGLE_DCHECK(GetArena() == other->GetArena());
    InternalSwap(other);
  }

  // implements Message ----------------------------------------------

  inline PlanFragment* New() const final {
    return CreateMaybeMessage<PlanFragment>(nullptr);
  }

  PlanFragment* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final {
    return CreateMaybeMessage<PlanFragment>(arena);
  }
  void CopyFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
  void MergeFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
  void CopyFrom(const PlanFragment& from);
  void MergeFrom(const PlanFragment& from);
  PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
  bool IsInitialized() const final;

  size_t ByteSizeLong() const final;
  const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
  ::PROTOBUF_NAMESPACE_ID::uint8* _InternalSerialize(
      ::PROTOBUF_NAMESPACE_ID::uint8* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
  int GetCachedSize() const final { return _cached_size_.Get(); }

  private:
  inline void SharedCtor();
  inline void SharedDtor();
  void SetCachedSize(int size) const final;
  void InternalSwap(PlanFragment* other);
  friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
  static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
    return "exec.bit.control.PlanFragment";
  }
  protected:
  explicit PlanFragment(::PROTOBUF_NAMESPACE_ID::Arena* arena);
  private:
  static void ArenaDtor(void* object);
  inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena);
  public:

  ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final;

  // nested types ----------------------------------------------------

  // accessors -------------------------------------------------------

  enum : int {
    kCollectorFieldNumber = 17,
    kFragmentJsonFieldNumber = 8,
    kOptionsJsonFieldNumber = 15,
    kHandleFieldNumber = 1,
    kAssignmentFieldNumber = 10,
    kForemanFieldNumber = 11,
    kCredentialsFieldNumber = 14,
    kContextFieldNumber = 16,
    kNetworkCostFieldNumber = 4,
    kCpuCostFieldNumber = 5,
    kDiskCostFieldNumber = 6,
    kMemoryCostFieldNumber = 7,
    kLeafFragmentFieldNumber = 9,
    kMemInitialFieldNumber = 12,
    kMemMaxFieldNumber = 13,
  };
  // repeated .exec.bit.control.Collector collector = 17;
  int collector_size() const;
  private:
  int _internal_collector_size() const;
  public:
  void clear_collector();
  ::exec::bit::control::Collector* mutable_collector(int index);
  ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::exec::bit::control::Collector >*
      mutable_collector();
  private:
  const ::exec::bit::control::Collector& _internal_collector(int index) const;
  ::exec::bit::control::Collector* _internal_add_collector();
  public:
  const ::exec::bit::control::Collector& collector(int index) const;
  ::exec::bit::control::Collector* add_collector();
  const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::exec::bit::control::Collector >&
      collector() const;

  // optional string fragment_json = 8;
  bool has_fragment_json() const;
  private:
  bool _internal_has_fragment_json() const;
  public:
  void clear_fragment_json();
  const std::string& fragment_json() const;
  template <typename ArgT0 = const std::string&, typename... ArgT>
  void set_fragment_json(ArgT0&& arg0, ArgT... args);
  std::string* mutable_fragment_json();
  std::string* release_fragment_json();
  void set_allocated_fragment_json(std::string* fragment_json);
  private:
  const std::string& _internal_fragment_json() const;
  void _internal_set_fragment_json(const std::string& value);
  std::string* _internal_mutable_fragment_json();
  public:

  // optional string options_json = 15;
  bool has_options_json() const;
  private:
  bool _internal_has_options_json() const;
  public:
  void clear_options_json();
  const std::string& options_json() const;
  template <typename ArgT0 = const std::string&, typename... ArgT>
  void set_options_json(ArgT0&& arg0, ArgT... args);
  std::string* mutable_options_json();
  std::string* release_options_json();
  void set_allocated_options_json(std::string* options_json);
  private:
  const std::string& _internal_options_json() const;
  void _internal_set_options_json(const std::string& value);
  std::string* _internal_mutable_options_json();
  public:

  // optional .exec.bit.FragmentHandle handle = 1;
  bool has_handle() const;
  private:
  bool _internal_has_handle() const;
  public:
  void clear_handle();
  const ::exec::bit::FragmentHandle& handle() const;
  ::exec::bit::FragmentHandle* release_handle();
  ::exec::bit::FragmentHandle* mutable_handle();
  void set_allocated_handle(::exec::bit::FragmentHandle* handle);
  private:
  const ::exec::bit::FragmentHandle& _internal_handle() const;
  ::exec::bit::FragmentHandle* _internal_mutable_handle();
  public:
  void unsafe_arena_set_allocated_handle(
      ::exec::bit::FragmentHandle* handle);
  ::exec::bit::FragmentHandle* unsafe_arena_release_handle();

  // optional .exec.DrillbitEndpoint assignment = 10;
  bool has_assignment() const;
  private:
  bool _internal_has_assignment() const;
  public:
  void clear_assignment();
  const ::exec::DrillbitEndpoint& assignment() const;
  ::exec::DrillbitEndpoint* release_assignment();
  ::exec::DrillbitEndpoint* mutable_assignment();
  void set_allocated_assignment(::exec::DrillbitEndpoint* assignment);
  private:
  const ::exec::DrillbitEndpoint& _internal_assignment() const;
  ::exec::DrillbitEndpoint* _internal_mutable_assignment();
  public:
  void unsafe_arena_set_allocated_assignment(
      ::exec::DrillbitEndpoint* assignment);
  ::exec::DrillbitEndpoint* unsafe_arena_release_assignment();

  // optional .exec.DrillbitEndpoint foreman = 11;
  bool has_foreman() const;
  private:
  bool _internal_has_foreman() const;
  public:
  void clear_foreman();
  const ::exec::DrillbitEndpoint& foreman() const;
  ::exec::DrillbitEndpoint* release_foreman();
  ::exec::DrillbitEndpoint* mutable_foreman();
  void set_allocated_foreman(::exec::DrillbitEndpoint* foreman);
  private:
  const ::exec::DrillbitEndpoint& _internal_foreman() const;
  ::exec::DrillbitEndpoint* _internal_mutable_foreman();
  public:
  void unsafe_arena_set_allocated_foreman(
      ::exec::DrillbitEndpoint* foreman);
  ::exec::DrillbitEndpoint* unsafe_arena_release_foreman();

  // optional .exec.shared.UserCredentials credentials = 14;
  bool has_credentials() const;
  private:
  bool _internal_has_credentials() const;
  public:
  void clear_credentials();
  const ::exec::shared::UserCredentials& credentials() const;
  ::exec::shared::UserCredentials* release_credentials();
  ::exec::shared::UserCredentials* mutable_credentials();
  void set_allocated_credentials(::exec::shared::UserCredentials* credentials);
  private:
  const ::exec::shared::UserCredentials& _internal_credentials() const;
  ::exec::shared::UserCredentials* _internal_mutable_credentials();
  public:
  void unsafe_arena_set_allocated_credentials(
      ::exec::shared::UserCredentials* credentials);
  ::exec::shared::UserCredentials* unsafe_arena_release_credentials();

  // optional .exec.bit.control.QueryContextInformation context = 16;
  bool has_context() const;
  private:
  bool _internal_has_context() const;
  public:
  void clear_context();
  const ::exec::bit::control::QueryContextInformation& context() const;
  ::exec::bit::control::QueryContextInformation* release_context();
  ::exec::bit::control::QueryContextInformation* mutable_context();
  void set_allocated_context(::exec::bit::control::QueryContextInformation* context);
  private:
  const ::exec::bit::control::QueryContextInformation& _internal_context() const;
  ::exec::bit::control::QueryContextInformation* _internal_mutable_context();
  public:
  void unsafe_arena_set_allocated_context(
      ::exec::bit::control::QueryContextInformation* context);
  ::exec::bit::control::QueryContextInformation* unsafe_arena_release_context();

  // optional float network_cost = 4;
  bool has_network_cost() const;
  private:
  bool _internal_has_network_cost() const;
  public:
  void clear_network_cost();
  float network_cost() const;
  void set_network_cost(float value);
  private:
  float _internal_network_cost() const;
  void _internal_set_network_cost(float value);
  public:

  // optional float cpu_cost = 5;
  bool has_cpu_cost() const;
  private:
  bool _internal_has_cpu_cost() const;
  public:
  void clear_cpu_cost();
  float cpu_cost() const;
  void set_cpu_cost(float value);
  private:
  float _internal_cpu_cost() const;
  void _internal_set_cpu_cost(float value);
  public:

  // optional float disk_cost = 6;
  bool has_disk_cost() const;
  private:
  bool _internal_has_disk_cost() const;
  public:
  void clear_disk_cost();
  float disk_cost() const;
  void set_disk_cost(float value);
  private:
  float _internal_disk_cost() const;
  void _internal_set_disk_cost(float value);
  public:

  // optional float memory_cost = 7;
  bool has_memory_cost() const;
  private:
  bool _internal_has_memory_cost() const;
  public:
  void clear_memory_cost();
  float memory_cost() const;
  void set_memory_cost(float value);
  private:
  float _internal_memory_cost() const;
  void _internal_set_memory_cost(float value);
  public:

  // optional bool leaf_fragment = 9;
  bool has_leaf_fragment() const;
  private:
  bool _internal_has_leaf_fragment() const;
  public:
  void clear_leaf_fragment();
  bool leaf_fragment() const;
  void set_leaf_fragment(bool value);
  private:
  bool _internal_leaf_fragment() const;
  void _internal_set_leaf_fragment(bool value);
  public:

  // optional int64 mem_initial = 12 [default = 20000000];
  bool has_mem_initial() const;
  private:
  bool _internal_has_mem_initial() const;
  public:
  void clear_mem_initial();
  ::PROTOBUF_NAMESPACE_ID::int64 mem_initial() const;
  void set_mem_initial(::PROTOBUF_NAMESPACE_ID::int64 value);
  private:
  ::PROTOBUF_NAMESPACE_ID::int64 _internal_mem_initial() const;
  void _internal_set_mem_initial(::PROTOBUF_NAMESPACE_ID::int64 value);
  public:

  // optional int64 mem_max = 13 [default = 2000000000];
  bool has_mem_max() const;
  private:
  bool _internal_has_mem_max() const;
  public:
  void clear_mem_max();
  ::PROTOBUF_NAMESPACE_ID::int64 mem_max() const;
  void set_mem_max(::PROTOBUF_NAMESPACE_ID::int64 value);
  private:
  ::PROTOBUF_NAMESPACE_ID::int64 _internal_mem_max() const;
  void _internal_set_mem_max(::PROTOBUF_NAMESPACE_ID::int64 value);
  public:

  // @@protoc_insertion_point(class_scope:exec.bit.control.PlanFragment)
 private:
  class _Internal;

  template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper;
  typedef void InternalArenaConstructable_;
  typedef void DestructorSkippable_;
  ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_;
  mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
  ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::exec::bit::control::Collector > collector_;
  ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr fragment_json_;
  ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr options_json_;
  ::exec::bit::FragmentHandle* handle_;
  ::exec::DrillbitEndpoint* assignment_;
  ::exec::DrillbitEndpoint* foreman_;
  ::exec::shared::UserCredentials* credentials_;
  ::exec::bit::control::QueryContextInformation* context_;
  float network_cost_;
  float cpu_cost_;
  float disk_cost_;
  float memory_cost_;
  bool leaf_fragment_;
  ::PROTOBUF_NAMESPACE_ID::int64 mem_initial_;
  ::PROTOBUF_NAMESPACE_ID::int64 mem_max_;
  friend struct ::TableStruct_BitControl_2eproto;
};
// -------------------------------------------------------------------

class Collector PROTOBUF_FINAL :
    public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:exec.bit.control.Collector) */ {
 public:
  inline Collector() : Collector(nullptr) {}
  ~Collector() override;
  explicit constexpr Collector(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);

  Collector(const Collector& from);
  Collector(Collector&& from) noexcept
    : Collector() {
    *this = ::std::move(from);
  }

  inline Collector& operator=(const Collector& from) {
    CopyFrom(from);
    return *this;
  }
  inline Collector& operator=(Collector&& from) noexcept {
    if (GetArena() == from.GetArena()) {
      if (this != &from) InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }

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

  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() {
    return GetDescriptor();
  }
  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() {
    return default_instance().GetMetadata().descriptor;
  }
  static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() {
    return default_instance().GetMetadata().reflection;
  }
  static const Collector& default_instance() {
    return *internal_default_instance();
  }
  static inline const Collector* internal_default_instance() {
    return reinterpret_cast<const Collector*>(
               &_Collector_default_instance_);
  }
  static constexpr int kIndexInFileMessages =
    6;

  friend void swap(Collector& a, Collector& b) {
    a.Swap(&b);
  }
  inline void Swap(Collector* other) {
    if (other == this) return;
    if (GetArena() == other->GetArena()) {
      InternalSwap(other);
    } else {
      ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);
    }
  }
  void UnsafeArenaSwap(Collector* other) {
    if (other == this) return;
    GOOGLE_DCHECK(GetArena() == other->GetArena());
    InternalSwap(other);
  }

  // implements Message ----------------------------------------------

  inline Collector* New() const final {
    return CreateMaybeMessage<Collector>(nullptr);
  }

  Collector* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final {
    return CreateMaybeMessage<Collector>(arena);
  }
  void CopyFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
  void MergeFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
  void CopyFrom(const Collector& from);
  void MergeFrom(const Collector& from);
  PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
  bool IsInitialized() const final;

  size_t ByteSizeLong() const final;
  const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
  ::PROTOBUF_NAMESPACE_ID::uint8* _InternalSerialize(
      ::PROTOBUF_NAMESPACE_ID::uint8* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
  int GetCachedSize() const final { return _cached_size_.Get(); }

  private:
  inline void SharedCtor();
  inline void SharedDtor();
  void SetCachedSize(int size) const final;
  void InternalSwap(Collector* other);
  friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
  static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
    return "exec.bit.control.Collector";
  }
  protected:
  explicit Collector(::PROTOBUF_NAMESPACE_ID::Arena* arena);
  private:
  static void ArenaDtor(void* object);
  inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena);
  public:

  ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final;

  // nested types ----------------------------------------------------

  // accessors -------------------------------------------------------

  enum : int {
    kIncomingMinorFragmentFieldNumber = 2,
    kOppositeMajorFragmentIdFieldNumber = 1,
    kSupportsOutOfOrderFieldNumber = 3,
    kIsSpoolingFieldNumber = 4,
    kEnableDynamicFcFieldNumber = 5,
  };
  // repeated int32 incoming_minor_fragment = 2 [packed = true];
  int incoming_minor_fragment_size() const;
  private:
  int _internal_incoming_minor_fragment_size() const;
  public:
  void clear_incoming_minor_fragment();
  private:
  ::PROTOBUF_NAMESPACE_ID::int32 _internal_incoming_minor_fragment(int index) const;
  const ::PROTOBUF_NAMESPACE_ID::RepeatedField< ::PROTOBUF_NAMESPACE_ID::int32 >&
      _internal_incoming_minor_fragment() const;
  void _internal_add_incoming_minor_fragment(::PROTOBUF_NAMESPACE_ID::int32 value);
  ::PROTOBUF_NAMESPACE_ID::RepeatedField< ::PROTOBUF_NAMESPACE_ID::int32 >*
      _internal_mutable_incoming_minor_fragment();
  public:
  ::PROTOBUF_NAMESPACE_ID::int32 incoming_minor_fragment(int index) const;
  void set_incoming_minor_fragment(int index, ::PROTOBUF_NAMESPACE_ID::int32 value);
  void add_incoming_minor_fragment(::PROTOBUF_NAMESPACE_ID::int32 value);
  const ::PROTOBUF_NAMESPACE_ID::RepeatedField< ::PROTOBUF_NAMESPACE_ID::int32 >&
      incoming_minor_fragment() const;
  ::PROTOBUF_NAMESPACE_ID::RepeatedField< ::PROTOBUF_NAMESPACE_ID::int32 >*
      mutable_incoming_minor_fragment();

  // optional int32 opposite_major_fragment_id = 1;
  bool has_opposite_major_fragment_id() const;
  private:
  bool _internal_has_opposite_major_fragment_id() const;
  public:
  void clear_opposite_major_fragment_id();
  ::PROTOBUF_NAMESPACE_ID::int32 opposite_major_fragment_id() const;
  void set_opposite_major_fragment_id(::PROTOBUF_NAMESPACE_ID::int32 value);
  private:
  ::PROTOBUF_NAMESPACE_ID::int32 _internal_opposite_major_fragment_id() const;
  void _internal_set_opposite_major_fragment_id(::PROTOBUF_NAMESPACE_ID::int32 value);
  public:

  // optional bool supports_out_of_order = 3;
  bool has_supports_out_of_order() const;
  private:
  bool _internal_has_supports_out_of_order() const;
  public:
  void clear_supports_out_of_order();
  bool supports_out_of_order() const;
  void set_supports_out_of_order(bool value);
  private:
  bool _internal_supports_out_of_order() const;
  void _internal_set_supports_out_of_order(bool value);
  public:

  // optional bool is_spooling = 4;
  bool has_is_spooling() const;
  private:
  bool _internal_has_is_spooling() const;
  public:
  void clear_is_spooling();
  bool is_spooling() const;
  void set_is_spooling(bool value);
  private:
  bool _internal_is_spooling() const;
  void _internal_set_is_spooling(bool value);
  public:

  // optional bool enable_dynamic_fc = 5;
  bool has_enable_dynamic_fc() const;
  private:
  bool _internal_has_enable_dynamic_fc() const;
  public:
  void clear_enable_dynamic_fc();
  bool enable_dynamic_fc() const;
  void set_enable_dynamic_fc(bool value);
  private:
  bool _internal_enable_dynamic_fc() const;
  void _internal_set_enable_dynamic_fc(bool value);
  public:

  // @@protoc_insertion_point(class_scope:exec.bit.control.Collector)
 private:
  class _Internal;

  template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper;
  typedef void InternalArenaConstructable_;
  typedef void DestructorSkippable_;
  ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_;
  mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
  ::PROTOBUF_NAMESPACE_ID::RepeatedField< ::PROTOBUF_NAMESPACE_ID::int32 > incoming_minor_fragment_;
  mutable std::atomic<int> _incoming_minor_fragment_cached_byte_size_;
  ::PROTOBUF_NAMESPACE_ID::int32 opposite_major_fragment_id_;
  bool supports_out_of_order_;
  bool is_spooling_;
  bool enable_dynamic_fc_;
  friend struct ::TableStruct_BitControl_2eproto;
};
// -------------------------------------------------------------------

class QueryContextInformation PROTOBUF_FINAL :
    public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:exec.bit.control.QueryContextInformation) */ {
 public:
  inline QueryContextInformation() : QueryContextInformation(nullptr) {}
  ~QueryContextInformation() override;
  explicit constexpr QueryContextInformation(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);

  QueryContextInformation(const QueryContextInformation& from);
  QueryContextInformation(QueryContextInformation&& from) noexcept
    : QueryContextInformation() {
    *this = ::std::move(from);
  }

  inline QueryContextInformation& operator=(const QueryContextInformation& from) {
    CopyFrom(from);
    return *this;
  }
  inline QueryContextInformation& operator=(QueryContextInformation&& from) noexcept {
    if (GetArena() == from.GetArena()) {
      if (this != &from) InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }

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

  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() {
    return GetDescriptor();
  }
  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() {
    return default_instance().GetMetadata().descriptor;
  }
  static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() {
    return default_instance().GetMetadata().reflection;
  }
  static const QueryContextInformation& default_instance() {
    return *internal_default_instance();
  }
  static inline const QueryContextInformation* internal_default_instance() {
    return reinterpret_cast<const QueryContextInformation*>(
               &_QueryContextInformation_default_instance_);
  }
  static constexpr int kIndexInFileMessages =
    7;

  friend void swap(QueryContextInformation& a, QueryContextInformation& b) {
    a.Swap(&b);
  }
  inline void Swap(QueryContextInformation* other) {
    if (other == this) return;
    if (GetArena() == other->GetArena()) {
      InternalSwap(other);
    } else {
      ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);
    }
  }
  void UnsafeArenaSwap(QueryContextInformation* other) {
    if (other == this) return;
    GOOGLE_DCHECK(GetArena() == other->GetArena());
    InternalSwap(other);
  }

  // implements Message ----------------------------------------------

  inline QueryContextInformation* New() const final {
    return CreateMaybeMessage<QueryContextInformation>(nullptr);
  }

  QueryContextInformation* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final {
    return CreateMaybeMessage<QueryContextInformation>(arena);
  }
  void CopyFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
  void MergeFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
  void CopyFrom(const QueryContextInformation& from);
  void MergeFrom(const QueryContextInformation& from);
  PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
  bool IsInitialized() const final;

  size_t ByteSizeLong() const final;
  const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
  ::PROTOBUF_NAMESPACE_ID::uint8* _InternalSerialize(
      ::PROTOBUF_NAMESPACE_ID::uint8* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
  int GetCachedSize() const final { return _cached_size_.Get(); }

  private:
  inline void SharedCtor();
  inline void SharedDtor();
  void SetCachedSize(int size) const final;
  void InternalSwap(QueryContextInformation* other);
  friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
  static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
    return "exec.bit.control.QueryContextInformation";
  }
  protected:
  explicit QueryContextInformation(::PROTOBUF_NAMESPACE_ID::Arena* arena);
  private:
  static void ArenaDtor(void* object);
  inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena);
  public:

  ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final;

  // nested types ----------------------------------------------------

  // accessors -------------------------------------------------------

  enum : int {
    kDefaultSchemaNameFieldNumber = 3,
    kSessionIdFieldNumber = 4,
    kQueryStartTimeFieldNumber = 1,
    kTimeZoneFieldNumber = 2,
  };
  // optional string default_schema_name = 3;
  bool has_default_schema_name() const;
  private:
  bool _internal_has_default_schema_name() const;
  public:
  void clear_default_schema_name();
  const std::string& default_schema_name() const;
  template <typename ArgT0 = const std::string&, typename... ArgT>
  void set_default_schema_name(ArgT0&& arg0, ArgT... args);
  std::string* mutable_default_schema_name();
  std::string* release_default_schema_name();
  void set_allocated_default_schema_name(std::string* default_schema_name);
  private:
  const std::string& _internal_default_schema_name() const;
  void _internal_set_default_schema_name(const std::string& value);
  std::string* _internal_mutable_default_schema_name();
  public:

  // optional string session_id = 4;
  bool has_session_id() const;
  private:
  bool _internal_has_session_id() const;
  public:
  void clear_session_id();
  const std::string& session_id() const;
  template <typename ArgT0 = const std::string&, typename... ArgT>
  void set_session_id(ArgT0&& arg0, ArgT... args);
  std::string* mutable_session_id();
  std::string* release_session_id();
  void set_allocated_session_id(std::string* session_id);
  private:
  const std::string& _internal_session_id() const;
  void _internal_set_session_id(const std::string& value);
  std::string* _internal_mutable_session_id();
  public:

  // optional int64 query_start_time = 1;
  bool has_query_start_time() const;
  private:
  bool _internal_has_query_start_time() const;
  public:
  void clear_query_start_time();
  ::PROTOBUF_NAMESPACE_ID::int64 query_start_time() const;
  void set_query_start_time(::PROTOBUF_NAMESPACE_ID::int64 value);
  private:
  ::PROTOBUF_NAMESPACE_ID::int64 _internal_query_start_time() const;
  void _internal_set_query_start_time(::PROTOBUF_NAMESPACE_ID::int64 value);
  public:

  // optional int32 time_zone = 2;
  bool has_time_zone() const;
  private:
  bool _internal_has_time_zone() const;
  public:
  void clear_time_zone();
  ::PROTOBUF_NAMESPACE_ID::int32 time_zone() const;
  void set_time_zone(::PROTOBUF_NAMESPACE_ID::int32 value);
  private:
  ::PROTOBUF_NAMESPACE_ID::int32 _internal_time_zone() const;
  void _internal_set_time_zone(::PROTOBUF_NAMESPACE_ID::int32 value);
  public:

  // @@protoc_insertion_point(class_scope:exec.bit.control.QueryContextInformation)
 private:
  class _Internal;

  template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper;
  typedef void InternalArenaConstructable_;
  typedef void DestructorSkippable_;
  ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_;
  mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
  ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr default_schema_name_;
  ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr session_id_;
  ::PROTOBUF_NAMESPACE_ID::int64 query_start_time_;
  ::PROTOBUF_NAMESPACE_ID::int32 time_zone_;
  friend struct ::TableStruct_BitControl_2eproto;
};
// -------------------------------------------------------------------

class WorkQueueStatus PROTOBUF_FINAL :
    public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:exec.bit.control.WorkQueueStatus) */ {
 public:
  inline WorkQueueStatus() : WorkQueueStatus(nullptr) {}
  ~WorkQueueStatus() override;
  explicit constexpr WorkQueueStatus(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);

  WorkQueueStatus(const WorkQueueStatus& from);
  WorkQueueStatus(WorkQueueStatus&& from) noexcept
    : WorkQueueStatus() {
    *this = ::std::move(from);
  }

  inline WorkQueueStatus& operator=(const WorkQueueStatus& from) {
    CopyFrom(from);
    return *this;
  }
  inline WorkQueueStatus& operator=(WorkQueueStatus&& from) noexcept {
    if (GetArena() == from.GetArena()) {
      if (this != &from) InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }

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

  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() {
    return GetDescriptor();
  }
  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() {
    return default_instance().GetMetadata().descriptor;
  }
  static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() {
    return default_instance().GetMetadata().reflection;
  }
  static const WorkQueueStatus& default_instance() {
    return *internal_default_instance();
  }
  static inline const WorkQueueStatus* internal_default_instance() {
    return reinterpret_cast<const WorkQueueStatus*>(
               &_WorkQueueStatus_default_instance_);
  }
  static constexpr int kIndexInFileMessages =
    8;

  friend void swap(WorkQueueStatus& a, WorkQueueStatus& b) {
    a.Swap(&b);
  }
  inline void Swap(WorkQueueStatus* other) {
    if (other == this) return;
    if (GetArena() == other->GetArena()) {
      InternalSwap(other);
    } else {
      ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);
    }
  }
  void UnsafeArenaSwap(WorkQueueStatus* other) {
    if (other == this) return;
    GOOGLE_DCHECK(GetArena() == other->GetArena());
    InternalSwap(other);
  }

  // implements Message ----------------------------------------------

  inline WorkQueueStatus* New() const final {
    return CreateMaybeMessage<WorkQueueStatus>(nullptr);
  }

  WorkQueueStatus* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final {
    return CreateMaybeMessage<WorkQueueStatus>(arena);
  }
  void CopyFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
  void MergeFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
  void CopyFrom(const WorkQueueStatus& from);
  void MergeFrom(const WorkQueueStatus& from);
  PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
  bool IsInitialized() const final;

  size_t ByteSizeLong() const final;
  const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
  ::PROTOBUF_NAMESPACE_ID::uint8* _InternalSerialize(
      ::PROTOBUF_NAMESPACE_ID::uint8* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
  int GetCachedSize() const final { return _cached_size_.Get(); }

  private:
  inline void SharedCtor();
  inline void SharedDtor();
  void SetCachedSize(int size) const final;
  void InternalSwap(WorkQueueStatus* other);
  friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
  static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
    return "exec.bit.control.WorkQueueStatus";
  }
  protected:
  explicit WorkQueueStatus(::PROTOBUF_NAMESPACE_ID::Arena* arena);
  private:
  static void ArenaDtor(void* object);
  inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena);
  public:

  ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final;

  // nested types ----------------------------------------------------

  // accessors -------------------------------------------------------

  enum : int {
    kEndpointFieldNumber = 1,
    kReportTimeFieldNumber = 3,
    kQueueLengthFieldNumber = 2,
  };
  // optional .exec.DrillbitEndpoint endpoint = 1;
  bool has_endpoint() const;
  private:
  bool _internal_has_endpoint() const;
  public:
  void clear_endpoint();
  const ::exec::DrillbitEndpoint& endpoint() const;
  ::exec::DrillbitEndpoint* release_endpoint();
  ::exec::DrillbitEndpoint* mutable_endpoint();
  void set_allocated_endpoint(::exec::DrillbitEndpoint* endpoint);
  private:
  const ::exec::DrillbitEndpoint& _internal_endpoint() const;
  ::exec::DrillbitEndpoint* _internal_mutable_endpoint();
  public:
  void unsafe_arena_set_allocated_endpoint(
      ::exec::DrillbitEndpoint* endpoint);
  ::exec::DrillbitEndpoint* unsafe_arena_release_endpoint();

  // optional int64 report_time = 3;
  bool has_report_time() const;
  private:
  bool _internal_has_report_time() const;
  public:
  void clear_report_time();
  ::PROTOBUF_NAMESPACE_ID::int64 report_time() const;
  void set_report_time(::PROTOBUF_NAMESPACE_ID::int64 value);
  private:
  ::PROTOBUF_NAMESPACE_ID::int64 _internal_report_time() const;
  void _internal_set_report_time(::PROTOBUF_NAMESPACE_ID::int64 value);
  public:

  // optional int32 queue_length = 2;
  bool has_queue_length() const;
  private:
  bool _internal_has_queue_length() const;
  public:
  void clear_queue_length();
  ::PROTOBUF_NAMESPACE_ID::int32 queue_length() const;
  void set_queue_length(::PROTOBUF_NAMESPACE_ID::int32 value);
  private:
  ::PROTOBUF_NAMESPACE_ID::int32 _internal_queue_length() const;
  void _internal_set_queue_length(::PROTOBUF_NAMESPACE_ID::int32 value);
  public:

  // @@protoc_insertion_point(class_scope:exec.bit.control.WorkQueueStatus)
 private:
  class _Internal;

  template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper;
  typedef void InternalArenaConstructable_;
  typedef void DestructorSkippable_;
  ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_;
  mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
  ::exec::DrillbitEndpoint* endpoint_;
  ::PROTOBUF_NAMESPACE_ID::int64 report_time_;
  ::PROTOBUF_NAMESPACE_ID::int32 queue_length_;
  friend struct ::TableStruct_BitControl_2eproto;
};
// -------------------------------------------------------------------

class FinishedReceiver PROTOBUF_FINAL :
    public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:exec.bit.control.FinishedReceiver) */ {
 public:
  inline FinishedReceiver() : FinishedReceiver(nullptr) {}
  ~FinishedReceiver() override;
  explicit constexpr FinishedReceiver(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);

  FinishedReceiver(const FinishedReceiver& from);
  FinishedReceiver(FinishedReceiver&& from) noexcept
    : FinishedReceiver() {
    *this = ::std::move(from);
  }

  inline FinishedReceiver& operator=(const FinishedReceiver& from) {
    CopyFrom(from);
    return *this;
  }
  inline FinishedReceiver& operator=(FinishedReceiver&& from) noexcept {
    if (GetArena() == from.GetArena()) {
      if (this != &from) InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }

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

  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() {
    return GetDescriptor();
  }
  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() {
    return default_instance().GetMetadata().descriptor;
  }
  static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() {
    return default_instance().GetMetadata().reflection;
  }
  static const FinishedReceiver& default_instance() {
    return *internal_default_instance();
  }
  static inline const FinishedReceiver* internal_default_instance() {
    return reinterpret_cast<const FinishedReceiver*>(
               &_FinishedReceiver_default_instance_);
  }
  static constexpr int kIndexInFileMessages =
    9;

  friend void swap(FinishedReceiver& a, FinishedReceiver& b) {
    a.Swap(&b);
  }
  inline void Swap(FinishedReceiver* other) {
    if (other == this) return;
    if (GetArena() == other->GetArena()) {
      InternalSwap(other);
    } else {
      ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);
    }
  }
  void UnsafeArenaSwap(FinishedReceiver* other) {
    if (other == this) return;
    GOOGLE_DCHECK(GetArena() == other->GetArena());
    InternalSwap(other);
  }

  // implements Message ----------------------------------------------

  inline FinishedReceiver* New() const final {
    return CreateMaybeMessage<FinishedReceiver>(nullptr);
  }

  FinishedReceiver* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final {
    return CreateMaybeMessage<FinishedReceiver>(arena);
  }
  void CopyFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
  void MergeFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
  void CopyFrom(const FinishedReceiver& from);
  void MergeFrom(const FinishedReceiver& from);
  PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
  bool IsInitialized() const final;

  size_t ByteSizeLong() const final;
  const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
  ::PROTOBUF_NAMESPACE_ID::uint8* _InternalSerialize(
      ::PROTOBUF_NAMESPACE_ID::uint8* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
  int GetCachedSize() const final { return _cached_size_.Get(); }

  private:
  inline void SharedCtor();
  inline void SharedDtor();
  void SetCachedSize(int size) const final;
  void InternalSwap(FinishedReceiver* other);
  friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
  static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
    return "exec.bit.control.FinishedReceiver";
  }
  protected:
  explicit FinishedReceiver(::PROTOBUF_NAMESPACE_ID::Arena* arena);
  private:
  static void ArenaDtor(void* object);
  inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena);
  public:

  ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final;

  // nested types ----------------------------------------------------

  // accessors -------------------------------------------------------

  enum : int {
    kReceiverFieldNumber = 1,
    kSenderFieldNumber = 2,
  };
  // optional .exec.bit.FragmentHandle receiver = 1;
  bool has_receiver() const;
  private:
  bool _internal_has_receiver() const;
  public:
  void clear_receiver();
  const ::exec::bit::FragmentHandle& receiver() const;
  ::exec::bit::FragmentHandle* release_receiver();
  ::exec::bit::FragmentHandle* mutable_receiver();
  void set_allocated_receiver(::exec::bit::FragmentHandle* receiver);
  private:
  const ::exec::bit::FragmentHandle& _internal_receiver() const;
  ::exec::bit::FragmentHandle* _internal_mutable_receiver();
  public:
  void unsafe_arena_set_allocated_receiver(
      ::exec::bit::FragmentHandle* receiver);
  ::exec::bit::FragmentHandle* unsafe_arena_release_receiver();

  // optional .exec.bit.FragmentHandle sender = 2;
  bool has_sender() const;
  private:
  bool _internal_has_sender() const;
  public:
  void clear_sender();
  const ::exec::bit::FragmentHandle& sender() const;
  ::exec::bit::FragmentHandle* release_sender();
  ::exec::bit::FragmentHandle* mutable_sender();
  void set_allocated_sender(::exec::bit::FragmentHandle* sender);
  private:
  const ::exec::bit::FragmentHandle& _internal_sender() const;
  ::exec::bit::FragmentHandle* _internal_mutable_sender();
  public:
  void unsafe_arena_set_allocated_sender(
      ::exec::bit::FragmentHandle* sender);
  ::exec::bit::FragmentHandle* unsafe_arena_release_sender();

  // @@protoc_insertion_point(class_scope:exec.bit.control.FinishedReceiver)
 private:
  class _Internal;

  template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper;
  typedef void InternalArenaConstructable_;
  typedef void DestructorSkippable_;
  ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_;
  mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
  ::exec::bit::FragmentHandle* receiver_;
  ::exec::bit::FragmentHandle* sender_;
  friend struct ::TableStruct_BitControl_2eproto;
};
// ===================================================================


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

#ifdef __GNUC__
  #pragma GCC diagnostic push
  #pragma GCC diagnostic ignored "-Wstrict-aliasing"
#endif  // __GNUC__
// BitControlHandshake

// optional int32 rpc_version = 1;
inline bool BitControlHandshake::_internal_has_rpc_version() const {
  bool value = (_has_bits_[0] & 0x00000002u) != 0;
  return value;
}
inline bool BitControlHandshake::has_rpc_version() const {
  return _internal_has_rpc_version();
}
inline void BitControlHandshake::clear_rpc_version() {
  rpc_version_ = 0;
  _has_bits_[0] &= ~0x00000002u;
}
inline ::PROTOBUF_NAMESPACE_ID::int32 BitControlHandshake::_internal_rpc_version() const {
  return rpc_version_;
}
inline ::PROTOBUF_NAMESPACE_ID::int32 BitControlHandshake::rpc_version() const {
  // @@protoc_insertion_point(field_get:exec.bit.control.BitControlHandshake.rpc_version)
  return _internal_rpc_version();
}
inline void BitControlHandshake::_internal_set_rpc_version(::PROTOBUF_NAMESPACE_ID::int32 value) {
  _has_bits_[0] |= 0x00000002u;
  rpc_version_ = value;
}
inline void BitControlHandshake::set_rpc_version(::PROTOBUF_NAMESPACE_ID::int32 value) {
  _internal_set_rpc_version(value);
  // @@protoc_insertion_point(field_set:exec.bit.control.BitControlHandshake.rpc_version)
}

// optional .exec.shared.RpcChannel channel = 2 [default = BIT_CONTROL];
inline bool BitControlHandshake::_internal_has_channel() const {
  bool value = (_has_bits_[0] & 0x00000004u) != 0;
  return value;
}
inline bool BitControlHandshake::has_channel() const {
  return _internal_has_channel();
}
inline void BitControlHandshake::clear_channel() {
  channel_ = 0;
  _has_bits_[0] &= ~0x00000004u;
}
inline ::exec::shared::RpcChannel BitControlHandshake::_internal_channel() const {
  return static_cast< ::exec::shared::RpcChannel >(channel_);
}
inline ::exec::shared::RpcChannel BitControlHandshake::channel() const {
  // @@protoc_insertion_point(field_get:exec.bit.control.BitControlHandshake.channel)
  return _internal_channel();
}
inline void BitControlHandshake::_internal_set_channel(::exec::shared::RpcChannel value) {
  assert(::exec::shared::RpcChannel_IsValid(value));
  _has_bits_[0] |= 0x00000004u;
  channel_ = value;
}
inline void BitControlHandshake::set_channel(::exec::shared::RpcChannel value) {
  _internal_set_channel(value);
  // @@protoc_insertion_point(field_set:exec.bit.control.BitControlHandshake.channel)
}

// optional .exec.DrillbitEndpoint endpoint = 3;
inline bool BitControlHandshake::_internal_has_endpoint() const {
  bool value = (_has_bits_[0] & 0x00000001u) != 0;
  PROTOBUF_ASSUME(!value || endpoint_ != nullptr);
  return value;
}
inline bool BitControlHandshake::has_endpoint() const {
  return _internal_has_endpoint();
}
inline const ::exec::DrillbitEndpoint& BitControlHandshake::_internal_endpoint() const {
  const ::exec::DrillbitEndpoint* p = endpoint_;
  return p != nullptr ? *p : reinterpret_cast<const ::exec::DrillbitEndpoint&>(
      ::exec::_DrillbitEndpoint_default_instance_);
}
inline const ::exec::DrillbitEndpoint& BitControlHandshake::endpoint() const {
  // @@protoc_insertion_point(field_get:exec.bit.control.BitControlHandshake.endpoint)
  return _internal_endpoint();
}
inline void BitControlHandshake::unsafe_arena_set_allocated_endpoint(
    ::exec::DrillbitEndpoint* endpoint) {
  if (GetArena() == nullptr) {
    delete reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(endpoint_);
  }
  endpoint_ = endpoint;
  if (endpoint) {
    _has_bits_[0] |= 0x00000001u;
  } else {
    _has_bits_[0] &= ~0x00000001u;
  }
  // @@protoc_insertion_point(field_unsafe_arena_set_allocated:exec.bit.control.BitControlHandshake.endpoint)
}
inline ::exec::DrillbitEndpoint* BitControlHandshake::release_endpoint() {
  _has_bits_[0] &= ~0x00000001u;
  ::exec::DrillbitEndpoint* temp = endpoint_;
  endpoint_ = nullptr;
  if (GetArena() != nullptr) {
    temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp);
  }
  return temp;
}
inline ::exec::DrillbitEndpoint* BitControlHandshake::unsafe_arena_release_endpoint() {
  // @@protoc_insertion_point(field_release:exec.bit.control.BitControlHandshake.endpoint)
  _has_bits_[0] &= ~0x00000001u;
  ::exec::DrillbitEndpoint* temp = endpoint_;
  endpoint_ = nullptr;
  return temp;
}
inline ::exec::DrillbitEndpoint* BitControlHandshake::_internal_mutable_endpoint() {
  _has_bits_[0] |= 0x00000001u;
  if (endpoint_ == nullptr) {
    auto* p = CreateMaybeMessage<::exec::DrillbitEndpoint>(GetArena());
    endpoint_ = p;
  }
  return endpoint_;
}
inline ::exec::DrillbitEndpoint* BitControlHandshake::mutable_endpoint() {
  // @@protoc_insertion_point(field_mutable:exec.bit.control.BitControlHandshake.endpoint)
  return _internal_mutable_endpoint();
}
inline void BitControlHandshake::set_allocated_endpoint(::exec::DrillbitEndpoint* endpoint) {
  ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArena();
  if (message_arena == nullptr) {
    delete reinterpret_cast< ::PROTOBUF_NAMESPACE_ID::MessageLite*>(endpoint_);
  }
  if (endpoint) {
    ::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena =
      reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(endpoint)->GetArena();
    if (message_arena != submessage_arena) {
      endpoint = ::PROTOBUF_NAMESPACE_ID::internal::GetOwnedMessage(
          message_arena, endpoint, submessage_arena);
    }
    _has_bits_[0] |= 0x00000001u;
  } else {
    _has_bits_[0] &= ~0x00000001u;
  }
  endpoint_ = endpoint;
  // @@protoc_insertion_point(field_set_allocated:exec.bit.control.BitControlHandshake.endpoint)
}

// repeated string authenticationMechanisms = 4;
inline int BitControlHandshake::_internal_authenticationmechanisms_size() const {
  return authenticationmechanisms_.size();
}
inline int BitControlHandshake::authenticationmechanisms_size() const {
  return _internal_authenticationmechanisms_size();
}
inline void BitControlHandshake::clear_authenticationmechanisms() {
  authenticationmechanisms_.Clear();
}
inline std::string* BitControlHandshake::add_authenticationmechanisms() {
  // @@protoc_insertion_point(field_add_mutable:exec.bit.control.BitControlHandshake.authenticationMechanisms)
  return _internal_add_authenticationmechanisms();
}
inline const std::string& BitControlHandshake::_internal_authenticationmechanisms(int index) const {
  return authenticationmechanisms_.Get(index);
}
inline const std::string& BitControlHandshake::authenticationmechanisms(int index) const {
  // @@protoc_insertion_point(field_get:exec.bit.control.BitControlHandshake.authenticationMechanisms)
  return _internal_authenticationmechanisms(index);
}
inline std::string* BitControlHandshake::mutable_authenticationmechanisms(int index) {
  // @@protoc_insertion_point(field_mutable:exec.bit.control.BitControlHandshake.authenticationMechanisms)
  return authenticationmechanisms_.Mutable(index);
}
inline void BitControlHandshake::set_authenticationmechanisms(int index, const std::string& value) {
  // @@protoc_insertion_point(field_set:exec.bit.control.BitControlHandshake.authenticationMechanisms)
  authenticationmechanisms_.Mutable(index)->assign(value);
}
inline void BitControlHandshake::set_authenticationmechanisms(int index, std::string&& value) {
  // @@protoc_insertion_point(field_set:exec.bit.control.BitControlHandshake.authenticationMechanisms)
  authenticationmechanisms_.Mutable(index)->assign(std::move(value));
}
inline void BitControlHandshake::set_authenticationmechanisms(int index, const char* value) {
  GOOGLE_DCHECK(value != nullptr);
  authenticationmechanisms_.Mutable(index)->assign(value);
  // @@protoc_insertion_point(field_set_char:exec.bit.control.BitControlHandshake.authenticationMechanisms)
}
inline void BitControlHandshake::set_authenticationmechanisms(int index, const char* value, size_t size) {
  authenticationmechanisms_.Mutable(index)->assign(
    reinterpret_cast<const char*>(value), size);
  // @@protoc_insertion_point(field_set_pointer:exec.bit.control.BitControlHandshake.authenticationMechanisms)
}
inline std::string* BitControlHandshake::_internal_add_authenticationmechanisms() {
  return authenticationmechanisms_.Add();
}
inline void BitControlHandshake::add_authenticationmechanisms(const std::string& value) {
  authenticationmechanisms_.Add()->assign(value);
  // @@protoc_insertion_point(field_add:exec.bit.control.BitControlHandshake.authenticationMechanisms)
}
inline void BitControlHandshake::add_authenticationmechanisms(std::string&& value) {
  authenticationmechanisms_.Add(std::move(value));
  // @@protoc_insertion_point(field_add:exec.bit.control.BitControlHandshake.authenticationMechanisms)
}
inline void BitControlHandshake::add_authenticationmechanisms(const char* value) {
  GOOGLE_DCHECK(value != nullptr);
  authenticationmechanisms_.Add()->assign(value);
  // @@protoc_insertion_point(field_add_char:exec.bit.control.BitControlHandshake.authenticationMechanisms)
}
inline void BitControlHandshake::add_authenticationmechanisms(const char* value, size_t size) {
  authenticationmechanisms_.Add()->assign(reinterpret_cast<const char*>(value), size);
  // @@protoc_insertion_point(field_add_pointer:exec.bit.control.BitControlHandshake.authenticationMechanisms)
}
inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField<std::string>&
BitControlHandshake::authenticationmechanisms() const {
  // @@protoc_insertion_point(field_list:exec.bit.control.BitControlHandshake.authenticationMechanisms)
  return authenticationmechanisms_;
}
inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField<std::string>*
BitControlHandshake::mutable_authenticationmechanisms() {
  // @@protoc_insertion_point(field_mutable_list:exec.bit.control.BitControlHandshake.authenticationMechanisms)
  return &authenticationmechanisms_;
}

// -------------------------------------------------------------------

// BitStatus

// repeated .exec.bit.control.FragmentStatus fragment_status = 1;
inline int BitStatus::_internal_fragment_status_size() const {
  return fragment_status_.size();
}
inline int BitStatus::fragment_status_size() const {
  return _internal_fragment_status_size();
}
inline void BitStatus::clear_fragment_status() {
  fragment_status_.Clear();
}
inline ::exec::bit::control::FragmentStatus* BitStatus::mutable_fragment_status(int index) {
  // @@protoc_insertion_point(field_mutable:exec.bit.control.BitStatus.fragment_status)
  return fragment_status_.Mutable(index);
}
inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::exec::bit::control::FragmentStatus >*
BitStatus::mutable_fragment_status() {
  // @@protoc_insertion_point(field_mutable_list:exec.bit.control.BitStatus.fragment_status)
  return &fragment_status_;
}
inline const ::exec::bit::control::FragmentStatus& BitStatus::_internal_fragment_status(int index) const {
  return fragment_status_.Get(index);
}
inline const ::exec::bit::control::FragmentStatus& BitStatus::fragment_status(int index) const {
  // @@protoc_insertion_point(field_get:exec.bit.control.BitStatus.fragment_status)
  return _internal_fragment_status(index);
}
inline ::exec::bit::control::FragmentStatus* BitStatus::_internal_add_fragment_status() {
  return fragment_status_.Add();
}
inline ::exec::bit::control::FragmentStatus* BitStatus::add_fragment_status() {
  // @@protoc_insertion_point(field_add:exec.bit.control.BitStatus.fragment_status)
  return _internal_add_fragment_status();
}
inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::exec::bit::control::FragmentStatus >&
BitStatus::fragment_status() const {
  // @@protoc_insertion_point(field_list:exec.bit.control.BitStatus.fragment_status)
  return fragment_status_;
}

// -------------------------------------------------------------------

// FragmentStatus

// optional .exec.shared.MinorFragmentProfile profile = 1;
inline bool FragmentStatus::_internal_has_profile() const {
  bool value = (_has_bits_[0] & 0x00000001u) != 0;
  PROTOBUF_ASSUME(!value || profile_ != nullptr);
  return value;
}
inline bool FragmentStatus::has_profile() const {
  return _internal_has_profile();
}
inline const ::exec::shared::MinorFragmentProfile& FragmentStatus::_internal_profile() const {
  const ::exec::shared::MinorFragmentProfile* p = profile_;
  return p != nullptr ? *p : reinterpret_cast<const ::exec::shared::MinorFragmentProfile&>(
      ::exec::shared::_MinorFragmentProfile_default_instance_);
}
inline const ::exec::shared::MinorFragmentProfile& FragmentStatus::profile() const {
  // @@protoc_insertion_point(field_get:exec.bit.control.FragmentStatus.profile)
  return _internal_profile();
}
inline void FragmentStatus::unsafe_arena_set_allocated_profile(
    ::exec::shared::MinorFragmentProfile* profile) {
  if (GetArena() == nullptr) {
    delete reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(profile_);
  }
  profile_ = profile;
  if (profile) {
    _has_bits_[0] |= 0x00000001u;
  } else {
    _has_bits_[0] &= ~0x00000001u;
  }
  // @@protoc_insertion_point(field_unsafe_arena_set_allocated:exec.bit.control.FragmentStatus.profile)
}
inline ::exec::shared::MinorFragmentProfile* FragmentStatus::release_profile() {
  _has_bits_[0] &= ~0x00000001u;
  ::exec::shared::MinorFragmentProfile* temp = profile_;
  profile_ = nullptr;
  if (GetArena() != nullptr) {
    temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp);
  }
  return temp;
}
inline ::exec::shared::MinorFragmentProfile* FragmentStatus::unsafe_arena_release_profile() {
  // @@protoc_insertion_point(field_release:exec.bit.control.FragmentStatus.profile)
  _has_bits_[0] &= ~0x00000001u;
  ::exec::shared::MinorFragmentProfile* temp = profile_;
  profile_ = nullptr;
  return temp;
}
inline ::exec::shared::MinorFragmentProfile* FragmentStatus::_internal_mutable_profile() {
  _has_bits_[0] |= 0x00000001u;
  if (profile_ == nullptr) {
    auto* p = CreateMaybeMessage<::exec::shared::MinorFragmentProfile>(GetArena());
    profile_ = p;
  }
  return profile_;
}
inline ::exec::shared::MinorFragmentProfile* FragmentStatus::mutable_profile() {
  // @@protoc_insertion_point(field_mutable:exec.bit.control.FragmentStatus.profile)
  return _internal_mutable_profile();
}
inline void FragmentStatus::set_allocated_profile(::exec::shared::MinorFragmentProfile* profile) {
  ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArena();
  if (message_arena == nullptr) {
    delete reinterpret_cast< ::PROTOBUF_NAMESPACE_ID::MessageLite*>(profile_);
  }
  if (profile) {
    ::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena =
      reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(profile)->GetArena();
    if (message_arena != submessage_arena) {
      profile = ::PROTOBUF_NAMESPACE_ID::internal::GetOwnedMessage(
          message_arena, profile, submessage_arena);
    }
    _has_bits_[0] |= 0x00000001u;
  } else {
    _has_bits_[0] &= ~0x00000001u;
  }
  profile_ = profile;
  // @@protoc_insertion_point(field_set_allocated:exec.bit.control.FragmentStatus.profile)
}

// optional .exec.bit.FragmentHandle handle = 2;
inline bool FragmentStatus::_internal_has_handle() const {
  bool value = (_has_bits_[0] & 0x00000002u) != 0;
  PROTOBUF_ASSUME(!value || handle_ != nullptr);
  return value;
}
inline bool FragmentStatus::has_handle() const {
  return _internal_has_handle();
}
inline const ::exec::bit::FragmentHandle& FragmentStatus::_internal_handle() const {
  const ::exec::bit::FragmentHandle* p = handle_;
  return p != nullptr ? *p : reinterpret_cast<const ::exec::bit::FragmentHandle&>(
      ::exec::bit::_FragmentHandle_default_instance_);
}
inline const ::exec::bit::FragmentHandle& FragmentStatus::handle() const {
  // @@protoc_insertion_point(field_get:exec.bit.control.FragmentStatus.handle)
  return _internal_handle();
}
inline void FragmentStatus::unsafe_arena_set_allocated_handle(
    ::exec::bit::FragmentHandle* handle) {
  if (GetArena() == nullptr) {
    delete reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(handle_);
  }
  handle_ = handle;
  if (handle) {
    _has_bits_[0] |= 0x00000002u;
  } else {
    _has_bits_[0] &= ~0x00000002u;
  }
  // @@protoc_insertion_point(field_unsafe_arena_set_allocated:exec.bit.control.FragmentStatus.handle)
}
inline ::exec::bit::FragmentHandle* FragmentStatus::release_handle() {
  _has_bits_[0] &= ~0x00000002u;
  ::exec::bit::FragmentHandle* temp = handle_;
  handle_ = nullptr;
  if (GetArena() != nullptr) {
    temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp);
  }
  return temp;
}
inline ::exec::bit::FragmentHandle* FragmentStatus::unsafe_arena_release_handle() {
  // @@protoc_insertion_point(field_release:exec.bit.control.FragmentStatus.handle)
  _has_bits_[0] &= ~0x00000002u;
  ::exec::bit::FragmentHandle* temp = handle_;
  handle_ = nullptr;
  return temp;
}
inline ::exec::bit::FragmentHandle* FragmentStatus::_internal_mutable_handle() {
  _has_bits_[0] |= 0x00000002u;
  if (handle_ == nullptr) {
    auto* p = CreateMaybeMessage<::exec::bit::FragmentHandle>(GetArena());
    handle_ = p;
  }
  return handle_;
}
inline ::exec::bit::FragmentHandle* FragmentStatus::mutable_handle() {
  // @@protoc_insertion_point(field_mutable:exec.bit.control.FragmentStatus.handle)
  return _internal_mutable_handle();
}
inline void FragmentStatus::set_allocated_handle(::exec::bit::FragmentHandle* handle) {
  ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArena();
  if (message_arena == nullptr) {
    delete reinterpret_cast< ::PROTOBUF_NAMESPACE_ID::MessageLite*>(handle_);
  }
  if (handle) {
    ::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena =
      reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(handle)->GetArena();
    if (message_arena != submessage_arena) {
      handle = ::PROTOBUF_NAMESPACE_ID::internal::GetOwnedMessage(
          message_arena, handle, submessage_arena);
    }
    _has_bits_[0] |= 0x00000002u;
  } else {
    _has_bits_[0] &= ~0x00000002u;
  }
  handle_ = handle;
  // @@protoc_insertion_point(field_set_allocated:exec.bit.control.FragmentStatus.handle)
}

// -------------------------------------------------------------------

// InitializeFragments

// repeated .exec.bit.control.PlanFragment fragment = 1;
inline int InitializeFragments::_internal_fragment_size() const {
  return fragment_.size();
}
inline int InitializeFragments::fragment_size() const {
  return _internal_fragment_size();
}
inline void InitializeFragments::clear_fragment() {
  fragment_.Clear();
}
inline ::exec::bit::control::PlanFragment* InitializeFragments::mutable_fragment(int index) {
  // @@protoc_insertion_point(field_mutable:exec.bit.control.InitializeFragments.fragment)
  return fragment_.Mutable(index);
}
inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::exec::bit::control::PlanFragment >*
InitializeFragments::mutable_fragment() {
  // @@protoc_insertion_point(field_mutable_list:exec.bit.control.InitializeFragments.fragment)
  return &fragment_;
}
inline const ::exec::bit::control::PlanFragment& InitializeFragments::_internal_fragment(int index) const {
  return fragment_.Get(index);
}
inline const ::exec::bit::control::PlanFragment& InitializeFragments::fragment(int index) const {
  // @@protoc_insertion_point(field_get:exec.bit.control.InitializeFragments.fragment)
  return _internal_fragment(index);
}
inline ::exec::bit::control::PlanFragment* InitializeFragments::_internal_add_fragment() {
  return fragment_.Add();
}
inline ::exec::bit::control::PlanFragment* InitializeFragments::add_fragment() {
  // @@protoc_insertion_point(field_add:exec.bit.control.InitializeFragments.fragment)
  return _internal_add_fragment();
}
inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::exec::bit::control::PlanFragment >&
InitializeFragments::fragment() const {
  // @@protoc_insertion_point(field_list:exec.bit.control.InitializeFragments.fragment)
  return fragment_;
}

// -------------------------------------------------------------------

// CustomMessage

// optional int32 type = 1;
inline bool CustomMessage::_internal_has_type() const {
  bool value = (_has_bits_[0] & 0x00000002u) != 0;
  return value;
}
inline bool CustomMessage::has_type() const {
  return _internal_has_type();
}
inline void CustomMessage::clear_type() {
  type_ = 0;
  _has_bits_[0] &= ~0x00000002u;
}
inline ::PROTOBUF_NAMESPACE_ID::int32 CustomMessage::_internal_type() const {
  return type_;
}
inline ::PROTOBUF_NAMESPACE_ID::int32 CustomMessage::type() const {
  // @@protoc_insertion_point(field_get:exec.bit.control.CustomMessage.type)
  return _internal_type();
}
inline void CustomMessage::_internal_set_type(::PROTOBUF_NAMESPACE_ID::int32 value) {
  _has_bits_[0] |= 0x00000002u;
  type_ = value;
}
inline void CustomMessage::set_type(::PROTOBUF_NAMESPACE_ID::int32 value) {
  _internal_set_type(value);
  // @@protoc_insertion_point(field_set:exec.bit.control.CustomMessage.type)
}

// optional bytes message = 2;
inline bool CustomMessage::_internal_has_message() const {
  bool value = (_has_bits_[0] & 0x00000001u) != 0;
  return value;
}
inline bool CustomMessage::has_message() const {
  return _internal_has_message();
}
inline void CustomMessage::clear_message() {
  message_.ClearToEmpty();
  _has_bits_[0] &= ~0x00000001u;
}
inline const std::string& CustomMessage::message() const {
  // @@protoc_insertion_point(field_get:exec.bit.control.CustomMessage.message)
  return _internal_message();
}
template <typename ArgT0, typename... ArgT>
PROTOBUF_ALWAYS_INLINE
inline void CustomMessage::set_message(ArgT0&& arg0, ArgT... args) {
 _has_bits_[0] |= 0x00000001u;
 message_.SetBytes(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArena());
  // @@protoc_insertion_point(field_set:exec.bit.control.CustomMessage.message)
}
inline std::string* CustomMessage::mutable_message() {
  // @@protoc_insertion_point(field_mutable:exec.bit.control.CustomMessage.message)
  return _internal_mutable_message();
}
inline const std::string& CustomMessage::_internal_message() const {
  return message_.Get();
}
inline void CustomMessage::_internal_set_message(const std::string& value) {
  _has_bits_[0] |= 0x00000001u;
  message_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena());
}
inline std::string* CustomMessage::_internal_mutable_message() {
  _has_bits_[0] |= 0x00000001u;
  return message_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena());
}
inline std::string* CustomMessage::release_message() {
  // @@protoc_insertion_point(field_release:exec.bit.control.CustomMessage.message)
  if (!_internal_has_message()) {
    return nullptr;
  }
  _has_bits_[0] &= ~0x00000001u;
  return message_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena());
}
inline void CustomMessage::set_allocated_message(std::string* message) {
  if (message != nullptr) {
    _has_bits_[0] |= 0x00000001u;
  } else {
    _has_bits_[0] &= ~0x00000001u;
  }
  message_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), message,
      GetArena());
  // @@protoc_insertion_point(field_set_allocated:exec.bit.control.CustomMessage.message)
}

// -------------------------------------------------------------------

// PlanFragment

// optional .exec.bit.FragmentHandle handle = 1;
inline bool PlanFragment::_internal_has_handle() const {
  bool value = (_has_bits_[0] & 0x00000004u) != 0;
  PROTOBUF_ASSUME(!value || handle_ != nullptr);
  return value;
}
inline bool PlanFragment::has_handle() const {
  return _internal_has_handle();
}
inline const ::exec::bit::FragmentHandle& PlanFragment::_internal_handle() const {
  const ::exec::bit::FragmentHandle* p = handle_;
  return p != nullptr ? *p : reinterpret_cast<const ::exec::bit::FragmentHandle&>(
      ::exec::bit::_FragmentHandle_default_instance_);
}
inline const ::exec::bit::FragmentHandle& PlanFragment::handle() const {
  // @@protoc_insertion_point(field_get:exec.bit.control.PlanFragment.handle)
  return _internal_handle();
}
inline void PlanFragment::unsafe_arena_set_allocated_handle(
    ::exec::bit::FragmentHandle* handle) {
  if (GetArena() == nullptr) {
    delete reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(handle_);
  }
  handle_ = handle;
  if (handle) {
    _has_bits_[0] |= 0x00000004u;
  } else {
    _has_bits_[0] &= ~0x00000004u;
  }
  // @@protoc_insertion_point(field_unsafe_arena_set_allocated:exec.bit.control.PlanFragment.handle)
}
inline ::exec::bit::FragmentHandle* PlanFragment::release_handle() {
  _has_bits_[0] &= ~0x00000004u;
  ::exec::bit::FragmentHandle* temp = handle_;
  handle_ = nullptr;
  if (GetArena() != nullptr) {
    temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp);
  }
  return temp;
}
inline ::exec::bit::FragmentHandle* PlanFragment::unsafe_arena_release_handle() {
  // @@protoc_insertion_point(field_release:exec.bit.control.PlanFragment.handle)
  _has_bits_[0] &= ~0x00000004u;
  ::exec::bit::FragmentHandle* temp = handle_;
  handle_ = nullptr;
  return temp;
}
inline ::exec::bit::FragmentHandle* PlanFragment::_internal_mutable_handle() {
  _has_bits_[0] |= 0x00000004u;
  if (handle_ == nullptr) {
    auto* p = CreateMaybeMessage<::exec::bit::FragmentHandle>(GetArena());
    handle_ = p;
  }
  return handle_;
}
inline ::exec::bit::FragmentHandle* PlanFragment::mutable_handle() {
  // @@protoc_insertion_point(field_mutable:exec.bit.control.PlanFragment.handle)
  return _internal_mutable_handle();
}
inline void PlanFragment::set_allocated_handle(::exec::bit::FragmentHandle* handle) {
  ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArena();
  if (message_arena == nullptr) {
    delete reinterpret_cast< ::PROTOBUF_NAMESPACE_ID::MessageLite*>(handle_);
  }
  if (handle) {
    ::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena =
      reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(handle)->GetArena();
    if (message_arena != submessage_arena) {
      handle = ::PROTOBUF_NAMESPACE_ID::internal::GetOwnedMessage(
          message_arena, handle, submessage_arena);
    }
    _has_bits_[0] |= 0x00000004u;
  } else {
    _has_bits_[0] &= ~0x00000004u;
  }
  handle_ = handle;
  // @@protoc_insertion_point(field_set_allocated:exec.bit.control.PlanFragment.handle)
}

// optional float network_cost = 4;
inline bool PlanFragment::_internal_has_network_cost() const {
  bool value = (_has_bits_[0] & 0x00000080u) != 0;
  return value;
}
inline bool PlanFragment::has_network_cost() const {
  return _internal_has_network_cost();
}
inline void PlanFragment::clear_network_cost() {
  network_cost_ = 0;
  _has_bits_[0] &= ~0x00000080u;
}
inline float PlanFragment::_internal_network_cost() const {
  return network_cost_;
}
inline float PlanFragment::network_cost() const {
  // @@protoc_insertion_point(field_get:exec.bit.control.PlanFragment.network_cost)
  return _internal_network_cost();
}
inline void PlanFragment::_internal_set_network_cost(float value) {
  _has_bits_[0] |= 0x00000080u;
  network_cost_ = value;
}
inline void PlanFragment::set_network_cost(float value) {
  _internal_set_network_cost(value);
  // @@protoc_insertion_point(field_set:exec.bit.control.PlanFragment.network_cost)
}

// optional float cpu_cost = 5;
inline bool PlanFragment::_internal_has_cpu_cost() const {
  bool value = (_has_bits_[0] & 0x00000100u) != 0;
  return value;
}
inline bool PlanFragment::has_cpu_cost() const {
  return _internal_has_cpu_cost();
}
inline void PlanFragment::clear_cpu_cost() {
  cpu_cost_ = 0;
  _has_bits_[0] &= ~0x00000100u;
}
inline float PlanFragment::_internal_cpu_cost() const {
  return cpu_cost_;
}
inline float PlanFragment::cpu_cost() const {
  // @@protoc_insertion_point(field_get:exec.bit.control.PlanFragment.cpu_cost)
  return _internal_cpu_cost();
}
inline void PlanFragment::_internal_set_cpu_cost(float value) {
  _has_bits_[0] |= 0x00000100u;
  cpu_cost_ = value;
}
inline void PlanFragment::set_cpu_cost(float value) {
  _internal_set_cpu_cost(value);
  // @@protoc_insertion_point(field_set:exec.bit.control.PlanFragment.cpu_cost)
}

// optional float disk_cost = 6;
inline bool PlanFragment::_internal_has_disk_cost() const {
  bool value = (_has_bits_[0] & 0x00000200u) != 0;
  return value;
}
inline bool PlanFragment::has_disk_cost() const {
  return _internal_has_disk_cost();
}
inline void PlanFragment::clear_disk_cost() {
  disk_cost_ = 0;
  _has_bits_[0] &= ~0x00000200u;
}
inline float PlanFragment::_internal_disk_cost() const {
  return disk_cost_;
}
inline float PlanFragment::disk_cost() const {
  // @@protoc_insertion_point(field_get:exec.bit.control.PlanFragment.disk_cost)
  return _internal_disk_cost();
}
inline void PlanFragment::_internal_set_disk_cost(float value) {
  _has_bits_[0] |= 0x00000200u;
  disk_cost_ = value;
}
inline void PlanFragment::set_disk_cost(float value) {
  _internal_set_disk_cost(value);
  // @@protoc_insertion_point(field_set:exec.bit.control.PlanFragment.disk_cost)
}

// optional float memory_cost = 7;
inline bool PlanFragment::_internal_has_memory_cost() const {
  bool value = (_has_bits_[0] & 0x00000400u) != 0;
  return value;
}
inline bool PlanFragment::has_memory_cost() const {
  return _internal_has_memory_cost();
}
inline void PlanFragment::clear_memory_cost() {
  memory_cost_ = 0;
  _has_bits_[0] &= ~0x00000400u;
}
inline float PlanFragment::_internal_memory_cost() const {
  return memory_cost_;
}
inline float PlanFragment::memory_cost() const {
  // @@protoc_insertion_point(field_get:exec.bit.control.PlanFragment.memory_cost)
  return _internal_memory_cost();
}
inline void PlanFragment::_internal_set_memory_cost(float value) {
  _has_bits_[0] |= 0x00000400u;
  memory_cost_ = value;
}
inline void PlanFragment::set_memory_cost(float value) {
  _internal_set_memory_cost(value);
  // @@protoc_insertion_point(field_set:exec.bit.control.PlanFragment.memory_cost)
}

// optional string fragment_json = 8;
inline bool PlanFragment::_internal_has_fragment_json() const {
  bool value = (_has_bits_[0] & 0x00000001u) != 0;
  return value;
}
inline bool PlanFragment::has_fragment_json() const {
  return _internal_has_fragment_json();
}
inline void PlanFragment::clear_fragment_json() {
  fragment_json_.ClearToEmpty();
  _has_bits_[0] &= ~0x00000001u;
}
inline const std::string& PlanFragment::fragment_json() const {
  // @@protoc_insertion_point(field_get:exec.bit.control.PlanFragment.fragment_json)
  return _internal_fragment_json();
}
template <typename ArgT0, typename... ArgT>
PROTOBUF_ALWAYS_INLINE
inline void PlanFragment::set_fragment_json(ArgT0&& arg0, ArgT... args) {
 _has_bits_[0] |= 0x00000001u;
 fragment_json_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArena());
  // @@protoc_insertion_point(field_set:exec.bit.control.PlanFragment.fragment_json)
}
inline std::string* PlanFragment::mutable_fragment_json() {
  // @@protoc_insertion_point(field_mutable:exec.bit.control.PlanFragment.fragment_json)
  return _internal_mutable_fragment_json();
}
inline const std::string& PlanFragment::_internal_fragment_json() const {
  return fragment_json_.Get();
}
inline void PlanFragment::_internal_set_fragment_json(const std::string& value) {
  _has_bits_[0] |= 0x00000001u;
  fragment_json_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena());
}
inline std::string* PlanFragment::_internal_mutable_fragment_json() {
  _has_bits_[0] |= 0x00000001u;
  return fragment_json_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena());
}
inline std::string* PlanFragment::release_fragment_json() {
  // @@protoc_insertion_point(field_release:exec.bit.control.PlanFragment.fragment_json)
  if (!_internal_has_fragment_json()) {
    return nullptr;
  }
  _has_bits_[0] &= ~0x00000001u;
  return fragment_json_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena());
}
inline void PlanFragment::set_allocated_fragment_json(std::string* fragment_json) {
  if (fragment_json != nullptr) {
    _has_bits_[0] |= 0x00000001u;
  } else {
    _has_bits_[0] &= ~0x00000001u;
  }
  fragment_json_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), fragment_json,
      GetArena());
  // @@protoc_insertion_point(field_set_allocated:exec.bit.control.PlanFragment.fragment_json)
}

// optional bool leaf_fragment = 9;
inline bool PlanFragment::_internal_has_leaf_fragment() const {
  bool value = (_has_bits_[0] & 0x00000800u) != 0;
  return value;
}
inline bool PlanFragment::has_leaf_fragment() const {
  return _internal_has_leaf_fragment();
}
inline void PlanFragment::clear_leaf_fragment() {
  leaf_fragment_ = false;
  _has_bits_[0] &= ~0x00000800u;
}
inline bool PlanFragment::_internal_leaf_fragment() const {
  return leaf_fragment_;
}
inline bool PlanFragment::leaf_fragment() const {
  // @@protoc_insertion_point(field_get:exec.bit.control.PlanFragment.leaf_fragment)
  return _internal_leaf_fragment();
}
inline void PlanFragment::_internal_set_leaf_fragment(bool value) {
  _has_bits_[0] |= 0x00000800u;
  leaf_fragment_ = value;
}
inline void PlanFragment::set_leaf_fragment(bool value) {
  _internal_set_leaf_fragment(value);
  // @@protoc_insertion_point(field_set:exec.bit.control.PlanFragment.leaf_fragment)
}

// optional .exec.DrillbitEndpoint assignment = 10;
inline bool PlanFragment::_internal_has_assignment() const {
  bool value = (_has_bits_[0] & 0x00000008u) != 0;
  PROTOBUF_ASSUME(!value || assignment_ != nullptr);
  return value;
}
inline bool PlanFragment::has_assignment() const {
  return _internal_has_assignment();
}
inline const ::exec::DrillbitEndpoint& PlanFragment::_internal_assignment() const {
  const ::exec::DrillbitEndpoint* p = assignment_;
  return p != nullptr ? *p : reinterpret_cast<const ::exec::DrillbitEndpoint&>(
      ::exec::_DrillbitEndpoint_default_instance_);
}
inline const ::exec::DrillbitEndpoint& PlanFragment::assignment() const {
  // @@protoc_insertion_point(field_get:exec.bit.control.PlanFragment.assignment)
  return _internal_assignment();
}
inline void PlanFragment::unsafe_arena_set_allocated_assignment(
    ::exec::DrillbitEndpoint* assignment) {
  if (GetArena() == nullptr) {
    delete reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(assignment_);
  }
  assignment_ = assignment;
  if (assignment) {
    _has_bits_[0] |= 0x00000008u;
  } else {
    _has_bits_[0] &= ~0x00000008u;
  }
  // @@protoc_insertion_point(field_unsafe_arena_set_allocated:exec.bit.control.PlanFragment.assignment)
}
inline ::exec::DrillbitEndpoint* PlanFragment::release_assignment() {
  _has_bits_[0] &= ~0x00000008u;
  ::exec::DrillbitEndpoint* temp = assignment_;
  assignment_ = nullptr;
  if (GetArena() != nullptr) {
    temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp);
  }
  return temp;
}
inline ::exec::DrillbitEndpoint* PlanFragment::unsafe_arena_release_assignment() {
  // @@protoc_insertion_point(field_release:exec.bit.control.PlanFragment.assignment)
  _has_bits_[0] &= ~0x00000008u;
  ::exec::DrillbitEndpoint* temp = assignment_;
  assignment_ = nullptr;
  return temp;
}
inline ::exec::DrillbitEndpoint* PlanFragment::_internal_mutable_assignment() {
  _has_bits_[0] |= 0x00000008u;
  if (assignment_ == nullptr) {
    auto* p = CreateMaybeMessage<::exec::DrillbitEndpoint>(GetArena());
    assignment_ = p;
  }
  return assignment_;
}
inline ::exec::DrillbitEndpoint* PlanFragment::mutable_assignment() {
  // @@protoc_insertion_point(field_mutable:exec.bit.control.PlanFragment.assignment)
  return _internal_mutable_assignment();
}
inline void PlanFragment::set_allocated_assignment(::exec::DrillbitEndpoint* assignment) {
  ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArena();
  if (message_arena == nullptr) {
    delete reinterpret_cast< ::PROTOBUF_NAMESPACE_ID::MessageLite*>(assignment_);
  }
  if (assignment) {
    ::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena =
      reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(assignment)->GetArena();
    if (message_arena != submessage_arena) {
      assignment = ::PROTOBUF_NAMESPACE_ID::internal::GetOwnedMessage(
          message_arena, assignment, submessage_arena);
    }
    _has_bits_[0] |= 0x00000008u;
  } else {
    _has_bits_[0] &= ~0x00000008u;
  }
  assignment_ = assignment;
  // @@protoc_insertion_point(field_set_allocated:exec.bit.control.PlanFragment.assignment)
}

// optional .exec.DrillbitEndpoint foreman = 11;
inline bool PlanFragment::_internal_has_foreman() const {
  bool value = (_has_bits_[0] & 0x00000010u) != 0;
  PROTOBUF_ASSUME(!value || foreman_ != nullptr);
  return value;
}
inline bool PlanFragment::has_foreman() const {
  return _internal_has_foreman();
}
inline const ::exec::DrillbitEndpoint& PlanFragment::_internal_foreman() const {
  const ::exec::DrillbitEndpoint* p = foreman_;
  return p != nullptr ? *p : reinterpret_cast<const ::exec::DrillbitEndpoint&>(
      ::exec::_DrillbitEndpoint_default_instance_);
}
inline const ::exec::DrillbitEndpoint& PlanFragment::foreman() const {
  // @@protoc_insertion_point(field_get:exec.bit.control.PlanFragment.foreman)
  return _internal_foreman();
}
inline void PlanFragment::unsafe_arena_set_allocated_foreman(
    ::exec::DrillbitEndpoint* foreman) {
  if (GetArena() == nullptr) {
    delete reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(foreman_);
  }
  foreman_ = foreman;
  if (foreman) {
    _has_bits_[0] |= 0x00000010u;
  } else {
    _has_bits_[0] &= ~0x00000010u;
  }
  // @@protoc_insertion_point(field_unsafe_arena_set_allocated:exec.bit.control.PlanFragment.foreman)
}
inline ::exec::DrillbitEndpoint* PlanFragment::release_foreman() {
  _has_bits_[0] &= ~0x00000010u;
  ::exec::DrillbitEndpoint* temp = foreman_;
  foreman_ = nullptr;
  if (GetArena() != nullptr) {
    temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp);
  }
  return temp;
}
inline ::exec::DrillbitEndpoint* PlanFragment::unsafe_arena_release_foreman() {
  // @@protoc_insertion_point(field_release:exec.bit.control.PlanFragment.foreman)
  _has_bits_[0] &= ~0x00000010u;
  ::exec::DrillbitEndpoint* temp = foreman_;
  foreman_ = nullptr;
  return temp;
}
inline ::exec::DrillbitEndpoint* PlanFragment::_internal_mutable_foreman() {
  _has_bits_[0] |= 0x00000010u;
  if (foreman_ == nullptr) {
    auto* p = CreateMaybeMessage<::exec::DrillbitEndpoint>(GetArena());
    foreman_ = p;
  }
  return foreman_;
}
inline ::exec::DrillbitEndpoint* PlanFragment::mutable_foreman() {
  // @@protoc_insertion_point(field_mutable:exec.bit.control.PlanFragment.foreman)
  return _internal_mutable_foreman();
}
inline void PlanFragment::set_allocated_foreman(::exec::DrillbitEndpoint* foreman) {
  ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArena();
  if (message_arena == nullptr) {
    delete reinterpret_cast< ::PROTOBUF_NAMESPACE_ID::MessageLite*>(foreman_);
  }
  if (foreman) {
    ::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena =
      reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(foreman)->GetArena();
    if (message_arena != submessage_arena) {
      foreman = ::PROTOBUF_NAMESPACE_ID::internal::GetOwnedMessage(
          message_arena, foreman, submessage_arena);
    }
    _has_bits_[0] |= 0x00000010u;
  } else {
    _has_bits_[0] &= ~0x00000010u;
  }
  foreman_ = foreman;
  // @@protoc_insertion_point(field_set_allocated:exec.bit.control.PlanFragment.foreman)
}

// optional int64 mem_initial = 12 [default = 20000000];
inline bool PlanFragment::_internal_has_mem_initial() const {
  bool value = (_has_bits_[0] & 0x00001000u) != 0;
  return value;
}
inline bool PlanFragment::has_mem_initial() const {
  return _internal_has_mem_initial();
}
inline void PlanFragment::clear_mem_initial() {
  mem_initial_ = PROTOBUF_LONGLONG(20000000);
  _has_bits_[0] &= ~0x00001000u;
}
inline ::PROTOBUF_NAMESPACE_ID::int64 PlanFragment::_internal_mem_initial() const {
  return mem_initial_;
}
inline ::PROTOBUF_NAMESPACE_ID::int64 PlanFragment::mem_initial() const {
  // @@protoc_insertion_point(field_get:exec.bit.control.PlanFragment.mem_initial)
  return _internal_mem_initial();
}
inline void PlanFragment::_internal_set_mem_initial(::PROTOBUF_NAMESPACE_ID::int64 value) {
  _has_bits_[0] |= 0x00001000u;
  mem_initial_ = value;
}
inline void PlanFragment::set_mem_initial(::PROTOBUF_NAMESPACE_ID::int64 value) {
  _internal_set_mem_initial(value);
  // @@protoc_insertion_point(field_set:exec.bit.control.PlanFragment.mem_initial)
}

// optional int64 mem_max = 13 [default = 2000000000];
inline bool PlanFragment::_internal_has_mem_max() const {
  bool value = (_has_bits_[0] & 0x00002000u) != 0;
  return value;
}
inline bool PlanFragment::has_mem_max() const {
  return _internal_has_mem_max();
}
inline void PlanFragment::clear_mem_max() {
  mem_max_ = PROTOBUF_LONGLONG(2000000000);
  _has_bits_[0] &= ~0x00002000u;
}
inline ::PROTOBUF_NAMESPACE_ID::int64 PlanFragment::_internal_mem_max() const {
  return mem_max_;
}
inline ::PROTOBUF_NAMESPACE_ID::int64 PlanFragment::mem_max() const {
  // @@protoc_insertion_point(field_get:exec.bit.control.PlanFragment.mem_max)
  return _internal_mem_max();
}
inline void PlanFragment::_internal_set_mem_max(::PROTOBUF_NAMESPACE_ID::int64 value) {
  _has_bits_[0] |= 0x00002000u;
  mem_max_ = value;
}
inline void PlanFragment::set_mem_max(::PROTOBUF_NAMESPACE_ID::int64 value) {
  _internal_set_mem_max(value);
  // @@protoc_insertion_point(field_set:exec.bit.control.PlanFragment.mem_max)
}

// optional .exec.shared.UserCredentials credentials = 14;
inline bool PlanFragment::_internal_has_credentials() const {
  bool value = (_has_bits_[0] & 0x00000020u) != 0;
  PROTOBUF_ASSUME(!value || credentials_ != nullptr);
  return value;
}
inline bool PlanFragment::has_credentials() const {
  return _internal_has_credentials();
}
inline const ::exec::shared::UserCredentials& PlanFragment::_internal_credentials() const {
  const ::exec::shared::UserCredentials* p = credentials_;
  return p != nullptr ? *p : reinterpret_cast<const ::exec::shared::UserCredentials&>(
      ::exec::shared::_UserCredentials_default_instance_);
}
inline const ::exec::shared::UserCredentials& PlanFragment::credentials() const {
  // @@protoc_insertion_point(field_get:exec.bit.control.PlanFragment.credentials)
  return _internal_credentials();
}
inline void PlanFragment::unsafe_arena_set_allocated_credentials(
    ::exec::shared::UserCredentials* credentials) {
  if (GetArena() == nullptr) {
    delete reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(credentials_);
  }
  credentials_ = credentials;
  if (credentials) {
    _has_bits_[0] |= 0x00000020u;
  } else {
    _has_bits_[0] &= ~0x00000020u;
  }
  // @@protoc_insertion_point(field_unsafe_arena_set_allocated:exec.bit.control.PlanFragment.credentials)
}
inline ::exec::shared::UserCredentials* PlanFragment::release_credentials() {
  _has_bits_[0] &= ~0x00000020u;
  ::exec::shared::UserCredentials* temp = credentials_;
  credentials_ = nullptr;
  if (GetArena() != nullptr) {
    temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp);
  }
  return temp;
}
inline ::exec::shared::UserCredentials* PlanFragment::unsafe_arena_release_credentials() {
  // @@protoc_insertion_point(field_release:exec.bit.control.PlanFragment.credentials)
  _has_bits_[0] &= ~0x00000020u;
  ::exec::shared::UserCredentials* temp = credentials_;
  credentials_ = nullptr;
  return temp;
}
inline ::exec::shared::UserCredentials* PlanFragment::_internal_mutable_credentials() {
  _has_bits_[0] |= 0x00000020u;
  if (credentials_ == nullptr) {
    auto* p = CreateMaybeMessage<::exec::shared::UserCredentials>(GetArena());
    credentials_ = p;
  }
  return credentials_;
}
inline ::exec::shared::UserCredentials* PlanFragment::mutable_credentials() {
  // @@protoc_insertion_point(field_mutable:exec.bit.control.PlanFragment.credentials)
  return _internal_mutable_credentials();
}
inline void PlanFragment::set_allocated_credentials(::exec::shared::UserCredentials* credentials) {
  ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArena();
  if (message_arena == nullptr) {
    delete reinterpret_cast< ::PROTOBUF_NAMESPACE_ID::MessageLite*>(credentials_);
  }
  if (credentials) {
    ::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena =
      reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(credentials)->GetArena();
    if (message_arena != submessage_arena) {
      credentials = ::PROTOBUF_NAMESPACE_ID::internal::GetOwnedMessage(
          message_arena, credentials, submessage_arena);
    }
    _has_bits_[0] |= 0x00000020u;
  } else {
    _has_bits_[0] &= ~0x00000020u;
  }
  credentials_ = credentials;
  // @@protoc_insertion_point(field_set_allocated:exec.bit.control.PlanFragment.credentials)
}

// optional string options_json = 15;
inline bool PlanFragment::_internal_has_options_json() const {
  bool value = (_has_bits_[0] & 0x00000002u) != 0;
  return value;
}
inline bool PlanFragment::has_options_json() const {
  return _internal_has_options_json();
}
inline void PlanFragment::clear_options_json() {
  options_json_.ClearToEmpty();
  _has_bits_[0] &= ~0x00000002u;
}
inline const std::string& PlanFragment::options_json() const {
  // @@protoc_insertion_point(field_get:exec.bit.control.PlanFragment.options_json)
  return _internal_options_json();
}
template <typename ArgT0, typename... ArgT>
PROTOBUF_ALWAYS_INLINE
inline void PlanFragment::set_options_json(ArgT0&& arg0, ArgT... args) {
 _has_bits_[0] |= 0x00000002u;
 options_json_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArena());
  // @@protoc_insertion_point(field_set:exec.bit.control.PlanFragment.options_json)
}
inline std::string* PlanFragment::mutable_options_json() {
  // @@protoc_insertion_point(field_mutable:exec.bit.control.PlanFragment.options_json)
  return _internal_mutable_options_json();
}
inline const std::string& PlanFragment::_internal_options_json() const {
  return options_json_.Get();
}
inline void PlanFragment::_internal_set_options_json(const std::string& value) {
  _has_bits_[0] |= 0x00000002u;
  options_json_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena());
}
inline std::string* PlanFragment::_internal_mutable_options_json() {
  _has_bits_[0] |= 0x00000002u;
  return options_json_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena());
}
inline std::string* PlanFragment::release_options_json() {
  // @@protoc_insertion_point(field_release:exec.bit.control.PlanFragment.options_json)
  if (!_internal_has_options_json()) {
    return nullptr;
  }
  _has_bits_[0] &= ~0x00000002u;
  return options_json_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena());
}
inline void PlanFragment::set_allocated_options_json(std::string* options_json) {
  if (options_json != nullptr) {
    _has_bits_[0] |= 0x00000002u;
  } else {
    _has_bits_[0] &= ~0x00000002u;
  }
  options_json_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), options_json,
      GetArena());
  // @@protoc_insertion_point(field_set_allocated:exec.bit.control.PlanFragment.options_json)
}

// optional .exec.bit.control.QueryContextInformation context = 16;
inline bool PlanFragment::_internal_has_context() const {
  bool value = (_has_bits_[0] & 0x00000040u) != 0;
  PROTOBUF_ASSUME(!value || context_ != nullptr);
  return value;
}
inline bool PlanFragment::has_context() const {
  return _internal_has_context();
}
inline void PlanFragment::clear_context() {
  if (context_ != nullptr) context_->Clear();
  _has_bits_[0] &= ~0x00000040u;
}
inline const ::exec::bit::control::QueryContextInformation& PlanFragment::_internal_context() const {
  const ::exec::bit::control::QueryContextInformation* p = context_;
  return p != nullptr ? *p : reinterpret_cast<const ::exec::bit::control::QueryContextInformation&>(
      ::exec::bit::control::_QueryContextInformation_default_instance_);
}
inline const ::exec::bit::control::QueryContextInformation& PlanFragment::context() const {
  // @@protoc_insertion_point(field_get:exec.bit.control.PlanFragment.context)
  return _internal_context();
}
inline void PlanFragment::unsafe_arena_set_allocated_context(
    ::exec::bit::control::QueryContextInformation* context) {
  if (GetArena() == nullptr) {
    delete reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(context_);
  }
  context_ = context;
  if (context) {
    _has_bits_[0] |= 0x00000040u;
  } else {
    _has_bits_[0] &= ~0x00000040u;
  }
  // @@protoc_insertion_point(field_unsafe_arena_set_allocated:exec.bit.control.PlanFragment.context)
}
inline ::exec::bit::control::QueryContextInformation* PlanFragment::release_context() {
  _has_bits_[0] &= ~0x00000040u;
  ::exec::bit::control::QueryContextInformation* temp = context_;
  context_ = nullptr;
  if (GetArena() != nullptr) {
    temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp);
  }
  return temp;
}
inline ::exec::bit::control::QueryContextInformation* PlanFragment::unsafe_arena_release_context() {
  // @@protoc_insertion_point(field_release:exec.bit.control.PlanFragment.context)
  _has_bits_[0] &= ~0x00000040u;
  ::exec::bit::control::QueryContextInformation* temp = context_;
  context_ = nullptr;
  return temp;
}
inline ::exec::bit::control::QueryContextInformation* PlanFragment::_internal_mutable_context() {
  _has_bits_[0] |= 0x00000040u;
  if (context_ == nullptr) {
    auto* p = CreateMaybeMessage<::exec::bit::control::QueryContextInformation>(GetArena());
    context_ = p;
  }
  return context_;
}
inline ::exec::bit::control::QueryContextInformation* PlanFragment::mutable_context() {
  // @@protoc_insertion_point(field_mutable:exec.bit.control.PlanFragment.context)
  return _internal_mutable_context();
}
inline void PlanFragment::set_allocated_context(::exec::bit::control::QueryContextInformation* context) {
  ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArena();
  if (message_arena == nullptr) {
    delete context_;
  }
  if (context) {
    ::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena =
      ::PROTOBUF_NAMESPACE_ID::Arena::GetArena(context);
    if (message_arena != submessage_arena) {
      context = ::PROTOBUF_NAMESPACE_ID::internal::GetOwnedMessage(
          message_arena, context, submessage_arena);
    }
    _has_bits_[0] |= 0x00000040u;
  } else {
    _has_bits_[0] &= ~0x00000040u;
  }
  context_ = context;
  // @@protoc_insertion_point(field_set_allocated:exec.bit.control.PlanFragment.context)
}

// repeated .exec.bit.control.Collector collector = 17;
inline int PlanFragment::_internal_collector_size() const {
  return collector_.size();
}
inline int PlanFragment::collector_size() const {
  return _internal_collector_size();
}
inline void PlanFragment::clear_collector() {
  collector_.Clear();
}
inline ::exec::bit::control::Collector* PlanFragment::mutable_collector(int index) {
  // @@protoc_insertion_point(field_mutable:exec.bit.control.PlanFragment.collector)
  return collector_.Mutable(index);
}
inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::exec::bit::control::Collector >*
PlanFragment::mutable_collector() {
  // @@protoc_insertion_point(field_mutable_list:exec.bit.control.PlanFragment.collector)
  return &collector_;
}
inline const ::exec::bit::control::Collector& PlanFragment::_internal_collector(int index) const {
  return collector_.Get(index);
}
inline const ::exec::bit::control::Collector& PlanFragment::collector(int index) const {
  // @@protoc_insertion_point(field_get:exec.bit.control.PlanFragment.collector)
  return _internal_collector(index);
}
inline ::exec::bit::control::Collector* PlanFragment::_internal_add_collector() {
  return collector_.Add();
}
inline ::exec::bit::control::Collector* PlanFragment::add_collector() {
  // @@protoc_insertion_point(field_add:exec.bit.control.PlanFragment.collector)
  return _internal_add_collector();
}
inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::exec::bit::control::Collector >&
PlanFragment::collector() const {
  // @@protoc_insertion_point(field_list:exec.bit.control.PlanFragment.collector)
  return collector_;
}

// -------------------------------------------------------------------

// Collector

// optional int32 opposite_major_fragment_id = 1;
inline bool Collector::_internal_has_opposite_major_fragment_id() const {
  bool value = (_has_bits_[0] & 0x00000001u) != 0;
  return value;
}
inline bool Collector::has_opposite_major_fragment_id() const {
  return _internal_has_opposite_major_fragment_id();
}
inline void Collector::clear_opposite_major_fragment_id() {
  opposite_major_fragment_id_ = 0;
  _has_bits_[0] &= ~0x00000001u;
}
inline ::PROTOBUF_NAMESPACE_ID::int32 Collector::_internal_opposite_major_fragment_id() const {
  return opposite_major_fragment_id_;
}
inline ::PROTOBUF_NAMESPACE_ID::int32 Collector::opposite_major_fragment_id() const {
  // @@protoc_insertion_point(field_get:exec.bit.control.Collector.opposite_major_fragment_id)
  return _internal_opposite_major_fragment_id();
}
inline void Collector::_internal_set_opposite_major_fragment_id(::PROTOBUF_NAMESPACE_ID::int32 value) {
  _has_bits_[0] |= 0x00000001u;
  opposite_major_fragment_id_ = value;
}
inline void Collector::set_opposite_major_fragment_id(::PROTOBUF_NAMESPACE_ID::int32 value) {
  _internal_set_opposite_major_fragment_id(value);
  // @@protoc_insertion_point(field_set:exec.bit.control.Collector.opposite_major_fragment_id)
}

// repeated int32 incoming_minor_fragment = 2 [packed = true];
inline int Collector::_internal_incoming_minor_fragment_size() const {
  return incoming_minor_fragment_.size();
}
inline int Collector::incoming_minor_fragment_size() const {
  return _internal_incoming_minor_fragment_size();
}
inline void Collector::clear_incoming_minor_fragment() {
  incoming_minor_fragment_.Clear();
}
inline ::PROTOBUF_NAMESPACE_ID::int32 Collector::_internal_incoming_minor_fragment(int index) const {
  return incoming_minor_fragment_.Get(index);
}
inline ::PROTOBUF_NAMESPACE_ID::int32 Collector::incoming_minor_fragment(int index) const {
  // @@protoc_insertion_point(field_get:exec.bit.control.Collector.incoming_minor_fragment)
  return _internal_incoming_minor_fragment(index);
}
inline void Collector::set_incoming_minor_fragment(int index, ::PROTOBUF_NAMESPACE_ID::int32 value) {
  incoming_minor_fragment_.Set(index, value);
  // @@protoc_insertion_point(field_set:exec.bit.control.Collector.incoming_minor_fragment)
}
inline void Collector::_internal_add_incoming_minor_fragment(::PROTOBUF_NAMESPACE_ID::int32 value) {
  incoming_minor_fragment_.Add(value);
}
inline void Collector::add_incoming_minor_fragment(::PROTOBUF_NAMESPACE_ID::int32 value) {
  _internal_add_incoming_minor_fragment(value);
  // @@protoc_insertion_point(field_add:exec.bit.control.Collector.incoming_minor_fragment)
}
inline const ::PROTOBUF_NAMESPACE_ID::RepeatedField< ::PROTOBUF_NAMESPACE_ID::int32 >&
Collector::_internal_incoming_minor_fragment() const {
  return incoming_minor_fragment_;
}
inline const ::PROTOBUF_NAMESPACE_ID::RepeatedField< ::PROTOBUF_NAMESPACE_ID::int32 >&
Collector::incoming_minor_fragment() const {
  // @@protoc_insertion_point(field_list:exec.bit.control.Collector.incoming_minor_fragment)
  return _internal_incoming_minor_fragment();
}
inline ::PROTOBUF_NAMESPACE_ID::RepeatedField< ::PROTOBUF_NAMESPACE_ID::int32 >*
Collector::_internal_mutable_incoming_minor_fragment() {
  return &incoming_minor_fragment_;
}
inline ::PROTOBUF_NAMESPACE_ID::RepeatedField< ::PROTOBUF_NAMESPACE_ID::int32 >*
Collector::mutable_incoming_minor_fragment() {
  // @@protoc_insertion_point(field_mutable_list:exec.bit.control.Collector.incoming_minor_fragment)
  return _internal_mutable_incoming_minor_fragment();
}

// optional bool supports_out_of_order = 3;
inline bool Collector::_internal_has_supports_out_of_order() const {
  bool value = (_has_bits_[0] & 0x00000002u) != 0;
  return value;
}
inline bool Collector::has_supports_out_of_order() const {
  return _internal_has_supports_out_of_order();
}
inline void Collector::clear_supports_out_of_order() {
  supports_out_of_order_ = false;
  _has_bits_[0] &= ~0x00000002u;
}
inline bool Collector::_internal_supports_out_of_order() const {
  return supports_out_of_order_;
}
inline bool Collector::supports_out_of_order() const {
  // @@protoc_insertion_point(field_get:exec.bit.control.Collector.supports_out_of_order)
  return _internal_supports_out_of_order();
}
inline void Collector::_internal_set_supports_out_of_order(bool value) {
  _has_bits_[0] |= 0x00000002u;
  supports_out_of_order_ = value;
}
inline void Collector::set_supports_out_of_order(bool value) {
  _internal_set_supports_out_of_order(value);
  // @@protoc_insertion_point(field_set:exec.bit.control.Collector.supports_out_of_order)
}

// optional bool is_spooling = 4;
inline bool Collector::_internal_has_is_spooling() const {
  bool value = (_has_bits_[0] & 0x00000004u) != 0;
  return value;
}
inline bool Collector::has_is_spooling() const {
  return _internal_has_is_spooling();
}
inline void Collector::clear_is_spooling() {
  is_spooling_ = false;
  _has_bits_[0] &= ~0x00000004u;
}
inline bool Collector::_internal_is_spooling() const {
  return is_spooling_;
}
inline bool Collector::is_spooling() const {
  // @@protoc_insertion_point(field_get:exec.bit.control.Collector.is_spooling)
  return _internal_is_spooling();
}
inline void Collector::_internal_set_is_spooling(bool value) {
  _has_bits_[0] |= 0x00000004u;
  is_spooling_ = value;
}
inline void Collector::set_is_spooling(bool value) {
  _internal_set_is_spooling(value);
  // @@protoc_insertion_point(field_set:exec.bit.control.Collector.is_spooling)
}

// optional bool enable_dynamic_fc = 5;
inline bool Collector::_internal_has_enable_dynamic_fc() const {
  bool value = (_has_bits_[0] & 0x00000008u) != 0;
  return value;
}
inline bool Collector::has_enable_dynamic_fc() const {
  return _internal_has_enable_dynamic_fc();
}
inline void Collector::clear_enable_dynamic_fc() {
  enable_dynamic_fc_ = false;
  _has_bits_[0] &= ~0x00000008u;
}
inline bool Collector::_internal_enable_dynamic_fc() const {
  return enable_dynamic_fc_;
}
inline bool Collector::enable_dynamic_fc() const {
  // @@protoc_insertion_point(field_get:exec.bit.control.Collector.enable_dynamic_fc)
  return _internal_enable_dynamic_fc();
}
inline void Collector::_internal_set_enable_dynamic_fc(bool value) {
  _has_bits_[0] |= 0x00000008u;
  enable_dynamic_fc_ = value;
}
inline void Collector::set_enable_dynamic_fc(bool value) {
  _internal_set_enable_dynamic_fc(value);
  // @@protoc_insertion_point(field_set:exec.bit.control.Collector.enable_dynamic_fc)
}

// -------------------------------------------------------------------

// QueryContextInformation

// optional int64 query_start_time = 1;
inline bool QueryContextInformation::_internal_has_query_start_time() const {
  bool value = (_has_bits_[0] & 0x00000004u) != 0;
  return value;
}
inline bool QueryContextInformation::has_query_start_time() const {
  return _internal_has_query_start_time();
}
inline void QueryContextInformation::clear_query_start_time() {
  query_start_time_ = PROTOBUF_LONGLONG(0);
  _has_bits_[0] &= ~0x00000004u;
}
inline ::PROTOBUF_NAMESPACE_ID::int64 QueryContextInformation::_internal_query_start_time() const {
  return query_start_time_;
}
inline ::PROTOBUF_NAMESPACE_ID::int64 QueryContextInformation::query_start_time() const {
  // @@protoc_insertion_point(field_get:exec.bit.control.QueryContextInformation.query_start_time)
  return _internal_query_start_time();
}
inline void QueryContextInformation::_internal_set_query_start_time(::PROTOBUF_NAMESPACE_ID::int64 value) {
  _has_bits_[0] |= 0x00000004u;
  query_start_time_ = value;
}
inline void QueryContextInformation::set_query_start_time(::PROTOBUF_NAMESPACE_ID::int64 value) {
  _internal_set_query_start_time(value);
  // @@protoc_insertion_point(field_set:exec.bit.control.QueryContextInformation.query_start_time)
}

// optional int32 time_zone = 2;
inline bool QueryContextInformation::_internal_has_time_zone() const {
  bool value = (_has_bits_[0] & 0x00000008u) != 0;
  return value;
}
inline bool QueryContextInformation::has_time_zone() const {
  return _internal_has_time_zone();
}
inline void QueryContextInformation::clear_time_zone() {
  time_zone_ = 0;
  _has_bits_[0] &= ~0x00000008u;
}
inline ::PROTOBUF_NAMESPACE_ID::int32 QueryContextInformation::_internal_time_zone() const {
  return time_zone_;
}
inline ::PROTOBUF_NAMESPACE_ID::int32 QueryContextInformation::time_zone() const {
  // @@protoc_insertion_point(field_get:exec.bit.control.QueryContextInformation.time_zone)
  return _internal_time_zone();
}
inline void QueryContextInformation::_internal_set_time_zone(::PROTOBUF_NAMESPACE_ID::int32 value) {
  _has_bits_[0] |= 0x00000008u;
  time_zone_ = value;
}
inline void QueryContextInformation::set_time_zone(::PROTOBUF_NAMESPACE_ID::int32 value) {
  _internal_set_time_zone(value);
  // @@protoc_insertion_point(field_set:exec.bit.control.QueryContextInformation.time_zone)
}

// optional string default_schema_name = 3;
inline bool QueryContextInformation::_internal_has_default_schema_name() const {
  bool value = (_has_bits_[0] & 0x00000001u) != 0;
  return value;
}
inline bool QueryContextInformation::has_default_schema_name() const {
  return _internal_has_default_schema_name();
}
inline void QueryContextInformation::clear_default_schema_name() {
  default_schema_name_.ClearToEmpty();
  _has_bits_[0] &= ~0x00000001u;
}
inline const std::string& QueryContextInformation::default_schema_name() const {
  // @@protoc_insertion_point(field_get:exec.bit.control.QueryContextInformation.default_schema_name)
  return _internal_default_schema_name();
}
template <typename ArgT0, typename... ArgT>
PROTOBUF_ALWAYS_INLINE
inline void QueryContextInformation::set_default_schema_name(ArgT0&& arg0, ArgT... args) {
 _has_bits_[0] |= 0x00000001u;
 default_schema_name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArena());
  // @@protoc_insertion_point(field_set:exec.bit.control.QueryContextInformation.default_schema_name)
}
inline std::string* QueryContextInformation::mutable_default_schema_name() {
  // @@protoc_insertion_point(field_mutable:exec.bit.control.QueryContextInformation.default_schema_name)
  return _internal_mutable_default_schema_name();
}
inline const std::string& QueryContextInformation::_internal_default_schema_name() const {
  return default_schema_name_.Get();
}
inline void QueryContextInformation::_internal_set_default_schema_name(const std::string& value) {
  _has_bits_[0] |= 0x00000001u;
  default_schema_name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena());
}
inline std::string* QueryContextInformation::_internal_mutable_default_schema_name() {
  _has_bits_[0] |= 0x00000001u;
  return default_schema_name_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena());
}
inline std::string* QueryContextInformation::release_default_schema_name() {
  // @@protoc_insertion_point(field_release:exec.bit.control.QueryContextInformation.default_schema_name)
  if (!_internal_has_default_schema_name()) {
    return nullptr;
  }
  _has_bits_[0] &= ~0x00000001u;
  return default_schema_name_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena());
}
inline void QueryContextInformation::set_allocated_default_schema_name(std::string* default_schema_name) {
  if (default_schema_name != nullptr) {
    _has_bits_[0] |= 0x00000001u;
  } else {
    _has_bits_[0] &= ~0x00000001u;
  }
  default_schema_name_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), default_schema_name,
      GetArena());
  // @@protoc_insertion_point(field_set_allocated:exec.bit.control.QueryContextInformation.default_schema_name)
}

// optional string session_id = 4;
inline bool QueryContextInformation::_internal_has_session_id() const {
  bool value = (_has_bits_[0] & 0x00000002u) != 0;
  return value;
}
inline bool QueryContextInformation::has_session_id() const {
  return _internal_has_session_id();
}
inline void QueryContextInformation::clear_session_id() {
  session_id_.ClearToEmpty();
  _has_bits_[0] &= ~0x00000002u;
}
inline const std::string& QueryContextInformation::session_id() const {
  // @@protoc_insertion_point(field_get:exec.bit.control.QueryContextInformation.session_id)
  return _internal_session_id();
}
template <typename ArgT0, typename... ArgT>
PROTOBUF_ALWAYS_INLINE
inline void QueryContextInformation::set_session_id(ArgT0&& arg0, ArgT... args) {
 _has_bits_[0] |= 0x00000002u;
 session_id_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArena());
  // @@protoc_insertion_point(field_set:exec.bit.control.QueryContextInformation.session_id)
}
inline std::string* QueryContextInformation::mutable_session_id() {
  // @@protoc_insertion_point(field_mutable:exec.bit.control.QueryContextInformation.session_id)
  return _internal_mutable_session_id();
}
inline const std::string& QueryContextInformation::_internal_session_id() const {
  return session_id_.Get();
}
inline void QueryContextInformation::_internal_set_session_id(const std::string& value) {
  _has_bits_[0] |= 0x00000002u;
  session_id_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena());
}
inline std::string* QueryContextInformation::_internal_mutable_session_id() {
  _has_bits_[0] |= 0x00000002u;
  return session_id_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena());
}
inline std::string* QueryContextInformation::release_session_id() {
  // @@protoc_insertion_point(field_release:exec.bit.control.QueryContextInformation.session_id)
  if (!_internal_has_session_id()) {
    return nullptr;
  }
  _has_bits_[0] &= ~0x00000002u;
  return session_id_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena());
}
inline void QueryContextInformation::set_allocated_session_id(std::string* session_id) {
  if (session_id != nullptr) {
    _has_bits_[0] |= 0x00000002u;
  } else {
    _has_bits_[0] &= ~0x00000002u;
  }
  session_id_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), session_id,
      GetArena());
  // @@protoc_insertion_point(field_set_allocated:exec.bit.control.QueryContextInformation.session_id)
}

// -------------------------------------------------------------------

// WorkQueueStatus

// optional .exec.DrillbitEndpoint endpoint = 1;
inline bool WorkQueueStatus::_internal_has_endpoint() const {
  bool value = (_has_bits_[0] & 0x00000001u) != 0;
  PROTOBUF_ASSUME(!value || endpoint_ != nullptr);
  return value;
}
inline bool WorkQueueStatus::has_endpoint() const {
  return _internal_has_endpoint();
}
inline const ::exec::DrillbitEndpoint& WorkQueueStatus::_internal_endpoint() const {
  const ::exec::DrillbitEndpoint* p = endpoint_;
  return p != nullptr ? *p : reinterpret_cast<const ::exec::DrillbitEndpoint&>(
      ::exec::_DrillbitEndpoint_default_instance_);
}
inline const ::exec::DrillbitEndpoint& WorkQueueStatus::endpoint() const {
  // @@protoc_insertion_point(field_get:exec.bit.control.WorkQueueStatus.endpoint)
  return _internal_endpoint();
}
inline void WorkQueueStatus::unsafe_arena_set_allocated_endpoint(
    ::exec::DrillbitEndpoint* endpoint) {
  if (GetArena() == nullptr) {
    delete reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(endpoint_);
  }
  endpoint_ = endpoint;
  if (endpoint) {
    _has_bits_[0] |= 0x00000001u;
  } else {
    _has_bits_[0] &= ~0x00000001u;
  }
  // @@protoc_insertion_point(field_unsafe_arena_set_allocated:exec.bit.control.WorkQueueStatus.endpoint)
}
inline ::exec::DrillbitEndpoint* WorkQueueStatus::release_endpoint() {
  _has_bits_[0] &= ~0x00000001u;
  ::exec::DrillbitEndpoint* temp = endpoint_;
  endpoint_ = nullptr;
  if (GetArena() != nullptr) {
    temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp);
  }
  return temp;
}
inline ::exec::DrillbitEndpoint* WorkQueueStatus::unsafe_arena_release_endpoint() {
  // @@protoc_insertion_point(field_release:exec.bit.control.WorkQueueStatus.endpoint)
  _has_bits_[0] &= ~0x00000001u;
  ::exec::DrillbitEndpoint* temp = endpoint_;
  endpoint_ = nullptr;
  return temp;
}
inline ::exec::DrillbitEndpoint* WorkQueueStatus::_internal_mutable_endpoint() {
  _has_bits_[0] |= 0x00000001u;
  if (endpoint_ == nullptr) {
    auto* p = CreateMaybeMessage<::exec::DrillbitEndpoint>(GetArena());
    endpoint_ = p;
  }
  return endpoint_;
}
inline ::exec::DrillbitEndpoint* WorkQueueStatus::mutable_endpoint() {
  // @@protoc_insertion_point(field_mutable:exec.bit.control.WorkQueueStatus.endpoint)
  return _internal_mutable_endpoint();
}
inline void WorkQueueStatus::set_allocated_endpoint(::exec::DrillbitEndpoint* endpoint) {
  ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArena();
  if (message_arena == nullptr) {
    delete reinterpret_cast< ::PROTOBUF_NAMESPACE_ID::MessageLite*>(endpoint_);
  }
  if (endpoint) {
    ::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena =
      reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(endpoint)->GetArena();
    if (message_arena != submessage_arena) {
      endpoint = ::PROTOBUF_NAMESPACE_ID::internal::GetOwnedMessage(
          message_arena, endpoint, submessage_arena);
    }
    _has_bits_[0] |= 0x00000001u;
  } else {
    _has_bits_[0] &= ~0x00000001u;
  }
  endpoint_ = endpoint;
  // @@protoc_insertion_point(field_set_allocated:exec.bit.control.WorkQueueStatus.endpoint)
}

// optional int32 queue_length = 2;
inline bool WorkQueueStatus::_internal_has_queue_length() const {
  bool value = (_has_bits_[0] & 0x00000004u) != 0;
  return value;
}
inline bool WorkQueueStatus::has_queue_length() const {
  return _internal_has_queue_length();
}
inline void WorkQueueStatus::clear_queue_length() {
  queue_length_ = 0;
  _has_bits_[0] &= ~0x00000004u;
}
inline ::PROTOBUF_NAMESPACE_ID::int32 WorkQueueStatus::_internal_queue_length() const {
  return queue_length_;
}
inline ::PROTOBUF_NAMESPACE_ID::int32 WorkQueueStatus::queue_length() const {
  // @@protoc_insertion_point(field_get:exec.bit.control.WorkQueueStatus.queue_length)
  return _internal_queue_length();
}
inline void WorkQueueStatus::_internal_set_queue_length(::PROTOBUF_NAMESPACE_ID::int32 value) {
  _has_bits_[0] |= 0x00000004u;
  queue_length_ = value;
}
inline void WorkQueueStatus::set_queue_length(::PROTOBUF_NAMESPACE_ID::int32 value) {
  _internal_set_queue_length(value);
  // @@protoc_insertion_point(field_set:exec.bit.control.WorkQueueStatus.queue_length)
}

// optional int64 report_time = 3;
inline bool WorkQueueStatus::_internal_has_report_time() const {
  bool value = (_has_bits_[0] & 0x00000002u) != 0;
  return value;
}
inline bool WorkQueueStatus::has_report_time() const {
  return _internal_has_report_time();
}
inline void WorkQueueStatus::clear_report_time() {
  report_time_ = PROTOBUF_LONGLONG(0);
  _has_bits_[0] &= ~0x00000002u;
}
inline ::PROTOBUF_NAMESPACE_ID::int64 WorkQueueStatus::_internal_report_time() const {
  return report_time_;
}
inline ::PROTOBUF_NAMESPACE_ID::int64 WorkQueueStatus::report_time() const {
  // @@protoc_insertion_point(field_get:exec.bit.control.WorkQueueStatus.report_time)
  return _internal_report_time();
}
inline void WorkQueueStatus::_internal_set_report_time(::PROTOBUF_NAMESPACE_ID::int64 value) {
  _has_bits_[0] |= 0x00000002u;
  report_time_ = value;
}
inline void WorkQueueStatus::set_report_time(::PROTOBUF_NAMESPACE_ID::int64 value) {
  _internal_set_report_time(value);
  // @@protoc_insertion_point(field_set:exec.bit.control.WorkQueueStatus.report_time)
}

// -------------------------------------------------------------------

// FinishedReceiver

// optional .exec.bit.FragmentHandle receiver = 1;
inline bool FinishedReceiver::_internal_has_receiver() const {
  bool value = (_has_bits_[0] & 0x00000001u) != 0;
  PROTOBUF_ASSUME(!value || receiver_ != nullptr);
  return value;
}
inline bool FinishedReceiver::has_receiver() const {
  return _internal_has_receiver();
}
inline const ::exec::bit::FragmentHandle& FinishedReceiver::_internal_receiver() const {
  const ::exec::bit::FragmentHandle* p = receiver_;
  return p != nullptr ? *p : reinterpret_cast<const ::exec::bit::FragmentHandle&>(
      ::exec::bit::_FragmentHandle_default_instance_);
}
inline const ::exec::bit::FragmentHandle& FinishedReceiver::receiver() const {
  // @@protoc_insertion_point(field_get:exec.bit.control.FinishedReceiver.receiver)
  return _internal_receiver();
}
inline void FinishedReceiver::unsafe_arena_set_allocated_receiver(
    ::exec::bit::FragmentHandle* receiver) {
  if (GetArena() == nullptr) {
    delete reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(receiver_);
  }
  receiver_ = receiver;
  if (receiver) {
    _has_bits_[0] |= 0x00000001u;
  } else {
    _has_bits_[0] &= ~0x00000001u;
  }
  // @@protoc_insertion_point(field_unsafe_arena_set_allocated:exec.bit.control.FinishedReceiver.receiver)
}
inline ::exec::bit::FragmentHandle* FinishedReceiver::release_receiver() {
  _has_bits_[0] &= ~0x00000001u;
  ::exec::bit::FragmentHandle* temp = receiver_;
  receiver_ = nullptr;
  if (GetArena() != nullptr) {
    temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp);
  }
  return temp;
}
inline ::exec::bit::FragmentHandle* FinishedReceiver::unsafe_arena_release_receiver() {
  // @@protoc_insertion_point(field_release:exec.bit.control.FinishedReceiver.receiver)
  _has_bits_[0] &= ~0x00000001u;
  ::exec::bit::FragmentHandle* temp = receiver_;
  receiver_ = nullptr;
  return temp;
}
inline ::exec::bit::FragmentHandle* FinishedReceiver::_internal_mutable_receiver() {
  _has_bits_[0] |= 0x00000001u;
  if (receiver_ == nullptr) {
    auto* p = CreateMaybeMessage<::exec::bit::FragmentHandle>(GetArena());
    receiver_ = p;
  }
  return receiver_;
}
inline ::exec::bit::FragmentHandle* FinishedReceiver::mutable_receiver() {
  // @@protoc_insertion_point(field_mutable:exec.bit.control.FinishedReceiver.receiver)
  return _internal_mutable_receiver();
}
inline void FinishedReceiver::set_allocated_receiver(::exec::bit::FragmentHandle* receiver) {
  ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArena();
  if (message_arena == nullptr) {
    delete reinterpret_cast< ::PROTOBUF_NAMESPACE_ID::MessageLite*>(receiver_);
  }
  if (receiver) {
    ::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena =
      reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(receiver)->GetArena();
    if (message_arena != submessage_arena) {
      receiver = ::PROTOBUF_NAMESPACE_ID::internal::GetOwnedMessage(
          message_arena, receiver, submessage_arena);
    }
    _has_bits_[0] |= 0x00000001u;
  } else {
    _has_bits_[0] &= ~0x00000001u;
  }
  receiver_ = receiver;
  // @@protoc_insertion_point(field_set_allocated:exec.bit.control.FinishedReceiver.receiver)
}

// optional .exec.bit.FragmentHandle sender = 2;
inline bool FinishedReceiver::_internal_has_sender() const {
  bool value = (_has_bits_[0] & 0x00000002u) != 0;
  PROTOBUF_ASSUME(!value || sender_ != nullptr);
  return value;
}
inline bool FinishedReceiver::has_sender() const {
  return _internal_has_sender();
}
inline const ::exec::bit::FragmentHandle& FinishedReceiver::_internal_sender() const {
  const ::exec::bit::FragmentHandle* p = sender_;
  return p != nullptr ? *p : reinterpret_cast<const ::exec::bit::FragmentHandle&>(
      ::exec::bit::_FragmentHandle_default_instance_);
}
inline const ::exec::bit::FragmentHandle& FinishedReceiver::sender() const {
  // @@protoc_insertion_point(field_get:exec.bit.control.FinishedReceiver.sender)
  return _internal_sender();
}
inline void FinishedReceiver::unsafe_arena_set_allocated_sender(
    ::exec::bit::FragmentHandle* sender) {
  if (GetArena() == nullptr) {
    delete reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(sender_);
  }
  sender_ = sender;
  if (sender) {
    _has_bits_[0] |= 0x00000002u;
  } else {
    _has_bits_[0] &= ~0x00000002u;
  }
  // @@protoc_insertion_point(field_unsafe_arena_set_allocated:exec.bit.control.FinishedReceiver.sender)
}
inline ::exec::bit::FragmentHandle* FinishedReceiver::release_sender() {
  _has_bits_[0] &= ~0x00000002u;
  ::exec::bit::FragmentHandle* temp = sender_;
  sender_ = nullptr;
  if (GetArena() != nullptr) {
    temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp);
  }
  return temp;
}
inline ::exec::bit::FragmentHandle* FinishedReceiver::unsafe_arena_release_sender() {
  // @@protoc_insertion_point(field_release:exec.bit.control.FinishedReceiver.sender)
  _has_bits_[0] &= ~0x00000002u;
  ::exec::bit::FragmentHandle* temp = sender_;
  sender_ = nullptr;
  return temp;
}
inline ::exec::bit::FragmentHandle* FinishedReceiver::_internal_mutable_sender() {
  _has_bits_[0] |= 0x00000002u;
  if (sender_ == nullptr) {
    auto* p = CreateMaybeMessage<::exec::bit::FragmentHandle>(GetArena());
    sender_ = p;
  }
  return sender_;
}
inline ::exec::bit::FragmentHandle* FinishedReceiver::mutable_sender() {
  // @@protoc_insertion_point(field_mutable:exec.bit.control.FinishedReceiver.sender)
  return _internal_mutable_sender();
}
inline void FinishedReceiver::set_allocated_sender(::exec::bit::FragmentHandle* sender) {
  ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArena();
  if (message_arena == nullptr) {
    delete reinterpret_cast< ::PROTOBUF_NAMESPACE_ID::MessageLite*>(sender_);
  }
  if (sender) {
    ::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena =
      reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(sender)->GetArena();
    if (message_arena != submessage_arena) {
      sender = ::PROTOBUF_NAMESPACE_ID::internal::GetOwnedMessage(
          message_arena, sender, submessage_arena);
    }
    _has_bits_[0] |= 0x00000002u;
  } else {
    _has_bits_[0] &= ~0x00000002u;
  }
  sender_ = sender;
  // @@protoc_insertion_point(field_set_allocated:exec.bit.control.FinishedReceiver.sender)
}

#ifdef __GNUC__
  #pragma GCC diagnostic pop
#endif  // __GNUC__
// -------------------------------------------------------------------

// -------------------------------------------------------------------

// -------------------------------------------------------------------

// -------------------------------------------------------------------

// -------------------------------------------------------------------

// -------------------------------------------------------------------

// -------------------------------------------------------------------

// -------------------------------------------------------------------

// -------------------------------------------------------------------


// @@protoc_insertion_point(namespace_scope)

}  // namespace control
}  // namespace bit
}  // namespace exec

PROTOBUF_NAMESPACE_OPEN

template <> struct is_proto_enum< ::exec::bit::control::RpcType> : ::std::true_type {};
template <>
inline const EnumDescriptor* GetEnumDescriptor< ::exec::bit::control::RpcType>() {
  return ::exec::bit::control::RpcType_descriptor();
}

PROTOBUF_NAMESPACE_CLOSE

// @@protoc_insertion_point(global_scope)

#include <google/protobuf/port_undef.inc>
#endif  // GOOGLE_PROTOBUF_INCLUDED_GOOGLE_PROTOBUF_INCLUDED_BitControl_2eproto
