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

#ifndef GOOGLE_PROTOBUF_INCLUDED_UserBitShared_2eproto
#define GOOGLE_PROTOBUF_INCLUDED_UserBitShared_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 "Types.pb.h"
#include "Coordination.pb.h"
#include "SchemaDef.pb.h"
// @@protoc_insertion_point(includes)
#include <google/protobuf/port_def.inc>
#define PROTOBUF_INTERNAL_EXPORT_UserBitShared_2eproto
PROTOBUF_NAMESPACE_OPEN
namespace internal {
class AnyMetadata;
}  // namespace internal
PROTOBUF_NAMESPACE_CLOSE

// Internal implementation detail -- do not use these members.
struct TableStruct_UserBitShared_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[22]
    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_UserBitShared_2eproto;
namespace exec {
namespace shared {
class DrillPBError;
struct DrillPBErrorDefaultTypeInternal;
extern DrillPBErrorDefaultTypeInternal _DrillPBError_default_instance_;
class ExceptionWrapper;
struct ExceptionWrapperDefaultTypeInternal;
extern ExceptionWrapperDefaultTypeInternal _ExceptionWrapper_default_instance_;
class Jar;
struct JarDefaultTypeInternal;
extern JarDefaultTypeInternal _Jar_default_instance_;
class MajorFragmentProfile;
struct MajorFragmentProfileDefaultTypeInternal;
extern MajorFragmentProfileDefaultTypeInternal _MajorFragmentProfile_default_instance_;
class MetricValue;
struct MetricValueDefaultTypeInternal;
extern MetricValueDefaultTypeInternal _MetricValue_default_instance_;
class MinorFragmentProfile;
struct MinorFragmentProfileDefaultTypeInternal;
extern MinorFragmentProfileDefaultTypeInternal _MinorFragmentProfile_default_instance_;
class NamePart;
struct NamePartDefaultTypeInternal;
extern NamePartDefaultTypeInternal _NamePart_default_instance_;
class NodeStatus;
struct NodeStatusDefaultTypeInternal;
extern NodeStatusDefaultTypeInternal _NodeStatus_default_instance_;
class OperatorProfile;
struct OperatorProfileDefaultTypeInternal;
extern OperatorProfileDefaultTypeInternal _OperatorProfile_default_instance_;
class ParsingError;
struct ParsingErrorDefaultTypeInternal;
extern ParsingErrorDefaultTypeInternal _ParsingError_default_instance_;
class QueryData;
struct QueryDataDefaultTypeInternal;
extern QueryDataDefaultTypeInternal _QueryData_default_instance_;
class QueryId;
struct QueryIdDefaultTypeInternal;
extern QueryIdDefaultTypeInternal _QueryId_default_instance_;
class QueryInfo;
struct QueryInfoDefaultTypeInternal;
extern QueryInfoDefaultTypeInternal _QueryInfo_default_instance_;
class QueryProfile;
struct QueryProfileDefaultTypeInternal;
extern QueryProfileDefaultTypeInternal _QueryProfile_default_instance_;
class QueryResult;
struct QueryResultDefaultTypeInternal;
extern QueryResultDefaultTypeInternal _QueryResult_default_instance_;
class RecordBatchDef;
struct RecordBatchDefDefaultTypeInternal;
extern RecordBatchDefDefaultTypeInternal _RecordBatchDef_default_instance_;
class Registry;
struct RegistryDefaultTypeInternal;
extern RegistryDefaultTypeInternal _Registry_default_instance_;
class SaslMessage;
struct SaslMessageDefaultTypeInternal;
extern SaslMessageDefaultTypeInternal _SaslMessage_default_instance_;
class SerializedField;
struct SerializedFieldDefaultTypeInternal;
extern SerializedFieldDefaultTypeInternal _SerializedField_default_instance_;
class StackTraceElementWrapper;
struct StackTraceElementWrapperDefaultTypeInternal;
extern StackTraceElementWrapperDefaultTypeInternal _StackTraceElementWrapper_default_instance_;
class StreamProfile;
struct StreamProfileDefaultTypeInternal;
extern StreamProfileDefaultTypeInternal _StreamProfile_default_instance_;
class UserCredentials;
struct UserCredentialsDefaultTypeInternal;
extern UserCredentialsDefaultTypeInternal _UserCredentials_default_instance_;
}  // namespace shared
}  // namespace exec
PROTOBUF_NAMESPACE_OPEN
template<> ::exec::shared::DrillPBError* Arena::CreateMaybeMessage<::exec::shared::DrillPBError>(Arena*);
template<> ::exec::shared::ExceptionWrapper* Arena::CreateMaybeMessage<::exec::shared::ExceptionWrapper>(Arena*);
template<> ::exec::shared::Jar* Arena::CreateMaybeMessage<::exec::shared::Jar>(Arena*);
template<> ::exec::shared::MajorFragmentProfile* Arena::CreateMaybeMessage<::exec::shared::MajorFragmentProfile>(Arena*);
template<> ::exec::shared::MetricValue* Arena::CreateMaybeMessage<::exec::shared::MetricValue>(Arena*);
template<> ::exec::shared::MinorFragmentProfile* Arena::CreateMaybeMessage<::exec::shared::MinorFragmentProfile>(Arena*);
template<> ::exec::shared::NamePart* Arena::CreateMaybeMessage<::exec::shared::NamePart>(Arena*);
template<> ::exec::shared::NodeStatus* Arena::CreateMaybeMessage<::exec::shared::NodeStatus>(Arena*);
template<> ::exec::shared::OperatorProfile* Arena::CreateMaybeMessage<::exec::shared::OperatorProfile>(Arena*);
template<> ::exec::shared::ParsingError* Arena::CreateMaybeMessage<::exec::shared::ParsingError>(Arena*);
template<> ::exec::shared::QueryData* Arena::CreateMaybeMessage<::exec::shared::QueryData>(Arena*);
template<> ::exec::shared::QueryId* Arena::CreateMaybeMessage<::exec::shared::QueryId>(Arena*);
template<> ::exec::shared::QueryInfo* Arena::CreateMaybeMessage<::exec::shared::QueryInfo>(Arena*);
template<> ::exec::shared::QueryProfile* Arena::CreateMaybeMessage<::exec::shared::QueryProfile>(Arena*);
template<> ::exec::shared::QueryResult* Arena::CreateMaybeMessage<::exec::shared::QueryResult>(Arena*);
template<> ::exec::shared::RecordBatchDef* Arena::CreateMaybeMessage<::exec::shared::RecordBatchDef>(Arena*);
template<> ::exec::shared::Registry* Arena::CreateMaybeMessage<::exec::shared::Registry>(Arena*);
template<> ::exec::shared::SaslMessage* Arena::CreateMaybeMessage<::exec::shared::SaslMessage>(Arena*);
template<> ::exec::shared::SerializedField* Arena::CreateMaybeMessage<::exec::shared::SerializedField>(Arena*);
template<> ::exec::shared::StackTraceElementWrapper* Arena::CreateMaybeMessage<::exec::shared::StackTraceElementWrapper>(Arena*);
template<> ::exec::shared::StreamProfile* Arena::CreateMaybeMessage<::exec::shared::StreamProfile>(Arena*);
template<> ::exec::shared::UserCredentials* Arena::CreateMaybeMessage<::exec::shared::UserCredentials>(Arena*);
PROTOBUF_NAMESPACE_CLOSE
namespace exec {
namespace shared {

enum DrillPBError_ErrorType : int {
  DrillPBError_ErrorType_CONNECTION = 0,
  DrillPBError_ErrorType_DATA_READ = 1,
  DrillPBError_ErrorType_DATA_WRITE = 2,
  DrillPBError_ErrorType_FUNCTION = 3,
  DrillPBError_ErrorType_PARSE = 4,
  DrillPBError_ErrorType_PERMISSION = 5,
  DrillPBError_ErrorType_PLAN = 6,
  DrillPBError_ErrorType_RESOURCE = 7,
  DrillPBError_ErrorType_SYSTEM = 8,
  DrillPBError_ErrorType_UNSUPPORTED_OPERATION = 9,
  DrillPBError_ErrorType_VALIDATION = 10,
  DrillPBError_ErrorType_EXECUTION_ERROR = 11,
  DrillPBError_ErrorType_INTERNAL_ERROR = 12,
  DrillPBError_ErrorType_UNSPECIFIED_ERROR = 13,
  DrillPBError_ErrorType_PLUGIN = 14
};
bool DrillPBError_ErrorType_IsValid(int value);
constexpr DrillPBError_ErrorType DrillPBError_ErrorType_ErrorType_MIN = DrillPBError_ErrorType_CONNECTION;
constexpr DrillPBError_ErrorType DrillPBError_ErrorType_ErrorType_MAX = DrillPBError_ErrorType_PLUGIN;
constexpr int DrillPBError_ErrorType_ErrorType_ARRAYSIZE = DrillPBError_ErrorType_ErrorType_MAX + 1;

const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor* DrillPBError_ErrorType_descriptor();
template<typename T>
inline const std::string& DrillPBError_ErrorType_Name(T enum_t_value) {
  static_assert(::std::is_same<T, DrillPBError_ErrorType>::value ||
    ::std::is_integral<T>::value,
    "Incorrect type passed to function DrillPBError_ErrorType_Name.");
  return ::PROTOBUF_NAMESPACE_ID::internal::NameOfEnum(
    DrillPBError_ErrorType_descriptor(), enum_t_value);
}
inline bool DrillPBError_ErrorType_Parse(
    ::PROTOBUF_NAMESPACE_ID::ConstStringParam name, DrillPBError_ErrorType* value) {
  return ::PROTOBUF_NAMESPACE_ID::internal::ParseNamedEnum<DrillPBError_ErrorType>(
    DrillPBError_ErrorType_descriptor(), name, value);
}
enum NamePart_Type : int {
  NamePart_Type_NAME = 0,
  NamePart_Type_ARRAY = 1
};
bool NamePart_Type_IsValid(int value);
constexpr NamePart_Type NamePart_Type_Type_MIN = NamePart_Type_NAME;
constexpr NamePart_Type NamePart_Type_Type_MAX = NamePart_Type_ARRAY;
constexpr int NamePart_Type_Type_ARRAYSIZE = NamePart_Type_Type_MAX + 1;

const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor* NamePart_Type_descriptor();
template<typename T>
inline const std::string& NamePart_Type_Name(T enum_t_value) {
  static_assert(::std::is_same<T, NamePart_Type>::value ||
    ::std::is_integral<T>::value,
    "Incorrect type passed to function NamePart_Type_Name.");
  return ::PROTOBUF_NAMESPACE_ID::internal::NameOfEnum(
    NamePart_Type_descriptor(), enum_t_value);
}
inline bool NamePart_Type_Parse(
    ::PROTOBUF_NAMESPACE_ID::ConstStringParam name, NamePart_Type* value) {
  return ::PROTOBUF_NAMESPACE_ID::internal::ParseNamedEnum<NamePart_Type>(
    NamePart_Type_descriptor(), name, value);
}
enum QueryResult_QueryState : int {
  QueryResult_QueryState_STARTING = 0,
  QueryResult_QueryState_RUNNING = 1,
  QueryResult_QueryState_COMPLETED = 2,
  QueryResult_QueryState_CANCELED = 3,
  QueryResult_QueryState_FAILED = 4,
  QueryResult_QueryState_CANCELLATION_REQUESTED = 5,
  QueryResult_QueryState_ENQUEUED = 6,
  QueryResult_QueryState_PREPARING = 7,
  QueryResult_QueryState_PLANNING = 8
};
bool QueryResult_QueryState_IsValid(int value);
constexpr QueryResult_QueryState QueryResult_QueryState_QueryState_MIN = QueryResult_QueryState_STARTING;
constexpr QueryResult_QueryState QueryResult_QueryState_QueryState_MAX = QueryResult_QueryState_PLANNING;
constexpr int QueryResult_QueryState_QueryState_ARRAYSIZE = QueryResult_QueryState_QueryState_MAX + 1;

const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor* QueryResult_QueryState_descriptor();
template<typename T>
inline const std::string& QueryResult_QueryState_Name(T enum_t_value) {
  static_assert(::std::is_same<T, QueryResult_QueryState>::value ||
    ::std::is_integral<T>::value,
    "Incorrect type passed to function QueryResult_QueryState_Name.");
  return ::PROTOBUF_NAMESPACE_ID::internal::NameOfEnum(
    QueryResult_QueryState_descriptor(), enum_t_value);
}
inline bool QueryResult_QueryState_Parse(
    ::PROTOBUF_NAMESPACE_ID::ConstStringParam name, QueryResult_QueryState* value) {
  return ::PROTOBUF_NAMESPACE_ID::internal::ParseNamedEnum<QueryResult_QueryState>(
    QueryResult_QueryState_descriptor(), name, value);
}
enum RpcChannel : int {
  BIT_CONTROL = 0,
  BIT_DATA = 1,
  USER = 2
};
bool RpcChannel_IsValid(int value);
constexpr RpcChannel RpcChannel_MIN = BIT_CONTROL;
constexpr RpcChannel RpcChannel_MAX = USER;
constexpr int RpcChannel_ARRAYSIZE = RpcChannel_MAX + 1;

const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor* RpcChannel_descriptor();
template<typename T>
inline const std::string& RpcChannel_Name(T enum_t_value) {
  static_assert(::std::is_same<T, RpcChannel>::value ||
    ::std::is_integral<T>::value,
    "Incorrect type passed to function RpcChannel_Name.");
  return ::PROTOBUF_NAMESPACE_ID::internal::NameOfEnum(
    RpcChannel_descriptor(), enum_t_value);
}
inline bool RpcChannel_Parse(
    ::PROTOBUF_NAMESPACE_ID::ConstStringParam name, RpcChannel* value) {
  return ::PROTOBUF_NAMESPACE_ID::internal::ParseNamedEnum<RpcChannel>(
    RpcChannel_descriptor(), name, value);
}
enum QueryType : int {
  SQL = 1,
  LOGICAL = 2,
  PHYSICAL = 3,
  EXECUTION = 4,
  PREPARED_STATEMENT = 5
};
bool QueryType_IsValid(int value);
constexpr QueryType QueryType_MIN = SQL;
constexpr QueryType QueryType_MAX = PREPARED_STATEMENT;
constexpr int QueryType_ARRAYSIZE = QueryType_MAX + 1;

const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor* QueryType_descriptor();
template<typename T>
inline const std::string& QueryType_Name(T enum_t_value) {
  static_assert(::std::is_same<T, QueryType>::value ||
    ::std::is_integral<T>::value,
    "Incorrect type passed to function QueryType_Name.");
  return ::PROTOBUF_NAMESPACE_ID::internal::NameOfEnum(
    QueryType_descriptor(), enum_t_value);
}
inline bool QueryType_Parse(
    ::PROTOBUF_NAMESPACE_ID::ConstStringParam name, QueryType* value) {
  return ::PROTOBUF_NAMESPACE_ID::internal::ParseNamedEnum<QueryType>(
    QueryType_descriptor(), name, value);
}
enum FragmentState : int {
  SENDING = 0,
  AWAITING_ALLOCATION = 1,
  RUNNING = 2,
  FINISHED = 3,
  CANCELLED = 4,
  FAILED = 5,
  CANCELLATION_REQUESTED = 6
};
bool FragmentState_IsValid(int value);
constexpr FragmentState FragmentState_MIN = SENDING;
constexpr FragmentState FragmentState_MAX = CANCELLATION_REQUESTED;
constexpr int FragmentState_ARRAYSIZE = FragmentState_MAX + 1;

const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor* FragmentState_descriptor();
template<typename T>
inline const std::string& FragmentState_Name(T enum_t_value) {
  static_assert(::std::is_same<T, FragmentState>::value ||
    ::std::is_integral<T>::value,
    "Incorrect type passed to function FragmentState_Name.");
  return ::PROTOBUF_NAMESPACE_ID::internal::NameOfEnum(
    FragmentState_descriptor(), enum_t_value);
}
inline bool FragmentState_Parse(
    ::PROTOBUF_NAMESPACE_ID::ConstStringParam name, FragmentState* value) {
  return ::PROTOBUF_NAMESPACE_ID::internal::ParseNamedEnum<FragmentState>(
    FragmentState_descriptor(), name, value);
}
enum SaslStatus : int {
  SASL_UNKNOWN = 0,
  SASL_START = 1,
  SASL_IN_PROGRESS = 2,
  SASL_SUCCESS = 3,
  SASL_FAILED = 4
};
bool SaslStatus_IsValid(int value);
constexpr SaslStatus SaslStatus_MIN = SASL_UNKNOWN;
constexpr SaslStatus SaslStatus_MAX = SASL_FAILED;
constexpr int SaslStatus_ARRAYSIZE = SaslStatus_MAX + 1;

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

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

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

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

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

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

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

  UserCredentials* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final {
    return CreateMaybeMessage<UserCredentials>(arena);
  }
  void CopyFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
  void MergeFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
  void CopyFrom(const UserCredentials& from);
  void MergeFrom(const UserCredentials& 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(UserCredentials* other);
  friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
  static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
    return "exec.shared.UserCredentials";
  }
  protected:
  explicit UserCredentials(::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 {
    kUserNameFieldNumber = 1,
  };
  // optional string user_name = 1;
  bool has_user_name() const;
  private:
  bool _internal_has_user_name() const;
  public:
  void clear_user_name();
  const std::string& user_name() const;
  template <typename ArgT0 = const std::string&, typename... ArgT>
  void set_user_name(ArgT0&& arg0, ArgT... args);
  std::string* mutable_user_name();
  std::string* release_user_name();
  void set_allocated_user_name(std::string* user_name);
  private:
  const std::string& _internal_user_name() const;
  void _internal_set_user_name(const std::string& value);
  std::string* _internal_mutable_user_name();
  public:

  // @@protoc_insertion_point(class_scope:exec.shared.UserCredentials)
 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 user_name_;
  friend struct ::TableStruct_UserBitShared_2eproto;
};
// -------------------------------------------------------------------

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

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

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

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

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

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

  QueryId* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final {
    return CreateMaybeMessage<QueryId>(arena);
  }
  void CopyFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
  void MergeFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
  void CopyFrom(const QueryId& from);
  void MergeFrom(const QueryId& 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(QueryId* other);
  friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
  static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
    return "exec.shared.QueryId";
  }
  protected:
  explicit QueryId(::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 {
    kPart1FieldNumber = 1,
    kPart2FieldNumber = 2,
  };
  // optional sfixed64 part1 = 1;
  bool has_part1() const;
  private:
  bool _internal_has_part1() const;
  public:
  void clear_part1();
  ::PROTOBUF_NAMESPACE_ID::int64 part1() const;
  void set_part1(::PROTOBUF_NAMESPACE_ID::int64 value);
  private:
  ::PROTOBUF_NAMESPACE_ID::int64 _internal_part1() const;
  void _internal_set_part1(::PROTOBUF_NAMESPACE_ID::int64 value);
  public:

  // optional sfixed64 part2 = 2;
  bool has_part2() const;
  private:
  bool _internal_has_part2() const;
  public:
  void clear_part2();
  ::PROTOBUF_NAMESPACE_ID::int64 part2() const;
  void set_part2(::PROTOBUF_NAMESPACE_ID::int64 value);
  private:
  ::PROTOBUF_NAMESPACE_ID::int64 _internal_part2() const;
  void _internal_set_part2(::PROTOBUF_NAMESPACE_ID::int64 value);
  public:

  // @@protoc_insertion_point(class_scope:exec.shared.QueryId)
 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::int64 part1_;
  ::PROTOBUF_NAMESPACE_ID::int64 part2_;
  friend struct ::TableStruct_UserBitShared_2eproto;
};
// -------------------------------------------------------------------

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

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

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

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

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

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

  DrillPBError* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final {
    return CreateMaybeMessage<DrillPBError>(arena);
  }
  void CopyFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
  void MergeFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
  void CopyFrom(const DrillPBError& from);
  void MergeFrom(const DrillPBError& 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(DrillPBError* other);
  friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
  static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
    return "exec.shared.DrillPBError";
  }
  protected:
  explicit DrillPBError(::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 ----------------------------------------------------

  typedef DrillPBError_ErrorType ErrorType;
  static constexpr ErrorType CONNECTION =
    DrillPBError_ErrorType_CONNECTION;
  static constexpr ErrorType DATA_READ =
    DrillPBError_ErrorType_DATA_READ;
  static constexpr ErrorType DATA_WRITE =
    DrillPBError_ErrorType_DATA_WRITE;
  static constexpr ErrorType FUNCTION =
    DrillPBError_ErrorType_FUNCTION;
  static constexpr ErrorType PARSE =
    DrillPBError_ErrorType_PARSE;
  static constexpr ErrorType PERMISSION =
    DrillPBError_ErrorType_PERMISSION;
  static constexpr ErrorType PLAN =
    DrillPBError_ErrorType_PLAN;
  static constexpr ErrorType RESOURCE =
    DrillPBError_ErrorType_RESOURCE;
  static constexpr ErrorType SYSTEM =
    DrillPBError_ErrorType_SYSTEM;
  static constexpr ErrorType UNSUPPORTED_OPERATION =
    DrillPBError_ErrorType_UNSUPPORTED_OPERATION;
  static constexpr ErrorType VALIDATION =
    DrillPBError_ErrorType_VALIDATION;
  static constexpr ErrorType EXECUTION_ERROR =
    DrillPBError_ErrorType_EXECUTION_ERROR;
  static constexpr ErrorType INTERNAL_ERROR =
    DrillPBError_ErrorType_INTERNAL_ERROR;
  static constexpr ErrorType UNSPECIFIED_ERROR =
    DrillPBError_ErrorType_UNSPECIFIED_ERROR;
  static constexpr ErrorType PLUGIN =
    DrillPBError_ErrorType_PLUGIN;
  static inline bool ErrorType_IsValid(int value) {
    return DrillPBError_ErrorType_IsValid(value);
  }
  static constexpr ErrorType ErrorType_MIN =
    DrillPBError_ErrorType_ErrorType_MIN;
  static constexpr ErrorType ErrorType_MAX =
    DrillPBError_ErrorType_ErrorType_MAX;
  static constexpr int ErrorType_ARRAYSIZE =
    DrillPBError_ErrorType_ErrorType_ARRAYSIZE;
  static inline const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor*
  ErrorType_descriptor() {
    return DrillPBError_ErrorType_descriptor();
  }
  template<typename T>
  static inline const std::string& ErrorType_Name(T enum_t_value) {
    static_assert(::std::is_same<T, ErrorType>::value ||
      ::std::is_integral<T>::value,
      "Incorrect type passed to function ErrorType_Name.");
    return DrillPBError_ErrorType_Name(enum_t_value);
  }
  static inline bool ErrorType_Parse(::PROTOBUF_NAMESPACE_ID::ConstStringParam name,
      ErrorType* value) {
    return DrillPBError_ErrorType_Parse(name, value);
  }

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

  enum : int {
    kParsingErrorFieldNumber = 6,
    kErrorIdFieldNumber = 1,
    kMessageFieldNumber = 4,
    kEndpointFieldNumber = 2,
    kExceptionFieldNumber = 5,
    kErrorTypeFieldNumber = 3,
  };
  // repeated .exec.shared.ParsingError parsing_error = 6;
  int parsing_error_size() const;
  private:
  int _internal_parsing_error_size() const;
  public:
  void clear_parsing_error();
  ::exec::shared::ParsingError* mutable_parsing_error(int index);
  ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::exec::shared::ParsingError >*
      mutable_parsing_error();
  private:
  const ::exec::shared::ParsingError& _internal_parsing_error(int index) const;
  ::exec::shared::ParsingError* _internal_add_parsing_error();
  public:
  const ::exec::shared::ParsingError& parsing_error(int index) const;
  ::exec::shared::ParsingError* add_parsing_error();
  const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::exec::shared::ParsingError >&
      parsing_error() const;

  // optional string error_id = 1;
  bool has_error_id() const;
  private:
  bool _internal_has_error_id() const;
  public:
  void clear_error_id();
  const std::string& error_id() const;
  template <typename ArgT0 = const std::string&, typename... ArgT>
  void set_error_id(ArgT0&& arg0, ArgT... args);
  std::string* mutable_error_id();
  std::string* release_error_id();
  void set_allocated_error_id(std::string* error_id);
  private:
  const std::string& _internal_error_id() const;
  void _internal_set_error_id(const std::string& value);
  std::string* _internal_mutable_error_id();
  public:

  // optional string message = 4;
  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 .exec.DrillbitEndpoint endpoint = 2;
  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 .exec.shared.ExceptionWrapper exception = 5;
  bool has_exception() const;
  private:
  bool _internal_has_exception() const;
  public:
  void clear_exception();
  const ::exec::shared::ExceptionWrapper& exception() const;
  ::exec::shared::ExceptionWrapper* release_exception();
  ::exec::shared::ExceptionWrapper* mutable_exception();
  void set_allocated_exception(::exec::shared::ExceptionWrapper* exception);
  private:
  const ::exec::shared::ExceptionWrapper& _internal_exception() const;
  ::exec::shared::ExceptionWrapper* _internal_mutable_exception();
  public:
  void unsafe_arena_set_allocated_exception(
      ::exec::shared::ExceptionWrapper* exception);
  ::exec::shared::ExceptionWrapper* unsafe_arena_release_exception();

  // optional .exec.shared.DrillPBError.ErrorType error_type = 3;
  bool has_error_type() const;
  private:
  bool _internal_has_error_type() const;
  public:
  void clear_error_type();
  ::exec::shared::DrillPBError_ErrorType error_type() const;
  void set_error_type(::exec::shared::DrillPBError_ErrorType value);
  private:
  ::exec::shared::DrillPBError_ErrorType _internal_error_type() const;
  void _internal_set_error_type(::exec::shared::DrillPBError_ErrorType value);
  public:

  // @@protoc_insertion_point(class_scope:exec.shared.DrillPBError)
 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::shared::ParsingError > parsing_error_;
  ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr error_id_;
  ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr message_;
  ::exec::DrillbitEndpoint* endpoint_;
  ::exec::shared::ExceptionWrapper* exception_;
  int error_type_;
  friend struct ::TableStruct_UserBitShared_2eproto;
};
// -------------------------------------------------------------------

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

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

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

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

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

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

  ExceptionWrapper* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final {
    return CreateMaybeMessage<ExceptionWrapper>(arena);
  }
  void CopyFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
  void MergeFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
  void CopyFrom(const ExceptionWrapper& from);
  void MergeFrom(const ExceptionWrapper& 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(ExceptionWrapper* other);
  friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
  static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
    return "exec.shared.ExceptionWrapper";
  }
  protected:
  explicit ExceptionWrapper(::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 {
    kStackTraceFieldNumber = 3,
    kExceptionClassFieldNumber = 1,
    kMessageFieldNumber = 2,
    kCauseFieldNumber = 4,
  };
  // repeated .exec.shared.StackTraceElementWrapper stack_trace = 3;
  int stack_trace_size() const;
  private:
  int _internal_stack_trace_size() const;
  public:
  void clear_stack_trace();
  ::exec::shared::StackTraceElementWrapper* mutable_stack_trace(int index);
  ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::exec::shared::StackTraceElementWrapper >*
      mutable_stack_trace();
  private:
  const ::exec::shared::StackTraceElementWrapper& _internal_stack_trace(int index) const;
  ::exec::shared::StackTraceElementWrapper* _internal_add_stack_trace();
  public:
  const ::exec::shared::StackTraceElementWrapper& stack_trace(int index) const;
  ::exec::shared::StackTraceElementWrapper* add_stack_trace();
  const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::exec::shared::StackTraceElementWrapper >&
      stack_trace() const;

  // optional string exception_class = 1;
  bool has_exception_class() const;
  private:
  bool _internal_has_exception_class() const;
  public:
  void clear_exception_class();
  const std::string& exception_class() const;
  template <typename ArgT0 = const std::string&, typename... ArgT>
  void set_exception_class(ArgT0&& arg0, ArgT... args);
  std::string* mutable_exception_class();
  std::string* release_exception_class();
  void set_allocated_exception_class(std::string* exception_class);
  private:
  const std::string& _internal_exception_class() const;
  void _internal_set_exception_class(const std::string& value);
  std::string* _internal_mutable_exception_class();
  public:

  // optional string 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 .exec.shared.ExceptionWrapper cause = 4;
  bool has_cause() const;
  private:
  bool _internal_has_cause() const;
  public:
  void clear_cause();
  const ::exec::shared::ExceptionWrapper& cause() const;
  ::exec::shared::ExceptionWrapper* release_cause();
  ::exec::shared::ExceptionWrapper* mutable_cause();
  void set_allocated_cause(::exec::shared::ExceptionWrapper* cause);
  private:
  const ::exec::shared::ExceptionWrapper& _internal_cause() const;
  ::exec::shared::ExceptionWrapper* _internal_mutable_cause();
  public:
  void unsafe_arena_set_allocated_cause(
      ::exec::shared::ExceptionWrapper* cause);
  ::exec::shared::ExceptionWrapper* unsafe_arena_release_cause();

  // @@protoc_insertion_point(class_scope:exec.shared.ExceptionWrapper)
 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::shared::StackTraceElementWrapper > stack_trace_;
  ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr exception_class_;
  ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr message_;
  ::exec::shared::ExceptionWrapper* cause_;
  friend struct ::TableStruct_UserBitShared_2eproto;
};
// -------------------------------------------------------------------

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

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

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

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

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

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

  StackTraceElementWrapper* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final {
    return CreateMaybeMessage<StackTraceElementWrapper>(arena);
  }
  void CopyFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
  void MergeFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
  void CopyFrom(const StackTraceElementWrapper& from);
  void MergeFrom(const StackTraceElementWrapper& 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(StackTraceElementWrapper* other);
  friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
  static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
    return "exec.shared.StackTraceElementWrapper";
  }
  protected:
  explicit StackTraceElementWrapper(::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 {
    kClassNameFieldNumber = 1,
    kFileNameFieldNumber = 2,
    kMethodNameFieldNumber = 4,
    kLineNumberFieldNumber = 3,
    kIsNativeMethodFieldNumber = 5,
  };
  // optional string class_name = 1;
  bool has_class_name() const;
  private:
  bool _internal_has_class_name() const;
  public:
  void clear_class_name();
  const std::string& class_name() const;
  template <typename ArgT0 = const std::string&, typename... ArgT>
  void set_class_name(ArgT0&& arg0, ArgT... args);
  std::string* mutable_class_name();
  std::string* release_class_name();
  void set_allocated_class_name(std::string* class_name);
  private:
  const std::string& _internal_class_name() const;
  void _internal_set_class_name(const std::string& value);
  std::string* _internal_mutable_class_name();
  public:

  // optional string file_name = 2;
  bool has_file_name() const;
  private:
  bool _internal_has_file_name() const;
  public:
  void clear_file_name();
  const std::string& file_name() const;
  template <typename ArgT0 = const std::string&, typename... ArgT>
  void set_file_name(ArgT0&& arg0, ArgT... args);
  std::string* mutable_file_name();
  std::string* release_file_name();
  void set_allocated_file_name(std::string* file_name);
  private:
  const std::string& _internal_file_name() const;
  void _internal_set_file_name(const std::string& value);
  std::string* _internal_mutable_file_name();
  public:

  // optional string method_name = 4;
  bool has_method_name() const;
  private:
  bool _internal_has_method_name() const;
  public:
  void clear_method_name();
  const std::string& method_name() const;
  template <typename ArgT0 = const std::string&, typename... ArgT>
  void set_method_name(ArgT0&& arg0, ArgT... args);
  std::string* mutable_method_name();
  std::string* release_method_name();
  void set_allocated_method_name(std::string* method_name);
  private:
  const std::string& _internal_method_name() const;
  void _internal_set_method_name(const std::string& value);
  std::string* _internal_mutable_method_name();
  public:

  // optional int32 line_number = 3;
  bool has_line_number() const;
  private:
  bool _internal_has_line_number() const;
  public:
  void clear_line_number();
  ::PROTOBUF_NAMESPACE_ID::int32 line_number() const;
  void set_line_number(::PROTOBUF_NAMESPACE_ID::int32 value);
  private:
  ::PROTOBUF_NAMESPACE_ID::int32 _internal_line_number() const;
  void _internal_set_line_number(::PROTOBUF_NAMESPACE_ID::int32 value);
  public:

  // optional bool is_native_method = 5;
  bool has_is_native_method() const;
  private:
  bool _internal_has_is_native_method() const;
  public:
  void clear_is_native_method();
  bool is_native_method() const;
  void set_is_native_method(bool value);
  private:
  bool _internal_is_native_method() const;
  void _internal_set_is_native_method(bool value);
  public:

  // @@protoc_insertion_point(class_scope:exec.shared.StackTraceElementWrapper)
 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 class_name_;
  ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr file_name_;
  ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr method_name_;
  ::PROTOBUF_NAMESPACE_ID::int32 line_number_;
  bool is_native_method_;
  friend struct ::TableStruct_UserBitShared_2eproto;
};
// -------------------------------------------------------------------

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

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

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

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

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

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

  ParsingError* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final {
    return CreateMaybeMessage<ParsingError>(arena);
  }
  void CopyFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
  void MergeFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
  void CopyFrom(const ParsingError& from);
  void MergeFrom(const ParsingError& 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(ParsingError* other);
  friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
  static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
    return "exec.shared.ParsingError";
  }
  protected:
  explicit ParsingError(::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 {
    kStartColumnFieldNumber = 2,
    kStartRowFieldNumber = 3,
    kEndColumnFieldNumber = 4,
    kEndRowFieldNumber = 5,
  };
  // optional int32 start_column = 2;
  bool has_start_column() const;
  private:
  bool _internal_has_start_column() const;
  public:
  void clear_start_column();
  ::PROTOBUF_NAMESPACE_ID::int32 start_column() const;
  void set_start_column(::PROTOBUF_NAMESPACE_ID::int32 value);
  private:
  ::PROTOBUF_NAMESPACE_ID::int32 _internal_start_column() const;
  void _internal_set_start_column(::PROTOBUF_NAMESPACE_ID::int32 value);
  public:

  // optional int32 start_row = 3;
  bool has_start_row() const;
  private:
  bool _internal_has_start_row() const;
  public:
  void clear_start_row();
  ::PROTOBUF_NAMESPACE_ID::int32 start_row() const;
  void set_start_row(::PROTOBUF_NAMESPACE_ID::int32 value);
  private:
  ::PROTOBUF_NAMESPACE_ID::int32 _internal_start_row() const;
  void _internal_set_start_row(::PROTOBUF_NAMESPACE_ID::int32 value);
  public:

  // optional int32 end_column = 4;
  bool has_end_column() const;
  private:
  bool _internal_has_end_column() const;
  public:
  void clear_end_column();
  ::PROTOBUF_NAMESPACE_ID::int32 end_column() const;
  void set_end_column(::PROTOBUF_NAMESPACE_ID::int32 value);
  private:
  ::PROTOBUF_NAMESPACE_ID::int32 _internal_end_column() const;
  void _internal_set_end_column(::PROTOBUF_NAMESPACE_ID::int32 value);
  public:

  // optional int32 end_row = 5;
  bool has_end_row() const;
  private:
  bool _internal_has_end_row() const;
  public:
  void clear_end_row();
  ::PROTOBUF_NAMESPACE_ID::int32 end_row() const;
  void set_end_row(::PROTOBUF_NAMESPACE_ID::int32 value);
  private:
  ::PROTOBUF_NAMESPACE_ID::int32 _internal_end_row() const;
  void _internal_set_end_row(::PROTOBUF_NAMESPACE_ID::int32 value);
  public:

  // @@protoc_insertion_point(class_scope:exec.shared.ParsingError)
 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 start_column_;
  ::PROTOBUF_NAMESPACE_ID::int32 start_row_;
  ::PROTOBUF_NAMESPACE_ID::int32 end_column_;
  ::PROTOBUF_NAMESPACE_ID::int32 end_row_;
  friend struct ::TableStruct_UserBitShared_2eproto;
};
// -------------------------------------------------------------------

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

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

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

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

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

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

