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

#ifndef GOOGLE_PROTOBUF_INCLUDED_BitData_2eproto
#define GOOGLE_PROTOBUF_INCLUDED_BitData_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_BitData_2eproto
PROTOBUF_NAMESPACE_OPEN
namespace internal {
class AnyMetadata;
}  // namespace internal
PROTOBUF_NAMESPACE_CLOSE

// Internal implementation detail -- do not use these members.
struct TableStruct_BitData_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[5]
    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_BitData_2eproto;
namespace exec {
namespace bit {
namespace data {
class AckWithCredit;
struct AckWithCreditDefaultTypeInternal;
extern AckWithCreditDefaultTypeInternal _AckWithCredit_default_instance_;
class BitClientHandshake;
struct BitClientHandshakeDefaultTypeInternal;
extern BitClientHandshakeDefaultTypeInternal _BitClientHandshake_default_instance_;
class BitServerHandshake;
struct BitServerHandshakeDefaultTypeInternal;
extern BitServerHandshakeDefaultTypeInternal _BitServerHandshake_default_instance_;
class FragmentRecordBatch;
struct FragmentRecordBatchDefaultTypeInternal;
extern FragmentRecordBatchDefaultTypeInternal _FragmentRecordBatch_default_instance_;
class RuntimeFilterBDef;
struct RuntimeFilterBDefDefaultTypeInternal;
extern RuntimeFilterBDefDefaultTypeInternal _RuntimeFilterBDef_default_instance_;
}  // namespace data
}  // namespace bit
}  // namespace exec
PROTOBUF_NAMESPACE_OPEN
template<> ::exec::bit::data::AckWithCredit* Arena::CreateMaybeMessage<::exec::bit::data::AckWithCredit>(Arena*);
template<> ::exec::bit::data::BitClientHandshake* Arena::CreateMaybeMessage<::exec::bit::data::BitClientHandshake>(Arena*);
template<> ::exec::bit::data::BitServerHandshake* Arena::CreateMaybeMessage<::exec::bit::data::BitServerHandshake>(Arena*);
template<> ::exec::bit::data::FragmentRecordBatch* Arena::CreateMaybeMessage<::exec::bit::data::FragmentRecordBatch>(Arena*);
template<> ::exec::bit::data::RuntimeFilterBDef* Arena::CreateMaybeMessage<::exec::bit::data::RuntimeFilterBDef>(Arena*);
PROTOBUF_NAMESPACE_CLOSE
namespace exec {
namespace bit {
namespace data {

enum RpcType : int {
  HANDSHAKE = 0,
  ACK = 1,
  GOODBYE = 2,
  REQ_RECORD_BATCH = 3,
  SASL_MESSAGE = 4,
  REQ_RUNTIME_FILTER = 5,
  DATA_ACK_WITH_CREDIT = 6
};
bool RpcType_IsValid(int value);
constexpr RpcType RpcType_MIN = HANDSHAKE;
constexpr RpcType RpcType_MAX = DATA_ACK_WITH_CREDIT;
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 BitClientHandshake PROTOBUF_FINAL :
    public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:exec.bit.data.BitClientHandshake) */ {
 public:
  inline BitClientHandshake() : BitClientHandshake(nullptr) {}
  ~BitClientHandshake() override;
  explicit constexpr BitClientHandshake(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);

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

  inline BitClientHandshake& operator=(const BitClientHandshake& from) {
    CopyFrom(from);
    return *this;
  }
  inline BitClientHandshake& operator=(BitClientHandshake&& 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 BitClientHandshake& default_instance() {
    return *internal_default_instance();
  }
  static inline const BitClientHandshake* internal_default_instance() {
    return reinterpret_cast<const BitClientHandshake*>(
               &_BitClientHandshake_default_instance_);
  }
  static constexpr int kIndexInFileMessages =
    0;

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

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

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

  BitClientHandshake* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final {
    return CreateMaybeMessage<BitClientHandshake>(arena);
  }
  void CopyFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
  void MergeFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
  void CopyFrom(const BitClientHandshake& from);
  void MergeFrom(const BitClientHandshake& 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(BitClientHandshake* other);
  friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
  static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
    return "exec.bit.data.BitClientHandshake";
  }
  protected:
  explicit BitClientHandshake(::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 {
    kRpcVersionFieldNumber = 1,
    kChannelFieldNumber = 2,
  };
  // 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_DATA];
  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.data.BitClientHandshake)
 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::int32 rpc_version_;
  int channel_;
  friend struct ::TableStruct_BitData_2eproto;
};
// -------------------------------------------------------------------

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

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

  inline BitServerHandshake& operator=(const BitServerHandshake& from) {
    CopyFrom(from);
    return *this;
  }
  inline BitServerHandshake& operator=(BitServerHandshake&& 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 BitServerHandshake& default_instance() {
    return *internal_default_instance();
  }
  static inline const BitServerHandshake* internal_default_instance() {
    return reinterpret_cast<const BitServerHandshake*>(
               &_BitServerHandshake_default_instance_);
  }
  static constexpr int kIndexInFileMessages =
    1;

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

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

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

  BitServerHandshake* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final {
    return CreateMaybeMessage<BitServerHandshake>(arena);
  }
  void CopyFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
  void MergeFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
  void CopyFrom(const BitServerHandshake& from);
  void MergeFrom(const BitServerHandshake& 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(BitServerHandshake* other);
  friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
  static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
    return "exec.bit.data.BitServerHandshake";
  }
  protected:
  explicit BitServerHandshake(::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 = 2,
    kRpcVersionFieldNumber = 1,
  };
  // repeated string authenticationMechanisms = 2;
  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 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:

  // @@protoc_insertion_point(class_scope:exec.bit.data.BitServerHandshake)
 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_;
  ::PROTOBUF_NAMESPACE_ID::int32 rpc_version_;
  friend struct ::TableStruct_BitData_2eproto;
};
// -------------------------------------------------------------------

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

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

  inline FragmentRecordBatch& operator=(const FragmentRecordBatch& from) {
    CopyFrom(from);
    return *this;
  }
  inline FragmentRecordBatch& operator=(FragmentRecordBatch&& 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 FragmentRecordBatch& default_instance() {
    return *internal_default_instance();
  }
  static inline const FragmentRecordBatch* internal_default_instance() {
    return reinterpret_cast<const FragmentRecordBatch*>(
               &_FragmentRecordBatch_default_instance_);
  }
  static constexpr int kIndexInFileMessages =
    2;

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

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

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

  FragmentRecordBatch* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final {
    return CreateMaybeMessage<FragmentRecordBatch>(arena);
  }
  void CopyFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
  void MergeFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
  void CopyFrom(const FragmentRecordBatch& from);
  void MergeFrom(const FragmentRecordBatch& 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(FragmentRecordBatch* other);
  friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
  static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
    return "exec.bit.data.FragmentRecordBatch";
  }
  protected:
  explicit FragmentRecordBatch(::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 {
    kReceivingMinorFragmentIdFieldNumber = 3,
    kQueryIdFieldNumber = 1,
    kDefFieldNumber = 6,
    kReceivingMajorFragmentIdFieldNumber = 2,
    kSendingMajorFragmentIdFieldNumber = 4,
    kSendingMinorFragmentIdFieldNumber = 5,
    kIsLastBatchFieldNumber = 7,
  };
  // repeated int32 receiving_minor_fragment_id = 3;
  int receiving_minor_fragment_id_size() const;
  private:
  int _internal_receiving_minor_fragment_id_size() const;
  public:
  void clear_receiving_minor_fragment_id();
  private:
  ::PROTOBUF_NAMESPACE_ID::int32 _internal_receiving_minor_fragment_id(int index) const;
  const ::PROTOBUF_NAMESPACE_ID::RepeatedField< ::PROTOBUF_NAMESPACE_ID::int32 >&
      _internal_receiving_minor_fragment_id() const;
  void _internal_add_receiving_minor_fragment_id(::PROTOBUF_NAMESPACE_ID::int32 value);
  ::PROTOBUF_NAMESPACE_ID::RepeatedField< ::PROTOBUF_NAMESPACE_ID::int32 >*
      _internal_mutable_receiving_minor_fragment_id();
  public:
  ::PROTOBUF_NAMESPACE_ID::int32 receiving_minor_fragment_id(int index) const;
  void set_receiving_minor_fragment_id(int index, ::PROTOBUF_NAMESPACE_ID::int32 value);
  void add_receiving_minor_fragment_id(::PROTOBUF_NAMESPACE_ID::int32 value);
  const ::PROTOBUF_NAMESPACE_ID::RepeatedField< ::PROTOBUF_NAMESPACE_ID::int32 >&
      receiving_minor_fragment_id() const;
  ::PROTOBUF_NAMESPACE_ID::RepeatedField< ::PROTOBUF_NAMESPACE_ID::int32 >*
      mutable_receiving_minor_fragment_id();

  // optional .exec.shared.QueryId query_id = 1;
  bool has_query_id() const;
  private:
  bool _internal_has_query_id() const;
  public:
  void clear_query_id();
  const ::exec::shared::QueryId& query_id() const;
  ::exec::shared::QueryId* release_query_id();
  ::exec::shared::QueryId* mutable_query_id();
  void set_allocated_query_id(::exec::shared::QueryId* query_id);
  private:
  const ::exec::shared::QueryId& _internal_query_id() const;
  ::exec::shared::QueryId* _internal_mutable_query_id();
  public:
  void unsafe_arena_set_allocated_query_id(
      ::exec::shared::QueryId* query_id);
  ::exec::shared::QueryId* unsafe_arena_release_query_id();

  // optional .exec.shared.RecordBatchDef def = 6;
  bool has_def() const;
  private:
  bool _internal_has_def() const;
  public:
  void clear_def();
  const ::exec::shared::RecordBatchDef& def() const;
  ::exec::shared::RecordBatchDef* release_def();
  ::exec::shared::RecordBatchDef* mutable_def();
  void set_allocated_def(::exec::shared::RecordBatchDef* def);
  private:
  const ::exec::shared::RecordBatchDef& _internal_def() const;
  ::exec::shared::RecordBatchDef* _internal_mutable_def();
  public:
  void unsafe_arena_set_allocated_def(
      ::exec::shared::RecordBatchDef* def);
  ::exec::shared::RecordBatchDef* unsafe_arena_release_def();

  // optional int32 receiving_major_fragment_id = 2;
  bool has_receiving_major_fragment_id() const;
  private:
  bool _internal_has_receiving_major_fragment_id() const;
  public:
  void clear_receiving_major_fragment_id();
  ::PROTOBUF_NAMESPACE_ID::int32 receiving_major_fragment_id() const;
  void set_receiving_major_fragment_id(::PROTOBUF_NAMESPACE_ID::int32 value);
  private:
  ::PROTOBUF_NAMESPACE_ID::int32 _internal_receiving_major_fragment_id() const;
  void _internal_set_receiving_major_fragment_id(::PROTOBUF_NAMESPACE_ID::int32 value);
  public:

  // optional int32 sending_major_fragment_id = 4;
  bool has_sending_major_fragment_id() const;
  private:
  bool _internal_has_sending_major_fragment_id() const;
  public:
  void clear_sending_major_fragment_id();
  ::PROTOBUF_NAMESPACE_ID::int32 sending_major_fragment_id() const;
  void set_sending_major_fragment_id(::PROTOBUF_NAMESPACE_ID::int32 value);
  private:
  ::PROTOBUF_NAMESPACE_ID::int32 _internal_sending_major_fragment_id() const;
  void _internal_set_sending_major_fragment_id(::PROTOBUF_NAMESPACE_ID::int32 value);
  public:

  // optional int32 sending_minor_fragment_id = 5;
  bool has_sending_minor_fragment_id() const;
  private:
  bool _internal_has_sending_minor_fragment_id() const;
  public:
  void clear_sending_minor_fragment_id();
  ::PROTOBUF_NAMESPACE_ID::int32 sending_minor_fragment_id() const;
  void set_sending_minor_fragment_id(::PROTOBUF_NAMESPACE_ID::int32 value);
  private:
  ::PROTOBUF_NAMESPACE_ID::int32 _internal_sending_minor_fragment_id() const;
  void _internal_set_sending_minor_fragment_id(::PROTOBUF_NAMESPACE_ID::int32 value);
  public:

  // optional bool isLastBatch = 7;
  bool has_islastbatch() const;
  private:
  bool _internal_has_islastbatch() const;
  public:
  void clear_islastbatch();
  bool islastbatch() const;
  void set_islastbatch(bool value);
  private:
  bool _internal_islastbatch() const;
  void _internal_set_islastbatch(bool value);
  public:

  // @@protoc_insertion_point(class_scope:exec.bit.data.FragmentRecordBatch)
 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 > receiving_minor_fragment_id_;
  ::exec::shared::QueryId* query_id_;
  ::exec::shared::RecordBatchDef* def_;
  ::PROTOBUF_NAMESPACE_ID::int32 receiving_major_fragment_id_;
  ::PROTOBUF_NAMESPACE_ID::int32 sending_major_fragment_id_;
  ::PROTOBUF_NAMESPACE_ID::int32 sending_minor_fragment_id_;
  bool islastbatch_;
  friend struct ::TableStruct_BitData_2eproto;
};
// -------------------------------------------------------------------

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

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

  inline RuntimeFilterBDef& operator=(const RuntimeFilterBDef& from) {
    CopyFrom(from);
    return *this;
  }
  inline RuntimeFilterBDef& operator=(RuntimeFilterBDef&& 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 RuntimeFilterBDef& default_instance() {
    return *internal_default_instance();
  }
  static inline const RuntimeFilterBDef* internal_default_instance() {
    return reinterpret_cast<const RuntimeFilterBDef*>(
               &_RuntimeFilterBDef_default_instance_);
  }
  static constexpr int kIndexInFileMessages =
    3;

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

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

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

  RuntimeFilterBDef* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final {
    return CreateMaybeMessage<RuntimeFilterBDef>(arena);
  }
  void CopyFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
  void MergeFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
  void CopyFrom(const RuntimeFilterBDef& from);
  void MergeFrom(const RuntimeFilterBDef& 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(RuntimeFilterBDef* other);
  friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
  static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
    return "exec.bit.data.RuntimeFilterBDef";
  }
  protected:
  explicit RuntimeFilterBDef(::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 {
    kBloomFilterSizeInBytesFieldNumber = 5,
    kProbeFieldsFieldNumber = 6,
    kQueryIdFieldNumber = 1,
    kMajorFragmentIdFieldNumber = 2,
    kMinorFragmentIdFieldNumber = 3,
    kToForemanFieldNumber = 4,
    kHjOpIdFieldNumber = 7,
    kRfIdentifierFieldNumber = 8,
  };
  // repeated int32 bloom_filter_size_in_bytes = 5;
  int bloom_filter_size_in_bytes_size() const;
  private:
  int _internal_bloom_filter_size_in_bytes_size() const;
  public:
  void clear_bloom_filter_size_in_bytes();
  private:
  ::PROTOBUF_NAMESPACE_ID::int32 _internal_bloom_filter_size_in_bytes(int index) const;
  const ::PROTOBUF_NAMESPACE_ID::RepeatedField< ::PROTOBUF_NAMESPACE_ID::int32 >&
      _internal_bloom_filter_size_in_bytes() const;
  void _internal_add_bloom_filter_size_in_bytes(::PROTOBUF_NAMESPACE_ID::int32 value);
  ::PROTOBUF_NAMESPACE_ID::RepeatedField< ::PROTOBUF_NAMESPACE_ID::int32 >*
      _internal_mutable_bloom_filter_size_in_bytes();
  public:
  ::PROTOBUF_NAMESPACE_ID::int32 bloom_filter_size_in_bytes(int index) const;
  void set_bloom_filter_size_in_bytes(int index, ::PROTOBUF_NAMESPACE_ID::int32 value);
  void add_bloom_filter_size_in_bytes(::PROTOBUF_NAMESPACE_ID::int32 value);
  const ::PROTOBUF_NAMESPACE_ID::RepeatedField< ::PROTOBUF_NAMESPACE_ID::int32 >&
      bloom_filter_size_in_bytes() const;
  ::PROTOBUF_NAMESPACE_ID::RepeatedField< ::PROTOBUF_NAMESPACE_ID::int32 >*
      mutable_bloom_filter_size_in_bytes();

  // repeated string probe_fields = 6;
  int probe_fields_size() const;
  private:
  int _internal_probe_fields_size() const;
  public:
  void clear_probe_fields();
  const std::string& probe_fields(int index) const;
  std::string* mutable_probe_fields(int index);
  void set_probe_fields(int index, const std::string& value);
  void set_probe_fields(int index, std::string&& value);
  void set_probe_fields(int index, const char* value);
  void set_probe_fields(int index, const char* value, size_t size);
  std::string* add_probe_fields();
  void add_probe_fields(const std::string& value);
  void add_probe_fields(std::string&& value);
  void add_probe_fields(const char* value);
  void add_probe_fields(const char* value, size_t size);
  const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField<std::string>& probe_fields() const;
  ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField<std::string>* mutable_probe_fields();
  private:
  const std::string& _internal_probe_fields(int index) const;
  std::string* _internal_add_probe_fields();
  public:

  // optional .exec.shared.QueryId query_id = 1;
  bool has_query_id() const;
  private:
  bool _internal_has_query_id() const;
  public:
  void clear_query_id();
  const ::exec::shared::QueryId& query_id() const;
  ::exec::shared::QueryId* release_query_id();
  ::exec::shared::QueryId* mutable_query_id();
  void set_allocated_query_id(::exec::shared::QueryId* query_id);
  private:
  const ::exec::shared::QueryId& _internal_query_id() const;
  ::exec::shared::QueryId* _internal_mutable_query_id();
  public:
  void unsafe_arena_set_allocated_query_id(
      ::exec::shared::QueryId* query_id);
  ::exec::shared::QueryId* unsafe_arena_release_query_id();

  // optional int32 major_fragment_id = 2;
  bool has_major_fragment_id() const;
  private:
  bool _internal_has_major_fragment_id() const;
  public:
  void clear_major_fragment_id();
  ::PROTOBUF_NAMESPACE_ID::int32 major_fragment_id() const;
  void set_major_fragment_id(::PROTOBUF_NAMESPACE_ID::int32 value);
  private:
  ::PROTOBUF_NAMESPACE_ID::int32 _internal_major_fragment_id() const;
  void _internal_set_major_fragment_id(::PROTOBUF_NAMESPACE_ID::int32 value);
  public:

  // optional int32 minor_fragment_id = 3;
  bool has_minor_fragment_id() const;
  private:
  bool _internal_has_minor_fragment_id() const;
  public:
  void clear_minor_fragment_id();
  ::PROTOBUF_NAMESPACE_ID::int32 minor_fragment_id() const;
  void set_minor_fragment_id(::PROTOBUF_NAMESPACE_ID::int32 value);
  private:
  ::PROTOBUF_NAMESPACE_ID::int32 _internal_minor_fragment_id() const;
  void _internal_set_minor_fragment_id(::PROTOBUF_NAMESPACE_ID::int32 value);
  public:

  // optional bool to_foreman = 4;
  bool has_to_foreman() const;
  private:
  bool _internal_has_to_foreman() const;
  public:
  void clear_to_foreman();
  bool to_foreman() const;
  void set_to_foreman(bool value);
  private:
  bool _internal_to_foreman() const;
  void _internal_set_to_foreman(bool value);
  public:

  // optional int32 hj_op_id = 7;
  bool has_hj_op_id() const;
  private:
  bool _internal_has_hj_op_id() const;
  public:
  void clear_hj_op_id();
  ::PROTOBUF_NAMESPACE_ID::int32 hj_op_id() const;
  void set_hj_op_id(::PROTOBUF_NAMESPACE_ID::int32 value);
  private:
  ::PROTOBUF_NAMESPACE_ID::int32 _internal_hj_op_id() const;
  void _internal_set_hj_op_id(::PROTOBUF_NAMESPACE_ID::int32 value);
  public:

  // optional int64 rf_identifier = 8;
  bool has_rf_identifier() const;
  private:
  bool _internal_has_rf_identifier() const;
  public:
  void clear_rf_identifier();
  ::PROTOBUF_NAMESPACE_ID::int64 rf_identifier() const;
  void set_rf_identifier(::PROTOBUF_NAMESPACE_ID::int64 value);
  private:
  ::PROTOBUF_NAMESPACE_ID::int64 _internal_rf_identifier() const;
  void _internal_set_rf_identifier(::PROTOBUF_NAMESPACE_ID::int64 value);
  public:

  // @@protoc_insertion_point(class_scope:exec.bit.data.RuntimeFilterBDef)
 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 > bloom_filter_size_in_bytes_;
  ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField<std::string> probe_fields_;
  ::exec::shared::QueryId* query_id_;
  ::PROTOBUF_NAMESPACE_ID::int32 major_fragment_id_;
  ::PROTOBUF_NAMESPACE_ID::int32 minor_fragment_id_;
  bool to_foreman_;
  ::PROTOBUF_NAMESPACE_ID::int32 hj_op_id_;
  ::PROTOBUF_NAMESPACE_ID::int64 rf_identifier_;
  friend struct ::TableStruct_BitData_2eproto;
};
// -------------------------------------------------------------------

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

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

  inline AckWithCredit& operator=(const AckWithCredit& from) {
    CopyFrom(from);
    return *this;
  }
  inline AckWithCredit& operator=(AckWithCredit&& 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 AckWithCredit& default_instance() {
    return *internal_default_instance();
  }
  static inline const AckWithCredit* internal_default_instance() {
    return reinterpret_cast<const AckWithCredit*>(
               &_AckWithCredit_default_instance_);
  }
  static constexpr int kIndexInFileMessages =
    4;

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

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

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

  AckWithCredit* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final {
    return CreateMaybeMessage<AckWithCredit>(arena);
  }
  void CopyFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
  void MergeFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
  void CopyFrom(const AckWithCredit& from);
  void MergeFrom(const AckWithCredit& 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(AckWithCredit* other);
  friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
  static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
    return "exec.bit.data.AckWithCredit";
  }
  protected:
  explicit AckWithCredit(::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 {
    kAllowedCreditFieldNumber = 1,
  };
  // optional int32 allowed_credit = 1;
  bool has_allowed_credit() const;
  private:
  bool _internal_has_allowed_credit() const;
  public:
  void clear_allowed_credit();
  ::PROTOBUF_NAMESPACE_ID::int32 allowed_credit() const;
  void set_allowed_credit(::PROTOBUF_NAMESPACE_ID::int32 value);
  private:
  ::PROTOBUF_NAMESPACE_ID::int32 _internal_allowed_credit() const;
  void _internal_set_allowed_credit(::PROTOBUF_NAMESPACE_ID::int32 value);
  public:

  // @@protoc_insertion_point(class_scope:exec.bit.data.AckWithCredit)
 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::int32 allowed_credit_;
  friend struct ::TableStruct_BitData_2eproto;
};
// ===================================================================


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

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

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

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

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

// BitServerHandshake

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

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

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

// FragmentRecordBatch

// optional .exec.shared.QueryId query_id = 1;
inline bool FragmentRecordBatch::_internal_has_query_id() const {
  bool value = (_has_bits_[0] & 0x00000001u) != 0;
  PROTOBUF_ASSUME(!value || query_id_ != nullptr);
  return value;
}
inline bool FragmentRecordBatch::has_query_id() const {
  return _internal_has_query_id();
}
inline const ::exec::shared::QueryId& FragmentRecordBatch::_internal_query_id() const {
  const ::exec::shared::QueryId* p = query_id_;
  return p != nullptr ? *p : reinterpret_cast<const ::exec::shared::QueryId&>(
      ::exec::shared::_QueryId_default_instance_);
}
inline const ::exec::shared::QueryId& FragmentRecordBatch::query_id() const {
  // @@protoc_insertion_point(field_get:exec.bit.data.FragmentRecordBatch.query_id)
  return _internal_query_id();
}
inline void FragmentRecordBatch::unsafe_arena_set_allocated_query_id(
    ::exec::shared::QueryId* query_id) {
  if (GetArena() == nullptr) {
    delete reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(query_id_);
  }
  query_id_ = query_id;
  if (query_id) {
    _has_bits_[0] |= 0x00000001u;
  } else {
    _has_bits_[0] &= ~0x00000001u;
  }
  // @@protoc_insertion_point(field_unsafe_arena_set_allocated:exec.bit.data.FragmentRecordBatch.query_id)
}
inline ::exec::shared::QueryId* FragmentRecordBatch::release_query_id() {
  _has_bits_[0] &= ~0x00000001u;
  ::exec::shared::QueryId* temp = query_id_;
  query_id_ = nullptr;
  if (GetArena() != nullptr) {
    temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp);
  }
  return temp;
}
inline ::exec::shared::QueryId* FragmentRecordBatch::unsafe_arena_release_query_id() {
  // @@protoc_insertion_point(field_release:exec.bit.data.FragmentRecordBatch.query_id)
  _has_bits_[0] &= ~0x00000001u;
  ::exec::shared::QueryId* temp = query_id_;
  query_id_ = nullptr;
  return temp;
}
inline ::exec::shared::QueryId* FragmentRecordBatch::_internal_mutable_query_id() {
  _has_bits_[0] |= 0x00000001u;
  if (query_id_ == nullptr) {
    auto* p = CreateMaybeMessage<::exec::shared::QueryId>(GetArena());
    query_id_ = p;
  }
  return query_id_;
}
inline ::exec::shared::QueryId* FragmentRecordBatch::mutable_query_id() {
  // @@protoc_insertion_point(field_mutable:exec.bit.data.FragmentRecordBatch.query_id)
  return _internal_mutable_query_id();
}
inline void FragmentRecordBatch::set_allocated_query_id(::exec::shared::QueryId* query_id) {
  ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArena();
  if (message_arena == nullptr) {
    delete reinterpret_cast< ::PROTOBUF_NAMESPACE_ID::MessageLite*>(query_id_);
  }
  if (query_id) {
    ::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena =
      reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(query_id)->GetArena();
    if (message_arena != submessage_arena) {
      query_id = ::PROTOBUF_NAMESPACE_ID::internal::GetOwnedMessage(
          message_arena, query_id, submessage_arena);
    }
    _has_bits_[0] |= 0x00000001u;
  } else {
    _has_bits_[0] &= ~0x00000001u;
  }
  query_id_ = query_id;
  // @@protoc_insertion_point(field_set_allocated:exec.bit.data.FragmentRecordBatch.query_id)
}

// optional int32 receiving_major_fragment_id = 2;
inline bool FragmentRecordBatch::_internal_has_receiving_major_fragment_id() const {
  bool value = (_has_bits_[0] & 0x00000004u) != 0;
  return value;
}
inline bool FragmentRecordBatch::has_receiving_major_fragment_id() const {
  return _internal_has_receiving_major_fragment_id();
}
inline void FragmentRecordBatch::clear_receiving_major_fragment_id() {
  receiving_major_fragment_id_ = 0;
  _has_bits_[0] &= ~0x00000004u;
}
inline ::PROTOBUF_NAMESPACE_ID::int32 FragmentRecordBatch::_internal_receiving_major_fragment_id() const {
  return receiving_major_fragment_id_;
}
inline ::PROTOBUF_NAMESPACE_ID::int32 FragmentRecordBatch::receiving_major_fragment_id() const {
  // @@protoc_insertion_point(field_get:exec.bit.data.FragmentRecordBatch.receiving_major_fragment_id)
  return _internal_receiving_major_fragment_id();
}
inline void FragmentRecordBatch::_internal_set_receiving_major_fragment_id(::PROTOBUF_NAMESPACE_ID::int32 value) {
  _has_bits_[0] |= 0x00000004u;
  receiving_major_fragment_id_ = value;
}
inline void FragmentRecordBatch::set_receiving_major_fragment_id(::PROTOBUF_NAMESPACE_ID::int32 value) {
  _internal_set_receiving_major_fragment_id(value);
  // @@protoc_insertion_point(field_set:exec.bit.data.FragmentRecordBatch.receiving_major_fragment_id)
}

// repeated int32 receiving_minor_fragment_id = 3;
inline int FragmentRecordBatch::_internal_receiving_minor_fragment_id_size() const {
  return receiving_minor_fragment_id_.size();
}
inline int FragmentRecordBatch::receiving_minor_fragment_id_size() const {
  return _internal_receiving_minor_fragment_id_size();
}
inline void FragmentRecordBatch::clear_receiving_minor_fragment_id() {
  receiving_minor_fragment_id_.Clear();
}
inline ::PROTOBUF_NAMESPACE_ID::int32 FragmentRecordBatch::_internal_receiving_minor_fragment_id(int index) const {
  return receiving_minor_fragment_id_.Get(index);
}
inline ::PROTOBUF_NAMESPACE_ID::int32 FragmentRecordBatch::receiving_minor_fragment_id(int index) const {
  // @@protoc_insertion_point(field_get:exec.bit.data.FragmentRecordBatch.receiving_minor_fragment_id)
  return _internal_receiving_minor_fragment_id(index);
}
inline void FragmentRecordBatch::set_receiving_minor_fragment_id(int index, ::PROTOBUF_NAMESPACE_ID::int32 value) {
  receiving_minor_fragment_id_.Set(index, value);
  // @@protoc_insertion_point(field_set:exec.bit.data.FragmentRecordBatch.receiving_minor_fragment_id)
}
inline void FragmentRecordBatch::_internal_add_receiving_minor_fragment_id(::PROTOBUF_NAMESPACE_ID::int32 value) {
  receiving_minor_fragment_id_.Add(value);
}
inline void FragmentRecordBatch::add_receiving_minor_fragment_id(::PROTOBUF_NAMESPACE_ID::int32 value) {
  _internal_add_receiving_minor_fragment_id(value);
  // @@protoc_insertion_point(field_add:exec.bit.data.FragmentRecordBatch.receiving_minor_fragment_id)
}
inline const ::PROTOBUF_NAMESPACE_ID::RepeatedField< ::PROTOBUF_NAMESPACE_ID::int32 >&
FragmentRecordBatch::_internal_receiving_minor_fragment_id() const {
  return receiving_minor_fragment_id_;
}
inline const ::PROTOBUF_NAMESPACE_ID::RepeatedField< ::PROTOBUF_NAMESPACE_ID::int32 >&
FragmentRecordBatch::receiving_minor_fragment_id() const {
  // @@protoc_insertion_point(field_list:exec.bit.data.FragmentRecordBatch.receiving_minor_fragment_id)
  return _internal_receiving_minor_fragment_id();
}
inline ::PROTOBUF_NAMESPACE_ID::RepeatedField< ::PROTOBUF_NAMESPACE_ID::int32 >*
FragmentRecordBatch::_internal_mutable_receiving_minor_fragment_id() {
  return &receiving_minor_fragment_id_;
}
inline ::PROTOBUF_NAMESPACE_ID::RepeatedField< ::PROTOBUF_NAMESPACE_ID::int32 >*
FragmentRecordBatch::mutable_receiving_minor_fragment_id() {
  // @@protoc_insertion_point(field_mutable_list:exec.bit.data.FragmentRecordBatch.receiving_minor_fragment_id)
  return _internal_mutable_receiving_minor_fragment_id();
}

// optional int32 sending_major_fragment_id = 4;
inline bool FragmentRecordBatch::_internal_has_sending_major_fragment_id() const {
  bool value = (_has_bits_[0] & 0x00000008u) != 0;
  return value;
}
inline bool FragmentRecordBatch::has_sending_major_fragment_id() const {
  return _internal_has_sending_major_fragment_id();
}
inline void FragmentRecordBatch::clear_sending_major_fragment_id() {
  sending_major_fragment_id_ = 0;
  _has_bits_[0] &= ~0x00000008u;
}
inline ::PROTOBUF_NAMESPACE_ID::int32 FragmentRecordBatch::_internal_sending_major_fragment_id() const {
  return sending_major_fragment_id_;
}
inline ::PROTOBUF_NAMESPACE_ID::int32 FragmentRecordBatch::sending_major_fragment_id() const {
  // @@protoc_insertion_point(field_get:exec.bit.data.FragmentRecordBatch.sending_major_fragment_id)
  return _internal_sending_major_fragment_id();
}
inline void FragmentRecordBatch::_internal_set_sending_major_fragment_id(::PROTOBUF_NAMESPACE_ID::int32 value) {
  _has_bits_[0] |= 0x00000008u;
  sending_major_fragment_id_ = value;
}
inline void FragmentRecordBatch::set_sending_major_fragment_id(::PROTOBUF_NAMESPACE_ID::int32 value) {
  _internal_set_sending_major_fragment_id(value);
  // @@protoc_insertion_point(field_set:exec.bit.data.FragmentRecordBatch.sending_major_fragment_id)
}

// optional int32 sending_minor_fragment_id = 5;
inline bool FragmentRecordBatch::_internal_has_sending_minor_fragment_id() const {
  bool value = (_has_bits_[0] & 0x00000010u) != 0;
  return value;
}
inline bool FragmentRecordBatch::has_sending_minor_fragment_id() const {
  return _internal_has_sending_minor_fragment_id();
}
inline void FragmentRecordBatch::clear_sending_minor_fragment_id() {
  sending_minor_fragment_id_ = 0;
  _has_bits_[0] &= ~0x00000010u;
}
inline ::PROTOBUF_NAMESPACE_ID::int32 FragmentRecordBatch::_internal_sending_minor_fragment_id() const {
  return sending_minor_fragment_id_;
}
inline ::PROTOBUF_NAMESPACE_ID::int32 FragmentRecordBatch::sending_minor_fragment_id() const {
  // @@protoc_insertion_point(field_get:exec.bit.data.FragmentRecordBatch.sending_minor_fragment_id)
  return _internal_sending_minor_fragment_id();
}
inline void FragmentRecordBatch::_internal_set_sending_minor_fragment_id(::PROTOBUF_NAMESPACE_ID::int32 value) {
  _has_bits_[0] |= 0x00000010u;
  sending_minor_fragment_id_ = value;
}
inline void FragmentRecordBatch::set_sending_minor_fragment_id(::PROTOBUF_NAMESPACE_ID::int32 value) {
  _internal_set_sending_minor_fragment_id(value);
  // @@protoc_insertion_point(field_set:exec.bit.data.FragmentRecordBatch.sending_minor_fragment_id)
}

// optional .exec.shared.RecordBatchDef def = 6;
inline bool FragmentRecordBatch::_internal_has_def() const {
  bool value = (_has_bits_[0] & 0x00000002u) != 0;
  PROTOBUF_ASSUME(!value || def_ != nullptr);
  return value;
}
inline bool FragmentRecordBatch::has_def() const {
  return _internal_has_def();
}
inline const ::exec::shared::RecordBatchDef& FragmentRecordBatch::_internal_def() const {
  const ::exec::shared::RecordBatchDef* p = def_;
  return p != nullptr ? *p : reinterpret_cast<const ::exec::shared::RecordBatchDef&>(
      ::exec::shared::_RecordBatchDef_default_instance_);
}
inline const ::exec::shared::RecordBatchDef& FragmentRecordBatch::def() const {
  // @@protoc_insertion_point(field_get:exec.bit.data.FragmentRecordBatch.def)
  return _internal_def();
}
inline void FragmentRecordBatch::unsafe_arena_set_allocated_def(
    ::exec::shared::RecordBatchDef* def) {
  if (GetArena() == nullptr) {
    delete reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(def_);
  }
  def_ = def;
  if (def) {
    _has_bits_[0] |= 0x00000002u;
  } else {
    _has_bits_[0] &= ~0x00000002u;
  }
  // @@protoc_insertion_point(field_unsafe_arena_set_allocated:exec.bit.data.FragmentRecordBatch.def)
}
inline ::exec::shared::RecordBatchDef* FragmentRecordBatch::release_def() {
  _has_bits_[0] &= ~0x00000002u;
  ::exec::shared::RecordBatchDef* temp = def_;
  def_ = nullptr;
  if (GetArena() != nullptr) {
    temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp);
  }
  return temp;
}
inline ::exec::shared::RecordBatchDef* FragmentRecordBatch::unsafe_arena_release_def() {
  // @@protoc_insertion_point(field_release:exec.bit.data.FragmentRecordBatch.def)
  _has_bits_[0] &= ~0x00000002u;
  ::exec::shared::RecordBatchDef* temp = def_;
  def_ = nullptr;
  return temp;
}
inline ::exec::shared::RecordBatchDef* FragmentRecordBatch::_internal_mutable_def() {
  _has_bits_[0] |= 0x00000002u;
  if (def_ == nullptr) {
    auto* p = CreateMaybeMessage<::exec::shared::RecordBatchDef>(GetArena());
    def_ = p;
  }
  return def_;
}
inline ::exec::shared::RecordBatchDef* FragmentRecordBatch::mutable_def() {
  // @@protoc_insertion_point(field_mutable:exec.bit.data.FragmentRecordBatch.def)
  return _internal_mutable_def();
}
inline void FragmentRecordBatch::set_allocated_def(::exec::shared::RecordBatchDef* def) {
  ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArena();
  if (message_arena == nullptr) {
    delete reinterpret_cast< ::PROTOBUF_NAMESPACE_ID::MessageLite*>(def_);
  }
  if (def) {
    ::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena =
      reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(def)->GetArena();
    if (message_arena != submessage_arena) {
      def = ::PROTOBUF_NAMESPACE_ID::internal::GetOwnedMessage(
          message_arena, def, submessage_arena);
    }
    _has_bits_[0] |= 0x00000002u;
  } else {
    _has_bits_[0] &= ~0x00000002u;
  }
  def_ = def;
  // @@protoc_insertion_point(field_set_allocated:exec.bit.data.FragmentRecordBatch.def)
}

// optional bool isLastBatch = 7;
inline bool FragmentRecordBatch::_internal_has_islastbatch() const {
  bool value = (_has_bits_[0] & 0x00000020u) != 0;
  return value;
}
inline bool FragmentRecordBatch::has_islastbatch() const {
  return _internal_has_islastbatch();
}
inline void FragmentRecordBatch::clear_islastbatch() {
  islastbatch_ = false;
  _has_bits_[0] &= ~0x00000020u;
}
inline bool FragmentRecordBatch::_internal_islastbatch() const {
  return islastbatch_;
}
inline bool FragmentRecordBatch::islastbatch() const {
  // @@protoc_insertion_point(field_get:exec.bit.data.FragmentRecordBatch.isLastBatch)
  return _internal_islastbatch();
}
inline void FragmentRecordBatch::_internal_set_islastbatch(bool value) {
  _has_bits_[0] |= 0x00000020u;
  islastbatch_ = value;
}
inline void FragmentRecordBatch::set_islastbatch(bool value) {
  _internal_set_islastbatch(value);
  // @@protoc_insertion_point(field_set:exec.bit.data.FragmentRecordBatch.isLastBatch)
}

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

// RuntimeFilterBDef

// optional .exec.shared.QueryId query_id = 1;
inline bool RuntimeFilterBDef::_internal_has_query_id() const {
  bool value = (_has_bits_[0] & 0x00000001u) != 0;
  PROTOBUF_ASSUME(!value || query_id_ != nullptr);
  return value;
}
inline bool RuntimeFilterBDef::has_query_id() const {
  return _internal_has_query_id();
}
inline const ::exec::shared::QueryId& RuntimeFilterBDef::_internal_query_id() const {
  const ::exec::shared::QueryId* p = query_id_;
  return p != nullptr ? *p : reinterpret_cast<const ::exec::shared::QueryId&>(
      ::exec::shared::_QueryId_default_instance_);
}
inline const ::exec::shared::QueryId& RuntimeFilterBDef::query_id() const {
  // @@protoc_insertion_point(field_get:exec.bit.data.RuntimeFilterBDef.query_id)
  return _internal_query_id();
}
inline void RuntimeFilterBDef::unsafe_arena_set_allocated_query_id(
    ::exec::shared::QueryId* query_id) {
  if (GetArena() == nullptr) {
    delete reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(query_id_);
  }
  query_id_ = query_id;
  if (query_id) {
    _has_bits_[0] |= 0x00000001u;
  } else {
    _has_bits_[0] &= ~0x00000001u;
  }
  // @@protoc_insertion_point(field_unsafe_arena_set_allocated:exec.bit.data.RuntimeFilterBDef.query_id)
}
inline ::exec::shared::QueryId* RuntimeFilterBDef::release_query_id() {
  _has_bits_[0] &= ~0x00000001u;
  ::exec::shared::QueryId* temp = query_id_;
  query_id_ = nullptr;
  if (GetArena() != nullptr) {
    temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp);
  }
  return temp;
}
inline ::exec::shared::QueryId* RuntimeFilterBDef::unsafe_arena_release_query_id() {
  // @@protoc_insertion_point(field_release:exec.bit.data.RuntimeFilterBDef.query_id)
  _has_bits_[0] &= ~0x00000001u;
  ::exec::shared::QueryId* temp = query_id_;
  query_id_ = nullptr;
  return temp;
}
inline ::exec::shared::QueryId* RuntimeFilterBDef::_internal_mutable_query_id() {
  _has_bits_[0] |= 0x00000001u;
  if (query_id_ == nullptr) {
    auto* p = CreateMaybeMessage<::exec::shared::QueryId>(GetArena());
    query_id_ = p;
  }
  return query_id_;
}
inline ::exec::shared::QueryId* RuntimeFilterBDef::mutable_query_id() {
  // @@protoc_insertion_point(field_mutable:exec.bit.data.RuntimeFilterBDef.query_id)
  return _internal_mutable_query_id();
}
inline void RuntimeFilterBDef::set_allocated_query_id(::exec::shared::QueryId* query_id) {
  ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArena();
  if (message_arena == nullptr) {
    delete reinterpret_cast< ::PROTOBUF_NAMESPACE_ID::MessageLite*>(query_id_);
  }
  if (query_id) {
    ::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena =
      reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(query_id)->GetArena();
    if (message_arena != submessage_arena) {
      query_id = ::PROTOBUF_NAMESPACE_ID::internal::GetOwnedMessage(
          message_arena, query_id, submessage_arena);
    }
    _has_bits_[0] |= 0x00000001u;
  } else {
    _has_bits_[0] &= ~0x00000001u;
  }
  query_id_ = query_id;
  // @@protoc_insertion_point(field_set_allocated:exec.bit.data.RuntimeFilterBDef.query_id)
}

// optional int32 major_fragment_id = 2;
inline bool RuntimeFilterBDef::_internal_has_major_fragment_id() const {
  bool value = (_has_bits_[0] & 0x00000002u) != 0;
  return value;
}
inline bool RuntimeFilterBDef::has_major_fragment_id() const {
  return _internal_has_major_fragment_id();
}
inline void RuntimeFilterBDef::clear_major_fragment_id() {
  major_fragment_id_ = 0;
  _has_bits_[0] &= ~0x00000002u;
}
inline ::PROTOBUF_NAMESPACE_ID::int32 RuntimeFilterBDef::_internal_major_fragment_id() const {
  return major_fragment_id_;
}
inline ::PROTOBUF_NAMESPACE_ID::int32 RuntimeFilterBDef::major_fragment_id() const {
  // @@protoc_insertion_point(field_get:exec.bit.data.RuntimeFilterBDef.major_fragment_id)
  return _internal_major_fragment_id();
}
inline void RuntimeFilterBDef::_internal_set_major_fragment_id(::PROTOBUF_NAMESPACE_ID::int32 value) {
  _has_bits_[0] |= 0x00000002u;
  major_fragment_id_ = value;
}
inline void RuntimeFilterBDef::set_major_fragment_id(::PROTOBUF_NAMESPACE_ID::int32 value) {
  _internal_set_major_fragment_id(value);
  // @@protoc_insertion_point(field_set:exec.bit.data.RuntimeFilterBDef.major_fragment_id)
}

// optional int32 minor_fragment_id = 3;
inline bool RuntimeFilterBDef::_internal_has_minor_fragment_id() const {
  bool value = (_has_bits_[0] & 0x00000004u) != 0;
  return value;
}
inline bool RuntimeFilterBDef::has_minor_fragment_id() const {
  return _internal_has_minor_fragment_id();
}
inline void RuntimeFilterBDef::clear_minor_fragment_id() {
  minor_fragment_id_ = 0;
  _has_bits_[0] &= ~0x00000004u;
}
inline ::PROTOBUF_NAMESPACE_ID::int32 RuntimeFilterBDef::_internal_minor_fragment_id() const {
  return minor_fragment_id_;
}
inline ::PROTOBUF_NAMESPACE_ID::int32 RuntimeFilterBDef::minor_fragment_id() const {
  // @@protoc_insertion_point(field_get:exec.bit.data.RuntimeFilterBDef.minor_fragment_id)
  return _internal_minor_fragment_id();
}
inline void RuntimeFilterBDef::_internal_set_minor_fragment_id(::PROTOBUF_NAMESPACE_ID::int32 value) {
  _has_bits_[0] |= 0x00000004u;
  minor_fragment_id_ = value;
}
inline void RuntimeFilterBDef::set_minor_fragment_id(::PROTOBUF_NAMESPACE_ID::int32 value) {
  _internal_set_minor_fragment_id(value);
  // @@protoc_insertion_point(field_set:exec.bit.data.RuntimeFilterBDef.minor_fragment_id)
}

// optional bool to_foreman = 4;
inline bool RuntimeFilterBDef::_internal_has_to_foreman() const {
  bool value = (_has_bits_[0] & 0x00000008u) != 0;
  return value;
}
inline bool RuntimeFilterBDef::has_to_foreman() const {
  return _internal_has_to_foreman();
}
inline void RuntimeFilterBDef::clear_to_foreman() {
  to_foreman_ = false;
  _has_bits_[0] &= ~0x00000008u;
}
inline bool RuntimeFilterBDef::_internal_to_foreman() const {
  return to_foreman_;
}
inline bool RuntimeFilterBDef::to_foreman() const {
  // @@protoc_insertion_point(field_get:exec.bit.data.RuntimeFilterBDef.to_foreman)
  return _internal_to_foreman();
}
inline void RuntimeFilterBDef::_internal_set_to_foreman(bool value) {
  _has_bits_[0] |= 0x00000008u;
  to_foreman_ = value;
}
inline void RuntimeFilterBDef::set_to_foreman(bool value) {
  _internal_set_to_foreman(value);
  // @@protoc_insertion_point(field_set:exec.bit.data.RuntimeFilterBDef.to_foreman)
}

// repeated int32 bloom_filter_size_in_bytes = 5;
inline int RuntimeFilterBDef::_internal_bloom_filter_size_in_bytes_size() const {
  return bloom_filter_size_in_bytes_.size();
}
inline int RuntimeFilterBDef::bloom_filter_size_in_bytes_size() const {
  return _internal_bloom_filter_size_in_bytes_size();
}
inline void RuntimeFilterBDef::clear_bloom_filter_size_in_bytes() {
  bloom_filter_size_in_bytes_.Clear();
}
inline ::PROTOBUF_NAMESPACE_ID::int32 RuntimeFilterBDef::_internal_bloom_filter_size_in_bytes(int index) const {
  return bloom_filter_size_in_bytes_.Get(index);
}
inline ::PROTOBUF_NAMESPACE_ID::int32 RuntimeFilterBDef::bloom_filter_size_in_bytes(int index) const {
  // @@protoc_insertion_point(field_get:exec.bit.data.RuntimeFilterBDef.bloom_filter_size_in_bytes)
  return _internal_bloom_filter_size_in_bytes(index);
}
inline void RuntimeFilterBDef::set_bloom_filter_size_in_bytes(int index, ::PROTOBUF_NAMESPACE_ID::int32 value) {
  bloom_filter_size_in_bytes_.Set(index, value);
  // @@protoc_insertion_point(field_set:exec.bit.data.RuntimeFilterBDef.bloom_filter_size_in_bytes)
}
inline void RuntimeFilterBDef::_internal_add_bloom_filter_size_in_bytes(::PROTOBUF_NAMESPACE_ID::int32 value) {
  bloom_filter_size_in_bytes_.Add(value);
}
inline void RuntimeFilterBDef::add_bloom_filter_size_in_bytes(::PROTOBUF_NAMESPACE_ID::int32 value) {
  _internal_add_bloom_filter_size_in_bytes(value);
  // @@protoc_insertion_point(field_add:exec.bit.data.RuntimeFilterBDef.bloom_filter_size_in_bytes)
}
inline const ::PROTOBUF_NAMESPACE_ID::RepeatedField< ::PROTOBUF_NAMESPACE_ID::int32 >&
RuntimeFilterBDef::_internal_bloom_filter_size_in_bytes() const {
  return bloom_filter_size_in_bytes_;
}
inline const ::PROTOBUF_NAMESPACE_ID::RepeatedField< ::PROTOBUF_NAMESPACE_ID::int32 >&
RuntimeFilterBDef::bloom_filter_size_in_bytes() const {
  // @@protoc_insertion_point(field_list:exec.bit.data.RuntimeFilterBDef.bloom_filter_size_in_bytes)
  return _internal_bloom_filter_size_in_bytes();
}
inline ::PROTOBUF_NAMESPACE_ID::RepeatedField< ::PROTOBUF_NAMESPACE_ID::int32 >*
RuntimeFilterBDef::_internal_mutable_bloom_filter_size_in_bytes() {
  return &bloom_filter_size_in_bytes_;
}
inline ::PROTOBUF_NAMESPACE_ID::RepeatedField< ::PROTOBUF_NAMESPACE_ID::int32 >*
RuntimeFilterBDef::mutable_bloom_filter_size_in_bytes() {
  // @@protoc_insertion_point(field_mutable_list:exec.bit.data.RuntimeFilterBDef.bloom_filter_size_in_bytes)
  return _internal_mutable_bloom_filter_size_in_bytes();
}

// repeated string probe_fields = 6;
inline int RuntimeFilterBDef::_internal_probe_fields_size() const {
  return probe_fields_.size();
}
inline int RuntimeFilterBDef::probe_fields_size() const {
  return _internal_probe_fields_size();
}
inline void RuntimeFilterBDef::clear_probe_fields() {
  probe_fields_.Clear();
}
inline std::string* RuntimeFilterBDef::add_probe_fields() {
  // @@protoc_insertion_point(field_add_mutable:exec.bit.data.RuntimeFilterBDef.probe_fields)
  return _internal_add_probe_fields();
}
inline const std::string& RuntimeFilterBDef::_internal_probe_fields(int index) const {
  return probe_fields_.Get(index);
}
inline const std::string& RuntimeFilterBDef::probe_fields(int index) const {
  // @@protoc_insertion_point(field_get:exec.bit.data.RuntimeFilterBDef.probe_fields)
  return _internal_probe_fields(index);
}
inline std::string* RuntimeFilterBDef::mutable_probe_fields(int index) {
  // @@protoc_insertion_point(field_mutable:exec.bit.data.RuntimeFilterBDef.probe_fields)
  return probe_fields_.Mutable(index);
}
inline void RuntimeFilterBDef::set_probe_fields(int index, const std::string& value) {
  // @@protoc_insertion_point(field_set:exec.bit.data.RuntimeFilterBDef.probe_fields)
  probe_fields_.Mutable(index)->assign(value);
}
inline void RuntimeFilterBDef::set_probe_fields(int index, std::string&& value) {
  // @@protoc_insertion_point(field_set:exec.bit.data.RuntimeFilterBDef.probe_fields)
  probe_fields_.Mutable(index)->assign(std::move(value));
}
inline void RuntimeFilterBDef::set_probe_fields(int index, const char* value) {
  GOOGLE_DCHECK(value != nullptr);
  probe_fields_.Mutable(index)->assign(value);
  // @@protoc_insertion_point(field_set_char:exec.bit.data.RuntimeFilterBDef.probe_fields)
}
inline void RuntimeFilterBDef::set_probe_fields(int index, const char* value, size_t size) {
  probe_fields_.Mutable(index)->assign(
    reinterpret_cast<const char*>(value), size);
  // @@protoc_insertion_point(field_set_pointer:exec.bit.data.RuntimeFilterBDef.probe_fields)
}
inline std::string* RuntimeFilterBDef::_internal_add_probe_fields() {
  return probe_fields_.Add();
}
inline void RuntimeFilterBDef::add_probe_fields(const std::string& value) {
  probe_fields_.Add()->assign(value);
  // @@protoc_insertion_point(field_add:exec.bit.data.RuntimeFilterBDef.probe_fields)
}
inline void RuntimeFilterBDef::add_probe_fields(std::string&& value) {
  probe_fields_.Add(std::move(value));
  // @@protoc_insertion_point(field_add:exec.bit.data.RuntimeFilterBDef.probe_fields)
}
inline void RuntimeFilterBDef::add_probe_fields(const char* value) {
  GOOGLE_DCHECK(value != nullptr);
  probe_fields_.Add()->assign(value);
  // @@protoc_insertion_point(field_add_char:exec.bit.data.RuntimeFilterBDef.probe_fields)
}
inline void RuntimeFilterBDef::add_probe_fields(const char* value, size_t size) {
  probe_fields_.Add()->assign(reinterpret_cast<const char*>(value), size);
  // @@protoc_insertion_point(field_add_pointer:exec.bit.data.RuntimeFilterBDef.probe_fields)
}
inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField<std::string>&
RuntimeFilterBDef::probe_fields() const {
  // @@protoc_insertion_point(field_list:exec.bit.data.RuntimeFilterBDef.probe_fields)
  return probe_fields_;
}
inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField<std::string>*
RuntimeFilterBDef::mutable_probe_fields() {
  // @@protoc_insertion_point(field_mutable_list:exec.bit.data.RuntimeFilterBDef.probe_fields)
  return &probe_fields_;
}

// optional int32 hj_op_id = 7;
inline bool RuntimeFilterBDef::_internal_has_hj_op_id() const {
  bool value = (_has_bits_[0] & 0x00000010u) != 0;
  return value;
}
inline bool RuntimeFilterBDef::has_hj_op_id() const {
  return _internal_has_hj_op_id();
}
inline void RuntimeFilterBDef::clear_hj_op_id() {
  hj_op_id_ = 0;
  _has_bits_[0] &= ~0x00000010u;
}
inline ::PROTOBUF_NAMESPACE_ID::int32 RuntimeFilterBDef::_internal_hj_op_id() const {
  return hj_op_id_;
}
inline ::PROTOBUF_NAMESPACE_ID::int32 RuntimeFilterBDef::hj_op_id() const {
  // @@protoc_insertion_point(field_get:exec.bit.data.RuntimeFilterBDef.hj_op_id)
  return _internal_hj_op_id();
}
inline void RuntimeFilterBDef::_internal_set_hj_op_id(::PROTOBUF_NAMESPACE_ID::int32 value) {
  _has_bits_[0] |= 0x00000010u;
  hj_op_id_ = value;
}
inline void RuntimeFilterBDef::set_hj_op_id(::PROTOBUF_NAMESPACE_ID::int32 value) {
  _internal_set_hj_op_id(value);
  // @@protoc_insertion_point(field_set:exec.bit.data.RuntimeFilterBDef.hj_op_id)
}

// optional int64 rf_identifier = 8;
inline bool RuntimeFilterBDef::_internal_has_rf_identifier() const {
  bool value = (_has_bits_[0] & 0x00000020u) != 0;
  return value;
}
inline bool RuntimeFilterBDef::has_rf_identifier() const {
  return _internal_has_rf_identifier();
}
inline void RuntimeFilterBDef::clear_rf_identifier() {
  rf_identifier_ = PROTOBUF_LONGLONG(0);
  _has_bits_[0] &= ~0x00000020u;
}
inline ::PROTOBUF_NAMESPACE_ID::int64 RuntimeFilterBDef::_internal_rf_identifier() const {
  return rf_identifier_;
}
inline ::PROTOBUF_NAMESPACE_ID::int64 RuntimeFilterBDef::rf_identifier() const {
  // @@protoc_insertion_point(field_get:exec.bit.data.RuntimeFilterBDef.rf_identifier)
  return _internal_rf_identifier();
}
inline void RuntimeFilterBDef::_internal_set_rf_identifier(::PROTOBUF_NAMESPACE_ID::int64 value) {
  _has_bits_[0] |= 0x00000020u;
  rf_identifier_ = value;
}
inline void RuntimeFilterBDef::set_rf_identifier(::PROTOBUF_NAMESPACE_ID::int64 value) {
  _internal_set_rf_identifier(value);
  // @@protoc_insertion_point(field_set:exec.bit.data.RuntimeFilterBDef.rf_identifier)
}

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

// AckWithCredit

// optional int32 allowed_credit = 1;
inline bool AckWithCredit::_internal_has_allowed_credit() const {
  bool value = (_has_bits_[0] & 0x00000001u) != 0;
  return value;
}
inline bool AckWithCredit::has_allowed_credit() const {
  return _internal_has_allowed_credit();
}
inline void AckWithCredit::clear_allowed_credit() {
  allowed_credit_ = 0;
  _has_bits_[0] &= ~0x00000001u;
}
inline ::PROTOBUF_NAMESPACE_ID::int32 AckWithCredit::_internal_allowed_credit() const {
  return allowed_credit_;
}
inline ::PROTOBUF_NAMESPACE_ID::int32 AckWithCredit::allowed_credit() const {
  // @@protoc_insertion_point(field_get:exec.bit.data.AckWithCredit.allowed_credit)
  return _internal_allowed_credit();
}
inline void AckWithCredit::_internal_set_allowed_credit(::PROTOBUF_NAMESPACE_ID::int32 value) {
  _has_bits_[0] |= 0x00000001u;
  allowed_credit_ = value;
}
inline void AckWithCredit::set_allowed_credit(::PROTOBUF_NAMESPACE_ID::int32 value) {
  _internal_set_allowed_credit(value);
  // @@protoc_insertion_point(field_set:exec.bit.data.AckWithCredit.allowed_credit)
}

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

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

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

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


// @@protoc_insertion_point(namespace_scope)

}  // namespace data
}  // namespace bit
}  // namespace exec

PROTOBUF_NAMESPACE_OPEN

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

PROTOBUF_NAMESPACE_CLOSE

// @@protoc_insertion_point(global_scope)

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