  RecordBatchDef* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final {
    return CreateMaybeMessage<RecordBatchDef>(arena);
  }
  void CopyFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
  void MergeFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
  void CopyFrom(const RecordBatchDef& from);
  void MergeFrom(const RecordBatchDef& 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(RecordBatchDef* other);
  friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
  static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
    return "exec.shared.RecordBatchDef";
  }
  protected:
  explicit RecordBatchDef(::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 {
    kFieldFieldNumber = 2,
    kRecordCountFieldNumber = 1,
    kCarriesTwoByteSelectionVectorFieldNumber = 3,
    kAffectedRowsCountFieldNumber = 4,
  };
  // repeated .exec.shared.SerializedField field = 2;
  int field_size() const;
  private:
  int _internal_field_size() const;
  public:
  void clear_field();
  ::exec::shared::SerializedField* mutable_field(int index);
  ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::exec::shared::SerializedField >*
      mutable_field();
  private:
  const ::exec::shared::SerializedField& _internal_field(int index) const;
  ::exec::shared::SerializedField* _internal_add_field();
  public:
  const ::exec::shared::SerializedField& field(int index) const;
  ::exec::shared::SerializedField* add_field();
  const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::exec::shared::SerializedField >&
      field() const;

  // optional int32 record_count = 1;
  bool has_record_count() const;
  private:
  bool _internal_has_record_count() const;
  public:
  void clear_record_count();
  ::PROTOBUF_NAMESPACE_ID::int32 record_count() const;
  void set_record_count(::PROTOBUF_NAMESPACE_ID::int32 value);
  private:
  ::PROTOBUF_NAMESPACE_ID::int32 _internal_record_count() const;
  void _internal_set_record_count(::PROTOBUF_NAMESPACE_ID::int32 value);
  public:

  // optional bool carries_two_byte_selection_vector = 3;
  bool has_carries_two_byte_selection_vector() const;
  private:
  bool _internal_has_carries_two_byte_selection_vector() const;
  public:
  void clear_carries_two_byte_selection_vector();
  bool carries_two_byte_selection_vector() const;
  void set_carries_two_byte_selection_vector(bool value);
  private:
  bool _internal_carries_two_byte_selection_vector() const;
  void _internal_set_carries_two_byte_selection_vector(bool value);
  public:

  // optional int32 affected_rows_count = 4;
  bool has_affected_rows_count() const;
  private:
  bool _internal_has_affected_rows_count() const;
  public:
  void clear_affected_rows_count();
  ::PROTOBUF_NAMESPACE_ID::int32 affected_rows_count() const;
  void set_affected_rows_count(::PROTOBUF_NAMESPACE_ID::int32 value);
  private:
  ::PROTOBUF_NAMESPACE_ID::int32 _internal_affected_rows_count() const;
  void _internal_set_affected_rows_count(::PROTOBUF_NAMESPACE_ID::int32 value);
  public:

  // @@protoc_insertion_point(class_scope:exec.shared.RecordBatchDef)
 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::shared::SerializedField > field_;
  ::PROTOBUF_NAMESPACE_ID::int32 record_count_;
  bool carries_two_byte_selection_vector_;
  ::PROTOBUF_NAMESPACE_ID::int32 affected_rows_count_;
  friend struct ::TableStruct_UserBitShared_2eproto;
};
// -------------------------------------------------------------------

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

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

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

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

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

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

  NamePart* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final {
    return CreateMaybeMessage<NamePart>(arena);
  }
  void CopyFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
  void MergeFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
  void CopyFrom(const NamePart& from);
  void MergeFrom(const NamePart& 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(NamePart* other);
  friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
  static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
    return "exec.shared.NamePart";
  }
  protected:
  explicit NamePart(::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 ----------------------------------------------------

  typedef NamePart_Type Type;
  static constexpr Type NAME =
    NamePart_Type_NAME;
  static constexpr Type ARRAY =
    NamePart_Type_ARRAY;
  static inline bool Type_IsValid(int value) {
    return NamePart_Type_IsValid(value);
  }
  static constexpr Type Type_MIN =
    NamePart_Type_Type_MIN;
  static constexpr Type Type_MAX =
    NamePart_Type_Type_MAX;
  static constexpr int Type_ARRAYSIZE =
    NamePart_Type_Type_ARRAYSIZE;
  static inline const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor*
  Type_descriptor() {
    return NamePart_Type_descriptor();
  }
  template<typename T>
  static inline const std::string& Type_Name(T enum_t_value) {
    static_assert(::std::is_same<T, Type>::value ||
      ::std::is_integral<T>::value,
      "Incorrect type passed to function Type_Name.");
    return NamePart_Type_Name(enum_t_value);
  }
  static inline bool Type_Parse(::PROTOBUF_NAMESPACE_ID::ConstStringParam name,
      Type* value) {
    return NamePart_Type_Parse(name, value);
  }

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

  enum : int {
    kNameFieldNumber = 2,
    kChildFieldNumber = 3,
    kTypeFieldNumber = 1,
  };
  // optional string name = 2;
  bool has_name() const;
  private:
  bool _internal_has_name() const;
  public:
  void clear_name();
  const std::string& name() const;
  template <typename ArgT0 = const std::string&, typename... ArgT>
  void set_name(ArgT0&& arg0, ArgT... args);
  std::string* mutable_name();
  std::string* release_name();
  void set_allocated_name(std::string* name);
  private:
  const std::string& _internal_name() const;
  void _internal_set_name(const std::string& value);
  std::string* _internal_mutable_name();
  public:

  // optional .exec.shared.NamePart child = 3;
  bool has_child() const;
  private:
  bool _internal_has_child() const;
  public:
  void clear_child();
  const ::exec::shared::NamePart& child() const;
  ::exec::shared::NamePart* release_child();
  ::exec::shared::NamePart* mutable_child();
  void set_allocated_child(::exec::shared::NamePart* child);
  private:
  const ::exec::shared::NamePart& _internal_child() const;
  ::exec::shared::NamePart* _internal_mutable_child();
  public:
  void unsafe_arena_set_allocated_child(
      ::exec::shared::NamePart* child);
  ::exec::shared::NamePart* unsafe_arena_release_child();

  // optional .exec.shared.NamePart.Type type = 1;
  bool has_type() const;
  private:
  bool _internal_has_type() const;
  public:
  void clear_type();
  ::exec::shared::NamePart_Type type() const;
  void set_type(::exec::shared::NamePart_Type value);
  private:
  ::exec::shared::NamePart_Type _internal_type() const;
  void _internal_set_type(::exec::shared::NamePart_Type value);
  public:

  // @@protoc_insertion_point(class_scope:exec.shared.NamePart)
 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 name_;
  ::exec::shared::NamePart* child_;
  int type_;
  friend struct ::TableStruct_UserBitShared_2eproto;
};
// -------------------------------------------------------------------

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

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

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

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

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

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

  SerializedField* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final {
    return CreateMaybeMessage<SerializedField>(arena);
  }
  void CopyFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
  void MergeFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
  void CopyFrom(const SerializedField& from);
  void MergeFrom(const SerializedField& 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(SerializedField* other);
  friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
  static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
    return "exec.shared.SerializedField";
  }
  protected:
  explicit SerializedField(::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 {
    kChildFieldNumber = 3,
    kMajorTypeFieldNumber = 1,
    kNamePartFieldNumber = 2,
    kValueCountFieldNumber = 4,
    kVarByteLengthFieldNumber = 5,
    kBufferLengthFieldNumber = 7,
  };
  // repeated .exec.shared.SerializedField child = 3;
  int child_size() const;
  private:
  int _internal_child_size() const;
  public:
  void clear_child();
  ::exec::shared::SerializedField* mutable_child(int index);
  ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::exec::shared::SerializedField >*
      mutable_child();
  private:
  const ::exec::shared::SerializedField& _internal_child(int index) const;
  ::exec::shared::SerializedField* _internal_add_child();
  public:
  const ::exec::shared::SerializedField& child(int index) const;
  ::exec::shared::SerializedField* add_child();
  const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::exec::shared::SerializedField >&
      child() const;

  // optional .common.MajorType major_type = 1;
  bool has_major_type() const;
  private:
  bool _internal_has_major_type() const;
  public:
  void clear_major_type();
  const ::common::MajorType& major_type() const;
  ::common::MajorType* release_major_type();
  ::common::MajorType* mutable_major_type();
  void set_allocated_major_type(::common::MajorType* major_type);
  private:
  const ::common::MajorType& _internal_major_type() const;
  ::common::MajorType* _internal_mutable_major_type();
  public:
  void unsafe_arena_set_allocated_major_type(
      ::common::MajorType* major_type);
  ::common::MajorType* unsafe_arena_release_major_type();

  // optional .exec.shared.NamePart name_part = 2;
  bool has_name_part() const;
  private:
  bool _internal_has_name_part() const;
  public:
  void clear_name_part();
  const ::exec::shared::NamePart& name_part() const;
  ::exec::shared::NamePart* release_name_part();
  ::exec::shared::NamePart* mutable_name_part();
  void set_allocated_name_part(::exec::shared::NamePart* name_part);
  private:
  const ::exec::shared::NamePart& _internal_name_part() const;
  ::exec::shared::NamePart* _internal_mutable_name_part();
  public:
  void unsafe_arena_set_allocated_name_part(
      ::exec::shared::NamePart* name_part);
  ::exec::shared::NamePart* unsafe_arena_release_name_part();

  // optional int32 value_count = 4;
  bool has_value_count() const;
  private:
  bool _internal_has_value_count() const;
  public:
  void clear_value_count();
  ::PROTOBUF_NAMESPACE_ID::int32 value_count() const;
  void set_value_count(::PROTOBUF_NAMESPACE_ID::int32 value);
  private:
  ::PROTOBUF_NAMESPACE_ID::int32 _internal_value_count() const;
  void _internal_set_value_count(::PROTOBUF_NAMESPACE_ID::int32 value);
  public:

  // optional int32 var_byte_length = 5;
  bool has_var_byte_length() const;
  private:
  bool _internal_has_var_byte_length() const;
  public:
  void clear_var_byte_length();
  ::PROTOBUF_NAMESPACE_ID::int32 var_byte_length() const;
  void set_var_byte_length(::PROTOBUF_NAMESPACE_ID::int32 value);
  private:
  ::PROTOBUF_NAMESPACE_ID::int32 _internal_var_byte_length() const;
  void _internal_set_var_byte_length(::PROTOBUF_NAMESPACE_ID::int32 value);
  public:

  // optional int32 buffer_length = 7;
  bool has_buffer_length() const;
  private:
  bool _internal_has_buffer_length() const;
  public:
  void clear_buffer_length();
  ::PROTOBUF_NAMESPACE_ID::int32 buffer_length() const;
  void set_buffer_length(::PROTOBUF_NAMESPACE_ID::int32 value);
  private:
  ::PROTOBUF_NAMESPACE_ID::int32 _internal_buffer_length() const;
  void _internal_set_buffer_length(::PROTOBUF_NAMESPACE_ID::int32 value);
  public:

  // @@protoc_insertion_point(class_scope:exec.shared.SerializedField)
 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::shared::SerializedField > child_;
  ::common::MajorType* major_type_;
  ::exec::shared::NamePart* name_part_;
  ::PROTOBUF_NAMESPACE_ID::int32 value_count_;
  ::PROTOBUF_NAMESPACE_ID::int32 var_byte_length_;
  ::PROTOBUF_NAMESPACE_ID::int32 buffer_length_;
  friend struct ::TableStruct_UserBitShared_2eproto;
};
// -------------------------------------------------------------------

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

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

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

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

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

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

  NodeStatus* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final {
    return CreateMaybeMessage<NodeStatus>(arena);
  }
  void CopyFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
  void MergeFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
  void CopyFrom(const NodeStatus& from);
  void MergeFrom(const NodeStatus& 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(NodeStatus* other);
  friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
  static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
    return "exec.shared.NodeStatus";
  }
  protected:
  explicit NodeStatus(::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 {
    kMemoryFootprintFieldNumber = 2,
    kNodeIdFieldNumber = 1,
  };
  // optional int64 memory_footprint = 2;
  bool has_memory_footprint() const;
  private:
  bool _internal_has_memory_footprint() const;
  public:
  void clear_memory_footprint();
  ::PROTOBUF_NAMESPACE_ID::int64 memory_footprint() const;
  void set_memory_footprint(::PROTOBUF_NAMESPACE_ID::int64 value);
  private:
  ::PROTOBUF_NAMESPACE_ID::int64 _internal_memory_footprint() const;
  void _internal_set_memory_footprint(::PROTOBUF_NAMESPACE_ID::int64 value);
  public:

  // optional int32 node_id = 1;
  bool has_node_id() const;
  private:
  bool _internal_has_node_id() const;
  public:
  void clear_node_id();
  ::PROTOBUF_NAMESPACE_ID::int32 node_id() const;
  void set_node_id(::PROTOBUF_NAMESPACE_ID::int32 value);
  private:
  ::PROTOBUF_NAMESPACE_ID::int32 _internal_node_id() const;
  void _internal_set_node_id(::PROTOBUF_NAMESPACE_ID::int32 value);
  public:

  // @@protoc_insertion_point(class_scope:exec.shared.NodeStatus)
 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::int64 memory_footprint_;
  ::PROTOBUF_NAMESPACE_ID::int32 node_id_;
  friend struct ::TableStruct_UserBitShared_2eproto;
};
// -------------------------------------------------------------------

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

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

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

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

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

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

  QueryResult* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final {
    return CreateMaybeMessage<QueryResult>(arena);
  }
  void CopyFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
  void MergeFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
  void CopyFrom(const QueryResult& from);
  void MergeFrom(const QueryResult& 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(QueryResult* other);
  friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
  static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
    return "exec.shared.QueryResult";
  }
  protected:
  explicit QueryResult(::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 ----------------------------------------------------

  typedef QueryResult_QueryState QueryState;
  static constexpr QueryState STARTING =
    QueryResult_QueryState_STARTING;
  static constexpr QueryState RUNNING =
    QueryResult_QueryState_RUNNING;
  static constexpr QueryState COMPLETED =
    QueryResult_QueryState_COMPLETED;
  static constexpr QueryState CANCELED =
    QueryResult_QueryState_CANCELED;
  static constexpr QueryState FAILED =
    QueryResult_QueryState_FAILED;
  static constexpr QueryState CANCELLATION_REQUESTED =
    QueryResult_QueryState_CANCELLATION_REQUESTED;
  static constexpr QueryState ENQUEUED =
    QueryResult_QueryState_ENQUEUED;
  static constexpr QueryState PREPARING =
    QueryResult_QueryState_PREPARING;
  static constexpr QueryState PLANNING =
    QueryResult_QueryState_PLANNING;
  static inline bool QueryState_IsValid(int value) {
    return QueryResult_QueryState_IsValid(value);
  }
  static constexpr QueryState QueryState_MIN =
    QueryResult_QueryState_QueryState_MIN;
  static constexpr QueryState QueryState_MAX =
    QueryResult_QueryState_QueryState_MAX;
  static constexpr int QueryState_ARRAYSIZE =
    QueryResult_QueryState_QueryState_ARRAYSIZE;
  static inline const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor*
  QueryState_descriptor() {
    return QueryResult_QueryState_descriptor();
  }
  template<typename T>
  static inline const std::string& QueryState_Name(T enum_t_value) {
    static_assert(::std::is_same<T, QueryState>::value ||
      ::std::is_integral<T>::value,
      "Incorrect type passed to function QueryState_Name.");
    return QueryResult_QueryState_Name(enum_t_value);
  }
  static inline bool QueryState_Parse(::PROTOBUF_NAMESPACE_ID::ConstStringParam name,
      QueryState* value) {
    return QueryResult_QueryState_Parse(name, value);
  }

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

  enum : int {
    kErrorFieldNumber = 3,
    kQueryIdFieldNumber = 2,
    kQueryStateFieldNumber = 1,
  };
  // repeated .exec.shared.DrillPBError error = 3;
  int error_size() const;
  private:
  int _internal_error_size() const;
  public:
  void clear_error();
  ::exec::shared::DrillPBError* mutable_error(int index);
  ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::exec::shared::DrillPBError >*
      mutable_error();
  private:
  const ::exec::shared::DrillPBError& _internal_error(int index) const;
  ::exec::shared::DrillPBError* _internal_add_error();
  public:
  const ::exec::shared::DrillPBError& error(int index) const;
  ::exec::shared::DrillPBError* add_error();
  const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::exec::shared::DrillPBError >&
      error() const;

  // optional .exec.shared.QueryId query_id = 2;
  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.QueryResult.QueryState query_state = 1;
  bool has_query_state() const;
  private:
  bool _internal_has_query_state() const;
  public:
  void clear_query_state();
  ::exec::shared::QueryResult_QueryState query_state() const;
  void set_query_state(::exec::shared::QueryResult_QueryState value);
  private:
  ::exec::shared::QueryResult_QueryState _internal_query_state() const;
  void _internal_set_query_state(::exec::shared::QueryResult_QueryState value);
  public:

  // @@protoc_insertion_point(class_scope:exec.shared.QueryResult)
 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::shared::DrillPBError > error_;
  ::exec::shared::QueryId* query_id_;
  int query_state_;
  friend struct ::TableStruct_UserBitShared_2eproto;
};
// -------------------------------------------------------------------

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

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

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

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

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

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

  QueryData* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final {
    return CreateMaybeMessage<QueryData>(arena);
  }
  void CopyFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
  void MergeFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
  void CopyFrom(const QueryData& from);
  void MergeFrom(const QueryData& 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(QueryData* other);
  friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
  static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
    return "exec.shared.QueryData";
  }
  protected:
  explicit QueryData(::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 {
    kQueryIdFieldNumber = 1,
    kDefFieldNumber = 3,
    kRowCountFieldNumber = 2,
    kAffectedRowsCountFieldNumber = 4,
  };
  // 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 = 3;
  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 row_count = 2;
  bool has_row_count() const;
  private:
  bool _internal_has_row_count() const;
  public:
  void clear_row_count();
  ::PROTOBUF_NAMESPACE_ID::int32 row_count() const;
  void set_row_count(::PROTOBUF_NAMESPACE_ID::int32 value);
  private:
  ::PROTOBUF_NAMESPACE_ID::int32 _internal_row_count() const;
  void _internal_set_row_count(::PROTOBUF_NAMESPACE_ID::int32 value);
  public:

  // optional int32 affected_rows_count = 4;
  bool has_affected_rows_count() const;
  private:
  bool _internal_has_affected_rows_count() const;
  public:
  void clear_affected_rows_count();
  ::PROTOBUF_NAMESPACE_ID::int32 affected_rows_count() const;
  void set_affected_rows_count(::PROTOBUF_NAMESPACE_ID::int32 value);
  private:
  ::PROTOBUF_NAMESPACE_ID::int32 _internal_affected_rows_count() const;
  void _internal_set_affected_rows_count(::PROTOBUF_NAMESPACE_ID::int32 value);
  public:

  // @@protoc_insertion_point(class_scope:exec.shared.QueryData)
 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::QueryId* query_id_;
  ::exec::shared::RecordBatchDef* def_;
  ::PROTOBUF_NAMESPACE_ID::int32 row_count_;
  ::PROTOBUF_NAMESPACE_ID::int32 affected_rows_count_;
  friend struct ::TableStruct_UserBitShared_2eproto;
};
// -------------------------------------------------------------------

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

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

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

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

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

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

  QueryInfo* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final {
    return CreateMaybeMessage<QueryInfo>(arena);
  }
  void CopyFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
  void MergeFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
  void CopyFrom(const QueryInfo& from);
  void MergeFrom(const QueryInfo& 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(QueryInfo* other);
  friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
  static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
    return "exec.shared.QueryInfo";
  }
  protected:
  explicit QueryInfo(::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 {
    kQueryFieldNumber = 1,
    kUserFieldNumber = 4,
    kOptionsJsonFieldNumber = 6,
    kQueueNameFieldNumber = 8,
    kForemanFieldNumber = 5,
    kStartFieldNumber = 2,
    kTotalCostFieldNumber = 7,
    kStateFieldNumber = 3,
  };
  // optional string query = 1;
  bool has_query() const;
  private:
  bool _internal_has_query() const;
  public:
  void clear_query();
  const std::string& query() const;
  template <typename ArgT0 = const std::string&, typename... ArgT>
  void set_query(ArgT0&& arg0, ArgT... args);
  std::string* mutable_query();
  std::string* release_query();
  void set_allocated_query(std::string* query);
  private:
  const std::string& _internal_query() const;
  void _internal_set_query(const std::string& value);
  std::string* _internal_mutable_query();
  public:

  // optional string user = 4 [default = "-"];
  bool has_user() const;
  private:
  bool _internal_has_user() const;
  public:
  void clear_user();
  const std::string& user() const;
  template <typename ArgT0 = const std::string&, typename... ArgT>
  void set_user(ArgT0&& arg0, ArgT... args);
  std::string* mutable_user();
  std::string* release_user();
  void set_allocated_user(std::string* user);
  private:
  const std::string& _internal_user() const;
  void _internal_set_user(const std::string& value);
  std::string* _internal_mutable_user();
  public:

  // optional string options_json = 6;
  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 string queue_name = 8 [default = "-"];
  bool has_queue_name() const;
  private:
  bool _internal_has_queue_name() const;
  public:
  void clear_queue_name();
  const std::string& queue_name() const;
  template <typename ArgT0 = const std::string&, typename... ArgT>
  void set_queue_name(ArgT0&& arg0, ArgT... args);
  std::string* mutable_queue_name();
  std::string* release_queue_name();
  void set_allocated_queue_name(std::string* queue_name);
  private:
  const std::string& _internal_queue_name() const;
  void _internal_set_queue_name(const std::string& value);
  std::string* _internal_mutable_queue_name();
  public:

  // optional .exec.DrillbitEndpoint foreman = 5;
  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 int64 start = 2;
  bool has_start() const;
  private:
  bool _internal_has_start() const;
  public:
  void clear_start();
  ::PROTOBUF_NAMESPACE_ID::int64 start() const;
  void set_start(::PROTOBUF_NAMESPACE_ID::int64 value);
  private:
  ::PROTOBUF_NAMESPACE_ID::int64 _internal_start() const;
  void _internal_set_start(::PROTOBUF_NAMESPACE_ID::int64 value);
  public:

  // optional double total_cost = 7;
  bool has_total_cost() const;
  private:
  bool _internal_has_total_cost() const;
  public:
  void clear_total_cost();
  double total_cost() const;
  void set_total_cost(double value);
  private:
  double _internal_total_cost() const;
  void _internal_set_total_cost(double value);
  public:

  // optional .exec.shared.QueryResult.QueryState state = 3;
  bool has_state() const;
  private:
  bool _internal_has_state() const;
  public:
  void clear_state();
  ::exec::shared::QueryResult_QueryState state() const;
  void set_state(::exec::shared::QueryResult_QueryState value);
  private:
  ::exec::shared::QueryResult_QueryState _internal_state() const;
  void _internal_set_state(::exec::shared::QueryResult_QueryState value);
  public:

  // @@protoc_insertion_point(class_scope:exec.shared.QueryInfo)
 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 query_;
  static const ::PROTOBUF_NAMESPACE_ID::internal::LazyString _i_give_permission_to_break_this_code_default_user_;
  ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr user_;
  ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr options_json_;
  static const ::PROTOBUF_NAMESPACE_ID::internal::LazyString _i_give_permission_to_break_this_code_default_queue_name_;
  ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr queue_name_;
  ::exec::DrillbitEndpoint* foreman_;
  ::PROTOBUF_NAMESPACE_ID::int64 start_;
  double total_cost_;
  int state_;
  friend struct ::TableStruct_UserBitShared_2eproto;
};
// -------------------------------------------------------------------

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

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

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

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

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

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

  QueryProfile* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final {
    return CreateMaybeMessage<QueryProfile>(arena);
  }
  void CopyFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
  void MergeFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
  void CopyFrom(const QueryProfile& from);
  void MergeFrom(const QueryProfile& 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(QueryProfile* other);
  friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
  static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
    return "exec.shared.QueryProfile";
  }
  protected:
  explicit QueryProfile(::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 {
    kFragmentProfileFieldNumber = 11,
    kScannedPluginsFieldNumber = 24,
    kQueryFieldNumber = 5,
    kPlanFieldNumber = 6,
    kUserFieldNumber = 12,
    kErrorFieldNumber = 13,
    kVerboseErrorFieldNumber = 14,
    kErrorIdFieldNumber = 15,
    kErrorNodeFieldNumber = 16,
    kOptionsJsonFieldNumber = 17,
    kQueueNameFieldNumber = 21,
    kQueryIdFieldNumber = 22,
    kIdFieldNumber = 1,
    kForemanFieldNumber = 7,
    kStartFieldNumber = 3,
    kEndFieldNumber = 4,
    kStateFieldNumber = 8,
    kTotalFragmentsFieldNumber = 9,
    kFinishedFragmentsFieldNumber = 10,
    kAutoLimitFieldNumber = 23,
    kPlanEndFieldNumber = 18,
    kQueueWaitEndFieldNumber = 19,
    kTotalCostFieldNumber = 20,
    kTypeFieldNumber = 2,
  };
  // repeated .exec.shared.MajorFragmentProfile fragment_profile = 11;
  int fragment_profile_size() const;
  private:
  int _internal_fragment_profile_size() const;
  public:
  void clear_fragment_profile();
  ::exec::shared::MajorFragmentProfile* mutable_fragment_profile(int index);
  ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::exec::shared::MajorFragmentProfile >*
      mutable_fragment_profile();
  private:
  const ::exec::shared::MajorFragmentProfile& _internal_fragment_profile(int index) const;
  ::exec::shared::MajorFragmentProfile* _internal_add_fragment_profile();
  public:
  const ::exec::shared::MajorFragmentProfile& fragment_profile(int index) const;
  ::exec::shared::MajorFragmentProfile* add_fragment_profile();
  const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::exec::shared::MajorFragmentProfile >&
      fragment_profile() const;

  // repeated string scanned_plugins = 24;
  int scanned_plugins_size() const;
  private:
  int _internal_scanned_plugins_size() const;
  public:
  void clear_scanned_plugins();
  const std::string& scanned_plugins(int index) const;
  std::string* mutable_scanned_plugins(int index);
  void set_scanned_plugins(int index, const std::string& value);
  void set_scanned_plugins(int index, std::string&& value);
  void set_scanned_plugins(int index, const char* value);
  void set_scanned_plugins(int index, const char* value, size_t size);
  std::string* add_scanned_plugins();
  void add_scanned_plugins(const std::string& value);
  void add_scanned_plugins(std::string&& value);
  void add_scanned_plugins(const char* value);
  void add_scanned_plugins(const char* value, size_t size);
  const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField<std::string>& scanned_plugins() const;
  ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField<std::string>* mutable_scanned_plugins();
  private:
  const std::string& _internal_scanned_plugins(int index) const;
  std::string* _internal_add_scanned_plugins();
  public:

  // optional string query = 5;
  bool has_query() const;
  private:
  bool _internal_has_query() const;
  public:
  void clear_query();
  const std::string& query() const;
  template <typename ArgT0 = const std::string&, typename... ArgT>
  void set_query(ArgT0&& arg0, ArgT... args);
  std::string* mutable_query();
  std::string* release_query();
  void set_allocated_query(std::string* query);
  private:
  const std::string& _internal_query() const;
  void _internal_set_query(const std::string& value);
  std::string* _internal_mutable_query();
  public:

  // optional string plan = 6;
  bool has_plan() const;
  private:
  bool _internal_has_plan() const;
  public:
  void clear_plan();
  const std::string& plan() const;
  template <typename ArgT0 = const std::string&, typename... ArgT>
  void set_plan(ArgT0&& arg0, ArgT... args);
  std::string* mutable_plan();
  std::string* release_plan();
  void set_allocated_plan(std::string* plan);
  private:
  const std::string& _internal_plan() const;
  void _internal_set_plan(const std::string& value);
  std::string* _internal_mutable_plan();
  public:

  // optional string user = 12 [default = "-"];
  bool has_user() const;
  private:
  bool _internal_has_user() const;
  public:
  void clear_user();
  const std::string& user() const;
  template <typename ArgT0 = const std::string&, typename... ArgT>
  void set_user(ArgT0&& arg0, ArgT... args);
  std::string* mutable_user();
  std::string* release_user();
  void set_allocated_user(std::string* user);
  private:
  const std::string& _internal_user() const;
  void _internal_set_user(const std::string& value);
  std::string* _internal_mutable_user();
  public:

  // optional string error = 13;
  bool has_error() const;
  private:
  bool _internal_has_error() const;
  public:
  void clear_error();
  const std::string& error() const;
  template <typename ArgT0 = const std::string&, typename... ArgT>
  void set_error(ArgT0&& arg0, ArgT... args);
  std::string* mutable_error();
  std::string* release_error();
  void set_allocated_error(std::string* error);
  private:
  const std::string& _internal_error() const;
  void _internal_set_error(const std::string& value);
  std::string* _internal_mutable_error();
  public:

  // optional string verboseError = 14;
  bool has_verboseerror() const;
  private:
  bool _internal_has_verboseerror() const;
  public:
  void clear_verboseerror();
  const std::string& verboseerror() const;
  template <typename ArgT0 = const std::string&, typename... ArgT>
  void set_verboseerror(ArgT0&& arg0, ArgT... args);
  std::string* mutable_verboseerror();
  std::string* release_verboseerror();
  void set_allocated_verboseerror(std::string* verboseerror);
  private:
  const std::string& _internal_verboseerror() const;
  void _internal_set_verboseerror(const std::string& value);
  std::string* _internal_mutable_verboseerror();
  public:

  // optional string error_id = 15;
  bool has_error_id() const;
  private:
  bool _internal_has_error_id() const;
  public:
  void clear_error_id();
  const std::string& error_id() const;
  template <typename ArgT0 = const std::string&, typename... ArgT>
  void set_error_id(ArgT0&& arg0, ArgT... args);
  std::string* mutable_error_id();
  std::string* release_error_id();
  void set_allocated_error_id(std::string* error_id);
  private:
  const std::string& _internal_error_id() const;
  void _internal_set_error_id(const std::string& value);
  std::string* _internal_mutable_error_id();
  public:

  // optional string error_node = 16;
  bool has_error_node() const;
  private:
  bool _internal_has_error_node() const;
  public:
  void clear_error_node();
  const std::string& error_node() const;
  template <typename ArgT0 = const std::string&, typename... ArgT>
  void set_error_node(ArgT0&& arg0, ArgT... args);
  std::string* mutable_error_node();
  std::string* release_error_node();
  void set_allocated_error_node(std::string* error_node);
  private:
  const std::string& _internal_error_node() const;
  void _internal_set_error_node(const std::string& value);
  std::string* _internal_mutable_error_node();
  public:

  // optional string options_json = 17;
  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 string queue_name = 21 [default = "-"];
  bool has_queue_name() const;
  private:
  bool _internal_has_queue_name() const;
  public:
  void clear_queue_name();
  const std::string& queue_name() const;
  template <typename ArgT0 = const std::string&, typename... ArgT>
  void set_queue_name(ArgT0&& arg0, ArgT... args);
  std::string* mutable_queue_name();
  std::string* release_queue_name();
  void set_allocated_queue_name(std::string* queue_name);
  private:
  const std::string& _internal_queue_name() const;
  void _internal_set_queue_name(const std::string& value);
  std::string* _internal_mutable_queue_name();
  public:

  // optional string queryId = 22;
  bool has_queryid() const;
  private:
  bool _internal_has_queryid() const;
  public:
  void clear_queryid();
  const std::string& queryid() const;
  template <typename ArgT0 = const std::string&, typename... ArgT>
  void set_queryid(ArgT0&& arg0, ArgT... args);
  std::string* mutable_queryid();
  std::string* release_queryid();
  void set_allocated_queryid(std::string* queryid);
  private:
  const std::string& _internal_queryid() const;
  void _internal_set_queryid(const std::string& value);
  std::string* _internal_mutable_queryid();
  public:

  // optional .exec.shared.QueryId id = 1;
  bool has_id() const;
  private:
  bool _internal_has_id() const;
  public:
  void clear_id();
  const ::exec::shared::QueryId& id() const;
  ::exec::shared::QueryId* release_id();
  ::exec::shared::QueryId* mutable_id();
  void set_allocated_id(::exec::shared::QueryId* id);
  private:
  const ::exec::shared::QueryId& _internal_id() const;
  ::exec::shared::QueryId* _internal_mutable_id();
  public:
  void unsafe_arena_set_allocated_id(
      ::exec::shared::QueryId* id);
  ::exec::shared::QueryId* unsafe_arena_release_id();

  // optional .exec.DrillbitEndpoint foreman = 7;
  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 int64 start = 3;
  bool has_start() const;
  private:
  bool _internal_has_start() const;
  public:
  void clear_start();
  ::PROTOBUF_NAMESPACE_ID::int64 start() const;
  void set_start(::PROTOBUF_NAMESPACE_ID::int64 value);
  private:
  ::PROTOBUF_NAMESPACE_ID::int64 _internal_start() const;
  void _internal_set_start(::PROTOBUF_NAMESPACE_ID::int64 value);
  public:

  // optional int64 end = 4;
  bool has_end() const;
  private:
  bool _internal_has_end() const;
  public:
  void clear_end();
  ::PROTOBUF_NAMESPACE_ID::int64 end() const;
  void set_end(::PROTOBUF_NAMESPACE_ID::int64 value);
  private:
  ::PROTOBUF_NAMESPACE_ID::int64 _internal_end() const;
  void _internal_set_end(::PROTOBUF_NAMESPACE_ID::int64 value);
  public:

  // optional .exec.shared.QueryResult.QueryState state = 8;
  bool has_state() const;
  private:
  bool _internal_has_state() const;
  public:
  void clear_state();
  ::exec::shared::QueryResult_QueryState state() const;
  void set_state(::exec::shared::QueryResult_QueryState value);
  private:
  ::exec::shared::QueryResult_QueryState _internal_state() const;
  void _internal_set_state(::exec::shared::QueryResult_QueryState value);
  public:

  // optional int32 total_fragments = 9;
  bool has_total_fragments() const;
  private:
  bool _internal_has_total_fragments() const;
  public:
  void clear_total_fragments();
  ::PROTOBUF_NAMESPACE_ID::int32 total_fragments() const;
  void set_total_fragments(::PROTOBUF_NAMESPACE_ID::int32 value);
  private:
  ::PROTOBUF_NAMESPACE_ID::int32 _internal_total_fragments() const;
  void _internal_set_total_fragments(::PROTOBUF_NAMESPACE_ID::int32 value);
  public:

  // optional int32 finished_fragments = 10;
  bool has_finished_fragments() const;
  private:
  bool _internal_has_finished_fragments() const;
  public:
  void clear_finished_fragments();
  ::PROTOBUF_NAMESPACE_ID::int32 finished_fragments() const;
  void set_finished_fragments(::PROTOBUF_NAMESPACE_ID::int32 value);
  private:
  ::PROTOBUF_NAMESPACE_ID::int32 _internal_finished_fragments() const;
  void _internal_set_finished_fragments(::PROTOBUF_NAMESPACE_ID::int32 value);
  public:

  // optional int32 autoLimit = 23;
  bool has_autolimit() const;
  private:
  bool _internal_has_autolimit() const;
  public:
  void clear_autolimit();
  ::PROTOBUF_NAMESPACE_ID::int32 autolimit() const;
  void set_autolimit(::PROTOBUF_NAMESPACE_ID::int32 value);
  private:
  ::PROTOBUF_NAMESPACE_ID::int32 _internal_autolimit() const;
  void _internal_set_autolimit(::PROTOBUF_NAMESPACE_ID::int32 value);
  public:

  // optional int64 planEnd = 18;
  bool has_planend() const;
  private:
  bool _internal_has_planend() const;
  public:
  void clear_planend();
  ::PROTOBUF_NAMESPACE_ID::int64 planend() const;
  void set_planend(::PROTOBUF_NAMESPACE_ID::int64 value);
  private:
  ::PROTOBUF_NAMESPACE_ID::int64 _internal_planend() const;
  void _internal_set_planend(::PROTOBUF_NAMESPACE_ID::int64 value);
  public:

  // optional int64 queueWaitEnd = 19;
  bool has_queuewaitend() const;
  private:
  bool _internal_has_queuewaitend() const;
  public:
  void clear_queuewaitend();
  ::PROTOBUF_NAMESPACE_ID::int64 queuewaitend() const;
  void set_queuewaitend(::PROTOBUF_NAMESPACE_ID::int64 value);
  private:
  ::PROTOBUF_NAMESPACE_ID::int64 _internal_queuewaitend() const;
  void _internal_set_queuewaitend(::PROTOBUF_NAMESPACE_ID::int64 value);
  public:

  // optional double total_cost = 20;
  bool has_total_cost() const;
  private:
  bool _internal_has_total_cost() const;
  public:
  void clear_total_cost();
  double total_cost() const;
  void set_total_cost(double value);
  private:
  double _internal_total_cost() const;
  void _internal_set_total_cost(double value);
  public:

  // optional .exec.shared.QueryType type = 2;
  bool has_type() const;
  private:
  bool _internal_has_type() const;
  public:
  void clear_type();
  ::exec::shared::QueryType type() const;
  void set_type(::exec::shared::QueryType value);
  private:
  ::exec::shared::QueryType _internal_type() const;
  void _internal_set_type(::exec::shared::QueryType value);
  public:

  // @@protoc_insertion_point(class_scope:exec.shared.QueryProfile)
 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::shared::MajorFragmentProfile > fragment_profile_;
  ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField<std::string> scanned_plugins_;
  ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr query_;
  ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr plan_;
  static const ::PROTOBUF_NAMESPACE_ID::internal::LazyString _i_give_permission_to_break_this_code_default_user_;
  ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr user_;
  ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr error_;
  ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr verboseerror_;
  ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr error_id_;
  ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr error_node_;
  ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr options_json_;
  static const ::PROTOBUF_NAMESPACE_ID::internal::LazyString _i_give_permission_to_break_this_code_default_queue_name_;
  ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr queue_name_;
  ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr queryid_;
  ::exec::shared::QueryId* id_;
  ::exec::DrillbitEndpoint* foreman_;
  ::PROTOBUF_NAMESPACE_ID::int64 start_;
  ::PROTOBUF_NAMESPACE_ID::int64 end_;
  int state_;
  ::PROTOBUF_NAMESPACE_ID::int32 total_fragments_;
  ::PROTOBUF_NAMESPACE_ID::int32 finished_fragments_;
  ::PROTOBUF_NAMESPACE_ID::int32 autolimit_;
  ::PROTOBUF_NAMESPACE_ID::int64 planend_;
  ::PROTOBUF_NAMESPACE_ID::int64 queuewaitend_;
  double total_cost_;
  int type_;
  friend struct ::TableStruct_UserBitShared_2eproto;
};
// -------------------------------------------------------------------

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

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

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

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

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

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

  MajorFragmentProfile* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final {
    return CreateMaybeMessage<MajorFragmentProfile>(arena);
  }
  void CopyFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
  void MergeFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
  void CopyFrom(const MajorFragmentProfile& from);
  void MergeFrom(const MajorFragmentProfile& 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(MajorFragmentProfile* other);
  friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
  static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
    return "exec.shared.MajorFragmentProfile";
  }
  protected:
  explicit MajorFragmentProfile(::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 {
    kMinorFragmentProfileFieldNumber = 2,
    kMajorFragmentIdFieldNumber = 1,
  };
  // repeated .exec.shared.MinorFragmentProfile minor_fragment_profile = 2;
  int minor_fragment_profile_size() const;
  private:
  int _internal_minor_fragment_profile_size() const;
  public:
  void clear_minor_fragment_profile();
  ::exec::shared::MinorFragmentProfile* mutable_minor_fragment_profile(int index);
  ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::exec::shared::MinorFragmentProfile >*
      mutable_minor_fragment_profile();
  private:
  const ::exec::shared::MinorFragmentProfile& _internal_minor_fragment_profile(int index) const;
  ::exec::shared::MinorFragmentProfile* _internal_add_minor_fragment_profile();
  public:
  const ::exec::shared::MinorFragmentProfile& minor_fragment_profile(int index) const;
  ::exec::shared::MinorFragmentProfile* add_minor_fragment_profile();
  const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::exec::shared::MinorFragmentProfile >&
      minor_fragment_profile() const;

  // optional int32 major_fragment_id = 1;
  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:

  // @@protoc_insertion_point(class_scope:exec.shared.MajorFragmentProfile)
 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::shared::MinorFragmentProfile > minor_fragment_profile_;
  ::PROTOBUF_NAMESPACE_ID::int32 major_fragment_id_;
  friend struct ::TableStruct_UserBitShared_2eproto;
};
// -------------------------------------------------------------------

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

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

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

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

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

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

  MinorFragmentProfile* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final {
    return CreateMaybeMessage<MinorFragmentProfile>(arena);
  }
  void CopyFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
  void MergeFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
  void CopyFrom(const MinorFragmentProfile& from);
  void MergeFrom(const MinorFragmentProfile& 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(MinorFragmentProfile* other);
  friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
  static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
    return "exec.shared.MinorFragmentProfile";
  }
  protected:
  explicit MinorFragmentProfile(::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 {
    kOperatorProfileFieldNumber = 4,
    kErrorFieldNumber = 2,
    kEndpointFieldNumber = 9,
    kStateFieldNumber = 1,
    kMinorFragmentIdFieldNumber = 3,
    kStartTimeFieldNumber = 5,
    kEndTimeFieldNumber = 6,
    kMemoryUsedFieldNumber = 7,
    kMaxMemoryUsedFieldNumber = 8,
    kLastUpdateFieldNumber = 10,
    kLastProgressFieldNumber = 11,
  };
  // repeated .exec.shared.OperatorProfile operator_profile = 4;
  int operator_profile_size() const;
  private:
  int _internal_operator_profile_size() const;
  public:
  void clear_operator_profile();
  ::exec::shared::OperatorProfile* mutable_operator_profile(int index);
  ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::exec::shared::OperatorProfile >*
      mutable_operator_profile();
  private:
  const ::exec::shared::OperatorProfile& _internal_operator_profile(int index) const;
  ::exec::shared::OperatorProfile* _internal_add_operator_profile();
  public:
  const ::exec::shared::OperatorProfile& operator_profile(int index) const;
  ::exec::shared::OperatorProfile* add_operator_profile();
  const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::exec::shared::OperatorProfile >&
      operator_profile() const;

  // optional .exec.shared.DrillPBError error = 2;
  bool has_error() const;
  private:
  bool _internal_has_error() const;
  public:
  void clear_error();
  const ::exec::shared::DrillPBError& error() const;
  ::exec::shared::DrillPBError* release_error();
  ::exec::shared::DrillPBError* mutable_error();
  void set_allocated_error(::exec::shared::DrillPBError* error);
  private:
  const ::exec::shared::DrillPBError& _internal_error() const;
  ::exec::shared::DrillPBError* _internal_mutable_error();
  public:
  void unsafe_arena_set_allocated_error(
      ::exec::shared::DrillPBError* error);
  ::exec::shared::DrillPBError* unsafe_arena_release_error();

  // optional .exec.DrillbitEndpoint endpoint = 9;
  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 .exec.shared.FragmentState state = 1;
  bool has_state() const;
  private:
  bool _internal_has_state() const;
  public:
  void clear_state();
  ::exec::shared::FragmentState state() const;
  void set_state(::exec::shared::FragmentState value);
  private:
  ::exec::shared::FragmentState _internal_state() const;
  void _internal_set_state(::exec::shared::FragmentState 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 int64 start_time = 5;
  bool has_start_time() const;
  private:
  bool _internal_has_start_time() const;
  public:
  void clear_start_time();
  ::PROTOBUF_NAMESPACE_ID::int64 start_time() const;
  void set_start_time(::PROTOBUF_NAMESPACE_ID::int64 value);
  private:
  ::PROTOBUF_NAMESPACE_ID::int64 _internal_start_time() const;
  void _internal_set_start_time(::PROTOBUF_NAMESPACE_ID::int64 value);
  public:

  // optional int64 end_time = 6;
  bool has_end_time() const;
  private:
  bool _internal_has_end_time() const;
  public:
  void clear_end_time();
  ::PROTOBUF_NAMESPACE_ID::int64 end_time() const;
  void set_end_time(::PROTOBUF_NAMESPACE_ID::int64 value);
  private:
  ::PROTOBUF_NAMESPACE_ID::int64 _internal_end_time() const;
  void _internal_set_end_time(::PROTOBUF_NAMESPACE_ID::int64 value);
  public:

  // optional int64 memory_used = 7;
  bool has_memory_used() const;
  private:
  bool _internal_has_memory_used() const;
  public:
  void clear_memory_used();
  ::PROTOBUF_NAMESPACE_ID::int64 memory_used() const;
  void set_memory_used(::PROTOBUF_NAMESPACE_ID::int64 value);
  private:
  ::PROTOBUF_NAMESPACE_ID::int64 _internal_memory_used() const;
  void _internal_set_memory_used(::PROTOBUF_NAMESPACE_ID::int64 value);
  public:

  // optional int64 max_memory_used = 8;
  bool has_max_memory_used() const;
  private:
  bool _internal_has_max_memory_used() const;
  public:
  void clear_max_memory_used();
  ::PROTOBUF_NAMESPACE_ID::int64 max_memory_used() const;
  void set_max_memory_used(::PROTOBUF_NAMESPACE_ID::int64 value);
  private:
  ::PROTOBUF_NAMESPACE_ID::int64 _internal_max_memory_used() const;
  void _internal_set_max_memory_used(::PROTOBUF_NAMESPACE_ID::int64 value);
  public:

  // optional int64 last_update = 10;
  bool has_last_update() const;
  private:
  bool _internal_has_last_update() const;
  public:
  void clear_last_update();
  ::PROTOBUF_NAMESPACE_ID::int64 last_update() const;
  void set_last_update(::PROTOBUF_NAMESPACE_ID::int64 value);
  private:
  ::PROTOBUF_NAMESPACE_ID::int64 _internal_last_update() const;
  void _internal_set_last_update(::PROTOBUF_NAMESPACE_ID::int64 value);
  public:

  // optional int64 last_progress = 11;
  bool has_last_progress() const;
  private:
  bool _internal_has_last_progress() const;
  public:
  void clear_last_progress();
  ::PROTOBUF_NAMESPACE_ID::int64 last_progress() const;
  void set_last_progress(::PROTOBUF_NAMESPACE_ID::int64 value);
  private:
  ::PROTOBUF_NAMESPACE_ID::int64 _internal_last_progress() const;
  void _internal_set_last_progress(::PROTOBUF_NAMESPACE_ID::int64 value);
  public:

  // @@protoc_insertion_point(class_scope:exec.shared.MinorFragmentProfile)
 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::shared::OperatorProfile > operator_profile_;
  ::exec::shared::DrillPBError* error_;
  ::exec::DrillbitEndpoint* endpoint_;
  int state_;
  ::PROTOBUF_NAMESPACE_ID::int32 minor_fragment_id_;
  ::PROTOBUF_NAMESPACE_ID::int64 start_time_;
  ::PROTOBUF_NAMESPACE_ID::int64 end_time_;
  ::PROTOBUF_NAMESPACE_ID::int64 memory_used_;
  ::PROTOBUF_NAMESPACE_ID::int64 max_memory_used_;
  ::PROTOBUF_NAMESPACE_ID::int64 last_update_;
  ::PROTOBUF_NAMESPACE_ID::int64 last_progress_;
  friend struct ::TableStruct_UserBitShared_2eproto;
};
// -------------------------------------------------------------------

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

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

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

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

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

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

  OperatorProfile* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final {
    return CreateMaybeMessage<OperatorProfile>(arena);
  }
  void CopyFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
  void MergeFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
  void CopyFrom(const OperatorProfile& from);
  void MergeFrom(const OperatorProfile& 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(OperatorProfile* other);
  friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
  static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
    return "exec.shared.OperatorProfile";
  }
  protected:
  explicit OperatorProfile(::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 {
    kInputProfileFieldNumber = 1,
    kMetricFieldNumber = 8,
    kOperatorTypeNameFieldNumber = 10,
    kOperatorIdFieldNumber = 3,
    kOperatorTypeFieldNumber = 4,
    kSetupNanosFieldNumber = 5,
    kProcessNanosFieldNumber = 6,
    kPeakLocalMemoryAllocatedFieldNumber = 7,
    kWaitNanosFieldNumber = 9,
  };
  // repeated .exec.shared.StreamProfile input_profile = 1;
  int input_profile_size() const;
  private:
  int _internal_input_profile_size() const;
  public:
  void clear_input_profile();
  ::exec::shared::StreamProfile* mutable_input_profile(int index);
  ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::exec::shared::StreamProfile >*
      mutable_input_profile();
  private:
  const ::exec::shared::StreamProfile& _internal_input_profile(int index) const;
  ::exec::shared::StreamProfile* _internal_add_input_profile();
  public:
  const ::exec::shared::StreamProfile& input_profile(int index) const;
  ::exec::shared::StreamProfile* add_input_profile();
  const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::exec::shared::StreamProfile >&
      input_profile() const;

  // repeated .exec.shared.MetricValue metric = 8;
  int metric_size() const;
  private:
  int _internal_metric_size() const;
  public:
  void clear_metric();
  ::exec::shared::MetricValue* mutable_metric(int index);
  ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::exec::shared::MetricValue >*
      mutable_metric();
  private:
  const ::exec::shared::MetricValue& _internal_metric(int index) const;
  ::exec::shared::MetricValue* _internal_add_metric();
  public:
  const ::exec::shared::MetricValue& metric(int index) const;
  ::exec::shared::MetricValue* add_metric();
  const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::exec::shared::MetricValue >&
      metric() const;

  // optional string operator_type_name = 10;
  bool has_operator_type_name() const;
  private:
  bool _internal_has_operator_type_name() const;
  public:
  void clear_operator_type_name();
  const std::string& operator_type_name() const;
  template <typename ArgT0 = const std::string&, typename... ArgT>
  void set_operator_type_name(ArgT0&& arg0, ArgT... args);
  std::string* mutable_operator_type_name();
  std::string* release_operator_type_name();
  void set_allocated_operator_type_name(std::string* operator_type_name);
  private:
  const std::string& _internal_operator_type_name() const;
  void _internal_set_operator_type_name(const std::string& value);
  std::string* _internal_mutable_operator_type_name();
  public:

  // optional int32 operator_id = 3;
  bool has_operator_id() const;
  private:
  bool _internal_has_operator_id() const;
  public:
  void clear_operator_id();
  ::PROTOBUF_NAMESPACE_ID::int32 operator_id() const;
  void set_operator_id(::PROTOBUF_NAMESPACE_ID::int32 value);
  private:
  ::PROTOBUF_NAMESPACE_ID::int32 _internal_operator_id() const;
  void _internal_set_operator_id(::PROTOBUF_NAMESPACE_ID::int32 value);
  public:

  // optional int32 operator_type = 4 [deprecated = true];
  PROTOBUF_DEPRECATED bool has_operator_type() const;
  private:
  bool _internal_has_operator_type() const;
  public:
  PROTOBUF_DEPRECATED void clear_operator_type();
  PROTOBUF_DEPRECATED ::PROTOBUF_NAMESPACE_ID::int32 operator_type() const;
  PROTOBUF_DEPRECATED void set_operator_type(::PROTOBUF_NAMESPACE_ID::int32 value);
  private:
  ::PROTOBUF_NAMESPACE_ID::int32 _internal_operator_type() const;
  void _internal_set_operator_type(::PROTOBUF_NAMESPACE_ID::int32 value);
  public:

  // optional int64 setup_nanos = 5;
  bool has_setup_nanos() const;
  private:
  bool _internal_has_setup_nanos() const;
  public:
  void clear_setup_nanos();
  ::PROTOBUF_NAMESPACE_ID::int64 setup_nanos() const;
  void set_setup_nanos(::PROTOBUF_NAMESPACE_ID::int64 value);
  private:
  ::PROTOBUF_NAMESPACE_ID::int64 _internal_setup_nanos() const;
  void _internal_set_setup_nanos(::PROTOBUF_NAMESPACE_ID::int64 value);
  public:

  // optional int64 process_nanos = 6;
  bool has_process_nanos() const;
  private:
  bool _internal_has_process_nanos() const;
  public:
  void clear_process_nanos();
  ::PROTOBUF_NAMESPACE_ID::int64 process_nanos() const;
  void set_process_nanos(::PROTOBUF_NAMESPACE_ID::int64 value);
  private:
  ::PROTOBUF_NAMESPACE_ID::int64 _internal_process_nanos() const;
  void _internal_set_process_nanos(::PROTOBUF_NAMESPACE_ID::int64 value);
  public:

  // optional int64 peak_local_memory_allocated = 7;
  bool has_peak_local_memory_allocated() const;
  private:
  bool _internal_has_peak_local_memory_allocated() const;
  public:
  void clear_peak_local_memory_allocated();
  ::PROTOBUF_NAMESPACE_ID::int64 peak_local_memory_allocated() const;
  void set_peak_local_memory_allocated(::PROTOBUF_NAMESPACE_ID::int64 value);
  private:
  ::PROTOBUF_NAMESPACE_ID::int64 _internal_peak_local_memory_allocated() const;
  void _internal_set_peak_local_memory_allocated(::PROTOBUF_NAMESPACE_ID::int64 value);
  public:

  // optional int64 wait_nanos = 9;
  bool has_wait_nanos() const;
  private:
  bool _internal_has_wait_nanos() const;
  public:
  void clear_wait_nanos();
  ::PROTOBUF_NAMESPACE_ID::int64 wait_nanos() const;
  void set_wait_nanos(::PROTOBUF_NAMESPACE_ID::int64 value);
  private:
  ::PROTOBUF_NAMESPACE_ID::int64 _internal_wait_nanos() const;
  void _internal_set_wait_nanos(::PROTOBUF_NAMESPACE_ID::int64 value);
  public:

  // @@protoc_insertion_point(class_scope:exec.shared.OperatorProfile)
 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::shared::StreamProfile > input_profile_;
  ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::exec::shared::MetricValue > metric_;
  ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr operator_type_name_;
  ::PROTOBUF_NAMESPACE_ID::int32 operator_id_;
  ::PROTOBUF_NAMESPACE_ID::int32 operator_type_;
  ::PROTOBUF_NAMESPACE_ID::int64 setup_nanos_;
  ::PROTOBUF_NAMESPACE_ID::int64 process_nanos_;
  ::PROTOBUF_NAMESPACE_ID::int64 peak_local_memory_allocated_;
  ::PROTOBUF_NAMESPACE_ID::int64 wait_nanos_;
  friend struct ::TableStruct_UserBitShared_2eproto;
};
// -------------------------------------------------------------------

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

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

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

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

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

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

  StreamProfile* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final {
    return CreateMaybeMessage<StreamProfile>(arena);
  }
  void CopyFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
  void MergeFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
  void CopyFrom(const StreamProfile& from);
  void MergeFrom(const StreamProfile& 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(StreamProfile* other);
  friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
  static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
    return "exec.shared.StreamProfile";
  }
  protected:
  explicit StreamProfile(::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 {
    kRecordsFieldNumber = 1,
    kBatchesFieldNumber = 2,
    kSchemasFieldNumber = 3,
  };
  // optional int64 records = 1;
  bool has_records() const;
  private:
  bool _internal_has_records() const;
  public:
  void clear_records();
  ::PROTOBUF_NAMESPACE_ID::int64 records() const;
  void set_records(::PROTOBUF_NAMESPACE_ID::int64 value);
  private:
  ::PROTOBUF_NAMESPACE_ID::int64 _internal_records() const;
  void _internal_set_records(::PROTOBUF_NAMESPACE_ID::int64 value);
  public:

  // optional int64 batches = 2;
  bool has_batches() const;
  private:
  bool _internal_has_batches() const;
  public:
  void clear_batches();
  ::PROTOBUF_NAMESPACE_ID::int64 batches() const;
  void set_batches(::PROTOBUF_NAMESPACE_ID::int64 value);
  private:
  ::PROTOBUF_NAMESPACE_ID::int64 _internal_batches() const;
  void _internal_set_batches(::PROTOBUF_NAMESPACE_ID::int64 value);
  public:

  // optional int64 schemas = 3;
  bool has_schemas() const;
  private:
  bool _internal_has_schemas() const;
  public:
  void clear_schemas();
  ::PROTOBUF_NAMESPACE_ID::int64 schemas() const;
  void set_schemas(::PROTOBUF_NAMESPACE_ID::int64 value);
  private:
  ::PROTOBUF_NAMESPACE_ID::int64 _internal_schemas() const;
  void _internal_set_schemas(::PROTOBUF_NAMESPACE_ID::int64 value);
  public:

  // @@protoc_insertion_point(class_scope:exec.shared.StreamProfile)
 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::int64 records_;
  ::PROTOBUF_NAMESPACE_ID::int64 batches_;
  ::PROTOBUF_NAMESPACE_ID::int64 schemas_;
  friend struct ::TableStruct_UserBitShared_2eproto;
};
// -------------------------------------------------------------------

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

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

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

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

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

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

  MetricValue* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final {
    return CreateMaybeMessage<MetricValue>(arena);
  }
  void CopyFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
  void MergeFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
  void CopyFrom(const MetricValue& from);
  void MergeFrom(const MetricValue& 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(MetricValue* other);
  friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
  static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
    return "exec.shared.MetricValue";
  }
  protected:
  explicit MetricValue(::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 {
    kLongValueFieldNumber = 2,
    kDoubleValueFieldNumber = 3,
    kMetricIdFieldNumber = 1,
  };
  // optional int64 long_value = 2;
  bool has_long_value() const;
  private:
  bool _internal_has_long_value() const;
  public:
  void clear_long_value();
  ::PROTOBUF_NAMESPACE_ID::int64 long_value() const;
  void set_long_value(::PROTOBUF_NAMESPACE_ID::int64 value);
  private:
  ::PROTOBUF_NAMESPACE_ID::int64 _internal_long_value() const;
  void _internal_set_long_value(::PROTOBUF_NAMESPACE_ID::int64 value);
  public:

  // optional double double_value = 3;
  bool has_double_value() const;
  private:
  bool _internal_has_double_value() const;
  public:
  void clear_double_value();
  double double_value() const;
  void set_double_value(double value);
  private:
  double _internal_double_value() const;
  void _internal_set_double_value(double value);
  public:

  // optional int32 metric_id = 1;
  bool has_metric_id() const;
  private:
  bool _internal_has_metric_id() const;
  public:
  void clear_metric_id();
  ::PROTOBUF_NAMESPACE_ID::int32 metric_id() const;
  void set_metric_id(::PROTOBUF_NAMESPACE_ID::int32 value);
  private:
  ::PROTOBUF_NAMESPACE_ID::int32 _internal_metric_id() const;
  void _internal_set_metric_id(::PROTOBUF_NAMESPACE_ID::int32 value);
  public:

  // @@protoc_insertion_point(class_scope:exec.shared.MetricValue)
 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::int64 long_value_;
  double double_value_;
  ::PROTOBUF_NAMESPACE_ID::int32 metric_id_;
  friend struct ::TableStruct_UserBitShared_2eproto;
};
// -------------------------------------------------------------------

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

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

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

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

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

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

  Registry* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final {
    return CreateMaybeMessage<Registry>(arena);
  }
  void CopyFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
  void MergeFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
  void CopyFrom(const Registry& from);
  void MergeFrom(const Registry& 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(Registry* other);
  friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
  static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
    return "exec.shared.Registry";
  }
  protected:
  explicit Registry(::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 {
    kJarFieldNumber = 1,
  };
  // repeated .exec.shared.Jar jar = 1;
  int jar_size() const;
  private:
  int _internal_jar_size() const;
  public:
  void clear_jar();
  ::exec::shared::Jar* mutable_jar(int index);
  ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::exec::shared::Jar >*
      mutable_jar();
  private:
  const ::exec::shared::Jar& _internal_jar(int index) const;
  ::exec::shared::Jar* _internal_add_jar();
  public:
  const ::exec::shared::Jar& jar(int index) const;
  ::exec::shared::Jar* add_jar();
  const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::exec::shared::Jar >&
      jar() const;

  // @@protoc_insertion_point(class_scope:exec.shared.Registry)
 private:
  class _Internal;

  template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper;
  typedef void InternalArenaConstructable_;
  typedef void DestructorSkippable_;
  ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::exec::shared::Jar > jar_;
  mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
  friend struct ::TableStruct_UserBitShared_2eproto;
};
// -------------------------------------------------------------------

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

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

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

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

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

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

  Jar* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final {
    return CreateMaybeMessage<Jar>(arena);
  }
  void CopyFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
  void MergeFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
  void CopyFrom(const Jar& from);
  void MergeFrom(const Jar& 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(Jar* other);
  friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
  static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
    return "exec.shared.Jar";
  }
  protected:
  explicit Jar(::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 {
    kFunctionSignatureFieldNumber = 2,
    kNameFieldNumber = 1,
  };
  // repeated string function_signature = 2;
  int function_signature_size() const;
  private:
  int _internal_function_signature_size() const;
  public:
  void clear_function_signature();
  const std::string& function_signature(int index) const;
  std::string* mutable_function_signature(int index);
  void set_function_signature(int index, const std::string& value);
  void set_function_signature(int index, std::string&& value);
  void set_function_signature(int index, const char* value);
  void set_function_signature(int index, const char* value, size_t size);
  std::string* add_function_signature();
  void add_function_signature(const std::string& value);
  void add_function_signature(std::string&& value);
  void add_function_signature(const char* value);
  void add_function_signature(const char* value, size_t size);
  const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField<std::string>& function_signature() const;
  ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField<std::string>* mutable_function_signature();
  private:
  const std::string& _internal_function_signature(int index) const;
  std::string* _internal_add_function_signature();
  public:

  // optional string name = 1;
  bool has_name() const;
  private:
  bool _internal_has_name() const;
  public:
  void clear_name();
  const std::string& name() const;
  template <typename ArgT0 = const std::string&, typename... ArgT>
  void set_name(ArgT0&& arg0, ArgT... args);
  std::string* mutable_name();
  std::string* release_name();
  void set_allocated_name(std::string* name);
  private:
  const std::string& _internal_name() const;
  void _internal_set_name(const std::string& value);
  std::string* _internal_mutable_name();
  public:

  // @@protoc_insertion_point(class_scope:exec.shared.Jar)
 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> function_signature_;
  ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr name_;
  friend struct ::TableStruct_UserBitShared_2eproto;
};
// -------------------------------------------------------------------

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

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

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

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

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

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

  SaslMessage* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final {
    return CreateMaybeMessage<SaslMessage>(arena);
  }
  void CopyFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
  void MergeFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
  void CopyFrom(const SaslMessage& from);
  void MergeFrom(const SaslMessage& 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(SaslMessage* other);
  friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
  static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
    return "exec.shared.SaslMessage";
  }
  protected:
  explicit SaslMessage(::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 {
    kMechanismFieldNumber = 1,
    kDataFieldNumber = 2,
    kStatusFieldNumber = 3,
  };
  // optional string mechanism = 1;
  bool has_mechanism() const;
  private:
  bool _internal_has_mechanism() const;
  public:
  void clear_mechanism();
  const std::string& mechanism() const;
  template <typename ArgT0 = const std::string&, typename... ArgT>
  void set_mechanism(ArgT0&& arg0, ArgT... args);
  std::string* mutable_mechanism();
  std::string* release_mechanism();
  void set_allocated_mechanism(std::string* mechanism);
  private:
  const std::string& _internal_mechanism() const;
  void _internal_set_mechanism(const std::string& value);
  std::string* _internal_mutable_mechanism();
  public:

  // optional bytes data = 2;
  bool has_data() const;
  private:
  bool _internal_has_data() const;
  public:
  void clear_data();
  const std::string& data() const;
  template <typename ArgT0 = const std::string&, typename... ArgT>
  void set_data(ArgT0&& arg0, ArgT... args);
  std::string* mutable_data();
  std::string* release_data();
  void set_allocated_data(std::string* data);
  private:
  const std::string& _internal_data() const;
  void _internal_set_data(const std::string& value);
  std::string* _internal_mutable_data();
  public:

  // optional .exec.shared.SaslStatus status = 3;
  bool has_status() const;
  private:
  bool _internal_has_status() const;
  public:
  void clear_status();
  ::exec::shared::SaslStatus status() const;
  void set_status(::exec::shared::SaslStatus value);
  private:
  ::exec::shared::SaslStatus _internal_status() const;
  void _internal_set_status(::exec::shared::SaslStatus value);
  public:

  // @@protoc_insertion_point(class_scope:exec.shared.SaslMessage)
 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 mechanism_;
  ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr data_;
  int status_;
  friend struct ::TableStruct_UserBitShared_2eproto;
};
// ===================================================================


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

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

// optional string user_name = 1;
inline bool UserCredentials::_internal_has_user_name() const {
  bool value = (_has_bits_[0] & 0x00000001u) != 0;
  return value;
}
inline bool UserCredentials::has_user_name() const {
  return _internal_has_user_name();
}
inline void UserCredentials::clear_user_name() {
  user_name_.ClearToEmpty();
  _has_bits_[0] &= ~0x00000001u;
}
inline const std::string& UserCredentials::user_name() const {
  // @@protoc_insertion_point(field_get:exec.shared.UserCredentials.user_name)
  return _internal_user_name();
}
template <typename ArgT0, typename... ArgT>
PROTOBUF_ALWAYS_INLINE
inline void UserCredentials::set_user_name(ArgT0&& arg0, ArgT... args) {
 _has_bits_[0] |= 0x00000001u;
 user_name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArena());
  // @@protoc_insertion_point(field_set:exec.shared.UserCredentials.user_name)
}
inline std::string* UserCredentials::mutable_user_name() {
  // @@protoc_insertion_point(field_mutable:exec.shared.UserCredentials.user_name)
  return _internal_mutable_user_name();
}
inline const std::string& UserCredentials::_internal_user_name() const {
  return user_name_.Get();
}
inline void UserCredentials::_internal_set_user_name(const std::string& value) {
  _has_bits_[0] |= 0x00000001u;
  user_name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena());
}
inline std::string* UserCredentials::_internal_mutable_user_name() {
  _has_bits_[0] |= 0x00000001u;
  return user_name_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena());
}
inline std::string* UserCredentials::release_user_name() {
  // @@protoc_insertion_point(field_release:exec.shared.UserCredentials.user_name)
  if (!_internal_has_user_name()) {
    return nullptr;
  }
  _has_bits_[0] &= ~0x00000001u;
  return user_name_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena());
}
inline void UserCredentials::set_allocated_user_name(std::string* user_name) {
  if (user_name != nullptr) {
    _has_bits_[0] |= 0x00000001u;
  } else {
    _has_bits_[0] &= ~0x00000001u;
  }
  user_name_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), user_name,
      GetArena());
  // @@protoc_insertion_point(field_set_allocated:exec.shared.UserCredentials.user_name)
}

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

// QueryId

// optional sfixed64 part1 = 1;
inline bool QueryId::_internal_has_part1() const {
  bool value = (_has_bits_[0] & 0x00000001u) != 0;
  return value;
}
inline bool QueryId::has_part1() const {
  return _internal_has_part1();
}
inline void QueryId::clear_part1() {
  part1_ = PROTOBUF_LONGLONG(0);
  _has_bits_[0] &= ~0x00000001u;
}
inline ::PROTOBUF_NAMESPACE_ID::int64 QueryId::_internal_part1() const {
  return part1_;
}
inline ::PROTOBUF_NAMESPACE_ID::int64 QueryId::part1() const {
  // @@protoc_insertion_point(field_get:exec.shared.QueryId.part1)
  return _internal_part1();
}
inline void QueryId::_internal_set_part1(::PROTOBUF_NAMESPACE_ID::int64 value) {
  _has_bits_[0] |= 0x00000001u;
  part1_ = value;
}
inline void QueryId::set_part1(::PROTOBUF_NAMESPACE_ID::int64 value) {
  _internal_set_part1(value);
  // @@protoc_insertion_point(field_set:exec.shared.QueryId.part1)
}

// optional sfixed64 part2 = 2;
inline bool QueryId::_internal_has_part2() const {
  bool value = (_has_bits_[0] & 0x00000002u) != 0;
  return value;
}
inline bool QueryId::has_part2() const {
  return _internal_has_part2();
}
inline void QueryId::clear_part2() {
  part2_ = PROTOBUF_LONGLONG(0);
  _has_bits_[0] &= ~0x00000002u;
}
inline ::PROTOBUF_NAMESPACE_ID::int64 QueryId::_internal_part2() const {
  return part2_;
}
inline ::PROTOBUF_NAMESPACE_ID::int64 QueryId::part2() const {
  // @@protoc_insertion_point(field_get:exec.shared.QueryId.part2)
  return _internal_part2();
}
inline void QueryId::_internal_set_part2(::PROTOBUF_NAMESPACE_ID::int64 value) {
  _has_bits_[0] |= 0x00000002u;
  part2_ = value;
}
inline void QueryId::set_part2(::PROTOBUF_NAMESPACE_ID::int64 value) {
  _internal_set_part2(value);
  // @@protoc_insertion_point(field_set:exec.shared.QueryId.part2)
}

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

// DrillPBError

// optional string error_id = 1;
inline bool DrillPBError::_internal_has_error_id() const {
  bool value = (_has_bits_[0] & 0x00000001u) != 0;
  return value;
}
inline bool DrillPBError::has_error_id() const {
  return _internal_has_error_id();
}
inline void DrillPBError::clear_error_id() {
  error_id_.ClearToEmpty();
  _has_bits_[0] &= ~0x00000001u;
}
inline const std::string& DrillPBError::error_id() const {
  // @@protoc_insertion_point(field_get:exec.shared.DrillPBError.error_id)
  return _internal_error_id();
}
template <typename ArgT0, typename... ArgT>
PROTOBUF_ALWAYS_INLINE
inline void DrillPBError::set_error_id(ArgT0&& arg0, ArgT... args) {
 _has_bits_[0] |= 0x00000001u;
 error_id_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArena());
  // @@protoc_insertion_point(field_set:exec.shared.DrillPBError.error_id)
}
inline std::string* DrillPBError::mutable_error_id() {
  // @@protoc_insertion_point(field_mutable:exec.shared.DrillPBError.error_id)
  return _internal_mutable_error_id();
}
inline const std::string& DrillPBError::_internal_error_id() const {
  return error_id_.Get();
}
inline void DrillPBError::_internal_set_error_id(const std::string& value) {
  _has_bits_[0] |= 0x00000001u;
  error_id_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena());
}
inline std::string* DrillPBError::_internal_mutable_error_id() {
  _has_bits_[0] |= 0x00000001u;
  return error_id_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena());
}
inline std::string* DrillPBError::release_error_id() {
  // @@protoc_insertion_point(field_release:exec.shared.DrillPBError.error_id)
  if (!_internal_has_error_id()) {
    return nullptr;
  }
  _has_bits_[0] &= ~0x00000001u;
  return error_id_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena());
}
inline void DrillPBError::set_allocated_error_id(std::string* error_id) {
  if (error_id != nullptr) {
    _has_bits_[0] |= 0x00000001u;
  } else {
    _has_bits_[0] &= ~0x00000001u;
  }
  error_id_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), error_id,
      GetArena());
  // @@protoc_insertion_point(field_set_allocated:exec.shared.DrillPBError.error_id)
}

// optional .exec.DrillbitEndpoint endpoint = 2;
inline bool DrillPBError::_internal_has_endpoint() const {
  bool value = (_has_bits_[0] & 0x00000004u) != 0;
  PROTOBUF_ASSUME(!value || endpoint_ != nullptr);
  return value;
}
inline bool DrillPBError::has_endpoint() const {
  return _internal_has_endpoint();
}
inline const ::exec::DrillbitEndpoint& DrillPBError::_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& DrillPBError::endpoint() const {
  // @@protoc_insertion_point(field_get:exec.shared.DrillPBError.endpoint)
  return _internal_endpoint();
}
inline void DrillPBError::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] |= 0x00000004u;
  } else {
    _has_bits_[0] &= ~0x00000004u;
  }
  // @@protoc_insertion_point(field_unsafe_arena_set_allocated:exec.shared.DrillPBError.endpoint)
}
inline ::exec::DrillbitEndpoint* DrillPBError::release_endpoint() {
  _has_bits_[0] &= ~0x00000004u;
  ::exec::DrillbitEndpoint* temp = endpoint_;
  endpoint_ = nullptr;
  if (GetArena() != nullptr) {
    temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp);
  }
  return temp;
}
inline ::exec::DrillbitEndpoint* DrillPBError::unsafe_arena_release_endpoint() {
  // @@protoc_insertion_point(field_release:exec.shared.DrillPBError.endpoint)
  _has_bits_[0] &= ~0x00000004u;
  ::exec::DrillbitEndpoint* temp = endpoint_;
  endpoint_ = nullptr;
  return temp;
}
inline ::exec::DrillbitEndpoint* DrillPBError::_internal_mutable_endpoint() {
  _has_bits_[0] |= 0x00000004u;
  if (endpoint_ == nullptr) {
    auto* p = CreateMaybeMessage<::exec::DrillbitEndpoint>(GetArena());
    endpoint_ = p;
  }
  return endpoint_;
}
inline ::exec::DrillbitEndpoint* DrillPBError::mutable_endpoint() {
  // @@protoc_insertion_point(field_mutable:exec.shared.DrillPBError.endpoint)
  return _internal_mutable_endpoint();
}
inline void DrillPBError::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] |= 0x00000004u;
  } else {
    _has_bits_[0] &= ~0x00000004u;
  }
  endpoint_ = endpoint;
  // @@protoc_insertion_point(field_set_allocated:exec.shared.DrillPBError.endpoint)
}

// optional .exec.shared.DrillPBError.ErrorType error_type = 3;
inline bool DrillPBError::_internal_has_error_type() const {
  bool value = (_has_bits_[0] & 0x00000010u) != 0;
  return value;
}
inline bool DrillPBError::has_error_type() const {
  return _internal_has_error_type();
}
inline void DrillPBError::clear_error_type() {
  error_type_ = 0;
  _has_bits_[0] &= ~0x00000010u;
}
inline ::exec::shared::DrillPBError_ErrorType DrillPBError::_internal_error_type() const {
  return static_cast< ::exec::shared::DrillPBError_ErrorType >(error_type_);
}
inline ::exec::shared::DrillPBError_ErrorType DrillPBError::error_type() const {
  // @@protoc_insertion_point(field_get:exec.shared.DrillPBError.error_type)
  return _internal_error_type();
}
inline void DrillPBError::_internal_set_error_type(::exec::shared::DrillPBError_ErrorType value) {
  assert(::exec::shared::DrillPBError_ErrorType_IsValid(value));
  _has_bits_[0] |= 0x00000010u;
  error_type_ = value;
}
inline void DrillPBError::set_error_type(::exec::shared::DrillPBError_ErrorType value) {
  _internal_set_error_type(value);
  // @@protoc_insertion_point(field_set:exec.shared.DrillPBError.error_type)
}

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

// optional .exec.shared.ExceptionWrapper exception = 5;
inline bool DrillPBError::_internal_has_exception() const {
  bool value = (_has_bits_[0] & 0x00000008u) != 0;
  PROTOBUF_ASSUME(!value || exception_ != nullptr);
  return value;
}
inline bool DrillPBError::has_exception() const {
  return _internal_has_exception();
}
inline void DrillPBError::clear_exception() {
  if (exception_ != nullptr) exception_->Clear();
  _has_bits_[0] &= ~0x00000008u;
}
inline const ::exec::shared::ExceptionWrapper& DrillPBError::_internal_exception() const {
  const ::exec::shared::ExceptionWrapper* p = exception_;
  return p != nullptr ? *p : reinterpret_cast<const ::exec::shared::ExceptionWrapper&>(
      ::exec::shared::_ExceptionWrapper_default_instance_);
}
inline const ::exec::shared::ExceptionWrapper& DrillPBError::exception() const {
  // @@protoc_insertion_point(field_get:exec.shared.DrillPBError.exception)
  return _internal_exception();
}
inline void DrillPBError::unsafe_arena_set_allocated_exception(
    ::exec::shared::ExceptionWrapper* exception) {
  if (GetArena() == nullptr) {
    delete reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(exception_);
  }
  exception_ = exception;
  if (exception) {
    _has_bits_[0] |= 0x00000008u;
  } else {
    _has_bits_[0] &= ~0x00000008u;
  }
  // @@protoc_insertion_point(field_unsafe_arena_set_allocated:exec.shared.DrillPBError.exception)
}
inline ::exec::shared::ExceptionWrapper* DrillPBError::release_exception() {
  _has_bits_[0] &= ~0x00000008u;
  ::exec::shared::ExceptionWrapper* temp = exception_;
  exception_ = nullptr;
  if (GetArena() != nullptr) {
    temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp);
  }
  return temp;
}
inline ::exec::shared::ExceptionWrapper* DrillPBError::unsafe_arena_release_exception() {
  // @@protoc_insertion_point(field_release:exec.shared.DrillPBError.exception)
  _has_bits_[0] &= ~0x00000008u;
  ::exec::shared::ExceptionWrapper* temp = exception_;
  exception_ = nullptr;
  return temp;
}
inline ::exec::shared::ExceptionWrapper* DrillPBError::_internal_mutable_exception() {
  _has_bits_[0] |= 0x00000008u;
  if (exception_ == nullptr) {
    auto* p = CreateMaybeMessage<::exec::shared::ExceptionWrapper>(GetArena());
    exception_ = p;
  }
  return exception_;
}
inline ::exec::shared::ExceptionWrapper* DrillPBError::mutable_exception() {
  // @@protoc_insertion_point(field_mutable:exec.shared.DrillPBError.exception)
  return _internal_mutable_exception();
}
inline void DrillPBError::set_allocated_exception(::exec::shared::ExceptionWrapper* exception) {
  ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArena();
  if (message_arena == nullptr) {
    delete exception_;
  }
  if (exception) {
    ::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena =
      ::PROTOBUF_NAMESPACE_ID::Arena::GetArena(exception);
    if (message_arena != submessage_arena) {
      exception = ::PROTOBUF_NAMESPACE_ID::internal::GetOwnedMessage(
          message_arena, exception, submessage_arena);
    }
    _has_bits_[0] |= 0x00000008u;
  } else {
    _has_bits_[0] &= ~0x00000008u;
  }
  exception_ = exception;
  // @@protoc_insertion_point(field_set_allocated:exec.shared.DrillPBError.exception)
}

// repeated .exec.shared.ParsingError parsing_error = 6;
inline int DrillPBError::_internal_parsing_error_size() const {
  return parsing_error_.size();
}
inline int DrillPBError::parsing_error_size() const {
  return _internal_parsing_error_size();
}
inline void DrillPBError::clear_parsing_error() {
  parsing_error_.Clear();
}
inline ::exec::shared::ParsingError* DrillPBError::mutable_parsing_error(int index) {
  // @@protoc_insertion_point(field_mutable:exec.shared.DrillPBError.parsing_error)
  return parsing_error_.Mutable(index);
}
inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::exec::shared::ParsingError >*
DrillPBError::mutable_parsing_error() {
  // @@protoc_insertion_point(field_mutable_list:exec.shared.DrillPBError.parsing_error)
  return &parsing_error_;
}
inline const ::exec::shared::ParsingError& DrillPBError::_internal_parsing_error(int index) const {
  return parsing_error_.Get(index);
}
inline const ::exec::shared::ParsingError& DrillPBError::parsing_error(int index) const {
  // @@protoc_insertion_point(field_get:exec.shared.DrillPBError.parsing_error)
  return _internal_parsing_error(index);
}
inline ::exec::shared::ParsingError* DrillPBError::_internal_add_parsing_error() {
  return parsing_error_.Add();
}
inline ::exec::shared::ParsingError* DrillPBError::add_parsing_error() {
  // @@protoc_insertion_point(field_add:exec.shared.DrillPBError.parsing_error)
  return _internal_add_parsing_error();
}
inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::exec::shared::ParsingError >&
DrillPBError::parsing_error() const {
  // @@protoc_insertion_point(field_list:exec.shared.DrillPBError.parsing_error)
  return parsing_error_;
}

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

// ExceptionWrapper

// optional string exception_class = 1;
inline bool ExceptionWrapper::_internal_has_exception_class() const {
  bool value = (_has_bits_[0] & 0x00000001u) != 0;
  return value;
}
inline bool ExceptionWrapper::has_exception_class() const {
  return _internal_has_exception_class();
}
inline void ExceptionWrapper::clear_exception_class() {
  exception_class_.ClearToEmpty();
  _has_bits_[0] &= ~0x00000001u;
}
inline const std::string& ExceptionWrapper::exception_class() const {
  // @@protoc_insertion_point(field_get:exec.shared.ExceptionWrapper.exception_class)
  return _internal_exception_class();
}
template <typename ArgT0, typename... ArgT>
PROTOBUF_ALWAYS_INLINE
inline void ExceptionWrapper::set_exception_class(ArgT0&& arg0, ArgT... args) {
 _has_bits_[0] |= 0x00000001u;
 exception_class_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArena());
  // @@protoc_insertion_point(field_set:exec.shared.ExceptionWrapper.exception_class)
}
inline std::string* ExceptionWrapper::mutable_exception_class() {
  // @@protoc_insertion_point(field_mutable:exec.shared.ExceptionWrapper.exception_class)
  return _internal_mutable_exception_class();
}
inline const std::string& ExceptionWrapper::_internal_exception_class() const {
  return exception_class_.Get();
}
inline void ExceptionWrapper::_internal_set_exception_class(const std::string& value) {
  _has_bits_[0] |= 0x00000001u;
  exception_class_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena());
}
inline std::string* ExceptionWrapper::_internal_mutable_exception_class() {
  _has_bits_[0] |= 0x00000001u;
  return exception_class_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena());
}
inline std::string* ExceptionWrapper::release_exception_class() {
  // @@protoc_insertion_point(field_release:exec.shared.ExceptionWrapper.exception_class)
  if (!_internal_has_exception_class()) {
    return nullptr;
  }
  _has_bits_[0] &= ~0x00000001u;
  return exception_class_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena());
}
inline void ExceptionWrapper::set_allocated_exception_class(std::string* exception_class) {
  if (exception_class != nullptr) {
    _has_bits_[0] |= 0x00000001u;
  } else {
    _has_bits_[0] &= ~0x00000001u;
  }
  exception_class_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), exception_class,
      GetArena());
  // @@protoc_insertion_point(field_set_allocated:exec.shared.ExceptionWrapper.exception_class)
}

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

// repeated .exec.shared.StackTraceElementWrapper stack_trace = 3;
inline int ExceptionWrapper::_internal_stack_trace_size() const {
  return stack_trace_.size();
}
inline int ExceptionWrapper::stack_trace_size() const {
  return _internal_stack_trace_size();
}
inline void ExceptionWrapper::clear_stack_trace() {
  stack_trace_.Clear();
}
inline ::exec::shared::StackTraceElementWrapper* ExceptionWrapper::mutable_stack_trace(int index) {
  // @@protoc_insertion_point(field_mutable:exec.shared.ExceptionWrapper.stack_trace)
  return stack_trace_.Mutable(index);
}
inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::exec::shared::StackTraceElementWrapper >*
ExceptionWrapper::mutable_stack_trace() {
  // @@protoc_insertion_point(field_mutable_list:exec.shared.ExceptionWrapper.stack_trace)
  return &stack_trace_;
}
inline const ::exec::shared::StackTraceElementWrapper& ExceptionWrapper::_internal_stack_trace(int index) const {
  return stack_trace_.Get(index);
}
inline const ::exec::shared::StackTraceElementWrapper& ExceptionWrapper::stack_trace(int index) const {
  // @@protoc_insertion_point(field_get:exec.shared.ExceptionWrapper.stack_trace)
  return _internal_stack_trace(index);
}
inline ::exec::shared::StackTraceElementWrapper* ExceptionWrapper::_internal_add_stack_trace() {
  return stack_trace_.Add();
}
inline ::exec::shared::StackTraceElementWrapper* ExceptionWrapper::add_stack_trace() {
  // @@protoc_insertion_point(field_add:exec.shared.ExceptionWrapper.stack_trace)
  return _internal_add_stack_trace();
}
inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::exec::shared::StackTraceElementWrapper >&
ExceptionWrapper::stack_trace() const {
  // @@protoc_insertion_point(field_list:exec.shared.ExceptionWrapper.stack_trace)
  return stack_trace_;
}

// optional .exec.shared.ExceptionWrapper cause = 4;
inline bool ExceptionWrapper::_internal_has_cause() const {
  bool value = (_has_bits_[0] & 0x00000004u) != 0;
  PROTOBUF_ASSUME(!value || cause_ != nullptr);
  return value;
}
inline bool ExceptionWrapper::has_cause() const {
  return _internal_has_cause();
}
inline void ExceptionWrapper::clear_cause() {
  if (cause_ != nullptr) cause_->Clear();
  _has_bits_[0] &= ~0x00000004u;
}
inline const ::exec::shared::ExceptionWrapper& ExceptionWrapper::_internal_cause() const {
  const ::exec::shared::ExceptionWrapper* p = cause_;
  return p != nullptr ? *p : reinterpret_cast<const ::exec::shared::ExceptionWrapper&>(
      ::exec::shared::_ExceptionWrapper_default_instance_);
}
inline const ::exec::shared::ExceptionWrapper& ExceptionWrapper::cause() const {
  // @@protoc_insertion_point(field_get:exec.shared.ExceptionWrapper.cause)
  return _internal_cause();
}
inline void ExceptionWrapper::unsafe_arena_set_allocated_cause(
    ::exec::shared::ExceptionWrapper* cause) {
  if (GetArena() == nullptr) {
    delete reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(cause_);
  }
  cause_ = cause;
  if (cause) {
    _has_bits_[0] |= 0x00000004u;
  } else {
    _has_bits_[0] &= ~0x00000004u;
  }
  // @@protoc_insertion_point(field_unsafe_arena_set_allocated:exec.shared.ExceptionWrapper.cause)
}
inline ::exec::shared::ExceptionWrapper* ExceptionWrapper::release_cause() {
  _has_bits_[0] &= ~0x00000004u;
  ::exec::shared::ExceptionWrapper* temp = cause_;
  cause_ = nullptr;
  if (GetArena() != nullptr) {
    temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp);
  }
  return temp;
}
inline ::exec::shared::ExceptionWrapper* ExceptionWrapper::unsafe_arena_release_cause() {
  // @@protoc_insertion_point(field_release:exec.shared.ExceptionWrapper.cause)
  _has_bits_[0] &= ~0x00000004u;
  ::exec::shared::ExceptionWrapper* temp = cause_;
  cause_ = nullptr;
  return temp;
}
inline ::exec::shared::ExceptionWrapper* ExceptionWrapper::_internal_mutable_cause() {
  _has_bits_[0] |= 0x00000004u;
  if (cause_ == nullptr) {
    auto* p = CreateMaybeMessage<::exec::shared::ExceptionWrapper>(GetArena());
    cause_ = p;
  }
  return cause_;
}
inline ::exec::shared::ExceptionWrapper* ExceptionWrapper::mutable_cause() {
  // @@protoc_insertion_point(field_mutable:exec.shared.ExceptionWrapper.cause)
  return _internal_mutable_cause();
}
inline void ExceptionWrapper::set_allocated_cause(::exec::shared::ExceptionWrapper* cause) {
  ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArena();
  if (message_arena == nullptr) {
    delete cause_;
  }
  if (cause) {
    ::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena =
      ::PROTOBUF_NAMESPACE_ID::Arena::GetArena(cause);
    if (message_arena != submessage_arena) {
      cause = ::PROTOBUF_NAMESPACE_ID::internal::GetOwnedMessage(
          message_arena, cause, submessage_arena);
    }
    _has_bits_[0] |= 0x00000004u;
  } else {
    _has_bits_[0] &= ~0x00000004u;
  }
  cause_ = cause;
  // @@protoc_insertion_point(field_set_allocated:exec.shared.ExceptionWrapper.cause)
}

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

// StackTraceElementWrapper

// optional string class_name = 1;
inline bool StackTraceElementWrapper::_internal_has_class_name() const {
  bool value = (_has_bits_[0] & 0x00000001u) != 0;
  return value;
}
inline bool StackTraceElementWrapper::has_class_name() const {
  return _internal_has_class_name();
}
inline void StackTraceElementWrapper::clear_class_name() {
  class_name_.ClearToEmpty();
  _has_bits_[0] &= ~0x00000001u;
}
inline const std::string& StackTraceElementWrapper::class_name() const {
  // @@protoc_insertion_point(field_get:exec.shared.StackTraceElementWrapper.class_name)
  return _internal_class_name();
}
template <typename ArgT0, typename... ArgT>
PROTOBUF_ALWAYS_INLINE
inline void StackTraceElementWrapper::set_class_name(ArgT0&& arg0, ArgT... args) {
 _has_bits_[0] |= 0x00000001u;
 class_name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArena());
  // @@protoc_insertion_point(field_set:exec.shared.StackTraceElementWrapper.class_name)
}
inline std::string* StackTraceElementWrapper::mutable_class_name() {
  // @@protoc_insertion_point(field_mutable:exec.shared.StackTraceElementWrapper.class_name)
  return _internal_mutable_class_name();
}
inline const std::string& StackTraceElementWrapper::_internal_class_name() const {
  return class_name_.Get();
}
inline void StackTraceElementWrapper::_internal_set_class_name(const std::string& value) {
  _has_bits_[0] |= 0x00000001u;
  class_name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena());
}
inline std::string* StackTraceElementWrapper::_internal_mutable_class_name() {
  _has_bits_[0] |= 0x00000001u;
  return class_name_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena());
}
inline std::string* StackTraceElementWrapper::release_class_name() {
  // @@protoc_insertion_point(field_release:exec.shared.StackTraceElementWrapper.class_name)
  if (!_internal_has_class_name()) {
    return nullptr;
  }
  _has_bits_[0] &= ~0x00000001u;
  return class_name_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena());
}
inline void StackTraceElementWrapper::set_allocated_class_name(std::string* class_name) {
  if (class_name != nullptr) {
    _has_bits_[0] |= 0x00000001u;
  } else {
    _has_bits_[0] &= ~0x00000001u;
  }
  class_name_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), class_name,
      GetArena());
  // @@protoc_insertion_point(field_set_allocated:exec.shared.StackTraceElementWrapper.class_name)
}

// optional string file_name = 2;
inline bool StackTraceElementWrapper::_internal_has_file_name() const {
  bool value = (_has_bits_[0] & 0x00000002u) != 0;
  return value;
}
inline bool StackTraceElementWrapper::has_file_name() const {
  return _internal_has_file_name();
}
inline void StackTraceElementWrapper::clear_file_name() {
  file_name_.ClearToEmpty();
  _has_bits_[0] &= ~0x00000002u;
}
inline const std::string& StackTraceElementWrapper::file_name() const {
  // @@protoc_insertion_point(field_get:exec.shared.StackTraceElementWrapper.file_name)
  return _internal_file_name();
}
template <typename ArgT0, typename... ArgT>
PROTOBUF_ALWAYS_INLINE
inline void StackTraceElementWrapper::set_file_name(ArgT0&& arg0, ArgT... args) {
 _has_bits_[0] |= 0x00000002u;
 file_name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArena());
  // @@protoc_insertion_point(field_set:exec.shared.StackTraceElementWrapper.file_name)
}
inline std::string* StackTraceElementWrapper::mutable_file_name() {
  // @@protoc_insertion_point(field_mutable:exec.shared.StackTraceElementWrapper.file_name)
  return _internal_mutable_file_name();
}
inline const std::string& StackTraceElementWrapper::_internal_file_name() const {
  return file_name_.Get();
}
inline void StackTraceElementWrapper::_internal_set_file_name(const std::string& value) {
  _has_bits_[0] |= 0x00000002u;
  file_name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena());
}
inline std::string* StackTraceElementWrapper::_internal_mutable_file_name() {
  _has_bits_[0] |= 0x00000002u;
  return file_name_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena());
}
inline std::string* StackTraceElementWrapper::release_file_name() {
  // @@protoc_insertion_point(field_release:exec.shared.StackTraceElementWrapper.file_name)
  if (!_internal_has_file_name()) {
    return nullptr;
  }
  _has_bits_[0] &= ~0x00000002u;
  return file_name_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena());
}
inline void StackTraceElementWrapper::set_allocated_file_name(std::string* file_name) {
  if (file_name != nullptr) {
    _has_bits_[0] |= 0x00000002u;
  } else {
    _has_bits_[0] &= ~0x00000002u;
  }
  file_name_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), file_name,
      GetArena());
  // @@protoc_insertion_point(field_set_allocated:exec.shared.StackTraceElementWrapper.file_name)
}

// optional int32 line_number = 3;
inline bool StackTraceElementWrapper::_internal_has_line_number() const {
  bool value = (_has_bits_[0] & 0x00000008u) != 0;
  return value;
}
inline bool StackTraceElementWrapper::has_line_number() const {
  return _internal_has_line_number();
}
inline void StackTraceElementWrapper::clear_line_number() {
  line_number_ = 0;
  _has_bits_[0] &= ~0x00000008u;
}
inline ::PROTOBUF_NAMESPACE_ID::int32 StackTraceElementWrapper::_internal_line_number() const {
  return line_number_;
}
inline ::PROTOBUF_NAMESPACE_ID::int32 StackTraceElementWrapper::line_number() const {
  // @@protoc_insertion_point(field_get:exec.shared.StackTraceElementWrapper.line_number)
  return _internal_line_number();
}
inline void StackTraceElementWrapper::_internal_set_line_number(::PROTOBUF_NAMESPACE_ID::int32 value) {
  _has_bits_[0] |= 0x00000008u;
  line_number_ = value;
}
inline void StackTraceElementWrapper::set_line_number(::PROTOBUF_NAMESPACE_ID::int32 value) {
  _internal_set_line_number(value);
  // @@protoc_insertion_point(field_set:exec.shared.StackTraceElementWrapper.line_number)
}

// optional string method_name = 4;
inline bool StackTraceElementWrapper::_internal_has_method_name() const {
  bool value = (_has_bits_[0] & 0x00000004u) != 0;
  return value;
}
inline bool StackTraceElementWrapper::has_method_name() const {
  return _internal_has_method_name();
}
inline void StackTraceElementWrapper::clear_method_name() {
  method_name_.ClearToEmpty();
  _has_bits_[0] &= ~0x00000004u;
}
inline const std::string& StackTraceElementWrapper::method_name() const {
  // @@protoc_insertion_point(field_get:exec.shared.StackTraceElementWrapper.method_name)
  return _internal_method_name();
}
template <typename ArgT0, typename... ArgT>
PROTOBUF_ALWAYS_INLINE
inline void StackTraceElementWrapper::set_method_name(ArgT0&& arg0, ArgT... args) {
 _has_bits_[0] |= 0x00000004u;
 method_name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArena());
  // @@protoc_insertion_point(field_set:exec.shared.StackTraceElementWrapper.method_name)
}
inline std::string* StackTraceElementWrapper::mutable_method_name() {
  // @@protoc_insertion_point(field_mutable:exec.shared.StackTraceElementWrapper.method_name)
  return _internal_mutable_method_name();
}
inline const std::string& StackTraceElementWrapper::_internal_method_name() const {
  return method_name_.Get();
}
inline void StackTraceElementWrapper::_internal_set_method_name(const std::string& value) {
  _has_bits_[0] |= 0x00000004u;
  method_name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena());
}
inline std::string* StackTraceElementWrapper::_internal_mutable_method_name() {
  _has_bits_[0] |= 0x00000004u;
  return method_name_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena());
}
inline std::string* StackTraceElementWrapper::release_method_name() {
  // @@protoc_insertion_point(field_release:exec.shared.StackTraceElementWrapper.method_name)
  if (!_internal_has_method_name()) {
    return nullptr;
  }
  _has_bits_[0] &= ~0x00000004u;
  return method_name_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena());
}
inline void StackTraceElementWrapper::set_allocated_method_name(std::string* method_name) {
  if (method_name != nullptr) {
    _has_bits_[0] |= 0x00000004u;
  } else {
    _has_bits_[0] &= ~0x00000004u;
  }
  method_name_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), method_name,
      GetArena());
  // @@protoc_insertion_point(field_set_allocated:exec.shared.StackTraceElementWrapper.method_name)
}

// optional bool is_native_method = 5;
inline bool StackTraceElementWrapper::_internal_has_is_native_method() const {
  bool value = (_has_bits_[0] & 0x00000010u) != 0;
  return value;
}
inline bool StackTraceElementWrapper::has_is_native_method() const {
  return _internal_has_is_native_method();
}
inline void StackTraceElementWrapper::clear_is_native_method() {
  is_native_method_ = false;
  _has_bits_[0] &= ~0x00000010u;
}
inline bool StackTraceElementWrapper::_internal_is_native_method() const {
  return is_native_method_;
}
inline bool StackTraceElementWrapper::is_native_method() const {
  // @@protoc_insertion_point(field_get:exec.shared.StackTraceElementWrapper.is_native_method)
  return _internal_is_native_method();
}
inline void StackTraceElementWrapper::_internal_set_is_native_method(bool value) {
  _has_bits_[0] |= 0x00000010u;
  is_native_method_ = value;
}
inline void StackTraceElementWrapper::set_is_native_method(bool value) {
  _internal_set_is_native_method(value);
  // @@protoc_insertion_point(field_set:exec.shared.StackTraceElementWrapper.is_native_method)
}

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

// ParsingError

// optional int32 start_column = 2;
inline bool ParsingError::_internal_has_start_column() const {
  bool value = (_has_bits_[0] & 0x00000001u) != 0;
  return value;
}
inline bool ParsingError::has_start_column() const {
  return _internal_has_start_column();
}
inline void ParsingError::clear_start_column() {
  start_column_ = 0;
  _has_bits_[0] &= ~0x00000001u;
}
inline ::PROTOBUF_NAMESPACE_ID::int32 ParsingError::_internal_start_column() const {
  return start_column_;
}
inline ::PROTOBUF_NAMESPACE_ID::int32 ParsingError::start_column() const {
  // @@protoc_insertion_point(field_get:exec.shared.ParsingError.start_column)
  return _internal_start_column();
}
inline void ParsingError::_internal_set_start_column(::PROTOBUF_NAMESPACE_ID::int32 value) {
  _has_bits_[0] |= 0x00000001u;
  start_column_ = value;
}
inline void ParsingError::set_start_column(::PROTOBUF_NAMESPACE_ID::int32 value) {
  _internal_set_start_column(value);
  // @@protoc_insertion_point(field_set:exec.shared.ParsingError.start_column)
}

// optional int32 start_row = 3;
inline bool ParsingError::_internal_has_start_row() const {
  bool value = (_has_bits_[0] & 0x00000002u) != 0;
  return value;
}
inline bool ParsingError::has_start_row() const {
  return _internal_has_start_row();
}
inline void ParsingError::clear_start_row() {
  start_row_ = 0;
  _has_bits_[0] &= ~0x00000002u;
}
inline ::PROTOBUF_NAMESPACE_ID::int32 ParsingError::_internal_start_row() const {
  return start_row_;
}
inline ::PROTOBUF_NAMESPACE_ID::int32 ParsingError::start_row() const {
  // @@protoc_insertion_point(field_get:exec.shared.ParsingError.start_row)
  return _internal_start_row();
}
inline void ParsingError::_internal_set_start_row(::PROTOBUF_NAMESPACE_ID::int32 value) {
  _has_bits_[0] |= 0x00000002u;
  start_row_ = value;
}
inline void ParsingError::set_start_row(::PROTOBUF_NAMESPACE_ID::int32 value) {
  _internal_set_start_row(value);
  // @@protoc_insertion_point(field_set:exec.shared.ParsingError.start_row)
}

// optional int32 end_column = 4;
inline bool ParsingError::_internal_has_end_column() const {
  bool value = (_has_bits_[0] & 0x00000004u) != 0;
  return value;
}
inline bool ParsingError::has_end_column() const {
  return _internal_has_end_column();
}
inline void ParsingError::clear_end_column() {
  end_column_ = 0;
  _has_bits_[0] &= ~0x00000004u;
}
inline ::PROTOBUF_NAMESPACE_ID::int32 ParsingError::_internal_end_column() const {
  return end_column_;
}
inline ::PROTOBUF_NAMESPACE_ID::int32 ParsingError::end_column() const {
  // @@protoc_insertion_point(field_get:exec.shared.ParsingError.end_column)
  return _internal_end_column();
}
inline void ParsingError::_internal_set_end_column(::PROTOBUF_NAMESPACE_ID::int32 value) {
  _has_bits_[0] |= 0x00000004u;
  end_column_ = value;
}
inline void ParsingError::set_end_column(::PROTOBUF_NAMESPACE_ID::int32 value) {
  _internal_set_end_column(value);
  // @@protoc_insertion_point(field_set:exec.shared.ParsingError.end_column)
}

// optional int32 end_row = 5;
inline bool ParsingError::_internal_has_end_row() const {
  bool value = (_has_bits_[0] & 0x00000008u) != 0;
  return value;
}
inline bool ParsingError::has_end_row() const {
  return _internal_has_end_row();
}
inline void ParsingError::clear_end_row() {
  end_row_ = 0;
  _has_bits_[0] &= ~0x00000008u;
}
inline ::PROTOBUF_NAMESPACE_ID::int32 ParsingError::_internal_end_row() const {
  return end_row_;
}
inline ::PROTOBUF_NAMESPACE_ID::int32 ParsingError::end_row() const {
  // @@protoc_insertion_point(field_get:exec.shared.ParsingError.end_row)
  return _internal_end_row();
}
inline void ParsingError::_internal_set_end_row(::PROTOBUF_NAMESPACE_ID::int32 value) {
  _has_bits_[0] |= 0x00000008u;
  end_row_ = value;
}
inline void ParsingError::set_end_row(::PROTOBUF_NAMESPACE_ID::int32 value) {
  _internal_set_end_row(value);
  // @@protoc_insertion_point(field_set:exec.shared.ParsingError.end_row)
}

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

// RecordBatchDef

// optional int32 record_count = 1;
inline bool RecordBatchDef::_internal_has_record_count() const {
  bool value = (_has_bits_[0] & 0x00000001u) != 0;
  return value;
}
inline bool RecordBatchDef::has_record_count() const {
  return _internal_has_record_count();
}
inline void RecordBatchDef::clear_record_count() {
  record_count_ = 0;
  _has_bits_[0] &= ~0x00000001u;
}
inline ::PROTOBUF_NAMESPACE_ID::int32 RecordBatchDef::_internal_record_count() const {
  return record_count_;
}
inline ::PROTOBUF_NAMESPACE_ID::int32 RecordBatchDef::record_count() const {
  // @@protoc_insertion_point(field_get:exec.shared.RecordBatchDef.record_count)
  return _internal_record_count();
}
inline void RecordBatchDef::_internal_set_record_count(::PROTOBUF_NAMESPACE_ID::int32 value) {
  _has_bits_[0] |= 0x00000001u;
  record_count_ = value;
}
inline void RecordBatchDef::set_record_count(::PROTOBUF_NAMESPACE_ID::int32 value) {
  _internal_set_record_count(value);
  // @@protoc_insertion_point(field_set:exec.shared.RecordBatchDef.record_count)
}

// repeated .exec.shared.SerializedField field = 2;
inline int RecordBatchDef::_internal_field_size() const {
  return field_.size();
}
inline int RecordBatchDef::field_size() const {
  return _internal_field_size();
}
inline void RecordBatchDef::clear_field() {
  field_.Clear();
}
inline ::exec::shared::SerializedField* RecordBatchDef::mutable_field(int index) {
  // @@protoc_insertion_point(field_mutable:exec.shared.RecordBatchDef.field)
  return field_.Mutable(index);
}
inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::exec::shared::SerializedField >*
RecordBatchDef::mutable_field() {
  // @@protoc_insertion_point(field_mutable_list:exec.shared.RecordBatchDef.field)
  return &field_;
}
inline const ::exec::shared::SerializedField& RecordBatchDef::_internal_field(int index) const {
  return field_.Get(index);
}
inline const ::exec::shared::SerializedField& RecordBatchDef::field(int index) const {
  // @@protoc_insertion_point(field_get:exec.shared.RecordBatchDef.field)
  return _internal_field(index);
}
inline ::exec::shared::SerializedField* RecordBatchDef::_internal_add_field() {
  return field_.Add();
}
inline ::exec::shared::SerializedField* RecordBatchDef::add_field() {
  // @@protoc_insertion_point(field_add:exec.shared.RecordBatchDef.field)
  return _internal_add_field();
}
inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::exec::shared::SerializedField >&
RecordBatchDef::field() const {
  // @@protoc_insertion_point(field_list:exec.shared.RecordBatchDef.field)
  return field_;
}

// optional bool carries_two_byte_selection_vector = 3;
inline bool RecordBatchDef::_internal_has_carries_two_byte_selection_vector() const {
  bool value = (_has_bits_[0] & 0x00000002u) != 0;
  return value;
}
inline bool RecordBatchDef::has_carries_two_byte_selection_vector() const {
  return _internal_has_carries_two_byte_selection_vector();
}
inline void RecordBatchDef::clear_carries_two_byte_selection_vector() {
  carries_two_byte_selection_vector_ = false;
  _has_bits_[0] &= ~0x00000002u;
}
inline bool RecordBatchDef::_internal_carries_two_byte_selection_vector() const {
  return carries_two_byte_selection_vector_;
}
inline bool RecordBatchDef::carries_two_byte_selection_vector() const {
  // @@protoc_insertion_point(field_get:exec.shared.RecordBatchDef.carries_two_byte_selection_vector)
  return _internal_carries_two_byte_selection_vector();
}
inline void RecordBatchDef::_internal_set_carries_two_byte_selection_vector(bool value) {
  _has_bits_[0] |= 0x00000002u;
  carries_two_byte_selection_vector_ = value;
}
inline void RecordBatchDef::set_carries_two_byte_selection_vector(bool value) {
  _internal_set_carries_two_byte_selection_vector(value);
  // @@protoc_insertion_point(field_set:exec.shared.RecordBatchDef.carries_two_byte_selection_vector)
}

// optional int32 affected_rows_count = 4;
inline bool RecordBatchDef::_internal_has_affected_rows_count() const {
  bool value = (_has_bits_[0] & 0x00000004u) != 0;
  return value;
}
inline bool RecordBatchDef::has_affected_rows_count() const {
  return _internal_has_affected_rows_count();
}
inline void RecordBatchDef::clear_affected_rows_count() {
  affected_rows_count_ = 0;
  _has_bits_[0] &= ~0x00000004u;
}
inline ::PROTOBUF_NAMESPACE_ID::int32 RecordBatchDef::_internal_affected_rows_count() const {
  return affected_rows_count_;
}
inline ::PROTOBUF_NAMESPACE_ID::int32 RecordBatchDef::affected_rows_count() const {
  // @@protoc_insertion_point(field_get:exec.shared.RecordBatchDef.affected_rows_count)
  return _internal_affected_rows_count();
}
inline void RecordBatchDef::_internal_set_affected_rows_count(::PROTOBUF_NAMESPACE_ID::int32 value) {
  _has_bits_[0] |= 0x00000004u;
  affected_rows_count_ = value;
}
inline void RecordBatchDef::set_affected_rows_count(::PROTOBUF_NAMESPACE_ID::int32 value) {
  _internal_set_affected_rows_count(value);
  // @@protoc_insertion_point(field_set:exec.shared.RecordBatchDef.affected_rows_count)
}

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

// NamePart

// optional .exec.shared.NamePart.Type type = 1;
inline bool NamePart::_internal_has_type() const {
  bool value = (_has_bits_[0] & 0x00000004u) != 0;
  return value;
}
inline bool NamePart::has_type() const {
  return _internal_has_type();
}
inline void NamePart::clear_type() {
  type_ = 0;
  _has_bits_[0] &= ~0x00000004u;
}
inline ::exec::shared::NamePart_Type NamePart::_internal_type() const {
  return static_cast< ::exec::shared::NamePart_Type >(type_);
}
inline ::exec::shared::NamePart_Type NamePart::type() const {
  // @@protoc_insertion_point(field_get:exec.shared.NamePart.type)
  return _internal_type();
}
inline void NamePart::_internal_set_type(::exec::shared::NamePart_Type value) {
  assert(::exec::shared::NamePart_Type_IsValid(value));
  _has_bits_[0] |= 0x00000004u;
  type_ = value;
}
inline void NamePart::set_type(::exec::shared::NamePart_Type value) {
  _internal_set_type(value);
  // @@protoc_insertion_point(field_set:exec.shared.NamePart.type)
}

// optional string name = 2;
inline bool NamePart::_internal_has_name() const {
  bool value = (_has_bits_[0] & 0x00000001u) != 0;
  return value;
}
inline bool NamePart::has_name() const {
  return _internal_has_name();
}
inline void NamePart::clear_name() {
  name_.ClearToEmpty();
  _has_bits_[0] &= ~0x00000001u;
}
inline const std::string& NamePart::name() const {
  // @@protoc_insertion_point(field_get:exec.shared.NamePart.name)
  return _internal_name();
}
template <typename ArgT0, typename... ArgT>
PROTOBUF_ALWAYS_INLINE
inline void NamePart::set_name(ArgT0&& arg0, ArgT... args) {
 _has_bits_[0] |= 0x00000001u;
 name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArena());
  // @@protoc_insertion_point(field_set:exec.shared.NamePart.name)
}
inline std::string* NamePart::mutable_name() {
  // @@protoc_insertion_point(field_mutable:exec.shared.NamePart.name)
  return _internal_mutable_name();
}
inline const std::string& NamePart::_internal_name() const {
  return name_.Get();
}
inline void NamePart::_internal_set_name(const std::string& value) {
  _has_bits_[0] |= 0x00000001u;
  name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena());
}
inline std::string* NamePart::_internal_mutable_name() {
  _has_bits_[0] |= 0x00000001u;
  return name_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena());
}
inline std::string* NamePart::release_name() {
  // @@protoc_insertion_point(field_release:exec.shared.NamePart.name)
  if (!_internal_has_name()) {
    return nullptr;
  }
  _has_bits_[0] &= ~0x00000001u;
  return name_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena());
}
inline void NamePart::set_allocated_name(std::string* name) {
  if (name != nullptr) {
    _has_bits_[0] |= 0x00000001u;
  } else {
    _has_bits_[0] &= ~0x00000001u;
  }
  name_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), name,
      GetArena());
  // @@protoc_insertion_point(field_set_allocated:exec.shared.NamePart.name)
}

// optional .exec.shared.NamePart child = 3;
inline bool NamePart::_internal_has_child() const {
  bool value = (_has_bits_[0] & 0x00000002u) != 0;
  PROTOBUF_ASSUME(!value || child_ != nullptr);
  return value;
}
inline bool NamePart::has_child() const {
  return _internal_has_child();
}
inline void NamePart::clear_child() {
  if (child_ != nullptr) child_->Clear();
  _has_bits_[0] &= ~0x00000002u;
}
inline const ::exec::shared::NamePart& NamePart::_internal_child() const {
  const ::exec::shared::NamePart* p = child_;
  return p != nullptr ? *p : reinterpret_cast<const ::exec::shared::NamePart&>(
      ::exec::shared::_NamePart_default_instance_);
}
inline const ::exec::shared::NamePart& NamePart::child() const {
  // @@protoc_insertion_point(field_get:exec.shared.NamePart.child)
  return _internal_child();
}
inline void NamePart::unsafe_arena_set_allocated_child(
    ::exec::shared::NamePart* child) {
  if (GetArena() == nullptr) {
    delete reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(child_);
  }
  child_ = child;
  if (child) {
    _has_bits_[0] |= 0x00000002u;
  } else {
    _has_bits_[0] &= ~0x00000002u;
  }
  // @@protoc_insertion_point(field_unsafe_arena_set_allocated:exec.shared.NamePart.child)
}
inline ::exec::shared::NamePart* NamePart::release_child() {
  _has_bits_[0] &= ~0x00000002u;
  ::exec::shared::NamePart* temp = child_;
  child_ = nullptr;
  if (GetArena() != nullptr) {
    temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp);
  }
  return temp;
}
inline ::exec::shared::NamePart* NamePart::unsafe_arena_release_child() {
  // @@protoc_insertion_point(field_release:exec.shared.NamePart.child)
  _has_bits_[0] &= ~0x00000002u;
  ::exec::shared::NamePart* temp = child_;
  child_ = nullptr;
  return temp;
}
inline ::exec::shared::NamePart* NamePart::_internal_mutable_child() {
  _has_bits_[0] |= 0x00000002u;
  if (child_ == nullptr) {
    auto* p = CreateMaybeMessage<::exec::shared::NamePart>(GetArena());
    child_ = p;
  }
  return child_;
}
inline ::exec::shared::NamePart* NamePart::mutable_child() {
  // @@protoc_insertion_point(field_mutable:exec.shared.NamePart.child)
  return _internal_mutable_child();
}
inline void NamePart::set_allocated_child(::exec::shared::NamePart* child) {
  ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArena();
  if (message_arena == nullptr) {
    delete child_;
  }
  if (child) {
    ::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena =
      ::PROTOBUF_NAMESPACE_ID::Arena::GetArena(child);
    if (message_arena != submessage_arena) {
      child = ::PROTOBUF_NAMESPACE_ID::internal::GetOwnedMessage(
          message_arena, child, submessage_arena);
    }
    _has_bits_[0] |= 0x00000002u;
  } else {
    _has_bits_[0] &= ~0x00000002u;
  }
  child_ = child;
  // @@protoc_insertion_point(field_set_allocated:exec.shared.NamePart.child)
}

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

// SerializedField

// optional .common.MajorType major_type = 1;
inline bool SerializedField::_internal_has_major_type() const {
  bool value = (_has_bits_[0] & 0x00000001u) != 0;
  PROTOBUF_ASSUME(!value || major_type_ != nullptr);
  return value;
}
inline bool SerializedField::has_major_type() const {
  return _internal_has_major_type();
}
inline const ::common::MajorType& SerializedField::_internal_major_type() const {
  const ::common::MajorType* p = major_type_;
  return p != nullptr ? *p : reinterpret_cast<const ::common::MajorType&>(
      ::common::_MajorType_default_instance_);
}
inline const ::common::MajorType& SerializedField::major_type() const {
  // @@protoc_insertion_point(field_get:exec.shared.SerializedField.major_type)
  return _internal_major_type();
}
inline void SerializedField::unsafe_arena_set_allocated_major_type(
    ::common::MajorType* major_type) {
  if (GetArena() == nullptr) {
    delete reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(major_type_);
  }
  major_type_ = major_type;
  if (major_type) {
    _has_bits_[0] |= 0x00000001u;
  } else {
    _has_bits_[0] &= ~0x00000001u;
  }
  // @@protoc_insertion_point(field_unsafe_arena_set_allocated:exec.shared.SerializedField.major_type)
}
inline ::common::MajorType* SerializedField::release_major_type() {
  _has_bits_[0] &= ~0x00000001u;
  ::common::MajorType* temp = major_type_;
  major_type_ = nullptr;
  if (GetArena() != nullptr) {
    temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp);
  }
  return temp;
}
inline ::common::MajorType* SerializedField::unsafe_arena_release_major_type() {
  // @@protoc_insertion_point(field_release:exec.shared.SerializedField.major_type)
  _has_bits_[0] &= ~0x00000001u;
  ::common::MajorType* temp = major_type_;
  major_type_ = nullptr;
  return temp;
}
inline ::common::MajorType* SerializedField::_internal_mutable_major_type() {
  _has_bits_[0] |= 0x00000001u;
  if (major_type_ == nullptr) {
    auto* p = CreateMaybeMessage<::common::MajorType>(GetArena());
    major_type_ = p;
  }
  return major_type_;
}
inline ::common::MajorType* SerializedField::mutable_major_type() {
  // @@protoc_insertion_point(field_mutable:exec.shared.SerializedField.major_type)
  return _internal_mutable_major_type();
}
inline void SerializedField::set_allocated_major_type(::common::MajorType* major_type) {
  ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArena();
  if (message_arena == nullptr) {
    delete reinterpret_cast< ::PROTOBUF_NAMESPACE_ID::MessageLite*>(major_type_);
  }
  if (major_type) {
    ::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena =
      reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(major_type)->GetArena();
    if (message_arena != submessage_arena) {
      major_type = ::PROTOBUF_NAMESPACE_ID::internal::GetOwnedMessage(
          message_arena, major_type, submessage_arena);
    }
    _has_bits_[0] |= 0x00000001u;
  } else {
    _has_bits_[0] &= ~0x00000001u;
  }
  major_type_ = major_type;
  // @@protoc_insertion_point(field_set_allocated:exec.shared.SerializedField.major_type)
}

// optional .exec.shared.NamePart name_part = 2;
inline bool SerializedField::_internal_has_name_part() const {
  bool value = (_has_bits_[0] & 0x00000002u) != 0;
  PROTOBUF_ASSUME(!value || name_part_ != nullptr);
  return value;
}
inline bool SerializedField::has_name_part() const {
  return _internal_has_name_part();
}
inline void SerializedField::clear_name_part() {
  if (name_part_ != nullptr) name_part_->Clear();
  _has_bits_[0] &= ~0x00000002u;
}
inline const ::exec::shared::NamePart& SerializedField::_internal_name_part() const {
  const ::exec::shared::NamePart* p = name_part_;
  return p != nullptr ? *p : reinterpret_cast<const ::exec::shared::NamePart&>(
      ::exec::shared::_NamePart_default_instance_);
}
inline const ::exec::shared::NamePart& SerializedField::name_part() const {
  // @@protoc_insertion_point(field_get:exec.shared.SerializedField.name_part)
  return _internal_name_part();
}
inline void SerializedField::unsafe_arena_set_allocated_name_part(
    ::exec::shared::NamePart* name_part) {
  if (GetArena() == nullptr) {
    delete reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(name_part_);
  }
  name_part_ = name_part;
  if (name_part) {
    _has_bits_[0] |= 0x00000002u;
  } else {
    _has_bits_[0] &= ~0x00000002u;
  }
  // @@protoc_insertion_point(field_unsafe_arena_set_allocated:exec.shared.SerializedField.name_part)
}
inline ::exec::shared::NamePart* SerializedField::release_name_part() {
  _has_bits_[0] &= ~0x00000002u;
  ::exec::shared::NamePart* temp = name_part_;
  name_part_ = nullptr;
  if (GetArena() != nullptr) {
    temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp);
  }
  return temp;
}
inline ::exec::shared::NamePart* SerializedField::unsafe_arena_release_name_part() {
  // @@protoc_insertion_point(field_release:exec.shared.SerializedField.name_part)
  _has_bits_[0] &= ~0x00000002u;
  ::exec::shared::NamePart* temp = name_part_;
  name_part_ = nullptr;
  return temp;
}
inline ::exec::shared::NamePart* SerializedField::_internal_mutable_name_part() {
  _has_bits_[0] |= 0x00000002u;
  if (name_part_ == nullptr) {
    auto* p = CreateMaybeMessage<::exec::shared::NamePart>(GetArena());
    name_part_ = p;
  }
  return name_part_;
}
inline ::exec::shared::NamePart* SerializedField::mutable_name_part() {
  // @@protoc_insertion_point(field_mutable:exec.shared.SerializedField.name_part)
  return _internal_mutable_name_part();
}
inline void SerializedField::set_allocated_name_part(::exec::shared::NamePart* name_part) {
  ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArena();
  if (message_arena == nullptr) {
    delete name_part_;
  }
  if (name_part) {
    ::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena =
      ::PROTOBUF_NAMESPACE_ID::Arena::GetArena(name_part);
    if (message_arena != submessage_arena) {
      name_part = ::PROTOBUF_NAMESPACE_ID::internal::GetOwnedMessage(
          message_arena, name_part, submessage_arena);
    }
    _has_bits_[0] |= 0x00000002u;
  } else {
    _has_bits_[0] &= ~0x00000002u;
  }
  name_part_ = name_part;
  // @@protoc_insertion_point(field_set_allocated:exec.shared.SerializedField.name_part)
}

// repeated .exec.shared.SerializedField child = 3;
inline int SerializedField::_internal_child_size() const {
  return child_.size();
}
inline int SerializedField::child_size() const {
  return _internal_child_size();
}
inline void SerializedField::clear_child() {
  child_.Clear();
}
inline ::exec::shared::SerializedField* SerializedField::mutable_child(int index) {
  // @@protoc_insertion_point(field_mutable:exec.shared.SerializedField.child)
  return child_.Mutable(index);
}
inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::exec::shared::SerializedField >*
SerializedField::mutable_child() {
  // @@protoc_insertion_point(field_mutable_list:exec.shared.SerializedField.child)
  return &child_;
}
inline const ::exec::shared::SerializedField& SerializedField::_internal_child(int index) const {
  return child_.Get(index);
}
inline const ::exec::shared::SerializedField& SerializedField::child(int index) const {
  // @@protoc_insertion_point(field_get:exec.shared.SerializedField.child)
  return _internal_child(index);
}
inline ::exec::shared::SerializedField* SerializedField::_internal_add_child() {
  return child_.Add();
}
inline ::exec::shared::SerializedField* SerializedField::add_child() {
  // @@protoc_insertion_point(field_add:exec.shared.SerializedField.child)
  return _internal_add_child();
}
inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::exec::shared::SerializedField >&
SerializedField::child() const {
  // @@protoc_insertion_point(field_list:exec.shared.SerializedField.child)
  return child_;
}

// optional int32 value_count = 4;
inline bool SerializedField::_internal_has_value_count() const {
  bool value = (_has_bits_[0] & 0x00000004u) != 0;
  return value;
}
inline bool SerializedField::has_value_count() const {
  return _internal_has_value_count();
}
inline void SerializedField::clear_value_count() {
  value_count_ = 0;
  _has_bits_[0] &= ~0x00000004u;
}
inline ::PROTOBUF_NAMESPACE_ID::int32 SerializedField::_internal_value_count() const {
  return value_count_;
}
inline ::PROTOBUF_NAMESPACE_ID::int32 SerializedField::value_count() const {
  // @@protoc_insertion_point(field_get:exec.shared.SerializedField.value_count)
  return _internal_value_count();
}
inline void SerializedField::_internal_set_value_count(::PROTOBUF_NAMESPACE_ID::int32 value) {
  _has_bits_[0] |= 0x00000004u;
  value_count_ = value;
}
inline void SerializedField::set_value_count(::PROTOBUF_NAMESPACE_ID::int32 value) {
  _internal_set_value_count(value);
  // @@protoc_insertion_point(field_set:exec.shared.SerializedField.value_count)
}

// optional int32 var_byte_length = 5;
inline bool SerializedField::_internal_has_var_byte_length() const {
  bool value = (_has_bits_[0] & 0x00000008u) != 0;
  return value;
}
inline bool SerializedField::has_var_byte_length() const {
  return _internal_has_var_byte_length();
}
inline void SerializedField::clear_var_byte_length() {
  var_byte_length_ = 0;
  _has_bits_[0] &= ~0x00000008u;
}
inline ::PROTOBUF_NAMESPACE_ID::int32 SerializedField::_internal_var_byte_length() const {
  return var_byte_length_;
}
inline ::PROTOBUF_NAMESPACE_ID::int32 SerializedField::var_byte_length() const {
  // @@protoc_insertion_point(field_get:exec.shared.SerializedField.var_byte_length)
  return _internal_var_byte_length();
}
inline void SerializedField::_internal_set_var_byte_length(::PROTOBUF_NAMESPACE_ID::int32 value) {
  _has_bits_[0] |= 0x00000008u;
  var_byte_length_ = value;
}
inline void SerializedField::set_var_byte_length(::PROTOBUF_NAMESPACE_ID::int32 value) {
  _internal_set_var_byte_length(value);
  // @@protoc_insertion_point(field_set:exec.shared.SerializedField.var_byte_length)
}

// optional int32 buffer_length = 7;
inline bool SerializedField::_internal_has_buffer_length() const {
  bool value = (_has_bits_[0] & 0x00000010u) != 0;
  return value;
}
inline bool SerializedField::has_buffer_length() const {
  return _internal_has_buffer_length();
}
inline void SerializedField::clear_buffer_length() {
  buffer_length_ = 0;
  _has_bits_[0] &= ~0x00000010u;
}
inline ::PROTOBUF_NAMESPACE_ID::int32 SerializedField::_internal_buffer_length() const {
  return buffer_length_;
}
inline ::PROTOBUF_NAMESPACE_ID::int32 SerializedField::buffer_length() const {
  // @@protoc_insertion_point(field_get:exec.shared.SerializedField.buffer_length)
  return _internal_buffer_length();
}
inline void SerializedField::_internal_set_buffer_length(::PROTOBUF_NAMESPACE_ID::int32 value) {
  _has_bits_[0] |= 0x00000010u;
  buffer_length_ = value;
}
inline void SerializedField::set_buffer_length(::PROTOBUF_NAMESPACE_ID::int32 value) {
  _internal_set_buffer_length(value);
  // @@protoc_insertion_point(field_set:exec.shared.SerializedField.buffer_length)
}

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

// NodeStatus

// optional int32 node_id = 1;
inline bool NodeStatus::_internal_has_node_id() const {
  bool value = (_has_bits_[0] & 0x00000002u) != 0;
  return value;
}
inline bool NodeStatus::has_node_id() const {
  return _internal_has_node_id();
}
inline void NodeStatus::clear_node_id() {
  node_id_ = 0;
  _has_bits_[0] &= ~0x00000002u;
}
inline ::PROTOBUF_NAMESPACE_ID::int32 NodeStatus::_internal_node_id() const {
  return node_id_;
}
inline ::PROTOBUF_NAMESPACE_ID::int32 NodeStatus::node_id() const {
  // @@protoc_insertion_point(field_get:exec.shared.NodeStatus.node_id)
  return _internal_node_id();
}
inline void NodeStatus::_internal_set_node_id(::PROTOBUF_NAMESPACE_ID::int32 value) {
  _has_bits_[0] |= 0x00000002u;
  node_id_ = value;
}
inline void NodeStatus::set_node_id(::PROTOBUF_NAMESPACE_ID::int32 value) {
  _internal_set_node_id(value);
  // @@protoc_insertion_point(field_set:exec.shared.NodeStatus.node_id)
}

// optional int64 memory_footprint = 2;
inline bool NodeStatus::_internal_has_memory_footprint() const {
  bool value = (_has_bits_[0] & 0x00000001u) != 0;
  return value;
}
inline bool NodeStatus::has_memory_footprint() const {
  return _internal_has_memory_footprint();
}
inline void NodeStatus::clear_memory_footprint() {
  memory_footprint_ = PROTOBUF_LONGLONG(0);
  _has_bits_[0] &= ~0x00000001u;
}
inline ::PROTOBUF_NAMESPACE_ID::int64 NodeStatus::_internal_memory_footprint() const {
  return memory_footprint_;
}
inline ::PROTOBUF_NAMESPACE_ID::int64 NodeStatus::memory_footprint() const {
  // @@protoc_insertion_point(field_get:exec.shared.NodeStatus.memory_footprint)
  return _internal_memory_footprint();
}
inline void NodeStatus::_internal_set_memory_footprint(::PROTOBUF_NAMESPACE_ID::int64 value) {
  _has_bits_[0] |= 0x00000001u;
  memory_footprint_ = value;
}
inline void NodeStatus::set_memory_footprint(::PROTOBUF_NAMESPACE_ID::int64 value) {
  _internal_set_memory_footprint(value);
  // @@protoc_insertion_point(field_set:exec.shared.NodeStatus.memory_footprint)
}

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

// QueryResult

// optional .exec.shared.QueryResult.QueryState query_state = 1;
inline bool QueryResult::_internal_has_query_state() const {
  bool value = (_has_bits_[0] & 0x00000002u) != 0;
  return value;
}
inline bool QueryResult::has_query_state() const {
  return _internal_has_query_state();
}
inline void QueryResult::clear_query_state() {
  query_state_ = 0;
  _has_bits_[0] &= ~0x00000002u;
}
inline ::exec::shared::QueryResult_QueryState QueryResult::_internal_query_state() const {
  return static_cast< ::exec::shared::QueryResult_QueryState >(query_state_);
}
inline ::exec::shared::QueryResult_QueryState QueryResult::query_state() const {
  // @@protoc_insertion_point(field_get:exec.shared.QueryResult.query_state)
  return _internal_query_state();
}
inline void QueryResult::_internal_set_query_state(::exec::shared::QueryResult_QueryState value) {
  assert(::exec::shared::QueryResult_QueryState_IsValid(value));
  _has_bits_[0] |= 0x00000002u;
  query_state_ = value;
}
inline void QueryResult::set_query_state(::exec::shared::QueryResult_QueryState value) {
  _internal_set_query_state(value);
  // @@protoc_insertion_point(field_set:exec.shared.QueryResult.query_state)
}

// optional .exec.shared.QueryId query_id = 2;
inline bool QueryResult::_internal_has_query_id() const {
  bool value = (_has_bits_[0] & 0x00000001u) != 0;
  PROTOBUF_ASSUME(!value || query_id_ != nullptr);
  return value;
}
inline bool QueryResult::has_query_id() const {
  return _internal_has_query_id();
}
inline void QueryResult::clear_query_id() {
  if (query_id_ != nullptr) query_id_->Clear();
  _has_bits_[0] &= ~0x00000001u;
}
inline const ::exec::shared::QueryId& QueryResult::_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& QueryResult::query_id() const {
  // @@protoc_insertion_point(field_get:exec.shared.QueryResult.query_id)
  return _internal_query_id();
}
inline void QueryResult::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.shared.QueryResult.query_id)
}
inline ::exec::shared::QueryId* QueryResult::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* QueryResult::unsafe_arena_release_query_id() {
  // @@protoc_insertion_point(field_release:exec.shared.QueryResult.query_id)
  _has_bits_[0] &= ~0x00000001u;
  ::exec::shared::QueryId* temp = query_id_;
  query_id_ = nullptr;
  return temp;
}
inline ::exec::shared::QueryId* QueryResult::_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* QueryResult::mutable_query_id() {
  // @@protoc_insertion_point(field_mutable:exec.shared.QueryResult.query_id)
  return _internal_mutable_query_id();
}
inline void QueryResult::set_allocated_query_id(::exec::shared::QueryId* query_id) {
  ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArena();
  if (message_arena == nullptr) {
    delete query_id_;
  }
  if (query_id) {
    ::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena =
      ::PROTOBUF_NAMESPACE_ID::Arena::GetArena(query_id);
    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.shared.QueryResult.query_id)
}

// repeated .exec.shared.DrillPBError error = 3;
inline int QueryResult::_internal_error_size() const {
  return error_.size();
}
inline int QueryResult::error_size() const {
  return _internal_error_size();
}
inline void QueryResult::clear_error() {
  error_.Clear();
}
inline ::exec::shared::DrillPBError* QueryResult::mutable_error(int index) {
  // @@protoc_insertion_point(field_mutable:exec.shared.QueryResult.error)
  return error_.Mutable(index);
}
inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::exec::shared::DrillPBError >*
QueryResult::mutable_error() {
  // @@protoc_insertion_point(field_mutable_list:exec.shared.QueryResult.error)
  return &error_;
}
inline const ::exec::shared::DrillPBError& QueryResult::_internal_error(int index) const {
  return error_.Get(index);
}
inline const ::exec::shared::DrillPBError& QueryResult::error(int index) const {
  // @@protoc_insertion_point(field_get:exec.shared.QueryResult.error)
  return _internal_error(index);
}
inline ::exec::shared::DrillPBError* QueryResult::_internal_add_error() {
  return error_.Add();
}
inline ::exec::shared::DrillPBError* QueryResult::add_error() {
  // @@protoc_insertion_point(field_add:exec.shared.QueryResult.error)
  return _internal_add_error();
}
inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::exec::shared::DrillPBError >&
QueryResult::error() const {
  // @@protoc_insertion_point(field_list:exec.shared.QueryResult.error)
  return error_;
}

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

// QueryData

// optional .exec.shared.QueryId query_id = 1;
inline bool QueryData::_internal_has_query_id() const {
  bool value = (_has_bits_[0] & 0x00000001u) != 0;
  PROTOBUF_ASSUME(!value || query_id_ != nullptr);
  return value;
}
inline bool QueryData::has_query_id() const {
  return _internal_has_query_id();
}
inline void QueryData::clear_query_id() {
  if (query_id_ != nullptr) query_id_->Clear();
  _has_bits_[0] &= ~0x00000001u;
}
inline const ::exec::shared::QueryId& QueryData::_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& QueryData::query_id() const {
  // @@protoc_insertion_point(field_get:exec.shared.QueryData.query_id)
  return _internal_query_id();
}
inline void QueryData::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.shared.QueryData.query_id)
}
inline ::exec::shared::QueryId* QueryData::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* QueryData::unsafe_arena_release_query_id() {
  // @@protoc_insertion_point(field_release:exec.shared.QueryData.query_id)
  _has_bits_[0] &= ~0x00000001u;
  ::exec::shared::QueryId* temp = query_id_;
  query_id_ = nullptr;
  return temp;
}
inline ::exec::shared::QueryId* QueryData::_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* QueryData::mutable_query_id() {
  // @@protoc_insertion_point(field_mutable:exec.shared.QueryData.query_id)
  return _internal_mutable_query_id();
}
inline void QueryData::set_allocated_query_id(::exec::shared::QueryId* query_id) {
  ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArena();
  if (message_arena == nullptr) {
    delete query_id_;
  }
  if (query_id) {
    ::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena =
      ::PROTOBUF_NAMESPACE_ID::Arena::GetArena(query_id);
    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.shared.QueryData.query_id)
}

// optional int32 row_count = 2;
inline bool QueryData::_internal_has_row_count() const {
  bool value = (_has_bits_[0] & 0x00000004u) != 0;
  return value;
}
inline bool QueryData::has_row_count() const {
  return _internal_has_row_count();
}
inline void QueryData::clear_row_count() {
  row_count_ = 0;
  _has_bits_[0] &= ~0x00000004u;
}
inline ::PROTOBUF_NAMESPACE_ID::int32 QueryData::_internal_row_count() const {
  return row_count_;
}
inline ::PROTOBUF_NAMESPACE_ID::int32 QueryData::row_count() const {
  // @@protoc_insertion_point(field_get:exec.shared.QueryData.row_count)
  return _internal_row_count();
}
inline void QueryData::_internal_set_row_count(::PROTOBUF_NAMESPACE_ID::int32 value) {
  _has_bits_[0] |= 0x00000004u;
  row_count_ = value;
}
inline void QueryData::set_row_count(::PROTOBUF_NAMESPACE_ID::int32 value) {
  _internal_set_row_count(value);
  // @@protoc_insertion_point(field_set:exec.shared.QueryData.row_count)
}

// optional .exec.shared.RecordBatchDef def = 3;
inline bool QueryData::_internal_has_def() const {
  bool value = (_has_bits_[0] & 0x00000002u) != 0;
  PROTOBUF_ASSUME(!value || def_ != nullptr);
  return value;
}
inline bool QueryData::has_def() const {
  return _internal_has_def();
}
inline void QueryData::clear_def() {
  if (def_ != nullptr) def_->Clear();
  _has_bits_[0] &= ~0x00000002u;
}
inline const ::exec::shared::RecordBatchDef& QueryData::_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& QueryData::def() const {
  // @@protoc_insertion_point(field_get:exec.shared.QueryData.def)
  return _internal_def();
}
inline void QueryData::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.shared.QueryData.def)
}
inline ::exec::shared::RecordBatchDef* QueryData::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* QueryData::unsafe_arena_release_def() {
  // @@protoc_insertion_point(field_release:exec.shared.QueryData.def)
  _has_bits_[0] &= ~0x00000002u;
  ::exec::shared::RecordBatchDef* temp = def_;
  def_ = nullptr;
  return temp;
}
inline ::exec::shared::RecordBatchDef* QueryData::_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* QueryData::mutable_def() {
  // @@protoc_insertion_point(field_mutable:exec.shared.QueryData.def)
  return _internal_mutable_def();
}
inline void QueryData::set_allocated_def(::exec::shared::RecordBatchDef* def) {
  ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArena();
  if (message_arena == nullptr) {
    delete def_;
  }
  if (def) {
    ::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena =
      ::PROTOBUF_NAMESPACE_ID::Arena::GetArena(def);
    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.shared.QueryData.def)
}

// optional int32 affected_rows_count = 4;
inline bool QueryData::_internal_has_affected_rows_count() const {
  bool value = (_has_bits_[0] & 0x00000008u) != 0;
  return value;
}
inline bool QueryData::has_affected_rows_count() const {
  return _internal_has_affected_rows_count();
}
inline void QueryData::clear_affected_rows_count() {
  affected_rows_count_ = 0;
  _has_bits_[0] &= ~0x00000008u;
}
inline ::PROTOBUF_NAMESPACE_ID::int32 QueryData::_internal_affected_rows_count() const {
  return affected_rows_count_;
}
inline ::PROTOBUF_NAMESPACE_ID::int32 QueryData::affected_rows_count() const {
  // @@protoc_insertion_point(field_get:exec.shared.QueryData.affected_rows_count)
  return _internal_affected_rows_count();
}
inline void QueryData::_internal_set_affected_rows_count(::PROTOBUF_NAMESPACE_ID::int32 value) {
  _has_bits_[0] |= 0x00000008u;
  affected_rows_count_ = value;
}
inline void QueryData::set_affected_rows_count(::PROTOBUF_NAMESPACE_ID::int32 value) {
  _internal_set_affected_rows_count(value);
  // @@protoc_insertion_point(field_set:exec.shared.QueryData.affected_rows_count)
}

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

// QueryInfo

// optional string query = 1;
inline bool QueryInfo::_internal_has_query() const {
  bool value = (_has_bits_[0] & 0x00000001u) != 0;
  return value;
}
inline bool QueryInfo::has_query() const {
  return _internal_has_query();
}
inline void QueryInfo::clear_query() {
  query_.ClearToEmpty();
  _has_bits_[0] &= ~0x00000001u;
}
inline const std::string& QueryInfo::query() const {
  // @@protoc_insertion_point(field_get:exec.shared.QueryInfo.query)
  return _internal_query();
}
template <typename ArgT0, typename... ArgT>
PROTOBUF_ALWAYS_INLINE
inline void QueryInfo::set_query(ArgT0&& arg0, ArgT... args) {
 _has_bits_[0] |= 0x00000001u;
 query_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArena());
  // @@protoc_insertion_point(field_set:exec.shared.QueryInfo.query)
}
inline std::string* QueryInfo::mutable_query() {
  // @@protoc_insertion_point(field_mutable:exec.shared.QueryInfo.query)
  return _internal_mutable_query();
}
inline const std::string& QueryInfo::_internal_query() const {
  return query_.Get();
}
inline void QueryInfo::_internal_set_query(const std::string& value) {
  _has_bits_[0] |= 0x00000001u;
  query_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena());
}
inline std::string* QueryInfo::_internal_mutable_query() {
  _has_bits_[0] |= 0x00000001u;
  return query_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena());
}
inline std::string* QueryInfo::release_query() {
  // @@protoc_insertion_point(field_release:exec.shared.QueryInfo.query)
  if (!_internal_has_query()) {
    return nullptr;
  }
  _has_bits_[0] &= ~0x00000001u;
  return query_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena());
}
inline void QueryInfo::set_allocated_query(std::string* query) {
  if (query != nullptr) {
    _has_bits_[0] |= 0x00000001u;
  } else {
    _has_bits_[0] &= ~0x00000001u;
  }
  query_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), query,
      GetArena());
  // @@protoc_insertion_point(field_set_allocated:exec.shared.QueryInfo.query)
}

// optional int64 start = 2;
inline bool QueryInfo::_internal_has_start() const {
  bool value = (_has_bits_[0] & 0x00000020u) != 0;
  return value;
}
inline bool QueryInfo::has_start() const {
  return _internal_has_start();
}
inline void QueryInfo::clear_start() {
  start_ = PROTOBUF_LONGLONG(0);
  _has_bits_[0] &= ~0x00000020u;
}
inline ::PROTOBUF_NAMESPACE_ID::int64 QueryInfo::_internal_start() const {
  return start_;
}
inline ::PROTOBUF_NAMESPACE_ID::int64 QueryInfo::start() const {
  // @@protoc_insertion_point(field_get:exec.shared.QueryInfo.start)
  return _internal_start();
}
inline void QueryInfo::_internal_set_start(::PROTOBUF_NAMESPACE_ID::int64 value) {
  _has_bits_[0] |= 0x00000020u;
  start_ = value;
}
inline void QueryInfo::set_start(::PROTOBUF_NAMESPACE_ID::int64 value) {
  _internal_set_start(value);
  // @@protoc_insertion_point(field_set:exec.shared.QueryInfo.start)
}

// optional .exec.shared.QueryResult.QueryState state = 3;
inline bool QueryInfo::_internal_has_state() const {
  bool value = (_has_bits_[0] & 0x00000080u) != 0;
  return value;
}
inline bool QueryInfo::has_state() const {
  return _internal_has_state();
}
inline void QueryInfo::clear_state() {
  state_ = 0;
  _has_bits_[0] &= ~0x00000080u;
}
inline ::exec::shared::QueryResult_QueryState QueryInfo::_internal_state() const {
  return static_cast< ::exec::shared::QueryResult_QueryState >(state_);
}
inline ::exec::shared::QueryResult_QueryState QueryInfo::state() const {
  // @@protoc_insertion_point(field_get:exec.shared.QueryInfo.state)
  return _internal_state();
}
inline void QueryInfo::_internal_set_state(::exec::shared::QueryResult_QueryState value) {
  assert(::exec::shared::QueryResult_QueryState_IsValid(value));
  _has_bits_[0] |= 0x00000080u;
  state_ = value;
}
inline void QueryInfo::set_state(::exec::shared::QueryResult_QueryState value) {
  _internal_set_state(value);
  // @@protoc_insertion_point(field_set:exec.shared.QueryInfo.state)
}

// optional string user = 4 [default = "-"];
inline bool QueryInfo::_internal_has_user() const {
  bool value = (_has_bits_[0] & 0x00000002u) != 0;
  return value;
}
inline bool QueryInfo::has_user() const {
  return _internal_has_user();
}
inline void QueryInfo::clear_user() {
  user_.ClearToDefault(::exec::shared::QueryInfo::_i_give_permission_to_break_this_code_default_user_, GetArena());
  _has_bits_[0] &= ~0x00000002u;
}
inline const std::string& QueryInfo::user() const {
  // @@protoc_insertion_point(field_get:exec.shared.QueryInfo.user)
  if (user_.IsDefault(nullptr)) return _i_give_permission_to_break_this_code_default_user_.get();
  return _internal_user();
}
template <typename ArgT0, typename... ArgT>
PROTOBUF_ALWAYS_INLINE
inline void QueryInfo::set_user(ArgT0&& arg0, ArgT... args) {
 _has_bits_[0] |= 0x00000002u;
 user_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::NonEmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArena());
  // @@protoc_insertion_point(field_set:exec.shared.QueryInfo.user)
}
inline std::string* QueryInfo::mutable_user() {
  // @@protoc_insertion_point(field_mutable:exec.shared.QueryInfo.user)
  return _internal_mutable_user();
}
inline const std::string& QueryInfo::_internal_user() const {
  return user_.Get();
}
inline void QueryInfo::_internal_set_user(const std::string& value) {
  _has_bits_[0] |= 0x00000002u;
  user_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::NonEmptyDefault{}, value, GetArena());
}
inline std::string* QueryInfo::_internal_mutable_user() {
  _has_bits_[0] |= 0x00000002u;
  return user_.Mutable(::exec::shared::QueryInfo::_i_give_permission_to_break_this_code_default_user_, GetArena());
}
inline std::string* QueryInfo::release_user() {
  // @@protoc_insertion_point(field_release:exec.shared.QueryInfo.user)
  if (!_internal_has_user()) {
    return nullptr;
  }
  _has_bits_[0] &= ~0x00000002u;
  return user_.ReleaseNonDefault(nullptr, GetArena());
}
inline void QueryInfo::set_allocated_user(std::string* user) {
  if (user != nullptr) {
    _has_bits_[0] |= 0x00000002u;
  } else {
    _has_bits_[0] &= ~0x00000002u;
  }
  user_.SetAllocated(nullptr, user,
      GetArena());
  // @@protoc_insertion_point(field_set_allocated:exec.shared.QueryInfo.user)
}

// optional .exec.DrillbitEndpoint foreman = 5;
inline bool QueryInfo::_internal_has_foreman() const {
  bool value = (_has_bits_[0] & 0x00000010u) != 0;
  PROTOBUF_ASSUME(!value || foreman_ != nullptr);
  return value;
}
inline bool QueryInfo::has_foreman() const {
  return _internal_has_foreman();
}
inline const ::exec::DrillbitEndpoint& QueryInfo::_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& QueryInfo::foreman() const {
  // @@protoc_insertion_point(field_get:exec.shared.QueryInfo.foreman)
  return _internal_foreman();
}
inline void QueryInfo::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.shared.QueryInfo.foreman)
}
inline ::exec::DrillbitEndpoint* QueryInfo::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* QueryInfo::unsafe_arena_release_foreman() {
  // @@protoc_insertion_point(field_release:exec.shared.QueryInfo.foreman)
  _has_bits_[0] &= ~0x00000010u;
  ::exec::DrillbitEndpoint* temp = foreman_;
  foreman_ = nullptr;
  return temp;
}
inline ::exec::DrillbitEndpoint* QueryInfo::_internal_mutable_foreman() {
  _has_bits_[0] |= 0x00000010u;
  if (foreman_ == nullptr) {
    auto* p = CreateMaybeMessage<::exec::DrillbitEndpoint>(GetArena());
    foreman_ = p;
  }
  return foreman_;
}
inline ::exec::DrillbitEndpoint* QueryInfo::mutable_foreman() {
  // @@protoc_insertion_point(field_mutable:exec.shared.QueryInfo.foreman)
  return _internal_mutable_foreman();
}
inline void QueryInfo::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.shared.QueryInfo.foreman)
}

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

// optional double total_cost = 7;
inline bool QueryInfo::_internal_has_total_cost() const {
  bool value = (_has_bits_[0] & 0x00000040u) != 0;
  return value;
}
inline bool QueryInfo::has_total_cost() const {
  return _internal_has_total_cost();
}
inline void QueryInfo::clear_total_cost() {
  total_cost_ = 0;
  _has_bits_[0] &= ~0x00000040u;
}
inline double QueryInfo::_internal_total_cost() const {
  return total_cost_;
}
inline double QueryInfo::total_cost() const {
  // @@protoc_insertion_point(field_get:exec.shared.QueryInfo.total_cost)
  return _internal_total_cost();
}
inline void QueryInfo::_internal_set_total_cost(double value) {
  _has_bits_[0] |= 0x00000040u;
  total_cost_ = value;
}
inline void QueryInfo::set_total_cost(double value) {
  _internal_set_total_cost(value);
  // @@protoc_insertion_point(field_set:exec.shared.QueryInfo.total_cost)
}

// optional string queue_name = 8 [default = "-"];
inline bool QueryInfo::_internal_has_queue_name() const {
  bool value = (_has_bits_[0] & 0x00000008u) != 0;
  return value;
}
inline bool QueryInfo::has_queue_name() const {
  return _internal_has_queue_name();
}
inline void QueryInfo::clear_queue_name() {
  queue_name_.ClearToDefault(::exec::shared::QueryInfo::_i_give_permission_to_break_this_code_default_queue_name_, GetArena());
  _has_bits_[0] &= ~0x00000008u;
}
inline const std::string& QueryInfo::queue_name() const {
  // @@protoc_insertion_point(field_get:exec.shared.QueryInfo.queue_name)
  if (queue_name_.IsDefault(nullptr)) return _i_give_permission_to_break_this_code_default_queue_name_.get();
  return _internal_queue_name();
}
template <typename ArgT0, typename... ArgT>
PROTOBUF_ALWAYS_INLINE
inline void QueryInfo::set_queue_name(ArgT0&& arg0, ArgT... args) {
 _has_bits_[0] |= 0x00000008u;
 queue_name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::NonEmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArena());
  // @@protoc_insertion_point(field_set:exec.shared.QueryInfo.queue_name)
}
inline std::string* QueryInfo::mutable_queue_name() {
  // @@protoc_insertion_point(field_mutable:exec.shared.QueryInfo.queue_name)
  return _internal_mutable_queue_name();
}
inline const std::string& QueryInfo::_internal_queue_name() const {
  return queue_name_.Get();
}
inline void QueryInfo::_internal_set_queue_name(const std::string& value) {
  _has_bits_[0] |= 0x00000008u;
  queue_name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::NonEmptyDefault{}, value, GetArena());
}
inline std::string* QueryInfo::_internal_mutable_queue_name() {
  _has_bits_[0] |= 0x00000008u;
  return queue_name_.Mutable(::exec::shared::QueryInfo::_i_give_permission_to_break_this_code_default_queue_name_, GetArena());
}
inline std::string* QueryInfo::release_queue_name() {
  // @@protoc_insertion_point(field_release:exec.shared.QueryInfo.queue_name)
  if (!_internal_has_queue_name()) {
    return nullptr;
  }
  _has_bits_[0] &= ~0x00000008u;
  return queue_name_.ReleaseNonDefault(nullptr, GetArena());
}
inline void QueryInfo::set_allocated_queue_name(std::string* queue_name) {
  if (queue_name != nullptr) {
    _has_bits_[0] |= 0x00000008u;
  } else {
    _has_bits_[0] &= ~0x00000008u;
  }
  queue_name_.SetAllocated(nullptr, queue_name,
      GetArena());
  // @@protoc_insertion_point(field_set_allocated:exec.shared.QueryInfo.queue_name)
}

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

// QueryProfile

// optional .exec.shared.QueryId id = 1;
inline bool QueryProfile::_internal_has_id() const {
  bool value = (_has_bits_[0] & 0x00000400u) != 0;
  PROTOBUF_ASSUME(!value || id_ != nullptr);
  return value;
}
inline bool QueryProfile::has_id() const {
  return _internal_has_id();
}
inline void QueryProfile::clear_id() {
  if (id_ != nullptr) id_->Clear();
  _has_bits_[0] &= ~0x00000400u;
}
inline const ::exec::shared::QueryId& QueryProfile::_internal_id() const {
  const ::exec::shared::QueryId* p = id_;
  return p != nullptr ? *p : reinterpret_cast<const ::exec::shared::QueryId&>(
      ::exec::shared::_QueryId_default_instance_);
}
inline const ::exec::shared::QueryId& QueryProfile::id() const {
  // @@protoc_insertion_point(field_get:exec.shared.QueryProfile.id)
  return _internal_id();
}
inline void QueryProfile::unsafe_arena_set_allocated_id(
    ::exec::shared::QueryId* id) {
  if (GetArena() == nullptr) {
    delete reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(id_);
  }
  id_ = id;
  if (id) {
    _has_bits_[0] |= 0x00000400u;
  } else {
    _has_bits_[0] &= ~0x00000400u;
  }
  // @@protoc_insertion_point(field_unsafe_arena_set_allocated:exec.shared.QueryProfile.id)
}
inline ::exec::shared::QueryId* QueryProfile::release_id() {
  _has_bits_[0] &= ~0x00000400u;
  ::exec::shared::QueryId* temp = id_;
  id_ = nullptr;
  if (GetArena() != nullptr) {
    temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp);
  }
  return temp;
}
inline ::exec::shared::QueryId* QueryProfile::unsafe_arena_release_id() {
  // @@protoc_insertion_point(field_release:exec.shared.QueryProfile.id)
  _has_bits_[0] &= ~0x00000400u;
  ::exec::shared::QueryId* temp = id_;
  id_ = nullptr;
  return temp;
}
inline ::exec::shared::QueryId* QueryProfile::_internal_mutable_id() {
  _has_bits_[0] |= 0x00000400u;
  if (id_ == nullptr) {
    auto* p = CreateMaybeMessage<::exec::shared::QueryId>(GetArena());
    id_ = p;
  }
  return id_;
}
inline ::exec::shared::QueryId* QueryProfile::mutable_id() {
  // @@protoc_insertion_point(field_mutable:exec.shared.QueryProfile.id)
  return _internal_mutable_id();
}
inline void QueryProfile::set_allocated_id(::exec::shared::QueryId* id) {
  ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArena();
  if (message_arena == nullptr) {
    delete id_;
  }
  if (id) {
    ::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena =
      ::PROTOBUF_NAMESPACE_ID::Arena::GetArena(id);
    if (message_arena != submessage_arena) {
      id = ::PROTOBUF_NAMESPACE_ID::internal::GetOwnedMessage(
          message_arena, id, submessage_arena);
    }
    _has_bits_[0] |= 0x00000400u;
  } else {
    _has_bits_[0] &= ~0x00000400u;
  }
  id_ = id;
  // @@protoc_insertion_point(field_set_allocated:exec.shared.QueryProfile.id)
}

// optional .exec.shared.QueryType type = 2;
inline bool QueryProfile::_internal_has_type() const {
  bool value = (_has_bits_[0] & 0x00200000u) != 0;
  return value;
}
inline bool QueryProfile::has_type() const {
  return _internal_has_type();
}
inline void QueryProfile::clear_type() {
  type_ = 1;
  _has_bits_[0] &= ~0x00200000u;
}
inline ::exec::shared::QueryType QueryProfile::_internal_type() const {
  return static_cast< ::exec::shared::QueryType >(type_);
}
inline ::exec::shared::QueryType QueryProfile::type() const {
  // @@protoc_insertion_point(field_get:exec.shared.QueryProfile.type)
  return _internal_type();
}
inline void QueryProfile::_internal_set_type(::exec::shared::QueryType value) {
  assert(::exec::shared::QueryType_IsValid(value));
  _has_bits_[0] |= 0x00200000u;
  type_ = value;
}
inline void QueryProfile::set_type(::exec::shared::QueryType value) {
  _internal_set_type(value);
  // @@protoc_insertion_point(field_set:exec.shared.QueryProfile.type)
}

// optional int64 start = 3;
inline bool QueryProfile::_internal_has_start() const {
  bool value = (_has_bits_[0] & 0x00001000u) != 0;
  return value;
}
inline bool QueryProfile::has_start() const {
  return _internal_has_start();
}
inline void QueryProfile::clear_start() {
  start_ = PROTOBUF_LONGLONG(0);
  _has_bits_[0] &= ~0x00001000u;
}
inline ::PROTOBUF_NAMESPACE_ID::int64 QueryProfile::_internal_start() const {
  return start_;
}
inline ::PROTOBUF_NAMESPACE_ID::int64 QueryProfile::start() const {
  // @@protoc_insertion_point(field_get:exec.shared.QueryProfile.start)
  return _internal_start();
}
inline void QueryProfile::_internal_set_start(::PROTOBUF_NAMESPACE_ID::int64 value) {
  _has_bits_[0] |= 0x00001000u;
  start_ = value;
}
inline void QueryProfile::set_start(::PROTOBUF_NAMESPACE_ID::int64 value) {
  _internal_set_start(value);
  // @@protoc_insertion_point(field_set:exec.shared.QueryProfile.start)
}

// optional int64 end = 4;
inline bool QueryProfile::_internal_has_end() const {
  bool value = (_has_bits_[0] & 0x00002000u) != 0;
  return value;
}
inline bool QueryProfile::has_end() const {
  return _internal_has_end();
}
inline void QueryProfile::clear_end() {
  end_ = PROTOBUF_LONGLONG(0);
  _has_bits_[0] &= ~0x00002000u;
}
inline ::PROTOBUF_NAMESPACE_ID::int64 QueryProfile::_internal_end() const {
  return end_;
}
inline ::PROTOBUF_NAMESPACE_ID::int64 QueryProfile::end() const {
  // @@protoc_insertion_point(field_get:exec.shared.QueryProfile.end)
  return _internal_end();
}
inline void QueryProfile::_internal_set_end(::PROTOBUF_NAMESPACE_ID::int64 value) {
  _has_bits_[0] |= 0x00002000u;
  end_ = value;
}
inline void QueryProfile::set_end(::PROTOBUF_NAMESPACE_ID::int64 value) {
  _internal_set_end(value);
  // @@protoc_insertion_point(field_set:exec.shared.QueryProfile.end)
}

// optional string query = 5;
inline bool QueryProfile::_internal_has_query() const {
  bool value = (_has_bits_[0] & 0x00000001u) != 0;
  return value;
}
inline bool QueryProfile::has_query() const {
  return _internal_has_query();
}
inline void QueryProfile::clear_query() {
  query_.ClearToEmpty();
  _has_bits_[0] &= ~0x00000001u;
}
inline const std::string& QueryProfile::query() const {
  // @@protoc_insertion_point(field_get:exec.shared.QueryProfile.query)
  return _internal_query();
}
template <typename ArgT0, typename... ArgT>
PROTOBUF_ALWAYS_INLINE
inline void QueryProfile::set_query(ArgT0&& arg0, ArgT... args) {
 _has_bits_[0] |= 0x00000001u;
 query_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArena());
  // @@protoc_insertion_point(field_set:exec.shared.QueryProfile.query)
}
inline std::string* QueryProfile::mutable_query() {
  // @@protoc_insertion_point(field_mutable:exec.shared.QueryProfile.query)
  return _internal_mutable_query();
}
inline const std::string& QueryProfile::_internal_query() const {
  return query_.Get();
}
inline void QueryProfile::_internal_set_query(const std::string& value) {
  _has_bits_[0] |= 0x00000001u;
  query_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena());
}
inline std::string* QueryProfile::_internal_mutable_query() {
  _has_bits_[0] |= 0x00000001u;
  return query_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena());
}
inline std::string* QueryProfile::release_query() {
  // @@protoc_insertion_point(field_release:exec.shared.QueryProfile.query)
  if (!_internal_has_query()) {
    return nullptr;
  }
  _has_bits_[0] &= ~0x00000001u;
  return query_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena());
}
inline void QueryProfile::set_allocated_query(std::string* query) {
  if (query != nullptr) {
    _has_bits_[0] |= 0x00000001u;
  } else {
    _has_bits_[0] &= ~0x00000001u;
  }
  query_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), query,
      GetArena());
  // @@protoc_insertion_point(field_set_allocated:exec.shared.QueryProfile.query)
}

// optional string plan = 6;
inline bool QueryProfile::_internal_has_plan() const {
  bool value = (_has_bits_[0] & 0x00000002u) != 0;
  return value;
}
inline bool QueryProfile::has_plan() const {
  return _internal_has_plan();
}
inline void QueryProfile::clear_plan() {
  plan_.ClearToEmpty();
  _has_bits_[0] &= ~0x00000002u;
}
inline const std::string& QueryProfile::plan() const {
  // @@protoc_insertion_point(field_get:exec.shared.QueryProfile.plan)
  return _internal_plan();
}
template <typename ArgT0, typename... ArgT>
PROTOBUF_ALWAYS_INLINE
inline void QueryProfile::set_plan(ArgT0&& arg0, ArgT... args) {
 _has_bits_[0] |= 0x00000002u;
 plan_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArena());
  // @@protoc_insertion_point(field_set:exec.shared.QueryProfile.plan)
}
inline std::string* QueryProfile::mutable_plan() {
  // @@protoc_insertion_point(field_mutable:exec.shared.QueryProfile.plan)
  return _internal_mutable_plan();
}
inline const std::string& QueryProfile::_internal_plan() const {
  return plan_.Get();
}
inline void QueryProfile::_internal_set_plan(const std::string& value) {
  _has_bits_[0] |= 0x00000002u;
  plan_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena());
}
inline std::string* QueryProfile::_internal_mutable_plan() {
  _has_bits_[0] |= 0x00000002u;
  return plan_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena());
}
inline std::string* QueryProfile::release_plan() {
  // @@protoc_insertion_point(field_release:exec.shared.QueryProfile.plan)
  if (!_internal_has_plan()) {
    return nullptr;
  }
  _has_bits_[0] &= ~0x00000002u;
  return plan_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena());
}
inline void QueryProfile::set_allocated_plan(std::string* plan) {
  if (plan != nullptr) {
    _has_bits_[0] |= 0x00000002u;
  } else {
    _has_bits_[0] &= ~0x00000002u;
  }
  plan_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), plan,
      GetArena());
  // @@protoc_insertion_point(field_set_allocated:exec.shared.QueryProfile.plan)
}

// optional .exec.DrillbitEndpoint foreman = 7;
inline bool QueryProfile::_internal_has_foreman() const {
  bool value = (_has_bits_[0] & 0x00000800u) != 0;
  PROTOBUF_ASSUME(!value || foreman_ != nullptr);
  return value;
}
inline bool QueryProfile::has_foreman() const {
  return _internal_has_foreman();
}
inline const ::exec::DrillbitEndpoint& QueryProfile::_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& QueryProfile::foreman() const {
  // @@protoc_insertion_point(field_get:exec.shared.QueryProfile.foreman)
  return _internal_foreman();
}
inline void QueryProfile::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] |= 0x00000800u;
  } else {
    _has_bits_[0] &= ~0x00000800u;
  }
  // @@protoc_insertion_point(field_unsafe_arena_set_allocated:exec.shared.QueryProfile.foreman)
}
inline ::exec::DrillbitEndpoint* QueryProfile::release_foreman() {
  _has_bits_[0] &= ~0x00000800u;
  ::exec::DrillbitEndpoint* temp = foreman_;
  foreman_ = nullptr;
  if (GetArena() != nullptr) {
    temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp);
  }
  return temp;
}
inline ::exec::DrillbitEndpoint* QueryProfile::unsafe_arena_release_foreman() {
  // @@protoc_insertion_point(field_release:exec.shared.QueryProfile.foreman)
  _has_bits_[0] &= ~0x00000800u;
  ::exec::DrillbitEndpoint* temp = foreman_;
  foreman_ = nullptr;
  return temp;
}
inline ::exec::DrillbitEndpoint* QueryProfile::_internal_mutable_foreman() {
  _has_bits_[0] |= 0x00000800u;
  if (foreman_ == nullptr) {
    auto* p = CreateMaybeMessage<::exec::DrillbitEndpoint>(GetArena());
    foreman_ = p;
  }
  return foreman_;
}
inline ::exec::DrillbitEndpoint* QueryProfile::mutable_foreman() {
  // @@protoc_insertion_point(field_mutable:exec.shared.QueryProfile.foreman)
  return _internal_mutable_foreman();
}
inline void QueryProfile::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] |= 0x00000800u;
  } else {
    _has_bits_[0] &= ~0x00000800u;
  }
  foreman_ = foreman;
  // @@protoc_insertion_point(field_set_allocated:exec.shared.QueryProfile.foreman)
}

// optional .exec.shared.QueryResult.QueryState state = 8;
inline bool QueryProfile::_internal_has_state() const {
  bool value = (_has_bits_[0] & 0x00004000u) != 0;
  return value;
}
inline bool QueryProfile::has_state() const {
  return _internal_has_state();
}
inline void QueryProfile::clear_state() {
  state_ = 0;
  _has_bits_[0] &= ~0x00004000u;
}
inline ::exec::shared::QueryResult_QueryState QueryProfile::_internal_state() const {
  return static_cast< ::exec::shared::QueryResult_QueryState >(state_);
}
inline ::exec::shared::QueryResult_QueryState QueryProfile::state() const {
  // @@protoc_insertion_point(field_get:exec.shared.QueryProfile.state)
  return _internal_state();
}
inline void QueryProfile::_internal_set_state(::exec::shared::QueryResult_QueryState value) {
  assert(::exec::shared::QueryResult_QueryState_IsValid(value));
  _has_bits_[0] |= 0x00004000u;
  state_ = value;
}
inline void QueryProfile::set_state(::exec::shared::QueryResult_QueryState value) {
  _internal_set_state(value);
  // @@protoc_insertion_point(field_set:exec.shared.QueryProfile.state)
}

// optional int32 total_fragments = 9;
inline bool QueryProfile::_internal_has_total_fragments() const {
  bool value = (_has_bits_[0] & 0x00008000u) != 0;
  return value;
}
inline bool QueryProfile::has_total_fragments() const {
  return _internal_has_total_fragments();
}
inline void QueryProfile::clear_total_fragments() {
  total_fragments_ = 0;
  _has_bits_[0] &= ~0x00008000u;
}
inline ::PROTOBUF_NAMESPACE_ID::int32 QueryProfile::_internal_total_fragments() const {
  return total_fragments_;
}
inline ::PROTOBUF_NAMESPACE_ID::int32 QueryProfile::total_fragments() const {
  // @@protoc_insertion_point(field_get:exec.shared.QueryProfile.total_fragments)
  return _internal_total_fragments();
}
inline void QueryProfile::_internal_set_total_fragments(::PROTOBUF_NAMESPACE_ID::int32 value) {
  _has_bits_[0] |= 0x00008000u;
  total_fragments_ = value;
}
inline void QueryProfile::set_total_fragments(::PROTOBUF_NAMESPACE_ID::int32 value) {
  _internal_set_total_fragments(value);
  // @@protoc_insertion_point(field_set:exec.shared.QueryProfile.total_fragments)
}

// optional int32 finished_fragments = 10;
inline bool QueryProfile::_internal_has_finished_fragments() const {
  bool value = (_has_bits_[0] & 0x00010000u) != 0;
  return value;
}
inline bool QueryProfile::has_finished_fragments() const {
  return _internal_has_finished_fragments();
}
inline void QueryProfile::clear_finished_fragments() {
  finished_fragments_ = 0;
  _has_bits_[0] &= ~0x00010000u;
}
inline ::PROTOBUF_NAMESPACE_ID::int32 QueryProfile::_internal_finished_fragments() const {
  return finished_fragments_;
}
inline ::PROTOBUF_NAMESPACE_ID::int32 QueryProfile::finished_fragments() const {
  // @@protoc_insertion_point(field_get:exec.shared.QueryProfile.finished_fragments)
  return _internal_finished_fragments();
}
inline void QueryProfile::_internal_set_finished_fragments(::PROTOBUF_NAMESPACE_ID::int32 value) {
  _has_bits_[0] |= 0x00010000u;
  finished_fragments_ = value;
}
inline void QueryProfile::set_finished_fragments(::PROTOBUF_NAMESPACE_ID::int32 value) {
  _internal_set_finished_fragments(value);
  // @@protoc_insertion_point(field_set:exec.shared.QueryProfile.finished_fragments)
}

// repeated .exec.shared.MajorFragmentProfile fragment_profile = 11;
inline int QueryProfile::_internal_fragment_profile_size() const {
  return fragment_profile_.size();
}
inline int QueryProfile::fragment_profile_size() const {
  return _internal_fragment_profile_size();
}
inline void QueryProfile::clear_fragment_profile() {
  fragment_profile_.Clear();
}
inline ::exec::shared::MajorFragmentProfile* QueryProfile::mutable_fragment_profile(int index) {
  // @@protoc_insertion_point(field_mutable:exec.shared.QueryProfile.fragment_profile)
  return fragment_profile_.Mutable(index);
}
inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::exec::shared::MajorFragmentProfile >*
QueryProfile::mutable_fragment_profile() {
  // @@protoc_insertion_point(field_mutable_list:exec.shared.QueryProfile.fragment_profile)
  return &fragment_profile_;
}
inline const ::exec::shared::MajorFragmentProfile& QueryProfile::_internal_fragment_profile(int index) const {
  return fragment_profile_.Get(index);
}
inline const ::exec::shared::MajorFragmentProfile& QueryProfile::fragment_profile(int index) const {
  // @@protoc_insertion_point(field_get:exec.shared.QueryProfile.fragment_profile)
  return _internal_fragment_profile(index);
}
inline ::exec::shared::MajorFragmentProfile* QueryProfile::_internal_add_fragment_profile() {
  return fragment_profile_.Add();
}
inline ::exec::shared::MajorFragmentProfile* QueryProfile::add_fragment_profile() {
  // @@protoc_insertion_point(field_add:exec.shared.QueryProfile.fragment_profile)
  return _internal_add_fragment_profile();
}
inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::exec::shared::MajorFragmentProfile >&
QueryProfile::fragment_profile() const {
  // @@protoc_insertion_point(field_list:exec.shared.QueryProfile.fragment_profile)
  return fragment_profile_;
}

// optional string user = 12 [default = "-"];
inline bool QueryProfile::_internal_has_user() const {
  bool value = (_has_bits_[0] & 0x00000004u) != 0;
  return value;
}
inline bool QueryProfile::has_user() const {
  return _internal_has_user();
}
inline void QueryProfile::clear_user() {
  user_.ClearToDefault(::exec::shared::QueryProfile::_i_give_permission_to_break_this_code_default_user_, GetArena());
  _has_bits_[0] &= ~0x00000004u;
}
inline const std::string& QueryProfile::user() const {
  // @@protoc_insertion_point(field_get:exec.shared.QueryProfile.user)
  if (user_.IsDefault(nullptr)) return _i_give_permission_to_break_this_code_default_user_.get();
  return _internal_user();
}
template <typename ArgT0, typename... ArgT>
PROTOBUF_ALWAYS_INLINE
inline void QueryProfile::set_user(ArgT0&& arg0, ArgT... args) {
 _has_bits_[0] |= 0x00000004u;
 user_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::NonEmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArena());
  // @@protoc_insertion_point(field_set:exec.shared.QueryProfile.user)
}
inline std::string* QueryProfile::mutable_user() {
  // @@protoc_insertion_point(field_mutable:exec.shared.QueryProfile.user)
  return _internal_mutable_user();
}
inline const std::string& QueryProfile::_internal_user() const {
  return user_.Get();
}
inline void QueryProfile::_internal_set_user(const std::string& value) {
  _has_bits_[0] |= 0x00000004u;
  user_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::NonEmptyDefault{}, value, GetArena());
}
inline std::string* QueryProfile::_internal_mutable_user() {
  _has_bits_[0] |= 0x00000004u;
  return user_.Mutable(::exec::shared::QueryProfile::_i_give_permission_to_break_this_code_default_user_, GetArena());
}
inline std::string* QueryProfile::release_user() {
  // @@protoc_insertion_point(field_release:exec.shared.QueryProfile.user)
  if (!_internal_has_user()) {
    return nullptr;
  }
  _has_bits_[0] &= ~0x00000004u;
  return user_.ReleaseNonDefault(nullptr, GetArena());
}
inline void QueryProfile::set_allocated_user(std::string* user) {
  if (user != nullptr) {
    _has_bits_[0] |= 0x00000004u;
  } else {
    _has_bits_[0] &= ~0x00000004u;
  }
  user_.SetAllocated(nullptr, user,
      GetArena());
  // @@protoc_insertion_point(field_set_allocated:exec.shared.QueryProfile.user)
}

// optional string error = 13;
inline bool QueryProfile::_internal_has_error() const {
  bool value = (_has_bits_[0] & 0x00000008u) != 0;
  return value;
}
inline bool QueryProfile::has_error() const {
  return _internal_has_error();
}
inline void QueryProfile::clear_error() {
  error_.ClearToEmpty();
  _has_bits_[0] &= ~0x00000008u;
}
inline const std::string& QueryProfile::error() const {
  // @@protoc_insertion_point(field_get:exec.shared.QueryProfile.error)
  return _internal_error();
}
template <typename ArgT0, typename... ArgT>
PROTOBUF_ALWAYS_INLINE
inline void QueryProfile::set_error(ArgT0&& arg0, ArgT... args) {
 _has_bits_[0] |= 0x00000008u;
 error_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArena());
  // @@protoc_insertion_point(field_set:exec.shared.QueryProfile.error)
}
inline std::string* QueryProfile::mutable_error() {
  // @@protoc_insertion_point(field_mutable:exec.shared.QueryProfile.error)
  return _internal_mutable_error();
}
inline const std::string& QueryProfile::_internal_error() const {
  return error_.Get();
}
inline void QueryProfile::_internal_set_error(const std::string& value) {
  _has_bits_[0] |= 0x00000008u;
  error_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena());
}
inline std::string* QueryProfile::_internal_mutable_error() {
  _has_bits_[0] |= 0x00000008u;
  return error_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena());
}
inline std::string* QueryProfile::release_error() {
  // @@protoc_insertion_point(field_release:exec.shared.QueryProfile.error)
  if (!_internal_has_error()) {
    return nullptr;
  }
  _has_bits_[0] &= ~0x00000008u;
  return error_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena());
}
inline void QueryProfile::set_allocated_error(std::string* error) {
  if (error != nullptr) {
    _has_bits_[0] |= 0x00000008u;
  } else {
    _has_bits_[0] &= ~0x00000008u;
  }
  error_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), error,
      GetArena());
  // @@protoc_insertion_point(field_set_allocated:exec.shared.QueryProfile.error)
}

// optional string verboseError = 14;
inline bool QueryProfile::_internal_has_verboseerror() const {
  bool value = (_has_bits_[0] & 0x00000010u) != 0;
  return value;
}
inline bool QueryProfile::has_verboseerror() const {
  return _internal_has_verboseerror();
}
inline void QueryProfile::clear_verboseerror() {
  verboseerror_.ClearToEmpty();
  _has_bits_[0] &= ~0x00000010u;
}
inline const std::string& QueryProfile::verboseerror() const {
  // @@protoc_insertion_point(field_get:exec.shared.QueryProfile.verboseError)
  return _internal_verboseerror();
}
template <typename ArgT0, typename... ArgT>
PROTOBUF_ALWAYS_INLINE
inline void QueryProfile::set_verboseerror(ArgT0&& arg0, ArgT... args) {
 _has_bits_[0] |= 0x00000010u;
 verboseerror_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArena());
  // @@protoc_insertion_point(field_set:exec.shared.QueryProfile.verboseError)
}
inline std::string* QueryProfile::mutable_verboseerror() {
  // @@protoc_insertion_point(field_mutable:exec.shared.QueryProfile.verboseError)
  return _internal_mutable_verboseerror();
}
inline const std::string& QueryProfile::_internal_verboseerror() const {
  return verboseerror_.Get();
}
inline void QueryProfile::_internal_set_verboseerror(const std::string& value) {
  _has_bits_[0] |= 0x00000010u;
  verboseerror_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena());
}
inline std::string* QueryProfile::_internal_mutable_verboseerror() {
  _has_bits_[0] |= 0x00000010u;
  return verboseerror_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena());
}
inline std::string* QueryProfile::release_verboseerror() {
  // @@protoc_insertion_point(field_release:exec.shared.QueryProfile.verboseError)
  if (!_internal_has_verboseerror()) {
    return nullptr;
  }
  _has_bits_[0] &= ~0x00000010u;
  return verboseerror_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena());
}
inline void QueryProfile::set_allocated_verboseerror(std::string* verboseerror) {
  if (verboseerror != nullptr) {
    _has_bits_[0] |= 0x00000010u;
  } else {
    _has_bits_[0] &= ~0x00000010u;
  }
  verboseerror_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), verboseerror,
      GetArena());
  // @@protoc_insertion_point(field_set_allocated:exec.shared.QueryProfile.verboseError)
}

// optional string error_id = 15;
inline bool QueryProfile::_internal_has_error_id() const {
  bool value = (_has_bits_[0] & 0x00000020u) != 0;
  return value;
}
inline bool QueryProfile::has_error_id() const {
  return _internal_has_error_id();
}
inline void QueryProfile::clear_error_id() {
  error_id_.ClearToEmpty();
  _has_bits_[0] &= ~0x00000020u;
}
inline const std::string& QueryProfile::error_id() const {
  // @@protoc_insertion_point(field_get:exec.shared.QueryProfile.error_id)
  return _internal_error_id();
}
template <typename ArgT0, typename... ArgT>
PROTOBUF_ALWAYS_INLINE
inline void QueryProfile::set_error_id(ArgT0&& arg0, ArgT... args) {
 _has_bits_[0] |= 0x00000020u;
 error_id_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArena());
  // @@protoc_insertion_point(field_set:exec.shared.QueryProfile.error_id)
}
inline std::string* QueryProfile::mutable_error_id() {
  // @@protoc_insertion_point(field_mutable:exec.shared.QueryProfile.error_id)
  return _internal_mutable_error_id();
}
inline const std::string& QueryProfile::_internal_error_id() const {
  return error_id_.Get();
}
inline void QueryProfile::_internal_set_error_id(const std::string& value) {
  _has_bits_[0] |= 0x00000020u;
  error_id_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena());
}
inline std::string* QueryProfile::_internal_mutable_error_id() {
  _has_bits_[0] |= 0x00000020u;
  return error_id_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena());
}
inline std::string* QueryProfile::release_error_id() {
  // @@protoc_insertion_point(field_release:exec.shared.QueryProfile.error_id)
  if (!_internal_has_error_id()) {
    return nullptr;
  }
  _has_bits_[0] &= ~0x00000020u;
  return error_id_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena());
}
inline void QueryProfile::set_allocated_error_id(std::string* error_id) {
  if (error_id != nullptr) {
    _has_bits_[0] |= 0x00000020u;
  } else {
    _has_bits_[0] &= ~0x00000020u;
  }
  error_id_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), error_id,
      GetArena());
  // @@protoc_insertion_point(field_set_allocated:exec.shared.QueryProfile.error_id)
}

// optional string error_node = 16;
inline bool QueryProfile::_internal_has_error_node() const {
  bool value = (_has_bits_[0] & 0x00000040u) != 0;
  return value;
}
inline bool QueryProfile::has_error_node() const {
  return _internal_has_error_node();
}
inline void QueryProfile::clear_error_node() {
  error_node_.ClearToEmpty();
  _has_bits_[0] &= ~0x00000040u;
}
inline const std::string& QueryProfile::error_node() const {
  // @@protoc_insertion_point(field_get:exec.shared.QueryProfile.error_node)
  return _internal_error_node();
}
template <typename ArgT0, typename... ArgT>
PROTOBUF_ALWAYS_INLINE
inline void QueryProfile::set_error_node(ArgT0&& arg0, ArgT... args) {
 _has_bits_[0] |= 0x00000040u;
 error_node_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArena());
  // @@protoc_insertion_point(field_set:exec.shared.QueryProfile.error_node)
}
inline std::string* QueryProfile::mutable_error_node() {
  // @@protoc_insertion_point(field_mutable:exec.shared.QueryProfile.error_node)
  return _internal_mutable_error_node();
}
inline const std::string& QueryProfile::_internal_error_node() const {
  return error_node_.Get();
}
inline void QueryProfile::_internal_set_error_node(const std::string& value) {
  _has_bits_[0] |= 0x00000040u;
  error_node_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena());
}
inline std::string* QueryProfile::_internal_mutable_error_node() {
  _has_bits_[0] |= 0x00000040u;
  return error_node_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena());
}
inline std::string* QueryProfile::release_error_node() {
  // @@protoc_insertion_point(field_release:exec.shared.QueryProfile.error_node)
  if (!_internal_has_error_node()) {
    return nullptr;
  }
  _has_bits_[0] &= ~0x00000040u;
  return error_node_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena());
}
inline void QueryProfile::set_allocated_error_node(std::string* error_node) {
  if (error_node != nullptr) {
    _has_bits_[0] |= 0x00000040u;
  } else {
    _has_bits_[0] &= ~0x00000040u;
  }
  error_node_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), error_node,
      GetArena());
  // @@protoc_insertion_point(field_set_allocated:exec.shared.QueryProfile.error_node)
}

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

// optional int64 planEnd = 18;
inline bool QueryProfile::_internal_has_planend() const {
  bool value = (_has_bits_[0] & 0x00040000u) != 0;
  return value;
}
inline bool QueryProfile::has_planend() const {
  return _internal_has_planend();
}
inline void QueryProfile::clear_planend() {
  planend_ = PROTOBUF_LONGLONG(0);
  _has_bits_[0] &= ~0x00040000u;
}
inline ::PROTOBUF_NAMESPACE_ID::int64 QueryProfile::_internal_planend() const {
  return planend_;
}
inline ::PROTOBUF_NAMESPACE_ID::int64 QueryProfile::planend() const {
  // @@protoc_insertion_point(field_get:exec.shared.QueryProfile.planEnd)
  return _internal_planend();
}
inline void QueryProfile::_internal_set_planend(::PROTOBUF_NAMESPACE_ID::int64 value) {
  _has_bits_[0] |= 0x00040000u;
  planend_ = value;
}
inline void QueryProfile::set_planend(::PROTOBUF_NAMESPACE_ID::int64 value) {
  _internal_set_planend(value);
  // @@protoc_insertion_point(field_set:exec.shared.QueryProfile.planEnd)
}

// optional int64 queueWaitEnd = 19;
inline bool QueryProfile::_internal_has_queuewaitend() const {
  bool value = (_has_bits_[0] & 0x00080000u) != 0;
  return value;
}
inline bool QueryProfile::has_queuewaitend() const {
  return _internal_has_queuewaitend();
}
inline void QueryProfile::clear_queuewaitend() {
  queuewaitend_ = PROTOBUF_LONGLONG(0);
  _has_bits_[0] &= ~0x00080000u;
}
inline ::PROTOBUF_NAMESPACE_ID::int64 QueryProfile::_internal_queuewaitend() const {
  return queuewaitend_;
}
inline ::PROTOBUF_NAMESPACE_ID::int64 QueryProfile::queuewaitend() const {
  // @@protoc_insertion_point(field_get:exec.shared.QueryProfile.queueWaitEnd)
  return _internal_queuewaitend();
}
inline void QueryProfile::_internal_set_queuewaitend(::PROTOBUF_NAMESPACE_ID::int64 value) {
  _has_bits_[0] |= 0x00080000u;
  queuewaitend_ = value;
}
inline void QueryProfile::set_queuewaitend(::PROTOBUF_NAMESPACE_ID::int64 value) {
  _internal_set_queuewaitend(value);
  // @@protoc_insertion_point(field_set:exec.shared.QueryProfile.queueWaitEnd)
}

// optional double total_cost = 20;
inline bool QueryProfile::_internal_has_total_cost() const {
  bool value = (_has_bits_[0] & 0x00100000u) != 0;
  return value;
}
inline bool QueryProfile::has_total_cost() const {
  return _internal_has_total_cost();
}
inline void QueryProfile::clear_total_cost() {
  total_cost_ = 0;
  _has_bits_[0] &= ~0x00100000u;
}
inline double QueryProfile::_internal_total_cost() const {
  return total_cost_;
}
inline double QueryProfile::total_cost() const {
  // @@protoc_insertion_point(field_get:exec.shared.QueryProfile.total_cost)
  return _internal_total_cost();
}
inline void QueryProfile::_internal_set_total_cost(double value) {
  _has_bits_[0] |= 0x00100000u;
  total_cost_ = value;
}
inline void QueryProfile::set_total_cost(double value) {
  _internal_set_total_cost(value);
  // @@protoc_insertion_point(field_set:exec.shared.QueryProfile.total_cost)
}

// optional string queue_name = 21 [default = "-"];
inline bool QueryProfile::_internal_has_queue_name() const {
  bool value = (_has_bits_[0] & 0x00000100u) != 0;
  return value;
}
inline bool QueryProfile::has_queue_name() const {
  return _internal_has_queue_name();
}
inline void QueryProfile::clear_queue_name() {
  queue_name_.ClearToDefault(::exec::shared::QueryProfile::_i_give_permission_to_break_this_code_default_queue_name_, GetArena());
  _has_bits_[0] &= ~0x00000100u;
}
inline const std::string& QueryProfile::queue_name() const {
  // @@protoc_insertion_point(field_get:exec.shared.QueryProfile.queue_name)
  if (queue_name_.IsDefault(nullptr)) return _i_give_permission_to_break_this_code_default_queue_name_.get();
  return _internal_queue_name();
}
template <typename ArgT0, typename... ArgT>
PROTOBUF_ALWAYS_INLINE
inline void QueryProfile::set_queue_name(ArgT0&& arg0, ArgT... args) {
 _has_bits_[0] |= 0x00000100u;
 queue_name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::NonEmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArena());
  // @@protoc_insertion_point(field_set:exec.shared.QueryProfile.queue_name)
}
inline std::string* QueryProfile::mutable_queue_name() {
  // @@protoc_insertion_point(field_mutable:exec.shared.QueryProfile.queue_name)
  return _internal_mutable_queue_name();
}
inline const std::string& QueryProfile::_internal_queue_name() const {
  return queue_name_.Get();
}
inline void QueryProfile::_internal_set_queue_name(const std::string& value) {
  _has_bits_[0] |= 0x00000100u;
  queue_name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::NonEmptyDefault{}, value, GetArena());
}
inline std::string* QueryProfile::_internal_mutable_queue_name() {
  _has_bits_[0] |= 0x00000100u;
  return queue_name_.Mutable(::exec::shared::QueryProfile::_i_give_permission_to_break_this_code_default_queue_name_, GetArena());
}
inline std::string* QueryProfile::release_queue_name() {
  // @@protoc_insertion_point(field_release:exec.shared.QueryProfile.queue_name)
  if (!_internal_has_queue_name()) {
    return nullptr;
  }
  _has_bits_[0] &= ~0x00000100u;
  return queue_name_.ReleaseNonDefault(nullptr, GetArena());
}
inline void QueryProfile::set_allocated_queue_name(std::string* queue_name) {
  if (queue_name != nullptr) {
    _has_bits_[0] |= 0x00000100u;
  } else {
    _has_bits_[0] &= ~0x00000100u;
  }
  queue_name_.SetAllocated(nullptr, queue_name,
      GetArena());
  // @@protoc_insertion_point(field_set_allocated:exec.shared.QueryProfile.queue_name)
}

// optional string queryId = 22;
inline bool QueryProfile::_internal_has_queryid() const {
  bool value = (_has_bits_[0] & 0x00000200u) != 0;
  return value;
}
inline bool QueryProfile::has_queryid() const {
  return _internal_has_queryid();
}
inline void QueryProfile::clear_queryid() {
  queryid_.ClearToEmpty();
  _has_bits_[0] &= ~0x00000200u;
}
inline const std::string& QueryProfile::queryid() const {
  // @@protoc_insertion_point(field_get:exec.shared.QueryProfile.queryId)
  return _internal_queryid();
}
template <typename ArgT0, typename... ArgT>
PROTOBUF_ALWAYS_INLINE
inline void QueryProfile::set_queryid(ArgT0&& arg0, ArgT... args) {
 _has_bits_[0] |= 0x00000200u;
 queryid_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArena());
  // @@protoc_insertion_point(field_set:exec.shared.QueryProfile.queryId)
}
inline std::string* QueryProfile::mutable_queryid() {
  // @@protoc_insertion_point(field_mutable:exec.shared.QueryProfile.queryId)
  return _internal_mutable_queryid();
}
inline const std::string& QueryProfile::_internal_queryid() const {
  return queryid_.Get();
}
inline void QueryProfile::_internal_set_queryid(const std::string& value) {
  _has_bits_[0] |= 0x00000200u;
  queryid_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena());
}
inline std::string* QueryProfile::_internal_mutable_queryid() {
  _has_bits_[0] |= 0x00000200u;
  return queryid_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena());
}
inline std::string* QueryProfile::release_queryid() {
  // @@protoc_insertion_point(field_release:exec.shared.QueryProfile.queryId)
  if (!_internal_has_queryid()) {
    return nullptr;
  }
  _has_bits_[0] &= ~0x00000200u;
  return queryid_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena());
}
inline void QueryProfile::set_allocated_queryid(std::string* queryid) {
  if (queryid != nullptr) {
    _has_bits_[0] |= 0x00000200u;
  } else {
    _has_bits_[0] &= ~0x00000200u;
  }
  queryid_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), queryid,
      GetArena());
  // @@protoc_insertion_point(field_set_allocated:exec.shared.QueryProfile.queryId)
}

// optional int32 autoLimit = 23;
inline bool QueryProfile::_internal_has_autolimit() const {
  bool value = (_has_bits_[0] & 0x00020000u) != 0;
  return value;
}
inline bool QueryProfile::has_autolimit() const {
  return _internal_has_autolimit();
}
inline void QueryProfile::clear_autolimit() {
  autolimit_ = 0;
  _has_bits_[0] &= ~0x00020000u;
}
inline ::PROTOBUF_NAMESPACE_ID::int32 QueryProfile::_internal_autolimit() const {
  return autolimit_;
}
inline ::PROTOBUF_NAMESPACE_ID::int32 QueryProfile::autolimit() const {
  // @@protoc_insertion_point(field_get:exec.shared.QueryProfile.autoLimit)
  return _internal_autolimit();
}
inline void QueryProfile::_internal_set_autolimit(::PROTOBUF_NAMESPACE_ID::int32 value) {
  _has_bits_[0] |= 0x00020000u;
  autolimit_ = value;
}
inline void QueryProfile::set_autolimit(::PROTOBUF_NAMESPACE_ID::int32 value) {
  _internal_set_autolimit(value);
  // @@protoc_insertion_point(field_set:exec.shared.QueryProfile.autoLimit)
}

// repeated string scanned_plugins = 24;
inline int QueryProfile::_internal_scanned_plugins_size() const {
  return scanned_plugins_.size();
}
inline int QueryProfile::scanned_plugins_size() const {
  return _internal_scanned_plugins_size();
}
inline void QueryProfile::clear_scanned_plugins() {
  scanned_plugins_.Clear();
}
inline std::string* QueryProfile::add_scanned_plugins() {
  // @@protoc_insertion_point(field_add_mutable:exec.shared.QueryProfile.scanned_plugins)
  return _internal_add_scanned_plugins();
}
inline const std::string& QueryProfile::_internal_scanned_plugins(int index) const {
  return scanned_plugins_.Get(index);
}
inline const std::string& QueryProfile::scanned_plugins(int index) const {
  // @@protoc_insertion_point(field_get:exec.shared.QueryProfile.scanned_plugins)
  return _internal_scanned_plugins(index);
}
inline std::string* QueryProfile::mutable_scanned_plugins(int index) {
  // @@protoc_insertion_point(field_mutable:exec.shared.QueryProfile.scanned_plugins)
  return scanned_plugins_.Mutable(index);
}
inline void QueryProfile::set_scanned_plugins(int index, const std::string& value) {
  // @@protoc_insertion_point(field_set:exec.shared.QueryProfile.scanned_plugins)
  scanned_plugins_.Mutable(index)->assign(value);
}
inline void QueryProfile::set_scanned_plugins(int index, std::string&& value) {
  // @@protoc_insertion_point(field_set:exec.shared.QueryProfile.scanned_plugins)
  scanned_plugins_.Mutable(index)->assign(std::move(value));
}
inline void QueryProfile::set_scanned_plugins(int index, const char* value) {
  GOOGLE_DCHECK(value != nullptr);
  scanned_plugins_.Mutable(index)->assign(value);
  // @@protoc_insertion_point(field_set_char:exec.shared.QueryProfile.scanned_plugins)
}
inline void QueryProfile::set_scanned_plugins(int index, const char* value, size_t size) {
  scanned_plugins_.Mutable(index)->assign(
    reinterpret_cast<const char*>(value), size);
  // @@protoc_insertion_point(field_set_pointer:exec.shared.QueryProfile.scanned_plugins)
}
inline std::string* QueryProfile::_internal_add_scanned_plugins() {
  return scanned_plugins_.Add();
}
inline void QueryProfile::add_scanned_plugins(const std::string& value) {
  scanned_plugins_.Add()->assign(value);
  // @@protoc_insertion_point(field_add:exec.shared.QueryProfile.scanned_plugins)
}
inline void QueryProfile::add_scanned_plugins(std::string&& value) {
  scanned_plugins_.Add(std::move(value));
  // @@protoc_insertion_point(field_add:exec.shared.QueryProfile.scanned_plugins)
}
inline void QueryProfile::add_scanned_plugins(const char* value) {
  GOOGLE_DCHECK(value != nullptr);
  scanned_plugins_.Add()->assign(value);
  // @@protoc_insertion_point(field_add_char:exec.shared.QueryProfile.scanned_plugins)
}
inline void QueryProfile::add_scanned_plugins(const char* value, size_t size) {
  scanned_plugins_.Add()->assign(reinterpret_cast<const char*>(value), size);
  // @@protoc_insertion_point(field_add_pointer:exec.shared.QueryProfile.scanned_plugins)
}
inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField<std::string>&
QueryProfile::scanned_plugins() const {
  // @@protoc_insertion_point(field_list:exec.shared.QueryProfile.scanned_plugins)
  return scanned_plugins_;
}
inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField<std::string>*
QueryProfile::mutable_scanned_plugins() {
  // @@protoc_insertion_point(field_mutable_list:exec.shared.QueryProfile.scanned_plugins)
  return &scanned_plugins_;
}

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

// MajorFragmentProfile

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

// repeated .exec.shared.MinorFragmentProfile minor_fragment_profile = 2;
inline int MajorFragmentProfile::_internal_minor_fragment_profile_size() const {
  return minor_fragment_profile_.size();
}
inline int MajorFragmentProfile::minor_fragment_profile_size() const {
  return _internal_minor_fragment_profile_size();
}
inline void MajorFragmentProfile::clear_minor_fragment_profile() {
  minor_fragment_profile_.Clear();
}
inline ::exec::shared::MinorFragmentProfile* MajorFragmentProfile::mutable_minor_fragment_profile(int index) {
  // @@protoc_insertion_point(field_mutable:exec.shared.MajorFragmentProfile.minor_fragment_profile)
  return minor_fragment_profile_.Mutable(index);
}
inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::exec::shared::MinorFragmentProfile >*
MajorFragmentProfile::mutable_minor_fragment_profile() {
  // @@protoc_insertion_point(field_mutable_list:exec.shared.MajorFragmentProfile.minor_fragment_profile)
  return &minor_fragment_profile_;
}
inline const ::exec::shared::MinorFragmentProfile& MajorFragmentProfile::_internal_minor_fragment_profile(int index) const {
  return minor_fragment_profile_.Get(index);
}
inline const ::exec::shared::MinorFragmentProfile& MajorFragmentProfile::minor_fragment_profile(int index) const {
  // @@protoc_insertion_point(field_get:exec.shared.MajorFragmentProfile.minor_fragment_profile)
  return _internal_minor_fragment_profile(index);
}
inline ::exec::shared::MinorFragmentProfile* MajorFragmentProfile::_internal_add_minor_fragment_profile() {
  return minor_fragment_profile_.Add();
}
inline ::exec::shared::MinorFragmentProfile* MajorFragmentProfile::add_minor_fragment_profile() {
  // @@protoc_insertion_point(field_add:exec.shared.MajorFragmentProfile.minor_fragment_profile)
  return _internal_add_minor_fragment_profile();
}
inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::exec::shared::MinorFragmentProfile >&
MajorFragmentProfile::minor_fragment_profile() const {
  // @@protoc_insertion_point(field_list:exec.shared.MajorFragmentProfile.minor_fragment_profile)
  return minor_fragment_profile_;
}

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

// MinorFragmentProfile

// optional .exec.shared.FragmentState state = 1;
inline bool MinorFragmentProfile::_internal_has_state() const {
  bool value = (_has_bits_[0] & 0x00000004u) != 0;
  return value;
}
inline bool MinorFragmentProfile::has_state() const {
  return _internal_has_state();
}
inline void MinorFragmentProfile::clear_state() {
  state_ = 0;
  _has_bits_[0] &= ~0x00000004u;
}
inline ::exec::shared::FragmentState MinorFragmentProfile::_internal_state() const {
  return static_cast< ::exec::shared::FragmentState >(state_);
}
inline ::exec::shared::FragmentState MinorFragmentProfile::state() const {
  // @@protoc_insertion_point(field_get:exec.shared.MinorFragmentProfile.state)
  return _internal_state();
}
inline void MinorFragmentProfile::_internal_set_state(::exec::shared::FragmentState value) {
  assert(::exec::shared::FragmentState_IsValid(value));
  _has_bits_[0] |= 0x00000004u;
  state_ = value;
}
inline void MinorFragmentProfile::set_state(::exec::shared::FragmentState value) {
  _internal_set_state(value);
  // @@protoc_insertion_point(field_set:exec.shared.MinorFragmentProfile.state)
}

// optional .exec.shared.DrillPBError error = 2;
inline bool MinorFragmentProfile::_internal_has_error() const {
  bool value = (_has_bits_[0] & 0x00000001u) != 0;
  PROTOBUF_ASSUME(!value || error_ != nullptr);
  return value;
}
inline bool MinorFragmentProfile::has_error() const {
  return _internal_has_error();
}
inline void MinorFragmentProfile::clear_error() {
  if (error_ != nullptr) error_->Clear();
  _has_bits_[0] &= ~0x00000001u;
}
inline const ::exec::shared::DrillPBError& MinorFragmentProfile::_internal_error() const {
  const ::exec::shared::DrillPBError* p = error_;
  return p != nullptr ? *p : reinterpret_cast<const ::exec::shared::DrillPBError&>(
      ::exec::shared::_DrillPBError_default_instance_);
}
inline const ::exec::shared::DrillPBError& MinorFragmentProfile::error() const {
  // @@protoc_insertion_point(field_get:exec.shared.MinorFragmentProfile.error)
  return _internal_error();
}
inline void MinorFragmentProfile::unsafe_arena_set_allocated_error(
    ::exec::shared::DrillPBError* error) {
  if (GetArena() == nullptr) {
    delete reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(error_);
  }
  error_ = error;
  if (error) {
    _has_bits_[0] |= 0x00000001u;
  } else {
    _has_bits_[0] &= ~0x00000001u;
  }
  // @@protoc_insertion_point(field_unsafe_arena_set_allocated:exec.shared.MinorFragmentProfile.error)
}
inline ::exec::shared::DrillPBError* MinorFragmentProfile::release_error() {
  _has_bits_[0] &= ~0x00000001u;
  ::exec::shared::DrillPBError* temp = error_;
  error_ = nullptr;
  if (GetArena() != nullptr) {
    temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp);
  }
  return temp;
}
inline ::exec::shared::DrillPBError* MinorFragmentProfile::unsafe_arena_release_error() {
  // @@protoc_insertion_point(field_release:exec.shared.MinorFragmentProfile.error)
  _has_bits_[0] &= ~0x00000001u;
  ::exec::shared::DrillPBError* temp = error_;
  error_ = nullptr;
  return temp;
}
inline ::exec::shared::DrillPBError* MinorFragmentProfile::_internal_mutable_error() {
  _has_bits_[0] |= 0x00000001u;
  if (error_ == nullptr) {
    auto* p = CreateMaybeMessage<::exec::shared::DrillPBError>(GetArena());
    error_ = p;
  }
  return error_;
}
inline ::exec::shared::DrillPBError* MinorFragmentProfile::mutable_error() {
  // @@protoc_insertion_point(field_mutable:exec.shared.MinorFragmentProfile.error)
  return _internal_mutable_error();
}
inline void MinorFragmentProfile::set_allocated_error(::exec::shared::DrillPBError* error) {
  ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArena();
  if (message_arena == nullptr) {
    delete error_;
  }
  if (error) {
    ::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena =
      ::PROTOBUF_NAMESPACE_ID::Arena::GetArena(error);
    if (message_arena != submessage_arena) {
      error = ::PROTOBUF_NAMESPACE_ID::internal::GetOwnedMessage(
          message_arena, error, submessage_arena);
    }
    _has_bits_[0] |= 0x00000001u;
  } else {
    _has_bits_[0] &= ~0x00000001u;
  }
  error_ = error;
  // @@protoc_insertion_point(field_set_allocated:exec.shared.MinorFragmentProfile.error)
}

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

// repeated .exec.shared.OperatorProfile operator_profile = 4;
inline int MinorFragmentProfile::_internal_operator_profile_size() const {
  return operator_profile_.size();
}
inline int MinorFragmentProfile::operator_profile_size() const {
  return _internal_operator_profile_size();
}
inline void MinorFragmentProfile::clear_operator_profile() {
  operator_profile_.Clear();
}
inline ::exec::shared::OperatorProfile* MinorFragmentProfile::mutable_operator_profile(int index) {
  // @@protoc_insertion_point(field_mutable:exec.shared.MinorFragmentProfile.operator_profile)
  return operator_profile_.Mutable(index);
}
inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::exec::shared::OperatorProfile >*
MinorFragmentProfile::mutable_operator_profile() {
  // @@protoc_insertion_point(field_mutable_list:exec.shared.MinorFragmentProfile.operator_profile)
  return &operator_profile_;
}
inline const ::exec::shared::OperatorProfile& MinorFragmentProfile::_internal_operator_profile(int index) const {
  return operator_profile_.Get(index);
}
inline const ::exec::shared::OperatorProfile& MinorFragmentProfile::operator_profile(int index) const {
  // @@protoc_insertion_point(field_get:exec.shared.MinorFragmentProfile.operator_profile)
  return _internal_operator_profile(index);
}
inline ::exec::shared::OperatorProfile* MinorFragmentProfile::_internal_add_operator_profile() {
  return operator_profile_.Add();
}
inline ::exec::shared::OperatorProfile* MinorFragmentProfile::add_operator_profile() {
  // @@protoc_insertion_point(field_add:exec.shared.MinorFragmentProfile.operator_profile)
  return _internal_add_operator_profile();
}
inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::exec::shared::OperatorProfile >&
MinorFragmentProfile::operator_profile() const {
  // @@protoc_insertion_point(field_list:exec.shared.MinorFragmentProfile.operator_profile)
  return operator_profile_;
}

// optional int64 start_time = 5;
inline bool MinorFragmentProfile::_internal_has_start_time() const {
  bool value = (_has_bits_[0] & 0x00000010u) != 0;
  return value;
}
inline bool MinorFragmentProfile::has_start_time() const {
  return _internal_has_start_time();
}
inline void MinorFragmentProfile::clear_start_time() {
  start_time_ = PROTOBUF_LONGLONG(0);
  _has_bits_[0] &= ~0x00000010u;
}
inline ::PROTOBUF_NAMESPACE_ID::int64 MinorFragmentProfile::_internal_start_time() const {
  return start_time_;
}
inline ::PROTOBUF_NAMESPACE_ID::int64 MinorFragmentProfile::start_time() const {
  // @@protoc_insertion_point(field_get:exec.shared.MinorFragmentProfile.start_time)
  return _internal_start_time();
}
inline void MinorFragmentProfile::_internal_set_start_time(::PROTOBUF_NAMESPACE_ID::int64 value) {
  _has_bits_[0] |= 0x00000010u;
  start_time_ = value;
}
inline void MinorFragmentProfile::set_start_time(::PROTOBUF_NAMESPACE_ID::int64 value) {
  _internal_set_start_time(value);
  // @@protoc_insertion_point(field_set:exec.shared.MinorFragmentProfile.start_time)
}

// optional int64 end_time = 6;
inline bool MinorFragmentProfile::_internal_has_end_time() const {
  bool value = (_has_bits_[0] & 0x00000020u) != 0;
  return value;
}
inline bool MinorFragmentProfile::has_end_time() const {
  return _internal_has_end_time();
}
inline void MinorFragmentProfile::clear_end_time() {
  end_time_ = PROTOBUF_LONGLONG(0);
  _has_bits_[0] &= ~0x00000020u;
}
inline ::PROTOBUF_NAMESPACE_ID::int64 MinorFragmentProfile::_internal_end_time() const {
  return end_time_;
}
inline ::PROTOBUF_NAMESPACE_ID::int64 MinorFragmentProfile::end_time() const {
  // @@protoc_insertion_point(field_get:exec.shared.MinorFragmentProfile.end_time)
  return _internal_end_time();
}
inline void MinorFragmentProfile::_internal_set_end_time(::PROTOBUF_NAMESPACE_ID::int64 value) {
  _has_bits_[0] |= 0x00000020u;
  end_time_ = value;
}
inline void MinorFragmentProfile::set_end_time(::PROTOBUF_NAMESPACE_ID::int64 value) {
  _internal_set_end_time(value);
  // @@protoc_insertion_point(field_set:exec.shared.MinorFragmentProfile.end_time)
}

// optional int64 memory_used = 7;
inline bool MinorFragmentProfile::_internal_has_memory_used() const {
  bool value = (_has_bits_[0] & 0x00000040u) != 0;
  return value;
}
inline bool MinorFragmentProfile::has_memory_used() const {
  return _internal_has_memory_used();
}
inline void MinorFragmentProfile::clear_memory_used() {
  memory_used_ = PROTOBUF_LONGLONG(0);
  _has_bits_[0] &= ~0x00000040u;
}
inline ::PROTOBUF_NAMESPACE_ID::int64 MinorFragmentProfile::_internal_memory_used() const {
  return memory_used_;
}
inline ::PROTOBUF_NAMESPACE_ID::int64 MinorFragmentProfile::memory_used() const {
  // @@protoc_insertion_point(field_get:exec.shared.MinorFragmentProfile.memory_used)
  return _internal_memory_used();
}
inline void MinorFragmentProfile::_internal_set_memory_used(::PROTOBUF_NAMESPACE_ID::int64 value) {
  _has_bits_[0] |= 0x00000040u;
  memory_used_ = value;
}
inline void MinorFragmentProfile::set_memory_used(::PROTOBUF_NAMESPACE_ID::int64 value) {
  _internal_set_memory_used(value);
  // @@protoc_insertion_point(field_set:exec.shared.MinorFragmentProfile.memory_used)
}

// optional int64 max_memory_used = 8;
inline bool MinorFragmentProfile::_internal_has_max_memory_used() const {
  bool value = (_has_bits_[0] & 0x00000080u) != 0;
  return value;
}
inline bool MinorFragmentProfile::has_max_memory_used() const {
  return _internal_has_max_memory_used();
}
inline void MinorFragmentProfile::clear_max_memory_used() {
  max_memory_used_ = PROTOBUF_LONGLONG(0);
  _has_bits_[0] &= ~0x00000080u;
}
inline ::PROTOBUF_NAMESPACE_ID::int64 MinorFragmentProfile::_internal_max_memory_used() const {
  return max_memory_used_;
}
inline ::PROTOBUF_NAMESPACE_ID::int64 MinorFragmentProfile::max_memory_used() const {
  // @@protoc_insertion_point(field_get:exec.shared.MinorFragmentProfile.max_memory_used)
  return _internal_max_memory_used();
}
inline void MinorFragmentProfile::_internal_set_max_memory_used(::PROTOBUF_NAMESPACE_ID::int64 value) {
  _has_bits_[0] |= 0x00000080u;
  max_memory_used_ = value;
}
inline void MinorFragmentProfile::set_max_memory_used(::PROTOBUF_NAMESPACE_ID::int64 value) {
  _internal_set_max_memory_used(value);
  // @@protoc_insertion_point(field_set:exec.shared.MinorFragmentProfile.max_memory_used)
}

// optional .exec.DrillbitEndpoint endpoint = 9;
inline bool MinorFragmentProfile::_internal_has_endpoint() const {
  bool value = (_has_bits_[0] & 0x00000002u) != 0;
  PROTOBUF_ASSUME(!value || endpoint_ != nullptr);
  return value;
}
inline bool MinorFragmentProfile::has_endpoint() const {
  return _internal_has_endpoint();
}
inline const ::exec::DrillbitEndpoint& MinorFragmentProfile::_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& MinorFragmentProfile::endpoint() const {
  // @@protoc_insertion_point(field_get:exec.shared.MinorFragmentProfile.endpoint)
  return _internal_endpoint();
}
inline void MinorFragmentProfile::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] |= 0x00000002u;
  } else {
    _has_bits_[0] &= ~0x00000002u;
  }
  // @@protoc_insertion_point(field_unsafe_arena_set_allocated:exec.shared.MinorFragmentProfile.endpoint)
}
inline ::exec::DrillbitEndpoint* MinorFragmentProfile::release_endpoint() {
  _has_bits_[0] &= ~0x00000002u;
  ::exec::DrillbitEndpoint* temp = endpoint_;
  endpoint_ = nullptr;
  if (GetArena() != nullptr) {
    temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp);
  }
  return temp;
}
inline ::exec::DrillbitEndpoint* MinorFragmentProfile::unsafe_arena_release_endpoint() {
  // @@protoc_insertion_point(field_release:exec.shared.MinorFragmentProfile.endpoint)
  _has_bits_[0] &= ~0x00000002u;
  ::exec::DrillbitEndpoint* temp = endpoint_;
  endpoint_ = nullptr;
  return temp;
}
inline ::exec::DrillbitEndpoint* MinorFragmentProfile::_internal_mutable_endpoint() {
  _has_bits_[0] |= 0x00000002u;
  if (endpoint_ == nullptr) {
    auto* p = CreateMaybeMessage<::exec::DrillbitEndpoint>(GetArena());
    endpoint_ = p;
  }
  return endpoint_;
}
inline ::exec::DrillbitEndpoint* MinorFragmentProfile::mutable_endpoint() {
  // @@protoc_insertion_point(field_mutable:exec.shared.MinorFragmentProfile.endpoint)
  return _internal_mutable_endpoint();
}
inline void MinorFragmentProfile::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] |= 0x00000002u;
  } else {
    _has_bits_[0] &= ~0x00000002u;
  }
  endpoint_ = endpoint;
  // @@protoc_insertion_point(field_set_allocated:exec.shared.MinorFragmentProfile.endpoint)
}

// optional int64 last_update = 10;
inline bool MinorFragmentProfile::_internal_has_last_update() const {
  bool value = (_has_bits_[0] & 0x00000100u) != 0;
  return value;
}
inline bool MinorFragmentProfile::has_last_update() const {
  return _internal_has_last_update();
}
inline void MinorFragmentProfile::clear_last_update() {
  last_update_ = PROTOBUF_LONGLONG(0);
  _has_bits_[0] &= ~0x00000100u;
}
inline ::PROTOBUF_NAMESPACE_ID::int64 MinorFragmentProfile::_internal_last_update() const {
  return last_update_;
}
inline ::PROTOBUF_NAMESPACE_ID::int64 MinorFragmentProfile::last_update() const {
  // @@protoc_insertion_point(field_get:exec.shared.MinorFragmentProfile.last_update)
  return _internal_last_update();
}
inline void MinorFragmentProfile::_internal_set_last_update(::PROTOBUF_NAMESPACE_ID::int64 value) {
  _has_bits_[0] |= 0x00000100u;
  last_update_ = value;
}
inline void MinorFragmentProfile::set_last_update(::PROTOBUF_NAMESPACE_ID::int64 value) {
  _internal_set_last_update(value);
  // @@protoc_insertion_point(field_set:exec.shared.MinorFragmentProfile.last_update)
}

// optional int64 last_progress = 11;
inline bool MinorFragmentProfile::_internal_has_last_progress() const {
  bool value = (_has_bits_[0] & 0x00000200u) != 0;
  return value;
}
inline bool MinorFragmentProfile::has_last_progress() const {
  return _internal_has_last_progress();
}
inline void MinorFragmentProfile::clear_last_progress() {
  last_progress_ = PROTOBUF_LONGLONG(0);
  _has_bits_[0] &= ~0x00000200u;
}
inline ::PROTOBUF_NAMESPACE_ID::int64 MinorFragmentProfile::_internal_last_progress() const {
  return last_progress_;
}
inline ::PROTOBUF_NAMESPACE_ID::int64 MinorFragmentProfile::last_progress() const {
  // @@protoc_insertion_point(field_get:exec.shared.MinorFragmentProfile.last_progress)
  return _internal_last_progress();
}
inline void MinorFragmentProfile::_internal_set_last_progress(::PROTOBUF_NAMESPACE_ID::int64 value) {
  _has_bits_[0] |= 0x00000200u;
  last_progress_ = value;
}
inline void MinorFragmentProfile::set_last_progress(::PROTOBUF_NAMESPACE_ID::int64 value) {
  _internal_set_last_progress(value);
  // @@protoc_insertion_point(field_set:exec.shared.MinorFragmentProfile.last_progress)
}

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

// OperatorProfile

// repeated .exec.shared.StreamProfile input_profile = 1;
inline int OperatorProfile::_internal_input_profile_size() const {
  return input_profile_.size();
}
inline int OperatorProfile::input_profile_size() const {
  return _internal_input_profile_size();
}
inline void OperatorProfile::clear_input_profile() {
  input_profile_.Clear();
}
inline ::exec::shared::StreamProfile* OperatorProfile::mutable_input_profile(int index) {
  // @@protoc_insertion_point(field_mutable:exec.shared.OperatorProfile.input_profile)
  return input_profile_.Mutable(index);
}
inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::exec::shared::StreamProfile >*
OperatorProfile::mutable_input_profile() {
  // @@protoc_insertion_point(field_mutable_list:exec.shared.OperatorProfile.input_profile)
  return &input_profile_;
}
inline const ::exec::shared::StreamProfile& OperatorProfile::_internal_input_profile(int index) const {
  return input_profile_.Get(index);
}
inline const ::exec::shared::StreamProfile& OperatorProfile::input_profile(int index) const {
  // @@protoc_insertion_point(field_get:exec.shared.OperatorProfile.input_profile)
  return _internal_input_profile(index);
}
inline ::exec::shared::StreamProfile* OperatorProfile::_internal_add_input_profile() {
  return input_profile_.Add();
}
inline ::exec::shared::StreamProfile* OperatorProfile::add_input_profile() {
  // @@protoc_insertion_point(field_add:exec.shared.OperatorProfile.input_profile)
  return _internal_add_input_profile();
}
inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::exec::shared::StreamProfile >&
OperatorProfile::input_profile() const {
  // @@protoc_insertion_point(field_list:exec.shared.OperatorProfile.input_profile)
  return input_profile_;
}

// optional int32 operator_id = 3;
inline bool OperatorProfile::_internal_has_operator_id() const {
  bool value = (_has_bits_[0] & 0x00000002u) != 0;
  return value;
}
inline bool OperatorProfile::has_operator_id() const {
  return _internal_has_operator_id();
}
inline void OperatorProfile::clear_operator_id() {
  operator_id_ = 0;
  _has_bits_[0] &= ~0x00000002u;
}
inline ::PROTOBUF_NAMESPACE_ID::int32 OperatorProfile::_internal_operator_id() const {
  return operator_id_;
}
inline ::PROTOBUF_NAMESPACE_ID::int32 OperatorProfile::operator_id() const {
  // @@protoc_insertion_point(field_get:exec.shared.OperatorProfile.operator_id)
  return _internal_operator_id();
}
inline void OperatorProfile::_internal_set_operator_id(::PROTOBUF_NAMESPACE_ID::int32 value) {
  _has_bits_[0] |= 0x00000002u;
  operator_id_ = value;
}
inline void OperatorProfile::set_operator_id(::PROTOBUF_NAMESPACE_ID::int32 value) {
  _internal_set_operator_id(value);
  // @@protoc_insertion_point(field_set:exec.shared.OperatorProfile.operator_id)
}

// optional int32 operator_type = 4 [deprecated = true];
inline bool OperatorProfile::_internal_has_operator_type() const {
  bool value = (_has_bits_[0] & 0x00000004u) != 0;
  return value;
}
inline bool OperatorProfile::has_operator_type() const {
  return _internal_has_operator_type();
}
inline void OperatorProfile::clear_operator_type() {
  operator_type_ = 0;
  _has_bits_[0] &= ~0x00000004u;
}
inline ::PROTOBUF_NAMESPACE_ID::int32 OperatorProfile::_internal_operator_type() const {
  return operator_type_;
}
inline ::PROTOBUF_NAMESPACE_ID::int32 OperatorProfile::operator_type() const {
  // @@protoc_insertion_point(field_get:exec.shared.OperatorProfile.operator_type)
  return _internal_operator_type();
}
inline void OperatorProfile::_internal_set_operator_type(::PROTOBUF_NAMESPACE_ID::int32 value) {
  _has_bits_[0] |= 0x00000004u;
  operator_type_ = value;
}
inline void OperatorProfile::set_operator_type(::PROTOBUF_NAMESPACE_ID::int32 value) {
  _internal_set_operator_type(value);
  // @@protoc_insertion_point(field_set:exec.shared.OperatorProfile.operator_type)
}

// optional int64 setup_nanos = 5;
inline bool OperatorProfile::_internal_has_setup_nanos() const {
  bool value = (_has_bits_[0] & 0x00000008u) != 0;
  return value;
}
inline bool OperatorProfile::has_setup_nanos() const {
  return _internal_has_setup_nanos();
}
inline void OperatorProfile::clear_setup_nanos() {
  setup_nanos_ = PROTOBUF_LONGLONG(0);
  _has_bits_[0] &= ~0x00000008u;
}
inline ::PROTOBUF_NAMESPACE_ID::int64 OperatorProfile::_internal_setup_nanos() const {
  return setup_nanos_;
}
inline ::PROTOBUF_NAMESPACE_ID::int64 OperatorProfile::setup_nanos() const {
  // @@protoc_insertion_point(field_get:exec.shared.OperatorProfile.setup_nanos)
  return _internal_setup_nanos();
}
inline void OperatorProfile::_internal_set_setup_nanos(::PROTOBUF_NAMESPACE_ID::int64 value) {
  _has_bits_[0] |= 0x00000008u;
  setup_nanos_ = value;
}
inline void OperatorProfile::set_setup_nanos(::PROTOBUF_NAMESPACE_ID::int64 value) {
  _internal_set_setup_nanos(value);
  // @@protoc_insertion_point(field_set:exec.shared.OperatorProfile.setup_nanos)
}

// optional int64 process_nanos = 6;
inline bool OperatorProfile::_internal_has_process_nanos() const {
  bool value = (_has_bits_[0] & 0x00000010u) != 0;
  return value;
}
inline bool OperatorProfile::has_process_nanos() const {
  return _internal_has_process_nanos();
}
inline void OperatorProfile::clear_process_nanos() {
  process_nanos_ = PROTOBUF_LONGLONG(0);
  _has_bits_[0] &= ~0x00000010u;
}
inline ::PROTOBUF_NAMESPACE_ID::int64 OperatorProfile::_internal_process_nanos() const {
  return process_nanos_;
}
inline ::PROTOBUF_NAMESPACE_ID::int64 OperatorProfile::process_nanos() const {
  // @@protoc_insertion_point(field_get:exec.shared.OperatorProfile.process_nanos)
  return _internal_process_nanos();
}
inline void OperatorProfile::_internal_set_process_nanos(::PROTOBUF_NAMESPACE_ID::int64 value) {
  _has_bits_[0] |= 0x00000010u;
  process_nanos_ = value;
}
inline void OperatorProfile::set_process_nanos(::PROTOBUF_NAMESPACE_ID::int64 value) {
  _internal_set_process_nanos(value);
  // @@protoc_insertion_point(field_set:exec.shared.OperatorProfile.process_nanos)
}

// optional int64 peak_local_memory_allocated = 7;
inline bool OperatorProfile::_internal_has_peak_local_memory_allocated() const {
  bool value = (_has_bits_[0] & 0x00000020u) != 0;
  return value;
}
inline bool OperatorProfile::has_peak_local_memory_allocated() const {
  return _internal_has_peak_local_memory_allocated();
}
inline void OperatorProfile::clear_peak_local_memory_allocated() {
  peak_local_memory_allocated_ = PROTOBUF_LONGLONG(0);
  _has_bits_[0] &= ~0x00000020u;
}
inline ::PROTOBUF_NAMESPACE_ID::int64 OperatorProfile::_internal_peak_local_memory_allocated() const {
  return peak_local_memory_allocated_;
}
inline ::PROTOBUF_NAMESPACE_ID::int64 OperatorProfile::peak_local_memory_allocated() const {
  // @@protoc_insertion_point(field_get:exec.shared.OperatorProfile.peak_local_memory_allocated)
  return _internal_peak_local_memory_allocated();
}
inline void OperatorProfile::_internal_set_peak_local_memory_allocated(::PROTOBUF_NAMESPACE_ID::int64 value) {
  _has_bits_[0] |= 0x00000020u;
  peak_local_memory_allocated_ = value;
}
inline void OperatorProfile::set_peak_local_memory_allocated(::PROTOBUF_NAMESPACE_ID::int64 value) {
  _internal_set_peak_local_memory_allocated(value);
  // @@protoc_insertion_point(field_set:exec.shared.OperatorProfile.peak_local_memory_allocated)
}

// repeated .exec.shared.MetricValue metric = 8;
inline int OperatorProfile::_internal_metric_size() const {
  return metric_.size();
}
inline int OperatorProfile::metric_size() const {
  return _internal_metric_size();
}
inline void OperatorProfile::clear_metric() {
  metric_.Clear();
}
inline ::exec::shared::MetricValue* OperatorProfile::mutable_metric(int index) {
  // @@protoc_insertion_point(field_mutable:exec.shared.OperatorProfile.metric)
  return metric_.Mutable(index);
}
inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::exec::shared::MetricValue >*
OperatorProfile::mutable_metric() {
  // @@protoc_insertion_point(field_mutable_list:exec.shared.OperatorProfile.metric)
  return &metric_;
}
inline const ::exec::shared::MetricValue& OperatorProfile::_internal_metric(int index) const {
  return metric_.Get(index);
}
inline const ::exec::shared::MetricValue& OperatorProfile::metric(int index) const {
  // @@protoc_insertion_point(field_get:exec.shared.OperatorProfile.metric)
  return _internal_metric(index);
}
inline ::exec::shared::MetricValue* OperatorProfile::_internal_add_metric() {
  return metric_.Add();
}
inline ::exec::shared::MetricValue* OperatorProfile::add_metric() {
  // @@protoc_insertion_point(field_add:exec.shared.OperatorProfile.metric)
  return _internal_add_metric();
}
inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::exec::shared::MetricValue >&
OperatorProfile::metric() const {
  // @@protoc_insertion_point(field_list:exec.shared.OperatorProfile.metric)
  return metric_;
}

// optional int64 wait_nanos = 9;
inline bool OperatorProfile::_internal_has_wait_nanos() const {
  bool value = (_has_bits_[0] & 0x00000040u) != 0;
  return value;
}
inline bool OperatorProfile::has_wait_nanos() const {
  return _internal_has_wait_nanos();
}
inline void OperatorProfile::clear_wait_nanos() {
  wait_nanos_ = PROTOBUF_LONGLONG(0);
  _has_bits_[0] &= ~0x00000040u;
}
inline ::PROTOBUF_NAMESPACE_ID::int64 OperatorProfile::_internal_wait_nanos() const {
  return wait_nanos_;
}
inline ::PROTOBUF_NAMESPACE_ID::int64 OperatorProfile::wait_nanos() const {
  // @@protoc_insertion_point(field_get:exec.shared.OperatorProfile.wait_nanos)
  return _internal_wait_nanos();
}
inline void OperatorProfile::_internal_set_wait_nanos(::PROTOBUF_NAMESPACE_ID::int64 value) {
  _has_bits_[0] |= 0x00000040u;
  wait_nanos_ = value;
}
inline void OperatorProfile::set_wait_nanos(::PROTOBUF_NAMESPACE_ID::int64 value) {
  _internal_set_wait_nanos(value);
  // @@protoc_insertion_point(field_set:exec.shared.OperatorProfile.wait_nanos)
}

// optional string operator_type_name = 10;
inline bool OperatorProfile::_internal_has_operator_type_name() const {
  bool value = (_has_bits_[0] & 0x00000001u) != 0;
  return value;
}
inline bool OperatorProfile::has_operator_type_name() const {
  return _internal_has_operator_type_name();
}
inline void OperatorProfile::clear_operator_type_name() {
  operator_type_name_.ClearToEmpty();
  _has_bits_[0] &= ~0x00000001u;
}
inline const std::string& OperatorProfile::operator_type_name() const {
  // @@protoc_insertion_point(field_get:exec.shared.OperatorProfile.operator_type_name)
  return _internal_operator_type_name();
}
template <typename ArgT0, typename... ArgT>
PROTOBUF_ALWAYS_INLINE
inline void OperatorProfile::set_operator_type_name(ArgT0&& arg0, ArgT... args) {
 _has_bits_[0] |= 0x00000001u;
 operator_type_name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArena());
  // @@protoc_insertion_point(field_set:exec.shared.OperatorProfile.operator_type_name)
}
inline std::string* OperatorProfile::mutable_operator_type_name() {
  // @@protoc_insertion_point(field_mutable:exec.shared.OperatorProfile.operator_type_name)
  return _internal_mutable_operator_type_name();
}
inline const std::string& OperatorProfile::_internal_operator_type_name() const {
  return operator_type_name_.Get();
}
inline void OperatorProfile::_internal_set_operator_type_name(const std::string& value) {
  _has_bits_[0] |= 0x00000001u;
  operator_type_name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena());
}
inline std::string* OperatorProfile::_internal_mutable_operator_type_name() {
  _has_bits_[0] |= 0x00000001u;
  return operator_type_name_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena());
}
inline std::string* OperatorProfile::release_operator_type_name() {
  // @@protoc_insertion_point(field_release:exec.shared.OperatorProfile.operator_type_name)
  if (!_internal_has_operator_type_name()) {
    return nullptr;
  }
  _has_bits_[0] &= ~0x00000001u;
  return operator_type_name_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena());
}
inline void OperatorProfile::set_allocated_operator_type_name(std::string* operator_type_name) {
  if (operator_type_name != nullptr) {
    _has_bits_[0] |= 0x00000001u;
  } else {
    _has_bits_[0] &= ~0x00000001u;
  }
  operator_type_name_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), operator_type_name,
      GetArena());
  // @@protoc_insertion_point(field_set_allocated:exec.shared.OperatorProfile.operator_type_name)
}

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

// StreamProfile

// optional int64 records = 1;
inline bool StreamProfile::_internal_has_records() const {
  bool value = (_has_bits_[0] & 0x00000001u) != 0;
  return value;
}
inline bool StreamProfile::has_records() const {
  return _internal_has_records();
}
inline void StreamProfile::clear_records() {
  records_ = PROTOBUF_LONGLONG(0);
  _has_bits_[0] &= ~0x00000001u;
}
inline ::PROTOBUF_NAMESPACE_ID::int64 StreamProfile::_internal_records() const {
  return records_;
}
inline ::PROTOBUF_NAMESPACE_ID::int64 StreamProfile::records() const {
  // @@protoc_insertion_point(field_get:exec.shared.StreamProfile.records)
  return _internal_records();
}
inline void StreamProfile::_internal_set_records(::PROTOBUF_NAMESPACE_ID::int64 value) {
  _has_bits_[0] |= 0x00000001u;
  records_ = value;
}
inline void StreamProfile::set_records(::PROTOBUF_NAMESPACE_ID::int64 value) {
  _internal_set_records(value);
  // @@protoc_insertion_point(field_set:exec.shared.StreamProfile.records)
}

// optional int64 batches = 2;
inline bool StreamProfile::_internal_has_batches() const {
  bool value = (_has_bits_[0] & 0x00000002u) != 0;
  return value;
}
inline bool StreamProfile::has_batches() const {
  return _internal_has_batches();
}
inline void StreamProfile::clear_batches() {
  batches_ = PROTOBUF_LONGLONG(0);
  _has_bits_[0] &= ~0x00000002u;
}
inline ::PROTOBUF_NAMESPACE_ID::int64 StreamProfile::_internal_batches() const {
  return batches_;
}
inline ::PROTOBUF_NAMESPACE_ID::int64 StreamProfile::batches() const {
  // @@protoc_insertion_point(field_get:exec.shared.StreamProfile.batches)
  return _internal_batches();
}
inline void StreamProfile::_internal_set_batches(::PROTOBUF_NAMESPACE_ID::int64 value) {
  _has_bits_[0] |= 0x00000002u;
  batches_ = value;
}
inline void StreamProfile::set_batches(::PROTOBUF_NAMESPACE_ID::int64 value) {
  _internal_set_batches(value);
  // @@protoc_insertion_point(field_set:exec.shared.StreamProfile.batches)
}

// optional int64 schemas = 3;
inline bool StreamProfile::_internal_has_schemas() const {
  bool value = (_has_bits_[0] & 0x00000004u) != 0;
  return value;
}
inline bool StreamProfile::has_schemas() const {
  return _internal_has_schemas();
}
inline void StreamProfile::clear_schemas() {
  schemas_ = PROTOBUF_LONGLONG(0);
  _has_bits_[0] &= ~0x00000004u;
}
inline ::PROTOBUF_NAMESPACE_ID::int64 StreamProfile::_internal_schemas() const {
  return schemas_;
}
inline ::PROTOBUF_NAMESPACE_ID::int64 StreamProfile::schemas() const {
  // @@protoc_insertion_point(field_get:exec.shared.StreamProfile.schemas)
  return _internal_schemas();
}
inline void StreamProfile::_internal_set_schemas(::PROTOBUF_NAMESPACE_ID::int64 value) {
  _has_bits_[0] |= 0x00000004u;
  schemas_ = value;
}
inline void StreamProfile::set_schemas(::PROTOBUF_NAMESPACE_ID::int64 value) {
  _internal_set_schemas(value);
  // @@protoc_insertion_point(field_set:exec.shared.StreamProfile.schemas)
}

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

// MetricValue

// optional int32 metric_id = 1;
inline bool MetricValue::_internal_has_metric_id() const {
  bool value = (_has_bits_[0] & 0x00000004u) != 0;
  return value;
}
inline bool MetricValue::has_metric_id() const {
  return _internal_has_metric_id();
}
inline void MetricValue::clear_metric_id() {
  metric_id_ = 0;
  _has_bits_[0] &= ~0x00000004u;
}
inline ::PROTOBUF_NAMESPACE_ID::int32 MetricValue::_internal_metric_id() const {
  return metric_id_;
}
inline ::PROTOBUF_NAMESPACE_ID::int32 MetricValue::metric_id() const {
  // @@protoc_insertion_point(field_get:exec.shared.MetricValue.metric_id)
  return _internal_metric_id();
}
inline void MetricValue::_internal_set_metric_id(::PROTOBUF_NAMESPACE_ID::int32 value) {
  _has_bits_[0] |= 0x00000004u;
  metric_id_ = value;
}
inline void MetricValue::set_metric_id(::PROTOBUF_NAMESPACE_ID::int32 value) {
  _internal_set_metric_id(value);
  // @@protoc_insertion_point(field_set:exec.shared.MetricValue.metric_id)
}

// optional int64 long_value = 2;
inline bool MetricValue::_internal_has_long_value() const {
  bool value = (_has_bits_[0] & 0x00000001u) != 0;
  return value;
}
inline bool MetricValue::has_long_value() const {
  return _internal_has_long_value();
}
inline void MetricValue::clear_long_value() {
  long_value_ = PROTOBUF_LONGLONG(0);
  _has_bits_[0] &= ~0x00000001u;
}
inline ::PROTOBUF_NAMESPACE_ID::int64 MetricValue::_internal_long_value() const {
  return long_value_;
}
inline ::PROTOBUF_NAMESPACE_ID::int64 MetricValue::long_value() const {
  // @@protoc_insertion_point(field_get:exec.shared.MetricValue.long_value)
  return _internal_long_value();
}
inline void MetricValue::_internal_set_long_value(::PROTOBUF_NAMESPACE_ID::int64 value) {
  _has_bits_[0] |= 0x00000001u;
  long_value_ = value;
}
inline void MetricValue::set_long_value(::PROTOBUF_NAMESPACE_ID::int64 value) {
  _internal_set_long_value(value);
  // @@protoc_insertion_point(field_set:exec.shared.MetricValue.long_value)
}

// optional double double_value = 3;
inline bool MetricValue::_internal_has_double_value() const {
  bool value = (_has_bits_[0] & 0x00000002u) != 0;
  return value;
}
inline bool MetricValue::has_double_value() const {
  return _internal_has_double_value();
}
inline void MetricValue::clear_double_value() {
  double_value_ = 0;
  _has_bits_[0] &= ~0x00000002u;
}
inline double MetricValue::_internal_double_value() const {
  return double_value_;
}
inline double MetricValue::double_value() const {
  // @@protoc_insertion_point(field_get:exec.shared.MetricValue.double_value)
  return _internal_double_value();
}
inline void MetricValue::_internal_set_double_value(double value) {
  _has_bits_[0] |= 0x00000002u;
  double_value_ = value;
}
inline void MetricValue::set_double_value(double value) {
  _internal_set_double_value(value);
  // @@protoc_insertion_point(field_set:exec.shared.MetricValue.double_value)
}

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

// Registry

// repeated .exec.shared.Jar jar = 1;
inline int Registry::_internal_jar_size() const {
  return jar_.size();
}
inline int Registry::jar_size() const {
  return _internal_jar_size();
}
inline void Registry::clear_jar() {
  jar_.Clear();
}
inline ::exec::shared::Jar* Registry::mutable_jar(int index) {
  // @@protoc_insertion_point(field_mutable:exec.shared.Registry.jar)
  return jar_.Mutable(index);
}
inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::exec::shared::Jar >*
Registry::mutable_jar() {
  // @@protoc_insertion_point(field_mutable_list:exec.shared.Registry.jar)
  return &jar_;
}
inline const ::exec::shared::Jar& Registry::_internal_jar(int index) const {
  return jar_.Get(index);
}
inline const ::exec::shared::Jar& Registry::jar(int index) const {
  // @@protoc_insertion_point(field_get:exec.shared.Registry.jar)
  return _internal_jar(index);
}
inline ::exec::shared::Jar* Registry::_internal_add_jar() {
  return jar_.Add();
}
inline ::exec::shared::Jar* Registry::add_jar() {
  // @@protoc_insertion_point(field_add:exec.shared.Registry.jar)
  return _internal_add_jar();
}
inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::exec::shared::Jar >&
Registry::jar() const {
  // @@protoc_insertion_point(field_list:exec.shared.Registry.jar)
  return jar_;
}

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

// Jar

// optional string name = 1;
inline bool Jar::_internal_has_name() const {
  bool value = (_has_bits_[0] & 0x00000001u) != 0;
  return value;
}
inline bool Jar::has_name() const {
  return _internal_has_name();
}
inline void Jar::clear_name() {
  name_.ClearToEmpty();
  _has_bits_[0] &= ~0x00000001u;
}
inline const std::string& Jar::name() const {
  // @@protoc_insertion_point(field_get:exec.shared.Jar.name)
  return _internal_name();
}
template <typename ArgT0, typename... ArgT>
PROTOBUF_ALWAYS_INLINE
inline void Jar::set_name(ArgT0&& arg0, ArgT... args) {
 _has_bits_[0] |= 0x00000001u;
 name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArena());
  // @@protoc_insertion_point(field_set:exec.shared.Jar.name)
}
inline std::string* Jar::mutable_name() {
  // @@protoc_insertion_point(field_mutable:exec.shared.Jar.name)
  return _internal_mutable_name();
}
inline const std::string& Jar::_internal_name() const {
  return name_.Get();
}
inline void Jar::_internal_set_name(const std::string& value) {
  _has_bits_[0] |= 0x00000001u;
  name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena());
}
inline std::string* Jar::_internal_mutable_name() {
  _has_bits_[0] |= 0x00000001u;
  return name_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena());
}
inline std::string* Jar::release_name() {
  // @@protoc_insertion_point(field_release:exec.shared.Jar.name)
  if (!_internal_has_name()) {
    return nullptr;
  }
  _has_bits_[0] &= ~0x00000001u;
  return name_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena());
}
inline void Jar::set_allocated_name(std::string* name) {
  if (name != nullptr) {
    _has_bits_[0] |= 0x00000001u;
  } else {
    _has_bits_[0] &= ~0x00000001u;
  }
  name_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), name,
      GetArena());
  // @@protoc_insertion_point(field_set_allocated:exec.shared.Jar.name)
}

// repeated string function_signature = 2;
inline int Jar::_internal_function_signature_size() const {
  return function_signature_.size();
}
inline int Jar::function_signature_size() const {
  return _internal_function_signature_size();
}
inline void Jar::clear_function_signature() {
  function_signature_.Clear();
}
inline std::string* Jar::add_function_signature() {
  // @@protoc_insertion_point(field_add_mutable:exec.shared.Jar.function_signature)
  return _internal_add_function_signature();
}
inline const std::string& Jar::_internal_function_signature(int index) const {
  return function_signature_.Get(index);
}
inline const std::string& Jar::function_signature(int index) const {
  // @@protoc_insertion_point(field_get:exec.shared.Jar.function_signature)
  return _internal_function_signature(index);
}
inline std::string* Jar::mutable_function_signature(int index) {
  // @@protoc_insertion_point(field_mutable:exec.shared.Jar.function_signature)
  return function_signature_.Mutable(index);
}
inline void Jar::set_function_signature(int index, const std::string& value) {
  // @@protoc_insertion_point(field_set:exec.shared.Jar.function_signature)
  function_signature_.Mutable(index)->assign(value);
}
inline void Jar::set_function_signature(int index, std::string&& value) {
  // @@protoc_insertion_point(field_set:exec.shared.Jar.function_signature)
  function_signature_.Mutable(index)->assign(std::move(value));
}
inline void Jar::set_function_signature(int index, const char* value) {
  GOOGLE_DCHECK(value != nullptr);
  function_signature_.Mutable(index)->assign(value);
  // @@protoc_insertion_point(field_set_char:exec.shared.Jar.function_signature)
}
inline void Jar::set_function_signature(int index, const char* value, size_t size) {
  function_signature_.Mutable(index)->assign(
    reinterpret_cast<const char*>(value), size);
  // @@protoc_insertion_point(field_set_pointer:exec.shared.Jar.function_signature)
}
inline std::string* Jar::_internal_add_function_signature() {
  return function_signature_.Add();
}
inline void Jar::add_function_signature(const std::string& value) {
  function_signature_.Add()->assign(value);
  // @@protoc_insertion_point(field_add:exec.shared.Jar.function_signature)
}
inline void Jar::add_function_signature(std::string&& value) {
  function_signature_.Add(std::move(value));
  // @@protoc_insertion_point(field_add:exec.shared.Jar.function_signature)
}
inline void Jar::add_function_signature(const char* value) {
  GOOGLE_DCHECK(value != nullptr);
  function_signature_.Add()->assign(value);
  // @@protoc_insertion_point(field_add_char:exec.shared.Jar.function_signature)
}
inline void Jar::add_function_signature(const char* value, size_t size) {
  function_signature_.Add()->assign(reinterpret_cast<const char*>(value), size);
  // @@protoc_insertion_point(field_add_pointer:exec.shared.Jar.function_signature)
}
inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField<std::string>&
Jar::function_signature() const {
  // @@protoc_insertion_point(field_list:exec.shared.Jar.function_signature)
  return function_signature_;
}
inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField<std::string>*
Jar::mutable_function_signature() {
  // @@protoc_insertion_point(field_mutable_list:exec.shared.Jar.function_signature)
  return &function_signature_;
}

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

// SaslMessage

// optional string mechanism = 1;
inline bool SaslMessage::_internal_has_mechanism() const {
  bool value = (_has_bits_[0] & 0x00000001u) != 0;
  return value;
}
inline bool SaslMessage::has_mechanism() const {
  return _internal_has_mechanism();
}
inline void SaslMessage::clear_mechanism() {
  mechanism_.ClearToEmpty();
  _has_bits_[0] &= ~0x00000001u;
}
inline const std::string& SaslMessage::mechanism() const {
  // @@protoc_insertion_point(field_get:exec.shared.SaslMessage.mechanism)
  return _internal_mechanism();
}
template <typename ArgT0, typename... ArgT>
PROTOBUF_ALWAYS_INLINE
inline void SaslMessage::set_mechanism(ArgT0&& arg0, ArgT... args) {
 _has_bits_[0] |= 0x00000001u;
 mechanism_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArena());
  // @@protoc_insertion_point(field_set:exec.shared.SaslMessage.mechanism)
}
inline std::string* SaslMessage::mutable_mechanism() {
  // @@protoc_insertion_point(field_mutable:exec.shared.SaslMessage.mechanism)
  return _internal_mutable_mechanism();
}
inline const std::string& SaslMessage::_internal_mechanism() const {
  return mechanism_.Get();
}
inline void SaslMessage::_internal_set_mechanism(const std::string& value) {
  _has_bits_[0] |= 0x00000001u;
  mechanism_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena());
}
inline std::string* SaslMessage::_internal_mutable_mechanism() {
  _has_bits_[0] |= 0x00000001u;
  return mechanism_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena());
}
inline std::string* SaslMessage::release_mechanism() {
  // @@protoc_insertion_point(field_release:exec.shared.SaslMessage.mechanism)
  if (!_internal_has_mechanism()) {
    return nullptr;
  }
  _has_bits_[0] &= ~0x00000001u;
  return mechanism_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena());
}
inline void SaslMessage::set_allocated_mechanism(std::string* mechanism) {
  if (mechanism != nullptr) {
    _has_bits_[0] |= 0x00000001u;
  } else {
    _has_bits_[0] &= ~0x00000001u;
  }
  mechanism_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), mechanism,
      GetArena());
  // @@protoc_insertion_point(field_set_allocated:exec.shared.SaslMessage.mechanism)
}

// optional bytes data = 2;
inline bool SaslMessage::_internal_has_data() const {
  bool value = (_has_bits_[0] & 0x00000002u) != 0;
  return value;
}
inline bool SaslMessage::has_data() const {
  return _internal_has_data();
}
inline void SaslMessage::clear_data() {
  data_.ClearToEmpty();
  _has_bits_[0] &= ~0x00000002u;
}
inline const std::string& SaslMessage::data() const {
  // @@protoc_insertion_point(field_get:exec.shared.SaslMessage.data)
  return _internal_data();
}
template <typename ArgT0, typename... ArgT>
PROTOBUF_ALWAYS_INLINE
inline void SaslMessage::set_data(ArgT0&& arg0, ArgT... args) {
 _has_bits_[0] |= 0x00000002u;
 data_.SetBytes(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArena());
  // @@protoc_insertion_point(field_set:exec.shared.SaslMessage.data)
}
inline std::string* SaslMessage::mutable_data() {
  // @@protoc_insertion_point(field_mutable:exec.shared.SaslMessage.data)
  return _internal_mutable_data();
}
inline const std::string& SaslMessage::_internal_data() const {
  return data_.Get();
}
inline void SaslMessage::_internal_set_data(const std::string& value) {
  _has_bits_[0] |= 0x00000002u;
  data_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena());
}
inline std::string* SaslMessage::_internal_mutable_data() {
  _has_bits_[0] |= 0x00000002u;
  return data_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena());
}
inline std::string* SaslMessage::release_data() {
  // @@protoc_insertion_point(field_release:exec.shared.SaslMessage.data)
  if (!_internal_has_data()) {
    return nullptr;
  }
  _has_bits_[0] &= ~0x00000002u;
  return data_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena());
}
inline void SaslMessage::set_allocated_data(std::string* data) {
  if (data != nullptr) {
    _has_bits_[0] |= 0x00000002u;
  } else {
    _has_bits_[0] &= ~0x00000002u;
  }
  data_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), data,
      GetArena());
  // @@protoc_insertion_point(field_set_allocated:exec.shared.SaslMessage.data)
}

// optional .exec.shared.SaslStatus status = 3;
inline bool SaslMessage::_internal_has_status() const {
  bool value = (_has_bits_[0] & 0x00000004u) != 0;
  return value;
}
inline bool SaslMessage::has_status() const {
  return _internal_has_status();
}
inline void SaslMessage::clear_status() {
  status_ = 0;
  _has_bits_[0] &= ~0x00000004u;
}
inline ::exec::shared::SaslStatus SaslMessage::_internal_status() const {
  return static_cast< ::exec::shared::SaslStatus >(status_);
}
inline ::exec::shared::SaslStatus SaslMessage::status() const {
  // @@protoc_insertion_point(field_get:exec.shared.SaslMessage.status)
  return _internal_status();
}
inline void SaslMessage::_internal_set_status(::exec::shared::SaslStatus value) {
  assert(::exec::shared::SaslStatus_IsValid(value));
  _has_bits_[0] |= 0x00000004u;
  status_ = value;
}
inline void SaslMessage::set_status(::exec::shared::SaslStatus value) {
  _internal_set_status(value);
  // @@protoc_insertion_point(field_set:exec.shared.SaslMessage.status)
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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


// @@protoc_insertion_point(namespace_scope)

}  // namespace shared
}  // namespace exec

PROTOBUF_NAMESPACE_OPEN

template <> struct is_proto_enum< ::exec::shared::DrillPBError_ErrorType> : ::std::true_type {};
template <>
inline const EnumDescriptor* GetEnumDescriptor< ::exec::shared::DrillPBError_ErrorType>() {
  return ::exec::shared::DrillPBError_ErrorType_descriptor();
}
template <> struct is_proto_enum< ::exec::shared::NamePart_Type> : ::std::true_type {};
template <>
inline const EnumDescriptor* GetEnumDescriptor< ::exec::shared::NamePart_Type>() {
  return ::exec::shared::NamePart_Type_descriptor();
}
template <> struct is_proto_enum< ::exec::shared::QueryResult_QueryState> : ::std::true_type {};
template <>
inline const EnumDescriptor* GetEnumDescriptor< ::exec::shared::QueryResult_QueryState>() {
  return ::exec::shared::QueryResult_QueryState_descriptor();
}
template <> struct is_proto_enum< ::exec::shared::RpcChannel> : ::std::true_type {};
template <>
inline const EnumDescriptor* GetEnumDescriptor< ::exec::shared::RpcChannel>() {
  return ::exec::shared::RpcChannel_descriptor();
}
template <> struct is_proto_enum< ::exec::shared::QueryType> : ::std::true_type {};
template <>
inline const EnumDescriptor* GetEnumDescriptor< ::exec::shared::QueryType>() {
  return ::exec::shared::QueryType_descriptor();
}
template <> struct is_proto_enum< ::exec::shared::FragmentState> : ::std::true_type {};
template <>
inline const EnumDescriptor* GetEnumDescriptor< ::exec::shared::FragmentState>() {
  return ::exec::shared::FragmentState_descriptor();
}
template <> struct is_proto_enum< ::exec::shared::SaslStatus> : ::std::true_type {};
template <>
inline const EnumDescriptor* GetEnumDescriptor< ::exec::shared::SaslStatus>() {
  return ::exec::shared::SaslStatus_descriptor();
}

PROTOBUF_NAMESPACE_CLOSE

// @@protoc_insertion_point(global_scope)

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