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

#ifndef PROTOBUF_INCLUDED_UserBitShared_2eproto
#define PROTOBUF_INCLUDED_UserBitShared_2eproto

#include <string>

#include <google/protobuf/stubs/common.h>

#if GOOGLE_PROTOBUF_VERSION < 3006001
#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 3006001 < GOOGLE_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/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/inlined_string_field.h>
#include <google/protobuf/metadata.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)
#define PROTOBUF_INTERNAL_EXPORT_protobuf_UserBitShared_2eproto 

namespace protobuf_UserBitShared_2eproto {
// Internal implementation detail -- do not use these members.
struct TableStruct {
  static const ::google::protobuf::internal::ParseTableField entries[];
  static const ::google::protobuf::internal::AuxillaryParseTableField aux[];
  static const ::google::protobuf::internal::ParseTable schema[22];
  static const ::google::protobuf::internal::FieldMetadata field_metadata[];
  static const ::google::protobuf::internal::SerializationTable serialization_table[];
  static const ::google::protobuf::uint32 offsets[];
};
void AddDescriptors();
}  // namespace protobuf_UserBitShared_2eproto
namespace exec {
namespace shared {
class DrillPBError;
class DrillPBErrorDefaultTypeInternal;
extern DrillPBErrorDefaultTypeInternal _DrillPBError_default_instance_;
class ExceptionWrapper;
class ExceptionWrapperDefaultTypeInternal;
extern ExceptionWrapperDefaultTypeInternal _ExceptionWrapper_default_instance_;
class Jar;
class JarDefaultTypeInternal;
extern JarDefaultTypeInternal _Jar_default_instance_;
class MajorFragmentProfile;
class MajorFragmentProfileDefaultTypeInternal;
extern MajorFragmentProfileDefaultTypeInternal _MajorFragmentProfile_default_instance_;
class MetricValue;
class MetricValueDefaultTypeInternal;
extern MetricValueDefaultTypeInternal _MetricValue_default_instance_;
class MinorFragmentProfile;
class MinorFragmentProfileDefaultTypeInternal;
extern MinorFragmentProfileDefaultTypeInternal _MinorFragmentProfile_default_instance_;
class NamePart;
class NamePartDefaultTypeInternal;
extern NamePartDefaultTypeInternal _NamePart_default_instance_;
class NodeStatus;
class NodeStatusDefaultTypeInternal;
extern NodeStatusDefaultTypeInternal _NodeStatus_default_instance_;
class OperatorProfile;
class OperatorProfileDefaultTypeInternal;
extern OperatorProfileDefaultTypeInternal _OperatorProfile_default_instance_;
class ParsingError;
class ParsingErrorDefaultTypeInternal;
extern ParsingErrorDefaultTypeInternal _ParsingError_default_instance_;
class QueryData;
class QueryDataDefaultTypeInternal;
extern QueryDataDefaultTypeInternal _QueryData_default_instance_;
class QueryId;
class QueryIdDefaultTypeInternal;
extern QueryIdDefaultTypeInternal _QueryId_default_instance_;
class QueryInfo;
class QueryInfoDefaultTypeInternal;
extern QueryInfoDefaultTypeInternal _QueryInfo_default_instance_;
class QueryProfile;
class QueryProfileDefaultTypeInternal;
extern QueryProfileDefaultTypeInternal _QueryProfile_default_instance_;
class QueryResult;
class QueryResultDefaultTypeInternal;
extern QueryResultDefaultTypeInternal _QueryResult_default_instance_;
class RecordBatchDef;
class RecordBatchDefDefaultTypeInternal;
extern RecordBatchDefDefaultTypeInternal _RecordBatchDef_default_instance_;
class Registry;
class RegistryDefaultTypeInternal;
extern RegistryDefaultTypeInternal _Registry_default_instance_;
class SaslMessage;
class SaslMessageDefaultTypeInternal;
extern SaslMessageDefaultTypeInternal _SaslMessage_default_instance_;
class SerializedField;
class SerializedFieldDefaultTypeInternal;
extern SerializedFieldDefaultTypeInternal _SerializedField_default_instance_;
class StackTraceElementWrapper;
class StackTraceElementWrapperDefaultTypeInternal;
extern StackTraceElementWrapperDefaultTypeInternal _StackTraceElementWrapper_default_instance_;
class StreamProfile;
class StreamProfileDefaultTypeInternal;
extern StreamProfileDefaultTypeInternal _StreamProfile_default_instance_;
class UserCredentials;
class UserCredentialsDefaultTypeInternal;
extern UserCredentialsDefaultTypeInternal _UserCredentials_default_instance_;
}  // namespace shared
}  // namespace exec
namespace google {
namespace protobuf {
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*);
}  // namespace protobuf
}  // namespace google
namespace exec {
namespace shared {

enum DrillPBError_ErrorType {
  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
};
bool DrillPBError_ErrorType_IsValid(int value);
const DrillPBError_ErrorType DrillPBError_ErrorType_ErrorType_MIN = DrillPBError_ErrorType_CONNECTION;
const DrillPBError_ErrorType DrillPBError_ErrorType_ErrorType_MAX = DrillPBError_ErrorType_UNSPECIFIED_ERROR;
const int DrillPBError_ErrorType_ErrorType_ARRAYSIZE = DrillPBError_ErrorType_ErrorType_MAX + 1;

const ::google::protobuf::EnumDescriptor* DrillPBError_ErrorType_descriptor();
inline const ::std::string& DrillPBError_ErrorType_Name(DrillPBError_ErrorType value) {
  return ::google::protobuf::internal::NameOfEnum(
    DrillPBError_ErrorType_descriptor(), value);
}
inline bool DrillPBError_ErrorType_Parse(
    const ::std::string& name, DrillPBError_ErrorType* value) {
  return ::google::protobuf::internal::ParseNamedEnum<DrillPBError_ErrorType>(
    DrillPBError_ErrorType_descriptor(), name, value);
}
enum NamePart_Type {
  NamePart_Type_NAME = 0,
  NamePart_Type_ARRAY = 1
};
bool NamePart_Type_IsValid(int value);
const NamePart_Type NamePart_Type_Type_MIN = NamePart_Type_NAME;
const NamePart_Type NamePart_Type_Type_MAX = NamePart_Type_ARRAY;
const int NamePart_Type_Type_ARRAYSIZE = NamePart_Type_Type_MAX + 1;

const ::google::protobuf::EnumDescriptor* NamePart_Type_descriptor();
inline const ::std::string& NamePart_Type_Name(NamePart_Type value) {
  return ::google::protobuf::internal::NameOfEnum(
    NamePart_Type_descriptor(), value);
}
inline bool NamePart_Type_Parse(
    const ::std::string& name, NamePart_Type* value) {
  return ::google::protobuf::internal::ParseNamedEnum<NamePart_Type>(
    NamePart_Type_descriptor(), name, value);
}
enum QueryResult_QueryState {
  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);
const QueryResult_QueryState QueryResult_QueryState_QueryState_MIN = QueryResult_QueryState_STARTING;
const QueryResult_QueryState QueryResult_QueryState_QueryState_MAX = QueryResult_QueryState_PLANNING;
const int QueryResult_QueryState_QueryState_ARRAYSIZE = QueryResult_QueryState_QueryState_MAX + 1;

const ::google::protobuf::EnumDescriptor* QueryResult_QueryState_descriptor();
inline const ::std::string& QueryResult_QueryState_Name(QueryResult_QueryState value) {
  return ::google::protobuf::internal::NameOfEnum(
    QueryResult_QueryState_descriptor(), value);
}
inline bool QueryResult_QueryState_Parse(
    const ::std::string& name, QueryResult_QueryState* value) {
  return ::google::protobuf::internal::ParseNamedEnum<QueryResult_QueryState>(
    QueryResult_QueryState_descriptor(), name, value);
}
enum RpcChannel {
  BIT_CONTROL = 0,
  BIT_DATA = 1,
  USER = 2
};
bool RpcChannel_IsValid(int value);
const RpcChannel RpcChannel_MIN = BIT_CONTROL;
const RpcChannel RpcChannel_MAX = USER;
const int RpcChannel_ARRAYSIZE = RpcChannel_MAX + 1;

const ::google::protobuf::EnumDescriptor* RpcChannel_descriptor();
inline const ::std::string& RpcChannel_Name(RpcChannel value) {
  return ::google::protobuf::internal::NameOfEnum(
    RpcChannel_descriptor(), value);
}
inline bool RpcChannel_Parse(
    const ::std::string& name, RpcChannel* value) {
  return ::google::protobuf::internal::ParseNamedEnum<RpcChannel>(
    RpcChannel_descriptor(), name, value);
}
enum QueryType {
  SQL = 1,
  LOGICAL = 2,
  PHYSICAL = 3,
  EXECUTION = 4,
  PREPARED_STATEMENT = 5
};
bool QueryType_IsValid(int value);
const QueryType QueryType_MIN = SQL;
const QueryType QueryType_MAX = PREPARED_STATEMENT;
const int QueryType_ARRAYSIZE = QueryType_MAX + 1;

const ::google::protobuf::EnumDescriptor* QueryType_descriptor();
inline const ::std::string& QueryType_Name(QueryType value) {
  return ::google::protobuf::internal::NameOfEnum(
    QueryType_descriptor(), value);
}
inline bool QueryType_Parse(
    const ::std::string& name, QueryType* value) {
  return ::google::protobuf::internal::ParseNamedEnum<QueryType>(
    QueryType_descriptor(), name, value);
}
enum FragmentState {
  SENDING = 0,
  AWAITING_ALLOCATION = 1,
  RUNNING = 2,
  FINISHED = 3,
  CANCELLED = 4,
  FAILED = 5,
  CANCELLATION_REQUESTED = 6
};
bool FragmentState_IsValid(int value);
const FragmentState FragmentState_MIN = SENDING;
const FragmentState FragmentState_MAX = CANCELLATION_REQUESTED;
const int FragmentState_ARRAYSIZE = FragmentState_MAX + 1;

const ::google::protobuf::EnumDescriptor* FragmentState_descriptor();
inline const ::std::string& FragmentState_Name(FragmentState value) {
  return ::google::protobuf::internal::NameOfEnum(
    FragmentState_descriptor(), value);
}
inline bool FragmentState_Parse(
    const ::std::string& name, FragmentState* value) {
  return ::google::protobuf::internal::ParseNamedEnum<FragmentState>(
    FragmentState_descriptor(), name, value);
}
enum CoreOperatorType {
  SINGLE_SENDER = 0,
  BROADCAST_SENDER = 1,
  FILTER = 2,
  HASH_AGGREGATE = 3,
  HASH_JOIN = 4,
  MERGE_JOIN = 5,
  HASH_PARTITION_SENDER = 6,
  LIMIT = 7,
  MERGING_RECEIVER = 8,
  ORDERED_PARTITION_SENDER = 9,
  PROJECT = 10,
  UNORDERED_RECEIVER = 11,
  RANGE_PARTITION_SENDER = 12,
  SCREEN = 13,
  SELECTION_VECTOR_REMOVER = 14,
  STREAMING_AGGREGATE = 15,
  TOP_N_SORT = 16,
  EXTERNAL_SORT = 17,
  TRACE = 18,
  UNION = 19,
  OLD_SORT = 20,
  PARQUET_ROW_GROUP_SCAN = 21,
  HIVE_SUB_SCAN = 22,
  SYSTEM_TABLE_SCAN = 23,
  MOCK_SUB_SCAN = 24,
  PARQUET_WRITER = 25,
  DIRECT_SUB_SCAN = 26,
  TEXT_WRITER = 27,
  TEXT_SUB_SCAN = 28,
  JSON_SUB_SCAN = 29,
  INFO_SCHEMA_SUB_SCAN = 30,
  COMPLEX_TO_JSON = 31,
  PRODUCER_CONSUMER = 32,
  HBASE_SUB_SCAN = 33,
  WINDOW = 34,
  NESTED_LOOP_JOIN = 35,
  AVRO_SUB_SCAN = 36,
  PCAP_SUB_SCAN = 37,
  KAFKA_SUB_SCAN = 38,
  KUDU_SUB_SCAN = 39,
  FLATTEN = 40,
  LATERAL_JOIN = 41,
  UNNEST = 42,
  HIVE_DRILL_NATIVE_PARQUET_ROW_GROUP_SCAN = 43,
  JDBC_SCAN = 44,
  REGEX_SUB_SCAN = 45,
  MAPRDB_SUB_SCAN = 46,
  MONGO_SUB_SCAN = 47,
  KUDU_WRITER = 48,
  OPEN_TSDB_SUB_SCAN = 49,
  JSON_WRITER = 50,
  HTPPD_LOG_SUB_SCAN = 51,
  IMAGE_SUB_SCAN = 52,
  SEQUENCE_SUB_SCAN = 53,
  PARTITION_LIMIT = 54,
  PCAPNG_SUB_SCAN = 55,
  RUNTIME_FILTER = 56,
  ROWKEY_JOIN = 57,
  SYSLOG_SUB_SCAN = 58,
  STATISTICS_AGGREGATE = 59,
  UNPIVOT_MAPS = 60,
  STATISTICS_MERGE = 61,
  LTSV_SUB_SCAN = 62,
  HDF5_SUB_SCAN = 63,
  EXCEL_SUB_SCAN = 64,
  SHP_SUB_SCAN = 65,
  METADATA_HANDLER = 66,
  METADATA_CONTROLLER = 67,
  HTTP_SUB_SCAN = 70
};
bool CoreOperatorType_IsValid(int value);
const CoreOperatorType CoreOperatorType_MIN = SINGLE_SENDER;
const CoreOperatorType CoreOperatorType_MAX = HTTP_SUB_SCAN;
const int CoreOperatorType_ARRAYSIZE = CoreOperatorType_MAX + 1;

const ::google::protobuf::EnumDescriptor* CoreOperatorType_descriptor();
inline const ::std::string& CoreOperatorType_Name(CoreOperatorType value) {
  return ::google::protobuf::internal::NameOfEnum(
    CoreOperatorType_descriptor(), value);
}
inline bool CoreOperatorType_Parse(
    const ::std::string& name, CoreOperatorType* value) {
  return ::google::protobuf::internal::ParseNamedEnum<CoreOperatorType>(
    CoreOperatorType_descriptor(), name, value);
}
enum SaslStatus {
  SASL_UNKNOWN = 0,
  SASL_START = 1,
  SASL_IN_PROGRESS = 2,
  SASL_SUCCESS = 3,
  SASL_FAILED = 4
};
bool SaslStatus_IsValid(int value);
const SaslStatus SaslStatus_MIN = SASL_UNKNOWN;
const SaslStatus SaslStatus_MAX = SASL_FAILED;
const int SaslStatus_ARRAYSIZE = SaslStatus_MAX + 1;

const ::google::protobuf::EnumDescriptor* SaslStatus_descriptor();
inline const ::std::string& SaslStatus_Name(SaslStatus value) {
  return ::google::protobuf::internal::NameOfEnum(
    SaslStatus_descriptor(), value);
}
inline bool SaslStatus_Parse(
    const ::std::string& name, SaslStatus* value) {
  return ::google::protobuf::internal::ParseNamedEnum<SaslStatus>(
    SaslStatus_descriptor(), name, value);
}
// ===================================================================

class UserCredentials : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:exec.shared.UserCredentials) */ {
 public:
  UserCredentials();
  virtual ~UserCredentials();

  UserCredentials(const UserCredentials& from);

  inline UserCredentials& operator=(const UserCredentials& from) {
    CopyFrom(from);
    return *this;
  }
  #if LANG_CXX11
  UserCredentials(UserCredentials&& from) noexcept
    : UserCredentials() {
    *this = ::std::move(from);
  }

  inline UserCredentials& operator=(UserCredentials&& from) noexcept {
    if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) {
      if (this != &from) InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }
  #endif
  inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
    return _internal_metadata_.unknown_fields();
  }
  inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
    return _internal_metadata_.mutable_unknown_fields();
  }

  static const ::google::protobuf::Descriptor* descriptor();
  static const UserCredentials& default_instance();

  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
  static inline const UserCredentials* internal_default_instance() {
    return reinterpret_cast<const UserCredentials*>(
               &_UserCredentials_default_instance_);
  }
  static constexpr int kIndexInFileMessages =
    0;

  void Swap(UserCredentials* other);
  friend void swap(UserCredentials& a, UserCredentials& b) {
    a.Swap(&b);
  }

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

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

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

  size_t ByteSizeLong() const final;
  bool MergePartialFromCodedStream(
      ::google::protobuf::io::CodedInputStream* input) final;
  void SerializeWithCachedSizes(
      ::google::protobuf::io::CodedOutputStream* output) const final;
  ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
      bool deterministic, ::google::protobuf::uint8* target) const final;
  int GetCachedSize() const final { return _cached_size_.Get(); }

  private:
  void SharedCtor();
  void SharedDtor();
  void SetCachedSize(int size) const final;
  void InternalSwap(UserCredentials* other);
  private:
  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
    return NULL;
  }
  inline void* MaybeArenaPtr() const {
    return NULL;
  }
  public:

  ::google::protobuf::Metadata GetMetadata() const final;

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

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

  // optional string user_name = 1;
  bool has_user_name() const;
  void clear_user_name();
  static const int kUserNameFieldNumber = 1;
  const ::std::string& user_name() const;
  void set_user_name(const ::std::string& value);
  #if LANG_CXX11
  void set_user_name(::std::string&& value);
  #endif
  void set_user_name(const char* value);
  void set_user_name(const char* value, size_t size);
  ::std::string* mutable_user_name();
  ::std::string* release_user_name();
  void set_allocated_user_name(::std::string* user_name);

  // @@protoc_insertion_point(class_scope:exec.shared.UserCredentials)
 private:
  void set_has_user_name();
  void clear_has_user_name();

  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
  ::google::protobuf::internal::HasBits<1> _has_bits_;
  mutable ::google::protobuf::internal::CachedSize _cached_size_;
  ::google::protobuf::internal::ArenaStringPtr user_name_;
  friend struct ::protobuf_UserBitShared_2eproto::TableStruct;
};
// -------------------------------------------------------------------

class QueryId : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:exec.shared.QueryId) */ {
 public:
  QueryId();
  virtual ~QueryId();

  QueryId(const QueryId& from);

  inline QueryId& operator=(const QueryId& from) {
    CopyFrom(from);
    return *this;
  }
  #if LANG_CXX11
  QueryId(QueryId&& from) noexcept
    : QueryId() {
    *this = ::std::move(from);
  }

  inline QueryId& operator=(QueryId&& from) noexcept {
    if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) {
      if (this != &from) InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }
  #endif
  inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
    return _internal_metadata_.unknown_fields();
  }
  inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
    return _internal_metadata_.mutable_unknown_fields();
  }

  static const ::google::protobuf::Descriptor* descriptor();
  static const QueryId& default_instance();

  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
  static inline const QueryId* internal_default_instance() {
    return reinterpret_cast<const QueryId*>(
               &_QueryId_default_instance_);
  }
  static constexpr int kIndexInFileMessages =
    1;

  void Swap(QueryId* other);
  friend void swap(QueryId& a, QueryId& b) {
    a.Swap(&b);
  }

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

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

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

  size_t ByteSizeLong() const final;
  bool MergePartialFromCodedStream(
      ::google::protobuf::io::CodedInputStream* input) final;
  void SerializeWithCachedSizes(
      ::google::protobuf::io::CodedOutputStream* output) const final;
  ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
      bool deterministic, ::google::protobuf::uint8* target) const final;
  int GetCachedSize() const final { return _cached_size_.Get(); }

  private:
  void SharedCtor();
  void SharedDtor();
  void SetCachedSize(int size) const final;
  void InternalSwap(QueryId* other);
  private:
  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
    return NULL;
  }
  inline void* MaybeArenaPtr() const {
    return NULL;
  }
  public:

  ::google::protobuf::Metadata GetMetadata() const final;

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

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

  // optional sfixed64 part1 = 1;
  bool has_part1() const;
  void clear_part1();
  static const int kPart1FieldNumber = 1;
  ::google::protobuf::int64 part1() const;
  void set_part1(::google::protobuf::int64 value);

  // optional sfixed64 part2 = 2;
  bool has_part2() const;
  void clear_part2();
  static const int kPart2FieldNumber = 2;
  ::google::protobuf::int64 part2() const;
  void set_part2(::google::protobuf::int64 value);

  // @@protoc_insertion_point(class_scope:exec.shared.QueryId)
 private:
  void set_has_part1();
  void clear_has_part1();
  void set_has_part2();
  void clear_has_part2();

  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
  ::google::protobuf::internal::HasBits<1> _has_bits_;
  mutable ::google::protobuf::internal::CachedSize _cached_size_;
  ::google::protobuf::int64 part1_;
  ::google::protobuf::int64 part2_;
  friend struct ::protobuf_UserBitShared_2eproto::TableStruct;
};
// -------------------------------------------------------------------

class DrillPBError : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:exec.shared.DrillPBError) */ {
 public:
  DrillPBError();
  virtual ~DrillPBError();

  DrillPBError(const DrillPBError& from);

  inline DrillPBError& operator=(const DrillPBError& from) {
    CopyFrom(from);
    return *this;
  }
  #if LANG_CXX11
  DrillPBError(DrillPBError&& from) noexcept
    : DrillPBError() {
    *this = ::std::move(from);
  }

  inline DrillPBError& operator=(DrillPBError&& from) noexcept {
    if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) {
      if (this != &from) InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }
  #endif
  inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
    return _internal_metadata_.unknown_fields();
  }
  inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
    return _internal_metadata_.mutable_unknown_fields();
  }

  static const ::google::protobuf::Descriptor* descriptor();
  static const DrillPBError& default_instance();

  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
  static inline const DrillPBError* internal_default_instance() {
    return reinterpret_cast<const DrillPBError*>(
               &_DrillPBError_default_instance_);
  }
  static constexpr int kIndexInFileMessages =
    2;

  void Swap(DrillPBError* other);
  friend void swap(DrillPBError& a, DrillPBError& b) {
    a.Swap(&b);
  }

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

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

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

  size_t ByteSizeLong() const final;
  bool MergePartialFromCodedStream(
      ::google::protobuf::io::CodedInputStream* input) final;
  void SerializeWithCachedSizes(
      ::google::protobuf::io::CodedOutputStream* output) const final;
  ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
      bool deterministic, ::google::protobuf::uint8* target) const final;
  int GetCachedSize() const final { return _cached_size_.Get(); }

  private:
  void SharedCtor();
  void SharedDtor();
  void SetCachedSize(int size) const final;
  void InternalSwap(DrillPBError* other);
  private:
  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
    return NULL;
  }
  inline void* MaybeArenaPtr() const {
    return NULL;
  }
  public:

  ::google::protobuf::Metadata GetMetadata() const final;

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

  typedef DrillPBError_ErrorType ErrorType;
  static const ErrorType CONNECTION =
    DrillPBError_ErrorType_CONNECTION;
  static const ErrorType DATA_READ =
    DrillPBError_ErrorType_DATA_READ;
  static const ErrorType DATA_WRITE =
    DrillPBError_ErrorType_DATA_WRITE;
  static const ErrorType FUNCTION =
    DrillPBError_ErrorType_FUNCTION;
  static const ErrorType PARSE =
    DrillPBError_ErrorType_PARSE;
  static const ErrorType PERMISSION =
    DrillPBError_ErrorType_PERMISSION;
  static const ErrorType PLAN =
    DrillPBError_ErrorType_PLAN;
  static const ErrorType RESOURCE =
    DrillPBError_ErrorType_RESOURCE;
  static const ErrorType SYSTEM =
    DrillPBError_ErrorType_SYSTEM;
  static const ErrorType UNSUPPORTED_OPERATION =
    DrillPBError_ErrorType_UNSUPPORTED_OPERATION;
  static const ErrorType VALIDATION =
    DrillPBError_ErrorType_VALIDATION;
  static const ErrorType EXECUTION_ERROR =
    DrillPBError_ErrorType_EXECUTION_ERROR;
  static const ErrorType INTERNAL_ERROR =
    DrillPBError_ErrorType_INTERNAL_ERROR;
  static const ErrorType UNSPECIFIED_ERROR =
    DrillPBError_ErrorType_UNSPECIFIED_ERROR;
  static inline bool ErrorType_IsValid(int value) {
    return DrillPBError_ErrorType_IsValid(value);
  }
  static const ErrorType ErrorType_MIN =
    DrillPBError_ErrorType_ErrorType_MIN;
  static const ErrorType ErrorType_MAX =
    DrillPBError_ErrorType_ErrorType_MAX;
  static const int ErrorType_ARRAYSIZE =
    DrillPBError_ErrorType_ErrorType_ARRAYSIZE;
  static inline const ::google::protobuf::EnumDescriptor*
  ErrorType_descriptor() {
    return DrillPBError_ErrorType_descriptor();
  }
  static inline const ::std::string& ErrorType_Name(ErrorType value) {
    return DrillPBError_ErrorType_Name(value);
  }
  static inline bool ErrorType_Parse(const ::std::string& name,
      ErrorType* value) {
    return DrillPBError_ErrorType_Parse(name, value);
  }

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

  // repeated .exec.shared.ParsingError parsing_error = 6;
  int parsing_error_size() const;
  void clear_parsing_error();
  static const int kParsingErrorFieldNumber = 6;
  ::exec::shared::ParsingError* mutable_parsing_error(int index);
  ::google::protobuf::RepeatedPtrField< ::exec::shared::ParsingError >*
      mutable_parsing_error();
  const ::exec::shared::ParsingError& parsing_error(int index) const;
  ::exec::shared::ParsingError* add_parsing_error();
  const ::google::protobuf::RepeatedPtrField< ::exec::shared::ParsingError >&
      parsing_error() const;

  // optional string error_id = 1;
  bool has_error_id() const;
  void clear_error_id();
  static const int kErrorIdFieldNumber = 1;
  const ::std::string& error_id() const;
  void set_error_id(const ::std::string& value);
  #if LANG_CXX11
  void set_error_id(::std::string&& value);
  #endif
  void set_error_id(const char* value);
  void set_error_id(const char* value, size_t size);
  ::std::string* mutable_error_id();
  ::std::string* release_error_id();
  void set_allocated_error_id(::std::string* error_id);

  // optional string message = 4;
  bool has_message() const;
  void clear_message();
  static const int kMessageFieldNumber = 4;
  const ::std::string& message() const;
  void set_message(const ::std::string& value);
  #if LANG_CXX11
  void set_message(::std::string&& value);
  #endif
  void set_message(const char* value);
  void set_message(const char* value, size_t size);
  ::std::string* mutable_message();
  ::std::string* release_message();
  void set_allocated_message(::std::string* message);

  // optional .exec.DrillbitEndpoint endpoint = 2;
  bool has_endpoint() const;
  void clear_endpoint();
  static const int kEndpointFieldNumber = 2;
  private:
  const ::exec::DrillbitEndpoint& _internal_endpoint() const;
  public:
  const ::exec::DrillbitEndpoint& endpoint() const;
  ::exec::DrillbitEndpoint* release_endpoint();
  ::exec::DrillbitEndpoint* mutable_endpoint();
  void set_allocated_endpoint(::exec::DrillbitEndpoint* endpoint);

  // optional .exec.shared.ExceptionWrapper exception = 5;
  bool has_exception() const;
  void clear_exception();
  static const int kExceptionFieldNumber = 5;
  private:
  const ::exec::shared::ExceptionWrapper& _internal_exception() const;
  public:
  const ::exec::shared::ExceptionWrapper& exception() const;
  ::exec::shared::ExceptionWrapper* release_exception();
  ::exec::shared::ExceptionWrapper* mutable_exception();
  void set_allocated_exception(::exec::shared::ExceptionWrapper* exception);

  // optional .exec.shared.DrillPBError.ErrorType error_type = 3;
  bool has_error_type() const;
  void clear_error_type();
  static const int kErrorTypeFieldNumber = 3;
  ::exec::shared::DrillPBError_ErrorType error_type() const;
  void set_error_type(::exec::shared::DrillPBError_ErrorType value);

  // @@protoc_insertion_point(class_scope:exec.shared.DrillPBError)
 private:
  void set_has_error_id();
  void clear_has_error_id();
  void set_has_endpoint();
  void clear_has_endpoint();
  void set_has_error_type();
  void clear_has_error_type();
  void set_has_message();
  void clear_has_message();
  void set_has_exception();
  void clear_has_exception();

  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
  ::google::protobuf::internal::HasBits<1> _has_bits_;
  mutable ::google::protobuf::internal::CachedSize _cached_size_;
  ::google::protobuf::RepeatedPtrField< ::exec::shared::ParsingError > parsing_error_;
  ::google::protobuf::internal::ArenaStringPtr error_id_;
  ::google::protobuf::internal::ArenaStringPtr message_;
  ::exec::DrillbitEndpoint* endpoint_;
  ::exec::shared::ExceptionWrapper* exception_;
  int error_type_;
  friend struct ::protobuf_UserBitShared_2eproto::TableStruct;
};
// -------------------------------------------------------------------

class ExceptionWrapper : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:exec.shared.ExceptionWrapper) */ {
 public:
  ExceptionWrapper();
  virtual ~ExceptionWrapper();

  ExceptionWrapper(const ExceptionWrapper& from);

  inline ExceptionWrapper& operator=(const ExceptionWrapper& from) {
    CopyFrom(from);
    return *this;
  }
  #if LANG_CXX11
  ExceptionWrapper(ExceptionWrapper&& from) noexcept
    : ExceptionWrapper() {
    *this = ::std::move(from);
  }

  inline ExceptionWrapper& operator=(ExceptionWrapper&& from) noexcept {
    if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) {
      if (this != &from) InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }
  #endif
  inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
    return _internal_metadata_.unknown_fields();
  }
  inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
    return _internal_metadata_.mutable_unknown_fields();
  }

  static const ::google::protobuf::Descriptor* descriptor();
  static const ExceptionWrapper& default_instance();

  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
  static inline const ExceptionWrapper* internal_default_instance() {
    return reinterpret_cast<const ExceptionWrapper*>(
               &_ExceptionWrapper_default_instance_);
  }
  static constexpr int kIndexInFileMessages =
    3;

  void Swap(ExceptionWrapper* other);
  friend void swap(ExceptionWrapper& a, ExceptionWrapper& b) {
    a.Swap(&b);
  }

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

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

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

  size_t ByteSizeLong() const final;
  bool MergePartialFromCodedStream(
      ::google::protobuf::io::CodedInputStream* input) final;
  void SerializeWithCachedSizes(
      ::google::protobuf::io::CodedOutputStream* output) const final;
  ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
      bool deterministic, ::google::protobuf::uint8* target) const final;
  int GetCachedSize() const final { return _cached_size_.Get(); }

  private:
  void SharedCtor();
  void SharedDtor();
  void SetCachedSize(int size) const final;
  void InternalSwap(ExceptionWrapper* other);
  private:
  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
    return NULL;
  }
  inline void* MaybeArenaPtr() const {
    return NULL;
  }
  public:

  ::google::protobuf::Metadata GetMetadata() const final;

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

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

  // repeated .exec.shared.StackTraceElementWrapper stack_trace = 3;
  int stack_trace_size() const;
  void clear_stack_trace();
  static const int kStackTraceFieldNumber = 3;
  ::exec::shared::StackTraceElementWrapper* mutable_stack_trace(int index);
  ::google::protobuf::RepeatedPtrField< ::exec::shared::StackTraceElementWrapper >*
      mutable_stack_trace();
  const ::exec::shared::StackTraceElementWrapper& stack_trace(int index) const;
  ::exec::shared::StackTraceElementWrapper* add_stack_trace();
  const ::google::protobuf::RepeatedPtrField< ::exec::shared::StackTraceElementWrapper >&
      stack_trace() const;

  // optional string exception_class = 1;
  bool has_exception_class() const;
  void clear_exception_class();
  static const int kExceptionClassFieldNumber = 1;
  const ::std::string& exception_class() const;
  void set_exception_class(const ::std::string& value);
  #if LANG_CXX11
  void set_exception_class(::std::string&& value);
  #endif
  void set_exception_class(const char* value);
  void set_exception_class(const char* value, size_t size);
  ::std::string* mutable_exception_class();
  ::std::string* release_exception_class();
  void set_allocated_exception_class(::std::string* exception_class);

  // optional string message = 2;
  bool has_message() const;
  void clear_message();
  static const int kMessageFieldNumber = 2;
  const ::std::string& message() const;
  void set_message(const ::std::string& value);
  #if LANG_CXX11
  void set_message(::std::string&& value);
  #endif
  void set_message(const char* value);
  void set_message(const char* value, size_t size);
  ::std::string* mutable_message();
  ::std::string* release_message();
  void set_allocated_message(::std::string* message);

  // optional .exec.shared.ExceptionWrapper cause = 4;
  bool has_cause() const;
  void clear_cause();
  static const int kCauseFieldNumber = 4;
  private:
  const ::exec::shared::ExceptionWrapper& _internal_cause() const;
  public:
  const ::exec::shared::ExceptionWrapper& cause() const;
  ::exec::shared::ExceptionWrapper* release_cause();
  ::exec::shared::ExceptionWrapper* mutable_cause();
  void set_allocated_cause(::exec::shared::ExceptionWrapper* cause);

  // @@protoc_insertion_point(class_scope:exec.shared.ExceptionWrapper)
 private:
  void set_has_exception_class();
  void clear_has_exception_class();
  void set_has_message();
  void clear_has_message();
  void set_has_cause();
  void clear_has_cause();

  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
  ::google::protobuf::internal::HasBits<1> _has_bits_;
  mutable ::google::protobuf::internal::CachedSize _cached_size_;
  ::google::protobuf::RepeatedPtrField< ::exec::shared::StackTraceElementWrapper > stack_trace_;
  ::google::protobuf::internal::ArenaStringPtr exception_class_;
  ::google::protobuf::internal::ArenaStringPtr message_;
  ::exec::shared::ExceptionWrapper* cause_;
  friend struct ::protobuf_UserBitShared_2eproto::TableStruct;
};
// -------------------------------------------------------------------

class StackTraceElementWrapper : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:exec.shared.StackTraceElementWrapper) */ {
 public:
  StackTraceElementWrapper();
  virtual ~StackTraceElementWrapper();

  StackTraceElementWrapper(const StackTraceElementWrapper& from);

  inline StackTraceElementWrapper& operator=(const StackTraceElementWrapper& from) {
    CopyFrom(from);
    return *this;
  }
  #if LANG_CXX11
  StackTraceElementWrapper(StackTraceElementWrapper&& from) noexcept
    : StackTraceElementWrapper() {
    *this = ::std::move(from);
  }

  inline StackTraceElementWrapper& operator=(StackTraceElementWrapper&& from) noexcept {
    if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) {
      if (this != &from) InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }
  #endif
  inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
    return _internal_metadata_.unknown_fields();
  }
  inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
    return _internal_metadata_.mutable_unknown_fields();
  }

  static const ::google::protobuf::Descriptor* descriptor();
  static const StackTraceElementWrapper& default_instance();

  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
  static inline const StackTraceElementWrapper* internal_default_instance() {
    return reinterpret_cast<const StackTraceElementWrapper*>(
               &_StackTraceElementWrapper_default_instance_);
  }
  static constexpr int kIndexInFileMessages =
    4;

  void Swap(StackTraceElementWrapper* other);
  friend void swap(StackTraceElementWrapper& a, StackTraceElementWrapper& b) {
    a.Swap(&b);
  }

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

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

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

  size_t ByteSizeLong() const final;
  bool MergePartialFromCodedStream(
      ::google::protobuf::io::CodedInputStream* input) final;
  void SerializeWithCachedSizes(
      ::google::protobuf::io::CodedOutputStream* output) const final;
  ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
      bool deterministic, ::google::protobuf::uint8* target) const final;
  int GetCachedSize() const final { return _cached_size_.Get(); }

  private:
  void SharedCtor();
  void SharedDtor();
  void SetCachedSize(int size) const final;
  void InternalSwap(StackTraceElementWrapper* other);
  private:
  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
    return NULL;
  }
  inline void* MaybeArenaPtr() const {
    return NULL;
  }
  public:

  ::google::protobuf::Metadata GetMetadata() const final;

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

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

  // optional string class_name = 1;
  bool has_class_name() const;
  void clear_class_name();
  static const int kClassNameFieldNumber = 1;
  const ::std::string& class_name() const;
  void set_class_name(const ::std::string& value);
  #if LANG_CXX11
  void set_class_name(::std::string&& value);
  #endif
  void set_class_name(const char* value);
  void set_class_name(const char* value, size_t size);
  ::std::string* mutable_class_name();
  ::std::string* release_class_name();
  void set_allocated_class_name(::std::string* class_name);

  // optional string file_name = 2;
  bool has_file_name() const;
  void clear_file_name();
  static const int kFileNameFieldNumber = 2;
  const ::std::string& file_name() const;
  void set_file_name(const ::std::string& value);
  #if LANG_CXX11
  void set_file_name(::std::string&& value);
  #endif
  void set_file_name(const char* value);
  void set_file_name(const char* value, size_t size);
  ::std::string* mutable_file_name();
  ::std::string* release_file_name();
  void set_allocated_file_name(::std::string* file_name);

  // optional string method_name = 4;
  bool has_method_name() const;
  void clear_method_name();
  static const int kMethodNameFieldNumber = 4;
  const ::std::string& method_name() const;
  void set_method_name(const ::std::string& value);
  #if LANG_CXX11
  void set_method_name(::std::string&& value);
  #endif
  void set_method_name(const char* value);
  void set_method_name(const char* value, size_t size);
  ::std::string* mutable_method_name();
  ::std::string* release_method_name();
  void set_allocated_method_name(::std::string* method_name);

  // optional int32 line_number = 3;
  bool has_line_number() const;
  void clear_line_number();
  static const int kLineNumberFieldNumber = 3;
  ::google::protobuf::int32 line_number() const;
  void set_line_number(::google::protobuf::int32 value);

  // optional bool is_native_method = 5;
  bool has_is_native_method() const;
  void clear_is_native_method();
  static const int kIsNativeMethodFieldNumber = 5;
  bool is_native_method() const;
  void set_is_native_method(bool value);

  // @@protoc_insertion_point(class_scope:exec.shared.StackTraceElementWrapper)
 private:
  void set_has_class_name();
  void clear_has_class_name();
  void set_has_file_name();
  void clear_has_file_name();
  void set_has_line_number();
  void clear_has_line_number();
  void set_has_method_name();
  void clear_has_method_name();
  void set_has_is_native_method();
  void clear_has_is_native_method();

  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
  ::google::protobuf::internal::HasBits<1> _has_bits_;
  mutable ::google::protobuf::internal::CachedSize _cached_size_;
  ::google::protobuf::internal::ArenaStringPtr class_name_;
  ::google::protobuf::internal::ArenaStringPtr file_name_;
  ::google::protobuf::internal::ArenaStringPtr method_name_;
  ::google::protobuf::int32 line_number_;
  bool is_native_method_;
  friend struct ::protobuf_UserBitShared_2eproto::TableStruct;
};
// -------------------------------------------------------------------

class ParsingError : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:exec.shared.ParsingError) */ {
 public:
  ParsingError();
  virtual ~ParsingError();

  ParsingError(const ParsingError& from);

  inline ParsingError& operator=(const ParsingError& from) {
    CopyFrom(from);
    return *this;
  }
  #if LANG_CXX11
  ParsingError(ParsingError&& from) noexcept
    : ParsingError() {
    *this = ::std::move(from);
  }

  inline ParsingError& operator=(ParsingError&& from) noexcept {
    if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) {
      if (this != &from) InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }
  #endif
  inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
    return _internal_metadata_.unknown_fields();
  }
  inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
    return _internal_metadata_.mutable_unknown_fields();
  }

  static const ::google::protobuf::Descriptor* descriptor();
  static const ParsingError& default_instance();

  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
  static inline const ParsingError* internal_default_instance() {
    return reinterpret_cast<const ParsingError*>(
               &_ParsingError_default_instance_);
  }
  static constexpr int kIndexInFileMessages =
    5;

  void Swap(ParsingError* other);
  friend void swap(ParsingError& a, ParsingError& b) {
    a.Swap(&b);
  }

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

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

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

  size_t ByteSizeLong() const final;
  bool MergePartialFromCodedStream(
      ::google::protobuf::io::CodedInputStream* input) final;
  void SerializeWithCachedSizes(
      ::google::protobuf::io::CodedOutputStream* output) const final;
  ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
      bool deterministic, ::google::protobuf::uint8* target) const final;
  int GetCachedSize() const final { return _cached_size_.Get(); }

  private:
  void SharedCtor();
  void SharedDtor();
  void SetCachedSize(int size) const final;
  void InternalSwap(ParsingError* other);
  private:
  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
    return NULL;
  }
  inline void* MaybeArenaPtr() const {
    return NULL;
  }
  public:

  ::google::protobuf::Metadata GetMetadata() const final;

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

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

  // optional int32 start_column = 2;
  bool has_start_column() const;
  void clear_start_column();
  static const int kStartColumnFieldNumber = 2;
  ::google::protobuf::int32 start_column() const;
  void set_start_column(::google::protobuf::int32 value);

  // optional int32 start_row = 3;
  bool has_start_row() const;
  void clear_start_row();
  static const int kStartRowFieldNumber = 3;
  ::google::protobuf::int32 start_row() const;
  void set_start_row(::google::protobuf::int32 value);

  // optional int32 end_column = 4;
  bool has_end_column() const;
  void clear_end_column();
  static const int kEndColumnFieldNumber = 4;
  ::google::protobuf::int32 end_column() const;
  void set_end_column(::google::protobuf::int32 value);

  // optional int32 end_row = 5;
  bool has_end_row() const;
  void clear_end_row();
  static const int kEndRowFieldNumber = 5;
  ::google::protobuf::int32 end_row() const;
  void set_end_row(::google::protobuf::int32 value);

  // @@protoc_insertion_point(class_scope:exec.shared.ParsingError)
 private:
  void set_has_start_column();
  void clear_has_start_column();
  void set_has_start_row();
  void clear_has_start_row();
  void set_has_end_column();
  void clear_has_end_column();
  void set_has_end_row();
  void clear_has_end_row();

  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
  ::google::protobuf::internal::HasBits<1> _has_bits_;
  mutable ::google::protobuf::internal::CachedSize _cached_size_;
  ::google::protobuf::int32 start_column_;
  ::google::protobuf::int32 start_row_;
  ::google::protobuf::int32 end_column_;
  ::google::protobuf::int32 end_row_;
  friend struct ::protobuf_UserBitShared_2eproto::TableStruct;
};
// -------------------------------------------------------------------

class RecordBatchDef : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:exec.shared.RecordBatchDef) */ {
 public:
  RecordBatchDef();
  virtual ~RecordBatchDef();

  RecordBatchDef(const RecordBatchDef& from);

  inline RecordBatchDef& operator=(const RecordBatchDef& from) {
    CopyFrom(from);
    return *this;
  }
  #if LANG_CXX11
  RecordBatchDef(RecordBatchDef&& from) noexcept
    : RecordBatchDef() {
    *this = ::std::move(from);
  }

  inline RecordBatchDef& operator=(RecordBatchDef&& from) noexcept {
    if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) {
      if (this != &from) InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }
  #endif
  inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
    return _internal_metadata_.unknown_fields();
  }
  inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
    return _internal_metadata_.mutable_unknown_fields();
  }

  static const ::google::protobuf::Descriptor* descriptor();
  static const RecordBatchDef& default_instance();

  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
  static inline const RecordBatchDef* internal_default_instance() {
    return reinterpret_cast<const RecordBatchDef*>(
               &_RecordBatchDef_default_instance_);
  }
  static constexpr int kIndexInFileMessages =
    6;

  void Swap(RecordBatchDef* other);
  friend void swap(RecordBatchDef& a, RecordBatchDef& b) {
    a.Swap(&b);
  }

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

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

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

  size_t ByteSizeLong() const final;
  bool MergePartialFromCodedStream(
      ::google::protobuf::io::CodedInputStream* input) final;
  void SerializeWithCachedSizes(
      ::google::protobuf::io::CodedOutputStream* output) const final;
  ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
      bool deterministic, ::google::protobuf::uint8* target) const final;
  int GetCachedSize() const final { return _cached_size_.Get(); }

  private:
  void SharedCtor();
  void SharedDtor();
  void SetCachedSize(int size) const final;
  void InternalSwap(RecordBatchDef* other);
  private:
  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
    return NULL;
  }
  inline void* MaybeArenaPtr() const {
    return NULL;
  }
  public:

  ::google::protobuf::Metadata GetMetadata() const final;

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

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

  // repeated .exec.shared.SerializedField field = 2;
  int field_size() const;
  void clear_field();
  static const int kFieldFieldNumber = 2;
  ::exec::shared::SerializedField* mutable_field(int index);
  ::google::protobuf::RepeatedPtrField< ::exec::shared::SerializedField >*
      mutable_field();
  const ::exec::shared::SerializedField& field(int index) const;
  ::exec::shared::SerializedField* add_field();
  const ::google::protobuf::RepeatedPtrField< ::exec::shared::SerializedField >&
      field() const;

  // optional int32 record_count = 1;
  bool has_record_count() const;
  void clear_record_count();
  static const int kRecordCountFieldNumber = 1;
  ::google::protobuf::int32 record_count() const;
  void set_record_count(::google::protobuf::int32 value);

  // optional bool carries_two_byte_selection_vector = 3;
  bool has_carries_two_byte_selection_vector() const;
  void clear_carries_two_byte_selection_vector();
  static const int kCarriesTwoByteSelectionVectorFieldNumber = 3;
  bool carries_two_byte_selection_vector() const;
  void set_carries_two_byte_selection_vector(bool value);

  // optional int32 affected_rows_count = 4;
  bool has_affected_rows_count() const;
  void clear_affected_rows_count();
  static const int kAffectedRowsCountFieldNumber = 4;
  ::google::protobuf::int32 affected_rows_count() const;
  void set_affected_rows_count(::google::protobuf::int32 value);

  // @@protoc_insertion_point(class_scope:exec.shared.RecordBatchDef)
 private:
  void set_has_record_count();
  void clear_has_record_count();
  void set_has_carries_two_byte_selection_vector();
  void clear_has_carries_two_byte_selection_vector();
  void set_has_affected_rows_count();
  void clear_has_affected_rows_count();

  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
  ::google::protobuf::internal::HasBits<1> _has_bits_;
  mutable ::google::protobuf::internal::CachedSize _cached_size_;
  ::google::protobuf::RepeatedPtrField< ::exec::shared::SerializedField > field_;
  ::google::protobuf::int32 record_count_;
  bool carries_two_byte_selection_vector_;
  ::google::protobuf::int32 affected_rows_count_;
  friend struct ::protobuf_UserBitShared_2eproto::TableStruct;
};
// -------------------------------------------------------------------

class NamePart : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:exec.shared.NamePart) */ {
 public:
  NamePart();
  virtual ~NamePart();

  NamePart(const NamePart& from);

  inline NamePart& operator=(const NamePart& from) {
    CopyFrom(from);
    return *this;
  }
  #if LANG_CXX11
  NamePart(NamePart&& from) noexcept
    : NamePart() {
    *this = ::std::move(from);
  }

  inline NamePart& operator=(NamePart&& from) noexcept {
    if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) {
      if (this != &from) InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }
  #endif
  inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
    return _internal_metadata_.unknown_fields();
  }
  inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
    return _internal_metadata_.mutable_unknown_fields();
  }

  static const ::google::protobuf::Descriptor* descriptor();
  static const NamePart& default_instance();

  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
  static inline const NamePart* internal_default_instance() {
    return reinterpret_cast<const NamePart*>(
               &_NamePart_default_instance_);
  }
  static constexpr int kIndexInFileMessages =
    7;

  void Swap(NamePart* other);
  friend void swap(NamePart& a, NamePart& b) {
    a.Swap(&b);
  }

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

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

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

  size_t ByteSizeLong() const final;
  bool MergePartialFromCodedStream(
      ::google::protobuf::io::CodedInputStream* input) final;
  void SerializeWithCachedSizes(
      ::google::protobuf::io::CodedOutputStream* output) const final;
  ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
      bool deterministic, ::google::protobuf::uint8* target) const final;
  int GetCachedSize() const final { return _cached_size_.Get(); }

  private:
  void SharedCtor();
  void SharedDtor();
  void SetCachedSize(int size) const final;
  void InternalSwap(NamePart* other);
  private:
  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
    return NULL;
  }
  inline void* MaybeArenaPtr() const {
    return NULL;
  }
  public:

  ::google::protobuf::Metadata GetMetadata() const final;

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

  typedef NamePart_Type Type;
  static const Type NAME =
    NamePart_Type_NAME;
  static const Type ARRAY =
    NamePart_Type_ARRAY;
  static inline bool Type_IsValid(int value) {
    return NamePart_Type_IsValid(value);
  }
  static const Type Type_MIN =
    NamePart_Type_Type_MIN;
  static const Type Type_MAX =
    NamePart_Type_Type_MAX;
  static const int Type_ARRAYSIZE =
    NamePart_Type_Type_ARRAYSIZE;
  static inline const ::google::protobuf::EnumDescriptor*
  Type_descriptor() {
    return NamePart_Type_descriptor();
  }
  static inline const ::std::string& Type_Name(Type value) {
    return NamePart_Type_Name(value);
  }
  static inline bool Type_Parse(const ::std::string& name,
      Type* value) {
    return NamePart_Type_Parse(name, value);
  }

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

  // optional string name = 2;
  bool has_name() const;
  void clear_name();
  static const int kNameFieldNumber = 2;
  const ::std::string& name() const;
  void set_name(const ::std::string& value);
  #if LANG_CXX11
  void set_name(::std::string&& value);
  #endif
  void set_name(const char* value);
  void set_name(const char* value, size_t size);
  ::std::string* mutable_name();
  ::std::string* release_name();
  void set_allocated_name(::std::string* name);

  // optional .exec.shared.NamePart child = 3;
  bool has_child() const;
  void clear_child();
  static const int kChildFieldNumber = 3;
  private:
  const ::exec::shared::NamePart& _internal_child() const;
  public:
  const ::exec::shared::NamePart& child() const;
  ::exec::shared::NamePart* release_child();
  ::exec::shared::NamePart* mutable_child();
  void set_allocated_child(::exec::shared::NamePart* child);

  // optional .exec.shared.NamePart.Type type = 1;
  bool has_type() const;
  void clear_type();
  static const int kTypeFieldNumber = 1;
  ::exec::shared::NamePart_Type type() const;
  void set_type(::exec::shared::NamePart_Type value);

  // @@protoc_insertion_point(class_scope:exec.shared.NamePart)
 private:
  void set_has_type();
  void clear_has_type();
  void set_has_name();
  void clear_has_name();
  void set_has_child();
  void clear_has_child();

  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
  ::google::protobuf::internal::HasBits<1> _has_bits_;
  mutable ::google::protobuf::internal::CachedSize _cached_size_;
  ::google::protobuf::internal::ArenaStringPtr name_;
  ::exec::shared::NamePart* child_;
  int type_;
  friend struct ::protobuf_UserBitShared_2eproto::TableStruct;
};
// -------------------------------------------------------------------

class SerializedField : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:exec.shared.SerializedField) */ {
 public:
  SerializedField();
  virtual ~SerializedField();

  SerializedField(const SerializedField& from);

  inline SerializedField& operator=(const SerializedField& from) {
    CopyFrom(from);
    return *this;
  }
  #if LANG_CXX11
  SerializedField(SerializedField&& from) noexcept
    : SerializedField() {
    *this = ::std::move(from);
  }

  inline SerializedField& operator=(SerializedField&& from) noexcept {
    if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) {
      if (this != &from) InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }
  #endif
  inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
    return _internal_metadata_.unknown_fields();
  }
  inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
    return _internal_metadata_.mutable_unknown_fields();
  }

  static const ::google::protobuf::Descriptor* descriptor();
  static const SerializedField& default_instance();

  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
  static inline const SerializedField* internal_default_instance() {
    return reinterpret_cast<const SerializedField*>(
               &_SerializedField_default_instance_);
  }
  static constexpr int kIndexInFileMessages =
    8;

  void Swap(SerializedField* other);
  friend void swap(SerializedField& a, SerializedField& b) {
    a.Swap(&b);
  }

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

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

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

  size_t ByteSizeLong() const final;
  bool MergePartialFromCodedStream(
      ::google::protobuf::io::CodedInputStream* input) final;
  void SerializeWithCachedSizes(
      ::google::protobuf::io::CodedOutputStream* output) const final;
  ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
      bool deterministic, ::google::protobuf::uint8* target) const final;
  int GetCachedSize() const final { return _cached_size_.Get(); }

  private:
  void SharedCtor();
  void SharedDtor();
  void SetCachedSize(int size) const final;
  void InternalSwap(SerializedField* other);
  private:
  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
    return NULL;
  }
  inline void* MaybeArenaPtr() const {
    return NULL;
  }
  public:

  ::google::protobuf::Metadata GetMetadata() const final;

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

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

  // repeated .exec.shared.SerializedField child = 3;
  int child_size() const;
  void clear_child();
  static const int kChildFieldNumber = 3;
  ::exec::shared::SerializedField* mutable_child(int index);
  ::google::protobuf::RepeatedPtrField< ::exec::shared::SerializedField >*
      mutable_child();
  const ::exec::shared::SerializedField& child(int index) const;
  ::exec::shared::SerializedField* add_child();
  const ::google::protobuf::RepeatedPtrField< ::exec::shared::SerializedField >&
      child() const;

  // optional .common.MajorType major_type = 1;
  bool has_major_type() const;
  void clear_major_type();
  static const int kMajorTypeFieldNumber = 1;
  private:
  const ::common::MajorType& _internal_major_type() const;
  public:
  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);

  // optional .exec.shared.NamePart name_part = 2;
  bool has_name_part() const;
  void clear_name_part();
  static const int kNamePartFieldNumber = 2;
  private:
  const ::exec::shared::NamePart& _internal_name_part() const;
  public:
  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);

  // optional int32 value_count = 4;
  bool has_value_count() const;
  void clear_value_count();
  static const int kValueCountFieldNumber = 4;
  ::google::protobuf::int32 value_count() const;
  void set_value_count(::google::protobuf::int32 value);

  // optional int32 var_byte_length = 5;
  bool has_var_byte_length() const;
  void clear_var_byte_length();
  static const int kVarByteLengthFieldNumber = 5;
  ::google::protobuf::int32 var_byte_length() const;
  void set_var_byte_length(::google::protobuf::int32 value);

  // optional int32 buffer_length = 7;
  bool has_buffer_length() const;
  void clear_buffer_length();
  static const int kBufferLengthFieldNumber = 7;
  ::google::protobuf::int32 buffer_length() const;
  void set_buffer_length(::google::protobuf::int32 value);

  // @@protoc_insertion_point(class_scope:exec.shared.SerializedField)
 private:
  void set_has_major_type();
  void clear_has_major_type();
  void set_has_name_part();
  void clear_has_name_part();
  void set_has_value_count();
  void clear_has_value_count();
  void set_has_var_byte_length();
  void clear_has_var_byte_length();
  void set_has_buffer_length();
  void clear_has_buffer_length();

  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
  ::google::protobuf::internal::HasBits<1> _has_bits_;
  mutable ::google::protobuf::internal::CachedSize _cached_size_;
  ::google::protobuf::RepeatedPtrField< ::exec::shared::SerializedField > child_;
  ::common::MajorType* major_type_;
  ::exec::shared::NamePart* name_part_;
  ::google::protobuf::int32 value_count_;
  ::google::protobuf::int32 var_byte_length_;
  ::google::protobuf::int32 buffer_length_;
  friend struct ::protobuf_UserBitShared_2eproto::TableStruct;
};
// -------------------------------------------------------------------

class NodeStatus : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:exec.shared.NodeStatus) */ {
 public:
  NodeStatus();
  virtual ~NodeStatus();

  NodeStatus(const NodeStatus& from);

  inline NodeStatus& operator=(const NodeStatus& from) {
    CopyFrom(from);
    return *this;
  }
  #if LANG_CXX11
  NodeStatus(NodeStatus&& from) noexcept
    : NodeStatus() {
    *this = ::std::move(from);
  }

  inline NodeStatus& operator=(NodeStatus&& from) noexcept {
    if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) {
      if (this != &from) InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }
  #endif
  inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
    return _internal_metadata_.unknown_fields();
  }
  inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
    return _internal_metadata_.mutable_unknown_fields();
  }

  static const ::google::protobuf::Descriptor* descriptor();
  static const NodeStatus& default_instance();

  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
  static inline const NodeStatus* internal_default_instance() {
    return reinterpret_cast<const NodeStatus*>(
               &_NodeStatus_default_instance_);
  }
  static constexpr int kIndexInFileMessages =
    9;

  void Swap(NodeStatus* other);
  friend void swap(NodeStatus& a, NodeStatus& b) {
    a.Swap(&b);
  }

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

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

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

  size_t ByteSizeLong() const final;
  bool MergePartialFromCodedStream(
      ::google::protobuf::io::CodedInputStream* input) final;
  void SerializeWithCachedSizes(
      ::google::protobuf::io::CodedOutputStream* output) const final;
  ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
      bool deterministic, ::google::protobuf::uint8* target) const final;
  int GetCachedSize() const final { return _cached_size_.Get(); }

  private:
  void SharedCtor();
  void SharedDtor();
  void SetCachedSize(int size) const final;
  void InternalSwap(NodeStatus* other);
  private:
  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
    return NULL;
  }
  inline void* MaybeArenaPtr() const {
    return NULL;
  }
  public:

  ::google::protobuf::Metadata GetMetadata() const final;

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

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

  // optional int64 memory_footprint = 2;
  bool has_memory_footprint() const;
  void clear_memory_footprint();
  static const int kMemoryFootprintFieldNumber = 2;
  ::google::protobuf::int64 memory_footprint() const;
  void set_memory_footprint(::google::protobuf::int64 value);

  // optional int32 node_id = 1;
  bool has_node_id() const;
  void clear_node_id();
  static const int kNodeIdFieldNumber = 1;
  ::google::protobuf::int32 node_id() const;
  void set_node_id(::google::protobuf::int32 value);

  // @@protoc_insertion_point(class_scope:exec.shared.NodeStatus)
 private:
  void set_has_node_id();
  void clear_has_node_id();
  void set_has_memory_footprint();
  void clear_has_memory_footprint();

  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
  ::google::protobuf::internal::HasBits<1> _has_bits_;
  mutable ::google::protobuf::internal::CachedSize _cached_size_;
  ::google::protobuf::int64 memory_footprint_;
  ::google::protobuf::int32 node_id_;
  friend struct ::protobuf_UserBitShared_2eproto::TableStruct;
};
// -------------------------------------------------------------------

class QueryResult : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:exec.shared.QueryResult) */ {
 public:
  QueryResult();
  virtual ~QueryResult();

  QueryResult(const QueryResult& from);

  inline QueryResult& operator=(const QueryResult& from) {
    CopyFrom(from);
    return *this;
  }
  #if LANG_CXX11
  QueryResult(QueryResult&& from) noexcept
    : QueryResult() {
    *this = ::std::move(from);
  }

  inline QueryResult& operator=(QueryResult&& from) noexcept {
    if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) {
      if (this != &from) InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }
  #endif
  inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
    return _internal_metadata_.unknown_fields();
  }
  inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
    return _internal_metadata_.mutable_unknown_fields();
  }

  static const ::google::protobuf::Descriptor* descriptor();
  static const QueryResult& default_instance();

  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
  static inline const QueryResult* internal_default_instance() {
    return reinterpret_cast<const QueryResult*>(
               &_QueryResult_default_instance_);
  }
  static constexpr int kIndexInFileMessages =
    10;

  void Swap(QueryResult* other);
  friend void swap(QueryResult& a, QueryResult& b) {
    a.Swap(&b);
  }

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

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

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

  size_t ByteSizeLong() const final;
  bool MergePartialFromCodedStream(
      ::google::protobuf::io::CodedInputStream* input) final;
  void SerializeWithCachedSizes(
      ::google::protobuf::io::CodedOutputStream* output) const final;
  ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
      bool deterministic, ::google::protobuf::uint8* target) const final;
  int GetCachedSize() const final { return _cached_size_.Get(); }

  private:
  void SharedCtor();
  void SharedDtor();
  void SetCachedSize(int size) const final;
  void InternalSwap(QueryResult* other);
  private:
  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
    return NULL;
  }
  inline void* MaybeArenaPtr() const {
    return NULL;
  }
  public:

  ::google::protobuf::Metadata GetMetadata() const final;

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

  typedef QueryResult_QueryState QueryState;
  static const QueryState STARTING =
    QueryResult_QueryState_STARTING;
  static const QueryState RUNNING =
    QueryResult_QueryState_RUNNING;
  static const QueryState COMPLETED =
    QueryResult_QueryState_COMPLETED;
  static const QueryState CANCELED =
    QueryResult_QueryState_CANCELED;
  static const QueryState FAILED =
    QueryResult_QueryState_FAILED;
  static const QueryState CANCELLATION_REQUESTED =
    QueryResult_QueryState_CANCELLATION_REQUESTED;
  static const QueryState ENQUEUED =
    QueryResult_QueryState_ENQUEUED;
  static const QueryState PREPARING =
    QueryResult_QueryState_PREPARING;
  static const QueryState PLANNING =
    QueryResult_QueryState_PLANNING;
  static inline bool QueryState_IsValid(int value) {
    return QueryResult_QueryState_IsValid(value);
  }
  static const QueryState QueryState_MIN =
    QueryResult_QueryState_QueryState_MIN;
  static const QueryState QueryState_MAX =
    QueryResult_QueryState_QueryState_MAX;
  static const int QueryState_ARRAYSIZE =
    QueryResult_QueryState_QueryState_ARRAYSIZE;
  static inline const ::google::protobuf::EnumDescriptor*
  QueryState_descriptor() {
    return QueryResult_QueryState_descriptor();
  }
  static inline const ::std::string& QueryState_Name(QueryState value) {
    return QueryResult_QueryState_Name(value);
  }
  static inline bool QueryState_Parse(const ::std::string& name,
      QueryState* value) {
    return QueryResult_QueryState_Parse(name, value);
  }

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

  // repeated .exec.shared.DrillPBError error = 3;
  int error_size() const;
  void clear_error();
  static const int kErrorFieldNumber = 3;
  ::exec::shared::DrillPBError* mutable_error(int index);
  ::google::protobuf::RepeatedPtrField< ::exec::shared::DrillPBError >*
      mutable_error();
  const ::exec::shared::DrillPBError& error(int index) const;
  ::exec::shared::DrillPBError* add_error();
  const ::google::protobuf::RepeatedPtrField< ::exec::shared::DrillPBError >&
      error() const;

  // optional .exec.shared.QueryId query_id = 2;
  bool has_query_id() const;
  void clear_query_id();
  static const int kQueryIdFieldNumber = 2;
  private:
  const ::exec::shared::QueryId& _internal_query_id() const;
  public:
  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);

  // optional .exec.shared.QueryResult.QueryState query_state = 1;
  bool has_query_state() const;
  void clear_query_state();
  static const int kQueryStateFieldNumber = 1;
  ::exec::shared::QueryResult_QueryState query_state() const;
  void set_query_state(::exec::shared::QueryResult_QueryState value);

  // @@protoc_insertion_point(class_scope:exec.shared.QueryResult)
 private:
  void set_has_query_state();
  void clear_has_query_state();
  void set_has_query_id();
  void clear_has_query_id();

  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
  ::google::protobuf::internal::HasBits<1> _has_bits_;
  mutable ::google::protobuf::internal::CachedSize _cached_size_;
  ::google::protobuf::RepeatedPtrField< ::exec::shared::DrillPBError > error_;
  ::exec::shared::QueryId* query_id_;
  int query_state_;
  friend struct ::protobuf_UserBitShared_2eproto::TableStruct;
};
// -------------------------------------------------------------------

class QueryData : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:exec.shared.QueryData) */ {
 public:
  QueryData();
  virtual ~QueryData();

  QueryData(const QueryData& from);

  inline QueryData& operator=(const QueryData& from) {
    CopyFrom(from);
    return *this;
  }
  #if LANG_CXX11
  QueryData(QueryData&& from) noexcept
    : QueryData() {
    *this = ::std::move(from);
  }

  inline QueryData& operator=(QueryData&& from) noexcept {
    if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) {
      if (this != &from) InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }
  #endif
  inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
    return _internal_metadata_.unknown_fields();
  }
  inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
    return _internal_metadata_.mutable_unknown_fields();
  }

  static const ::google::protobuf::Descriptor* descriptor();
  static const QueryData& default_instance();

  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
  static inline const QueryData* internal_default_instance() {
    return reinterpret_cast<const QueryData*>(
               &_QueryData_default_instance_);
  }
  static constexpr int kIndexInFileMessages =
    11;

  void Swap(QueryData* other);
  friend void swap(QueryData& a, QueryData& b) {
    a.Swap(&b);
  }

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

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

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

  size_t ByteSizeLong() const final;
  bool MergePartialFromCodedStream(
      ::google::protobuf::io::CodedInputStream* input) final;
  void SerializeWithCachedSizes(
      ::google::protobuf::io::CodedOutputStream* output) const final;
  ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
      bool deterministic, ::google::protobuf::uint8* target) const final;
  int GetCachedSize() const final { return _cached_size_.Get(); }

  private:
  void SharedCtor();
  void SharedDtor();
  void SetCachedSize(int size) const final;
  void InternalSwap(QueryData* other);
  private:
  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
    return NULL;
  }
  inline void* MaybeArenaPtr() const {
    return NULL;
  }
  public:

  ::google::protobuf::Metadata GetMetadata() const final;

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

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

  // optional .exec.shared.QueryId query_id = 1;
  bool has_query_id() const;
  void clear_query_id();
  static const int kQueryIdFieldNumber = 1;
  private:
  const ::exec::shared::QueryId& _internal_query_id() const;
  public:
  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);

  // optional .exec.shared.RecordBatchDef def = 3;
  bool has_def() const;
  void clear_def();
  static const int kDefFieldNumber = 3;
  private:
  const ::exec::shared::RecordBatchDef& _internal_def() const;
  public:
  const ::exec::shared::RecordBatchDef& def() const;
  ::exec::shared::RecordBatchDef* release_def();
  ::exec::shared::RecordBatchDef* mutable_def();
  void set_allocated_def(::exec::shared::RecordBatchDef* def);

  // optional int32 row_count = 2;
  bool has_row_count() const;
  void clear_row_count();
  static const int kRowCountFieldNumber = 2;
  ::google::protobuf::int32 row_count() const;
  void set_row_count(::google::protobuf::int32 value);

  // optional int32 affected_rows_count = 4;
  bool has_affected_rows_count() const;
  void clear_affected_rows_count();
  static const int kAffectedRowsCountFieldNumber = 4;
  ::google::protobuf::int32 affected_rows_count() const;
  void set_affected_rows_count(::google::protobuf::int32 value);

  // @@protoc_insertion_point(class_scope:exec.shared.QueryData)
 private:
  void set_has_query_id();
  void clear_has_query_id();
  void set_has_row_count();
  void clear_has_row_count();
  void set_has_def();
  void clear_has_def();
  void set_has_affected_rows_count();
  void clear_has_affected_rows_count();

  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
  ::google::protobuf::internal::HasBits<1> _has_bits_;
  mutable ::google::protobuf::internal::CachedSize _cached_size_;
  ::exec::shared::QueryId* query_id_;
  ::exec::shared::RecordBatchDef* def_;
  ::google::protobuf::int32 row_count_;
  ::google::protobuf::int32 affected_rows_count_;
  friend struct ::protobuf_UserBitShared_2eproto::TableStruct;
};
// -------------------------------------------------------------------

class QueryInfo : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:exec.shared.QueryInfo) */ {
 public:
  QueryInfo();
  virtual ~QueryInfo();

  QueryInfo(const QueryInfo& from);

  inline QueryInfo& operator=(const QueryInfo& from) {
    CopyFrom(from);
    return *this;
  }
  #if LANG_CXX11
  QueryInfo(QueryInfo&& from) noexcept
    : QueryInfo() {
    *this = ::std::move(from);
  }

  inline QueryInfo& operator=(QueryInfo&& from) noexcept {
    if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) {
      if (this != &from) InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }
  #endif
  inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
    return _internal_metadata_.unknown_fields();
  }
  inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
    return _internal_metadata_.mutable_unknown_fields();
  }

  static const ::google::protobuf::Descriptor* descriptor();
  static const QueryInfo& default_instance();

  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
  static inline const QueryInfo* internal_default_instance() {
    return reinterpret_cast<const QueryInfo*>(
               &_QueryInfo_default_instance_);
  }
  static constexpr int kIndexInFileMessages =
    12;

  void Swap(QueryInfo* other);
  friend void swap(QueryInfo& a, QueryInfo& b) {
    a.Swap(&b);
  }

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

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

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

  size_t ByteSizeLong() const final;
  bool MergePartialFromCodedStream(
      ::google::protobuf::io::CodedInputStream* input) final;
  void SerializeWithCachedSizes(
      ::google::protobuf::io::CodedOutputStream* output) const final;
  ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
      bool deterministic, ::google::protobuf::uint8* target) const final;
  int GetCachedSize() const final { return _cached_size_.Get(); }

  private:
  void SharedCtor();
  void SharedDtor();
  void SetCachedSize(int size) const final;
  void InternalSwap(QueryInfo* other);
  private:
  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
    return NULL;
  }
  inline void* MaybeArenaPtr() const {
    return NULL;
  }
  public:

  ::google::protobuf::Metadata GetMetadata() const final;

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

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

  // optional string query = 1;
  bool has_query() const;
  void clear_query();
  static const int kQueryFieldNumber = 1;
  const ::std::string& query() const;
  void set_query(const ::std::string& value);
  #if LANG_CXX11
  void set_query(::std::string&& value);
  #endif
  void set_query(const char* value);
  void set_query(const char* value, size_t size);
  ::std::string* mutable_query();
  ::std::string* release_query();
  void set_allocated_query(::std::string* query);

  // optional string user = 4 [default = "-"];
  bool has_user() const;
  void clear_user();
  static const int kUserFieldNumber = 4;
  const ::std::string& user() const;
  void set_user(const ::std::string& value);
  #if LANG_CXX11
  void set_user(::std::string&& value);
  #endif
  void set_user(const char* value);
  void set_user(const char* value, size_t size);
  ::std::string* mutable_user();
  ::std::string* release_user();
  void set_allocated_user(::std::string* user);

  // optional string options_json = 6;
  bool has_options_json() const;
  void clear_options_json();
  static const int kOptionsJsonFieldNumber = 6;
  const ::std::string& options_json() const;
  void set_options_json(const ::std::string& value);
  #if LANG_CXX11
  void set_options_json(::std::string&& value);
  #endif
  void set_options_json(const char* value);
  void set_options_json(const char* value, size_t size);
  ::std::string* mutable_options_json();
  ::std::string* release_options_json();
  void set_allocated_options_json(::std::string* options_json);

  // optional string queue_name = 8 [default = "-"];
  bool has_queue_name() const;
  void clear_queue_name();
  static const int kQueueNameFieldNumber = 8;
  const ::std::string& queue_name() const;
  void set_queue_name(const ::std::string& value);
  #if LANG_CXX11
  void set_queue_name(::std::string&& value);
  #endif
  void set_queue_name(const char* value);
  void set_queue_name(const char* value, size_t size);
  ::std::string* mutable_queue_name();
  ::std::string* release_queue_name();
  void set_allocated_queue_name(::std::string* queue_name);

  // optional .exec.DrillbitEndpoint foreman = 5;
  bool has_foreman() const;
  void clear_foreman();
  static const int kForemanFieldNumber = 5;
  private:
  const ::exec::DrillbitEndpoint& _internal_foreman() const;
  public:
  const ::exec::DrillbitEndpoint& foreman() const;
  ::exec::DrillbitEndpoint* release_foreman();
  ::exec::DrillbitEndpoint* mutable_foreman();
  void set_allocated_foreman(::exec::DrillbitEndpoint* foreman);

  // optional int64 start = 2;
  bool has_start() const;
  void clear_start();
  static const int kStartFieldNumber = 2;
  ::google::protobuf::int64 start() const;
  void set_start(::google::protobuf::int64 value);

  // optional double total_cost = 7;
  bool has_total_cost() const;
  void clear_total_cost();
  static const int kTotalCostFieldNumber = 7;
  double total_cost() const;
  void set_total_cost(double value);

  // optional .exec.shared.QueryResult.QueryState state = 3;
  bool has_state() const;
  void clear_state();
  static const int kStateFieldNumber = 3;
  ::exec::shared::QueryResult_QueryState state() const;
  void set_state(::exec::shared::QueryResult_QueryState value);

  // @@protoc_insertion_point(class_scope:exec.shared.QueryInfo)
 private:
  void set_has_query();
  void clear_has_query();
  void set_has_start();
  void clear_has_start();
  void set_has_state();
  void clear_has_state();
  void set_has_user();
  void clear_has_user();
  void set_has_foreman();
  void clear_has_foreman();
  void set_has_options_json();
  void clear_has_options_json();
  void set_has_total_cost();
  void clear_has_total_cost();
  void set_has_queue_name();
  void clear_has_queue_name();

  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
  ::google::protobuf::internal::HasBits<1> _has_bits_;
  mutable ::google::protobuf::internal::CachedSize _cached_size_;
  ::google::protobuf::internal::ArenaStringPtr query_;
  public:
  static ::google::protobuf::internal::ExplicitlyConstructed< ::std::string> _i_give_permission_to_break_this_code_default_user_;
  private:
  ::google::protobuf::internal::ArenaStringPtr user_;
  ::google::protobuf::internal::ArenaStringPtr options_json_;
  public:
  static ::google::protobuf::internal::ExplicitlyConstructed< ::std::string> _i_give_permission_to_break_this_code_default_queue_name_;
  private:
  ::google::protobuf::internal::ArenaStringPtr queue_name_;
  ::exec::DrillbitEndpoint* foreman_;
  ::google::protobuf::int64 start_;
  double total_cost_;
  int state_;
  friend struct ::protobuf_UserBitShared_2eproto::TableStruct;
};
// -------------------------------------------------------------------

class QueryProfile : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:exec.shared.QueryProfile) */ {
 public:
  QueryProfile();
  virtual ~QueryProfile();

  QueryProfile(const QueryProfile& from);

  inline QueryProfile& operator=(const QueryProfile& from) {
    CopyFrom(from);
    return *this;
  }
  #if LANG_CXX11
  QueryProfile(QueryProfile&& from) noexcept
    : QueryProfile() {
    *this = ::std::move(from);
  }

  inline QueryProfile& operator=(QueryProfile&& from) noexcept {
    if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) {
      if (this != &from) InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }
  #endif
  inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
    return _internal_metadata_.unknown_fields();
  }
  inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
    return _internal_metadata_.mutable_unknown_fields();
  }

  static const ::google::protobuf::Descriptor* descriptor();
  static const QueryProfile& default_instance();

  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
  static inline const QueryProfile* internal_default_instance() {
    return reinterpret_cast<const QueryProfile*>(
               &_QueryProfile_default_instance_);
  }
  static constexpr int kIndexInFileMessages =
    13;

  void Swap(QueryProfile* other);
  friend void swap(QueryProfile& a, QueryProfile& b) {
    a.Swap(&b);
  }

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

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

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

  size_t ByteSizeLong() const final;
  bool MergePartialFromCodedStream(
      ::google::protobuf::io::CodedInputStream* input) final;
  void SerializeWithCachedSizes(
      ::google::protobuf::io::CodedOutputStream* output) const final;
  ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
      bool deterministic, ::google::protobuf::uint8* target) const final;
  int GetCachedSize() const final { return _cached_size_.Get(); }

  private:
  void SharedCtor();
  void SharedDtor();
  void SetCachedSize(int size) const final;
  void InternalSwap(QueryProfile* other);
  private:
  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
    return NULL;
  }
  inline void* MaybeArenaPtr() const {
    return NULL;
  }
  public:

  ::google::protobuf::Metadata GetMetadata() const final;

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

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

  // repeated .exec.shared.MajorFragmentProfile fragment_profile = 11;
  int fragment_profile_size() const;
  void clear_fragment_profile();
  static const int kFragmentProfileFieldNumber = 11;
  ::exec::shared::MajorFragmentProfile* mutable_fragment_profile(int index);
  ::google::protobuf::RepeatedPtrField< ::exec::shared::MajorFragmentProfile >*
      mutable_fragment_profile();
  const ::exec::shared::MajorFragmentProfile& fragment_profile(int index) const;
  ::exec::shared::MajorFragmentProfile* add_fragment_profile();
  const ::google::protobuf::RepeatedPtrField< ::exec::shared::MajorFragmentProfile >&
      fragment_profile() const;

  // optional string query = 5;
  bool has_query() const;
  void clear_query();
  static const int kQueryFieldNumber = 5;
  const ::std::string& query() const;
  void set_query(const ::std::string& value);
  #if LANG_CXX11
  void set_query(::std::string&& value);
  #endif
  void set_query(const char* value);
  void set_query(const char* value, size_t size);
  ::std::string* mutable_query();
  ::std::string* release_query();
  void set_allocated_query(::std::string* query);

  // optional string plan = 6;
  bool has_plan() const;
  void clear_plan();
  static const int kPlanFieldNumber = 6;
  const ::std::string& plan() const;
  void set_plan(const ::std::string& value);
  #if LANG_CXX11
  void set_plan(::std::string&& value);
  #endif
  void set_plan(const char* value);
  void set_plan(const char* value, size_t size);
  ::std::string* mutable_plan();
  ::std::string* release_plan();
  void set_allocated_plan(::std::string* plan);

  // optional string user = 12 [default = "-"];
  bool has_user() const;
  void clear_user();
  static const int kUserFieldNumber = 12;
  const ::std::string& user() const;
  void set_user(const ::std::string& value);
  #if LANG_CXX11
  void set_user(::std::string&& value);
  #endif
  void set_user(const char* value);
  void set_user(const char* value, size_t size);
  ::std::string* mutable_user();
  ::std::string* release_user();
  void set_allocated_user(::std::string* user);

  // optional string error = 13;
  bool has_error() const;
  void clear_error();
  static const int kErrorFieldNumber = 13;
  const ::std::string& error() const;
  void set_error(const ::std::string& value);
  #if LANG_CXX11
  void set_error(::std::string&& value);
  #endif
  void set_error(const char* value);
  void set_error(const char* value, size_t size);
  ::std::string* mutable_error();
  ::std::string* release_error();
  void set_allocated_error(::std::string* error);

  // optional string verboseError = 14;
  bool has_verboseerror() const;
  void clear_verboseerror();
  static const int kVerboseErrorFieldNumber = 14;
  const ::std::string& verboseerror() const;
  void set_verboseerror(const ::std::string& value);
  #if LANG_CXX11
  void set_verboseerror(::std::string&& value);
  #endif
  void set_verboseerror(const char* value);
  void set_verboseerror(const char* value, size_t size);
  ::std::string* mutable_verboseerror();
  ::std::string* release_verboseerror();
  void set_allocated_verboseerror(::std::string* verboseerror);

  // optional string error_id = 15;
  bool has_error_id() const;
  void clear_error_id();
  static const int kErrorIdFieldNumber = 15;
  const ::std::string& error_id() const;
  void set_error_id(const ::std::string& value);
  #if LANG_CXX11
  void set_error_id(::std::string&& value);
  #endif
  void set_error_id(const char* value);
  void set_error_id(const char* value, size_t size);
  ::std::string* mutable_error_id();
  ::std::string* release_error_id();
  void set_allocated_error_id(::std::string* error_id);

  // optional string error_node = 16;
  bool has_error_node() const;
  void clear_error_node();
  static const int kErrorNodeFieldNumber = 16;
  const ::std::string& error_node() const;
  void set_error_node(const ::std::string& value);
  #if LANG_CXX11
  void set_error_node(::std::string&& value);
  #endif
  void set_error_node(const char* value);
  void set_error_node(const char* value, size_t size);
  ::std::string* mutable_error_node();
  ::std::string* release_error_node();
  void set_allocated_error_node(::std::string* error_node);

  // optional string options_json = 17;
  bool has_options_json() const;
  void clear_options_json();
  static const int kOptionsJsonFieldNumber = 17;
  const ::std::string& options_json() const;
  void set_options_json(const ::std::string& value);
  #if LANG_CXX11
  void set_options_json(::std::string&& value);
  #endif
  void set_options_json(const char* value);
  void set_options_json(const char* value, size_t size);
  ::std::string* mutable_options_json();
  ::std::string* release_options_json();
  void set_allocated_options_json(::std::string* options_json);

  // optional string queue_name = 21 [default = "-"];
  bool has_queue_name() const;
  void clear_queue_name();
  static const int kQueueNameFieldNumber = 21;
  const ::std::string& queue_name() const;
  void set_queue_name(const ::std::string& value);
  #if LANG_CXX11
  void set_queue_name(::std::string&& value);
  #endif
  void set_queue_name(const char* value);
  void set_queue_name(const char* value, size_t size);
  ::std::string* mutable_queue_name();
  ::std::string* release_queue_name();
  void set_allocated_queue_name(::std::string* queue_name);

  // optional string queryId = 22;
  bool has_queryid() const;
  void clear_queryid();
  static const int kQueryIdFieldNumber = 22;
  const ::std::string& queryid() const;
  void set_queryid(const ::std::string& value);
  #if LANG_CXX11
  void set_queryid(::std::string&& value);
  #endif
  void set_queryid(const char* value);
  void set_queryid(const char* value, size_t size);
  ::std::string* mutable_queryid();
  ::std::string* release_queryid();
  void set_allocated_queryid(::std::string* queryid);

  // optional .exec.shared.QueryId id = 1;
  bool has_id() const;
  void clear_id();
  static const int kIdFieldNumber = 1;
  private:
  const ::exec::shared::QueryId& _internal_id() const;
  public:
  const ::exec::shared::QueryId& id() const;
  ::exec::shared::QueryId* release_id();
  ::exec::shared::QueryId* mutable_id();
  void set_allocated_id(::exec::shared::QueryId* id);

  // optional .exec.DrillbitEndpoint foreman = 7;
  bool has_foreman() const;
  void clear_foreman();
  static const int kForemanFieldNumber = 7;
  private:
  const ::exec::DrillbitEndpoint& _internal_foreman() const;
  public:
  const ::exec::DrillbitEndpoint& foreman() const;
  ::exec::DrillbitEndpoint* release_foreman();
  ::exec::DrillbitEndpoint* mutable_foreman();
  void set_allocated_foreman(::exec::DrillbitEndpoint* foreman);

  // optional int64 start = 3;
  bool has_start() const;
  void clear_start();
  static const int kStartFieldNumber = 3;
  ::google::protobuf::int64 start() const;
  void set_start(::google::protobuf::int64 value);

  // optional int64 end = 4;
  bool has_end() const;
  void clear_end();
  static const int kEndFieldNumber = 4;
  ::google::protobuf::int64 end() const;
  void set_end(::google::protobuf::int64 value);

  // optional .exec.shared.QueryResult.QueryState state = 8;
  bool has_state() const;
  void clear_state();
  static const int kStateFieldNumber = 8;
  ::exec::shared::QueryResult_QueryState state() const;
  void set_state(::exec::shared::QueryResult_QueryState value);

  // optional int32 total_fragments = 9;
  bool has_total_fragments() const;
  void clear_total_fragments();
  static const int kTotalFragmentsFieldNumber = 9;
  ::google::protobuf::int32 total_fragments() const;
  void set_total_fragments(::google::protobuf::int32 value);

  // optional int32 finished_fragments = 10;
  bool has_finished_fragments() const;
  void clear_finished_fragments();
  static const int kFinishedFragmentsFieldNumber = 10;
  ::google::protobuf::int32 finished_fragments() const;
  void set_finished_fragments(::google::protobuf::int32 value);

  // optional int32 autoLimit = 23;
  bool has_autolimit() const;
  void clear_autolimit();
  static const int kAutoLimitFieldNumber = 23;
  ::google::protobuf::int32 autolimit() const;
  void set_autolimit(::google::protobuf::int32 value);

  // optional int64 planEnd = 18;
  bool has_planend() const;
  void clear_planend();
  static const int kPlanEndFieldNumber = 18;
  ::google::protobuf::int64 planend() const;
  void set_planend(::google::protobuf::int64 value);

  // optional int64 queueWaitEnd = 19;
  bool has_queuewaitend() const;
  void clear_queuewaitend();
  static const int kQueueWaitEndFieldNumber = 19;
  ::google::protobuf::int64 queuewaitend() const;
  void set_queuewaitend(::google::protobuf::int64 value);

  // optional double total_cost = 20;
  bool has_total_cost() const;
  void clear_total_cost();
  static const int kTotalCostFieldNumber = 20;
  double total_cost() const;
  void set_total_cost(double value);

  // optional .exec.shared.QueryType type = 2;
  bool has_type() const;
  void clear_type();
  static const int kTypeFieldNumber = 2;
  ::exec::shared::QueryType type() const;
  void set_type(::exec::shared::QueryType value);

  // @@protoc_insertion_point(class_scope:exec.shared.QueryProfile)
 private:
  void set_has_id();
  void clear_has_id();
  void set_has_type();
  void clear_has_type();
  void set_has_start();
  void clear_has_start();
  void set_has_end();
  void clear_has_end();
  void set_has_query();
  void clear_has_query();
  void set_has_plan();
  void clear_has_plan();
  void set_has_foreman();
  void clear_has_foreman();
  void set_has_state();
  void clear_has_state();
  void set_has_total_fragments();
  void clear_has_total_fragments();
  void set_has_finished_fragments();
  void clear_has_finished_fragments();
  void set_has_user();
  void clear_has_user();
  void set_has_error();
  void clear_has_error();
  void set_has_verboseerror();
  void clear_has_verboseerror();
  void set_has_error_id();
  void clear_has_error_id();
  void set_has_error_node();
  void clear_has_error_node();
  void set_has_options_json();
  void clear_has_options_json();
  void set_has_planend();
  void clear_has_planend();
  void set_has_queuewaitend();
  void clear_has_queuewaitend();
  void set_has_total_cost();
  void clear_has_total_cost();
  void set_has_queue_name();
  void clear_has_queue_name();
  void set_has_queryid();
  void clear_has_queryid();
  void set_has_autolimit();
  void clear_has_autolimit();

  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
  ::google::protobuf::internal::HasBits<1> _has_bits_;
  mutable ::google::protobuf::internal::CachedSize _cached_size_;
  ::google::protobuf::RepeatedPtrField< ::exec::shared::MajorFragmentProfile > fragment_profile_;
  ::google::protobuf::internal::ArenaStringPtr query_;
  ::google::protobuf::internal::ArenaStringPtr plan_;
  public:
  static ::google::protobuf::internal::ExplicitlyConstructed< ::std::string> _i_give_permission_to_break_this_code_default_user_;
  private:
  ::google::protobuf::internal::ArenaStringPtr user_;
  ::google::protobuf::internal::ArenaStringPtr error_;
  ::google::protobuf::internal::ArenaStringPtr verboseerror_;
  ::google::protobuf::internal::ArenaStringPtr error_id_;
  ::google::protobuf::internal::ArenaStringPtr error_node_;
  ::google::protobuf::internal::ArenaStringPtr options_json_;
  public:
  static ::google::protobuf::internal::ExplicitlyConstructed< ::std::string> _i_give_permission_to_break_this_code_default_queue_name_;
  private:
  ::google::protobuf::internal::ArenaStringPtr queue_name_;
  ::google::protobuf::internal::ArenaStringPtr queryid_;
  ::exec::shared::QueryId* id_;
  ::exec::DrillbitEndpoint* foreman_;
  ::google::protobuf::int64 start_;
  ::google::protobuf::int64 end_;
  int state_;
  ::google::protobuf::int32 total_fragments_;
  ::google::protobuf::int32 finished_fragments_;
  ::google::protobuf::int32 autolimit_;
  ::google::protobuf::int64 planend_;
  ::google::protobuf::int64 queuewaitend_;
  double total_cost_;
  int type_;
  friend struct ::protobuf_UserBitShared_2eproto::TableStruct;
};
// -------------------------------------------------------------------

class MajorFragmentProfile : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:exec.shared.MajorFragmentProfile) */ {
 public:
  MajorFragmentProfile();
  virtual ~MajorFragmentProfile();

  MajorFragmentProfile(const MajorFragmentProfile& from);

  inline MajorFragmentProfile& operator=(const MajorFragmentProfile& from) {
    CopyFrom(from);
    return *this;
  }
  #if LANG_CXX11
  MajorFragmentProfile(MajorFragmentProfile&& from) noexcept
    : MajorFragmentProfile() {
    *this = ::std::move(from);
  }

  inline MajorFragmentProfile& operator=(MajorFragmentProfile&& from) noexcept {
    if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) {
      if (this != &from) InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }
  #endif
  inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
    return _internal_metadata_.unknown_fields();
  }
  inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
    return _internal_metadata_.mutable_unknown_fields();
  }

  static const ::google::protobuf::Descriptor* descriptor();
  static const MajorFragmentProfile& default_instance();

  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
  static inline const MajorFragmentProfile* internal_default_instance() {
    return reinterpret_cast<const MajorFragmentProfile*>(
               &_MajorFragmentProfile_default_instance_);
  }
  static constexpr int kIndexInFileMessages =
    14;

  void Swap(MajorFragmentProfile* other);
  friend void swap(MajorFragmentProfile& a, MajorFragmentProfile& b) {
    a.Swap(&b);
  }

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

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

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

  size_t ByteSizeLong() const final;
  bool MergePartialFromCodedStream(
      ::google::protobuf::io::CodedInputStream* input) final;
  void SerializeWithCachedSizes(
      ::google::protobuf::io::CodedOutputStream* output) const final;
  ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
      bool deterministic, ::google::protobuf::uint8* target) const final;
  int GetCachedSize() const final { return _cached_size_.Get(); }

  private:
  void SharedCtor();
  void SharedDtor();
  void SetCachedSize(int size) const final;
  void InternalSwap(MajorFragmentProfile* other);
  private:
  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
    return NULL;
  }
  inline void* MaybeArenaPtr() const {
    return NULL;
  }
  public:

  ::google::protobuf::Metadata GetMetadata() const final;

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

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

  // repeated .exec.shared.MinorFragmentProfile minor_fragment_profile = 2;
  int minor_fragment_profile_size() const;
  void clear_minor_fragment_profile();
  static const int kMinorFragmentProfileFieldNumber = 2;
  ::exec::shared::MinorFragmentProfile* mutable_minor_fragment_profile(int index);
  ::google::protobuf::RepeatedPtrField< ::exec::shared::MinorFragmentProfile >*
      mutable_minor_fragment_profile();
  const ::exec::shared::MinorFragmentProfile& minor_fragment_profile(int index) const;
  ::exec::shared::MinorFragmentProfile* add_minor_fragment_profile();
  const ::google::protobuf::RepeatedPtrField< ::exec::shared::MinorFragmentProfile >&
      minor_fragment_profile() const;

  // optional int32 major_fragment_id = 1;
  bool has_major_fragment_id() const;
  void clear_major_fragment_id();
  static const int kMajorFragmentIdFieldNumber = 1;
  ::google::protobuf::int32 major_fragment_id() const;
  void set_major_fragment_id(::google::protobuf::int32 value);

  // @@protoc_insertion_point(class_scope:exec.shared.MajorFragmentProfile)
 private:
  void set_has_major_fragment_id();
  void clear_has_major_fragment_id();

  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
  ::google::protobuf::internal::HasBits<1> _has_bits_;
  mutable ::google::protobuf::internal::CachedSize _cached_size_;
  ::google::protobuf::RepeatedPtrField< ::exec::shared::MinorFragmentProfile > minor_fragment_profile_;
  ::google::protobuf::int32 major_fragment_id_;
  friend struct ::protobuf_UserBitShared_2eproto::TableStruct;
};
// -------------------------------------------------------------------

class MinorFragmentProfile : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:exec.shared.MinorFragmentProfile) */ {
 public:
  MinorFragmentProfile();
  virtual ~MinorFragmentProfile();

  MinorFragmentProfile(const MinorFragmentProfile& from);

  inline MinorFragmentProfile& operator=(const MinorFragmentProfile& from) {
    CopyFrom(from);
    return *this;
  }
  #if LANG_CXX11
  MinorFragmentProfile(MinorFragmentProfile&& from) noexcept
    : MinorFragmentProfile() {
    *this = ::std::move(from);
  }

  inline MinorFragmentProfile& operator=(MinorFragmentProfile&& from) noexcept {
    if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) {
      if (this != &from) InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }
  #endif
  inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
    return _internal_metadata_.unknown_fields();
  }
  inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
    return _internal_metadata_.mutable_unknown_fields();
  }

  static const ::google::protobuf::Descriptor* descriptor();
  static const MinorFragmentProfile& default_instance();

  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
  static inline const MinorFragmentProfile* internal_default_instance() {
    return reinterpret_cast<const MinorFragmentProfile*>(
               &_MinorFragmentProfile_default_instance_);
  }
  static constexpr int kIndexInFileMessages =
    15;

  void Swap(MinorFragmentProfile* other);
  friend void swap(MinorFragmentProfile& a, MinorFragmentProfile& b) {
    a.Swap(&b);
  }

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

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

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

  size_t ByteSizeLong() const final;
  bool MergePartialFromCodedStream(
      ::google::protobuf::io::CodedInputStream* input) final;
  void SerializeWithCachedSizes(
      ::google::protobuf::io::CodedOutputStream* output) const final;
  ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
      bool deterministic, ::google::protobuf::uint8* target) const final;
  int GetCachedSize() const final { return _cached_size_.Get(); }

  private:
  void SharedCtor();
  void SharedDtor();
  void SetCachedSize(int size) const final;
  void InternalSwap(MinorFragmentProfile* other);
  private:
  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
    return NULL;
  }
  inline void* MaybeArenaPtr() const {
    return NULL;
  }
  public:

  ::google::protobuf::Metadata GetMetadata() const final;

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

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

  // repeated .exec.shared.OperatorProfile operator_profile = 4;
  int operator_profile_size() const;
  void clear_operator_profile();
  static const int kOperatorProfileFieldNumber = 4;
  ::exec::shared::OperatorProfile* mutable_operator_profile(int index);
  ::google::protobuf::RepeatedPtrField< ::exec::shared::OperatorProfile >*
      mutable_operator_profile();
  const ::exec::shared::OperatorProfile& operator_profile(int index) const;
  ::exec::shared::OperatorProfile* add_operator_profile();
  const ::google::protobuf::RepeatedPtrField< ::exec::shared::OperatorProfile >&
      operator_profile() const;

  // optional .exec.shared.DrillPBError error = 2;
  bool has_error() const;
  void clear_error();
  static const int kErrorFieldNumber = 2;
  private:
  const ::exec::shared::DrillPBError& _internal_error() const;
  public:
  const ::exec::shared::DrillPBError& error() const;
  ::exec::shared::DrillPBError* release_error();
  ::exec::shared::DrillPBError* mutable_error();
  void set_allocated_error(::exec::shared::DrillPBError* error);

  // optional .exec.DrillbitEndpoint endpoint = 9;
  bool has_endpoint() const;
  void clear_endpoint();
  static const int kEndpointFieldNumber = 9;
  private:
  const ::exec::DrillbitEndpoint& _internal_endpoint() const;
  public:
  const ::exec::DrillbitEndpoint& endpoint() const;
  ::exec::DrillbitEndpoint* release_endpoint();
  ::exec::DrillbitEndpoint* mutable_endpoint();
  void set_allocated_endpoint(::exec::DrillbitEndpoint* endpoint);

  // optional .exec.shared.FragmentState state = 1;
  bool has_state() const;
  void clear_state();
  static const int kStateFieldNumber = 1;
  ::exec::shared::FragmentState state() const;
  void set_state(::exec::shared::FragmentState value);

  // optional int32 minor_fragment_id = 3;
  bool has_minor_fragment_id() const;
  void clear_minor_fragment_id();
  static const int kMinorFragmentIdFieldNumber = 3;
  ::google::protobuf::int32 minor_fragment_id() const;
  void set_minor_fragment_id(::google::protobuf::int32 value);

  // optional int64 start_time = 5;
  bool has_start_time() const;
  void clear_start_time();
  static const int kStartTimeFieldNumber = 5;
  ::google::protobuf::int64 start_time() const;
  void set_start_time(::google::protobuf::int64 value);

  // optional int64 end_time = 6;
  bool has_end_time() const;
  void clear_end_time();
  static const int kEndTimeFieldNumber = 6;
  ::google::protobuf::int64 end_time() const;
  void set_end_time(::google::protobuf::int64 value);

  // optional int64 memory_used = 7;
  bool has_memory_used() const;
  void clear_memory_used();
  static const int kMemoryUsedFieldNumber = 7;
  ::google::protobuf::int64 memory_used() const;
  void set_memory_used(::google::protobuf::int64 value);

  // optional int64 max_memory_used = 8;
  bool has_max_memory_used() const;
  void clear_max_memory_used();
  static const int kMaxMemoryUsedFieldNumber = 8;
  ::google::protobuf::int64 max_memory_used() const;
  void set_max_memory_used(::google::protobuf::int64 value);

  // optional int64 last_update = 10;
  bool has_last_update() const;
  void clear_last_update();
  static const int kLastUpdateFieldNumber = 10;
  ::google::protobuf::int64 last_update() const;
  void set_last_update(::google::protobuf::int64 value);

  // optional int64 last_progress = 11;
  bool has_last_progress() const;
  void clear_last_progress();
  static const int kLastProgressFieldNumber = 11;
  ::google::protobuf::int64 last_progress() const;
  void set_last_progress(::google::protobuf::int64 value);

  // @@protoc_insertion_point(class_scope:exec.shared.MinorFragmentProfile)
 private:
  void set_has_state();
  void clear_has_state();
  void set_has_error();
  void clear_has_error();
  void set_has_minor_fragment_id();
  void clear_has_minor_fragment_id();
  void set_has_start_time();
  void clear_has_start_time();
  void set_has_end_time();
  void clear_has_end_time();
  void set_has_memory_used();
  void clear_has_memory_used();
  void set_has_max_memory_used();
  void clear_has_max_memory_used();
  void set_has_endpoint();
  void clear_has_endpoint();
  void set_has_last_update();
  void clear_has_last_update();
  void set_has_last_progress();
  void clear_has_last_progress();

  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
  ::google::protobuf::internal::HasBits<1> _has_bits_;
  mutable ::google::protobuf::internal::CachedSize _cached_size_;
  ::google::protobuf::RepeatedPtrField< ::exec::shared::OperatorProfile > operator_profile_;
  ::exec::shared::DrillPBError* error_;
  ::exec::DrillbitEndpoint* endpoint_;
  int state_;
  ::google::protobuf::int32 minor_fragment_id_;
  ::google::protobuf::int64 start_time_;
  ::google::protobuf::int64 end_time_;
  ::google::protobuf::int64 memory_used_;
  ::google::protobuf::int64 max_memory_used_;
  ::google::protobuf::int64 last_update_;
  ::google::protobuf::int64 last_progress_;
  friend struct ::protobuf_UserBitShared_2eproto::TableStruct;
};
// -------------------------------------------------------------------

class OperatorProfile : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:exec.shared.OperatorProfile) */ {
 public:
  OperatorProfile();
  virtual ~OperatorProfile();

  OperatorProfile(const OperatorProfile& from);

  inline OperatorProfile& operator=(const OperatorProfile& from) {
    CopyFrom(from);
    return *this;
  }
  #if LANG_CXX11
  OperatorProfile(OperatorProfile&& from) noexcept
    : OperatorProfile() {
    *this = ::std::move(from);
  }

  inline OperatorProfile& operator=(OperatorProfile&& from) noexcept {
    if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) {
      if (this != &from) InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }
  #endif
  inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
    return _internal_metadata_.unknown_fields();
  }
  inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
    return _internal_metadata_.mutable_unknown_fields();
  }

  static const ::google::protobuf::Descriptor* descriptor();
  static const OperatorProfile& default_instance();

  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
  static inline const OperatorProfile* internal_default_instance() {
    return reinterpret_cast<const OperatorProfile*>(
               &_OperatorProfile_default_instance_);
  }
  static constexpr int kIndexInFileMessages =
    16;

  void Swap(OperatorProfile* other);
  friend void swap(OperatorProfile& a, OperatorProfile& b) {
    a.Swap(&b);
  }

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

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

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

  size_t ByteSizeLong() const final;
  bool MergePartialFromCodedStream(
      ::google::protobuf::io::CodedInputStream* input) final;
  void SerializeWithCachedSizes(
      ::google::protobuf::io::CodedOutputStream* output) const final;
  ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
      bool deterministic, ::google::protobuf::uint8* target) const final;
  int GetCachedSize() const final { return _cached_size_.Get(); }

  private:
  void SharedCtor();
  void SharedDtor();
  void SetCachedSize(int size) const final;
  void InternalSwap(OperatorProfile* other);
  private:
  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
    return NULL;
  }
  inline void* MaybeArenaPtr() const {
    return NULL;
  }
  public:

  ::google::protobuf::Metadata GetMetadata() const final;

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

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

  // repeated .exec.shared.StreamProfile input_profile = 1;
  int input_profile_size() const;
  void clear_input_profile();
  static const int kInputProfileFieldNumber = 1;
  ::exec::shared::StreamProfile* mutable_input_profile(int index);
  ::google::protobuf::RepeatedPtrField< ::exec::shared::StreamProfile >*
      mutable_input_profile();
  const ::exec::shared::StreamProfile& input_profile(int index) const;
  ::exec::shared::StreamProfile* add_input_profile();
  const ::google::protobuf::RepeatedPtrField< ::exec::shared::StreamProfile >&
      input_profile() const;

  // repeated .exec.shared.MetricValue metric = 8;
  int metric_size() const;
  void clear_metric();
  static const int kMetricFieldNumber = 8;
  ::exec::shared::MetricValue* mutable_metric(int index);
  ::google::protobuf::RepeatedPtrField< ::exec::shared::MetricValue >*
      mutable_metric();
  const ::exec::shared::MetricValue& metric(int index) const;
  ::exec::shared::MetricValue* add_metric();
  const ::google::protobuf::RepeatedPtrField< ::exec::shared::MetricValue >&
      metric() const;

  // optional int32 operator_id = 3;
  bool has_operator_id() const;
  void clear_operator_id();
  static const int kOperatorIdFieldNumber = 3;
  ::google::protobuf::int32 operator_id() const;
  void set_operator_id(::google::protobuf::int32 value);

  // optional int32 operator_type = 4;
  bool has_operator_type() const;
  void clear_operator_type();
  static const int kOperatorTypeFieldNumber = 4;
  ::google::protobuf::int32 operator_type() const;
  void set_operator_type(::google::protobuf::int32 value);

  // optional int64 setup_nanos = 5;
  bool has_setup_nanos() const;
  void clear_setup_nanos();
  static const int kSetupNanosFieldNumber = 5;
  ::google::protobuf::int64 setup_nanos() const;
  void set_setup_nanos(::google::protobuf::int64 value);

  // optional int64 process_nanos = 6;
  bool has_process_nanos() const;
  void clear_process_nanos();
  static const int kProcessNanosFieldNumber = 6;
  ::google::protobuf::int64 process_nanos() const;
  void set_process_nanos(::google::protobuf::int64 value);

  // optional int64 peak_local_memory_allocated = 7;
  bool has_peak_local_memory_allocated() const;
  void clear_peak_local_memory_allocated();
  static const int kPeakLocalMemoryAllocatedFieldNumber = 7;
  ::google::protobuf::int64 peak_local_memory_allocated() const;
  void set_peak_local_memory_allocated(::google::protobuf::int64 value);

  // optional int64 wait_nanos = 9;
  bool has_wait_nanos() const;
  void clear_wait_nanos();
  static const int kWaitNanosFieldNumber = 9;
  ::google::protobuf::int64 wait_nanos() const;
  void set_wait_nanos(::google::protobuf::int64 value);

  // @@protoc_insertion_point(class_scope:exec.shared.OperatorProfile)
 private:
  void set_has_operator_id();
  void clear_has_operator_id();
  void set_has_operator_type();
  void clear_has_operator_type();
  void set_has_setup_nanos();
  void clear_has_setup_nanos();
  void set_has_process_nanos();
  void clear_has_process_nanos();
  void set_has_peak_local_memory_allocated();
  void clear_has_peak_local_memory_allocated();
  void set_has_wait_nanos();
  void clear_has_wait_nanos();

  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
  ::google::protobuf::internal::HasBits<1> _has_bits_;
  mutable ::google::protobuf::internal::CachedSize _cached_size_;
  ::google::protobuf::RepeatedPtrField< ::exec::shared::StreamProfile > input_profile_;
  ::google::protobuf::RepeatedPtrField< ::exec::shared::MetricValue > metric_;
  ::google::protobuf::int32 operator_id_;
  ::google::protobuf::int32 operator_type_;
  ::google::protobuf::int64 setup_nanos_;
  ::google::protobuf::int64 process_nanos_;
  ::google::protobuf::int64 peak_local_memory_allocated_;
  ::google::protobuf::int64 wait_nanos_;
  friend struct ::protobuf_UserBitShared_2eproto::TableStruct;
};
// -------------------------------------------------------------------

class StreamProfile : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:exec.shared.StreamProfile) */ {
 public:
  StreamProfile();
  virtual ~StreamProfile();

  StreamProfile(const StreamProfile& from);

  inline StreamProfile& operator=(const StreamProfile& from) {
    CopyFrom(from);
    return *this;
  }
  #if LANG_CXX11
  StreamProfile(StreamProfile&& from) noexcept
    : StreamProfile() {
    *this = ::std::move(from);
  }

  inline StreamProfile& operator=(StreamProfile&& from) noexcept {
    if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) {
      if (this != &from) InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }
  #endif
  inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
    return _internal_metadata_.unknown_fields();
  }
  inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
    return _internal_metadata_.mutable_unknown_fields();
  }

  static const ::google::protobuf::Descriptor* descriptor();
  static const StreamProfile& default_instance();

  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
  static inline const StreamProfile* internal_default_instance() {
    return reinterpret_cast<const StreamProfile*>(
               &_StreamProfile_default_instance_);
  }
  static constexpr int kIndexInFileMessages =
    17;

  void Swap(StreamProfile* other);
  friend void swap(StreamProfile& a, StreamProfile& b) {
    a.Swap(&b);
  }

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

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

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

  size_t ByteSizeLong() const final;
  bool MergePartialFromCodedStream(
      ::google::protobuf::io::CodedInputStream* input) final;
  void SerializeWithCachedSizes(
      ::google::protobuf::io::CodedOutputStream* output) const final;
  ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
      bool deterministic, ::google::protobuf::uint8* target) const final;
  int GetCachedSize() const final { return _cached_size_.Get(); }

  private:
  void SharedCtor();
  void SharedDtor();
  void SetCachedSize(int size) const final;
  void InternalSwap(StreamProfile* other);
  private:
  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
    return NULL;
  }
  inline void* MaybeArenaPtr() const {
    return NULL;
  }
  public:

  ::google::protobuf::Metadata GetMetadata() const final;

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

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

  // optional int64 records = 1;
  bool has_records() const;
  void clear_records();
  static const int kRecordsFieldNumber = 1;
  ::google::protobuf::int64 records() const;
  void set_records(::google::protobuf::int64 value);

  // optional int64 batches = 2;
  bool has_batches() const;
  void clear_batches();
  static const int kBatchesFieldNumber = 2;
  ::google::protobuf::int64 batches() const;
  void set_batches(::google::protobuf::int64 value);

  // optional int64 schemas = 3;
  bool has_schemas() const;
  void clear_schemas();
  static const int kSchemasFieldNumber = 3;
  ::google::protobuf::int64 schemas() const;
  void set_schemas(::google::protobuf::int64 value);

  // @@protoc_insertion_point(class_scope:exec.shared.StreamProfile)
 private:
  void set_has_records();
  void clear_has_records();
  void set_has_batches();
  void clear_has_batches();
  void set_has_schemas();
  void clear_has_schemas();

  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
  ::google::protobuf::internal::HasBits<1> _has_bits_;
  mutable ::google::protobuf::internal::CachedSize _cached_size_;
  ::google::protobuf::int64 records_;
  ::google::protobuf::int64 batches_;
  ::google::protobuf::int64 schemas_;
  friend struct ::protobuf_UserBitShared_2eproto::TableStruct;
};
// -------------------------------------------------------------------

class MetricValue : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:exec.shared.MetricValue) */ {
 public:
  MetricValue();
  virtual ~MetricValue();

  MetricValue(const MetricValue& from);

  inline MetricValue& operator=(const MetricValue& from) {
    CopyFrom(from);
    return *this;
  }
  #if LANG_CXX11
  MetricValue(MetricValue&& from) noexcept
    : MetricValue() {
    *this = ::std::move(from);
  }

  inline MetricValue& operator=(MetricValue&& from) noexcept {
    if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) {
      if (this != &from) InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }
  #endif
  inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
    return _internal_metadata_.unknown_fields();
  }
  inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
    return _internal_metadata_.mutable_unknown_fields();
  }

  static const ::google::protobuf::Descriptor* descriptor();
  static const MetricValue& default_instance();

  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
  static inline const MetricValue* internal_default_instance() {
    return reinterpret_cast<const MetricValue*>(
               &_MetricValue_default_instance_);
  }
  static constexpr int kIndexInFileMessages =
    18;

  void Swap(MetricValue* other);
  friend void swap(MetricValue& a, MetricValue& b) {
    a.Swap(&b);
  }

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

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

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

  size_t ByteSizeLong() const final;
  bool MergePartialFromCodedStream(
      ::google::protobuf::io::CodedInputStream* input) final;
  void SerializeWithCachedSizes(
      ::google::protobuf::io::CodedOutputStream* output) const final;
  ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
      bool deterministic, ::google::protobuf::uint8* target) const final;
  int GetCachedSize() const final { return _cached_size_.Get(); }

  private:
  void SharedCtor();
  void SharedDtor();
  void SetCachedSize(int size) const final;
  void InternalSwap(MetricValue* other);
  private:
  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
    return NULL;
  }
  inline void* MaybeArenaPtr() const {
    return NULL;
  }
  public:

  ::google::protobuf::Metadata GetMetadata() const final;

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

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

  // optional int64 long_value = 2;
  bool has_long_value() const;
  void clear_long_value();
  static const int kLongValueFieldNumber = 2;
  ::google::protobuf::int64 long_value() const;
  void set_long_value(::google::protobuf::int64 value);

  // optional double double_value = 3;
  bool has_double_value() const;
  void clear_double_value();
  static const int kDoubleValueFieldNumber = 3;
  double double_value() const;
  void set_double_value(double value);

  // optional int32 metric_id = 1;
  bool has_metric_id() const;
  void clear_metric_id();
  static const int kMetricIdFieldNumber = 1;
  ::google::protobuf::int32 metric_id() const;
  void set_metric_id(::google::protobuf::int32 value);

  // @@protoc_insertion_point(class_scope:exec.shared.MetricValue)
 private:
  void set_has_metric_id();
  void clear_has_metric_id();
  void set_has_long_value();
  void clear_has_long_value();
  void set_has_double_value();
  void clear_has_double_value();

  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
  ::google::protobuf::internal::HasBits<1> _has_bits_;
  mutable ::google::protobuf::internal::CachedSize _cached_size_;
  ::google::protobuf::int64 long_value_;
  double double_value_;
  ::google::protobuf::int32 metric_id_;
  friend struct ::protobuf_UserBitShared_2eproto::TableStruct;
};
// -------------------------------------------------------------------

class Registry : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:exec.shared.Registry) */ {
 public:
  Registry();
  virtual ~Registry();

  Registry(const Registry& from);

  inline Registry& operator=(const Registry& from) {
    CopyFrom(from);
    return *this;
  }
  #if LANG_CXX11
  Registry(Registry&& from) noexcept
    : Registry() {
    *this = ::std::move(from);
  }

  inline Registry& operator=(Registry&& from) noexcept {
    if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) {
      if (this != &from) InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }
  #endif
  inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
    return _internal_metadata_.unknown_fields();
  }
  inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
    return _internal_metadata_.mutable_unknown_fields();
  }

  static const ::google::protobuf::Descriptor* descriptor();
  static const Registry& default_instance();

  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
  static inline const Registry* internal_default_instance() {
    return reinterpret_cast<const Registry*>(
               &_Registry_default_instance_);
  }
  static constexpr int kIndexInFileMessages =
    19;

  void Swap(Registry* other);
  friend void swap(Registry& a, Registry& b) {
    a.Swap(&b);
  }

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

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

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

  size_t ByteSizeLong() const final;
  bool MergePartialFromCodedStream(
      ::google::protobuf::io::CodedInputStream* input) final;
  void SerializeWithCachedSizes(
      ::google::protobuf::io::CodedOutputStream* output) const final;
  ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
      bool deterministic, ::google::protobuf::uint8* target) const final;
  int GetCachedSize() const final { return _cached_size_.Get(); }

  private:
  void SharedCtor();
  void SharedDtor();
  void SetCachedSize(int size) const final;
  void InternalSwap(Registry* other);
  private:
  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
    return NULL;
  }
  inline void* MaybeArenaPtr() const {
    return NULL;
  }
  public:

  ::google::protobuf::Metadata GetMetadata() const final;

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

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

  // repeated .exec.shared.Jar jar = 1;
  int jar_size() const;
  void clear_jar();
  static const int kJarFieldNumber = 1;
  ::exec::shared::Jar* mutable_jar(int index);
  ::google::protobuf::RepeatedPtrField< ::exec::shared::Jar >*
      mutable_jar();
  const ::exec::shared::Jar& jar(int index) const;
  ::exec::shared::Jar* add_jar();
  const ::google::protobuf::RepeatedPtrField< ::exec::shared::Jar >&
      jar() const;

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

  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
  ::google::protobuf::internal::HasBits<1> _has_bits_;
  mutable ::google::protobuf::internal::CachedSize _cached_size_;
  ::google::protobuf::RepeatedPtrField< ::exec::shared::Jar > jar_;
  friend struct ::protobuf_UserBitShared_2eproto::TableStruct;
};
// -------------------------------------------------------------------

class Jar : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:exec.shared.Jar) */ {
 public:
  Jar();
  virtual ~Jar();

  Jar(const Jar& from);

  inline Jar& operator=(const Jar& from) {
    CopyFrom(from);
    return *this;
  }
  #if LANG_CXX11
  Jar(Jar&& from) noexcept
    : Jar() {
    *this = ::std::move(from);
  }

  inline Jar& operator=(Jar&& from) noexcept {
    if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) {
      if (this != &from) InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }
  #endif
  inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
    return _internal_metadata_.unknown_fields();
  }
  inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
    return _internal_metadata_.mutable_unknown_fields();
  }

  static const ::google::protobuf::Descriptor* descriptor();
  static const Jar& default_instance();

  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
  static inline const Jar* internal_default_instance() {
    return reinterpret_cast<const Jar*>(
               &_Jar_default_instance_);
  }
  static constexpr int kIndexInFileMessages =
    20;

  void Swap(Jar* other);
  friend void swap(Jar& a, Jar& b) {
    a.Swap(&b);
  }

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

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

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

  size_t ByteSizeLong() const final;
  bool MergePartialFromCodedStream(
      ::google::protobuf::io::CodedInputStream* input) final;
  void SerializeWithCachedSizes(
      ::google::protobuf::io::CodedOutputStream* output) const final;
  ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
      bool deterministic, ::google::protobuf::uint8* target) const final;
  int GetCachedSize() const final { return _cached_size_.Get(); }

  private:
  void SharedCtor();
  void SharedDtor();
  void SetCachedSize(int size) const final;
  void InternalSwap(Jar* other);
  private:
  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
    return NULL;
  }
  inline void* MaybeArenaPtr() const {
    return NULL;
  }
  public:

  ::google::protobuf::Metadata GetMetadata() const final;

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

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

  // repeated string function_signature = 2;
  int function_signature_size() const;
  void clear_function_signature();
  static const int kFunctionSignatureFieldNumber = 2;
  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);
  #if LANG_CXX11
  void set_function_signature(int index, ::std::string&& value);
  #endif
  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);
  #if LANG_CXX11
  void add_function_signature(::std::string&& value);
  #endif
  void add_function_signature(const char* value);
  void add_function_signature(const char* value, size_t size);
  const ::google::protobuf::RepeatedPtrField< ::std::string>& function_signature() const;
  ::google::protobuf::RepeatedPtrField< ::std::string>* mutable_function_signature();

  // optional string name = 1;
  bool has_name() const;
  void clear_name();
  static const int kNameFieldNumber = 1;
  const ::std::string& name() const;
  void set_name(const ::std::string& value);
  #if LANG_CXX11
  void set_name(::std::string&& value);
  #endif
  void set_name(const char* value);
  void set_name(const char* value, size_t size);
  ::std::string* mutable_name();
  ::std::string* release_name();
  void set_allocated_name(::std::string* name);

  // @@protoc_insertion_point(class_scope:exec.shared.Jar)
 private:
  void set_has_name();
  void clear_has_name();

  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
  ::google::protobuf::internal::HasBits<1> _has_bits_;
  mutable ::google::protobuf::internal::CachedSize _cached_size_;
  ::google::protobuf::RepeatedPtrField< ::std::string> function_signature_;
  ::google::protobuf::internal::ArenaStringPtr name_;
  friend struct ::protobuf_UserBitShared_2eproto::TableStruct;
};
// -------------------------------------------------------------------

class SaslMessage : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:exec.shared.SaslMessage) */ {
 public:
  SaslMessage();
  virtual ~SaslMessage();

  SaslMessage(const SaslMessage& from);

  inline SaslMessage& operator=(const SaslMessage& from) {
    CopyFrom(from);
    return *this;
  }
  #if LANG_CXX11
  SaslMessage(SaslMessage&& from) noexcept
    : SaslMessage() {
    *this = ::std::move(from);
  }

  inline SaslMessage& operator=(SaslMessage&& from) noexcept {
    if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) {
      if (this != &from) InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }
  #endif
  inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
    return _internal_metadata_.unknown_fields();
  }
  inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
    return _internal_metadata_.mutable_unknown_fields();
  }

  static const ::google::protobuf::Descriptor* descriptor();
  static const SaslMessage& default_instance();

  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
  static inline const SaslMessage* internal_default_instance() {
    return reinterpret_cast<const SaslMessage*>(
               &_SaslMessage_default_instance_);
  }
  static constexpr int kIndexInFileMessages =
    21;

  void Swap(SaslMessage* other);
  friend void swap(SaslMessage& a, SaslMessage& b) {
    a.Swap(&b);
  }

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

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

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

  size_t ByteSizeLong() const final;
  bool MergePartialFromCodedStream(
      ::google::protobuf::io::CodedInputStream* input) final;
  void SerializeWithCachedSizes(
      ::google::protobuf::io::CodedOutputStream* output) const final;
  ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
      bool deterministic, ::google::protobuf::uint8* target) const final;
  int GetCachedSize() const final { return _cached_size_.Get(); }

  private:
  void SharedCtor();
  void SharedDtor();
  void SetCachedSize(int size) const final;
  void InternalSwap(SaslMessage* other);
  private:
  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
    return NULL;
  }
  inline void* MaybeArenaPtr() const {
    return NULL;
  }
  public:

  ::google::protobuf::Metadata GetMetadata() const final;

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

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

  // optional string mechanism = 1;
  bool has_mechanism() const;
  void clear_mechanism();
  static const int kMechanismFieldNumber = 1;
  const ::std::string& mechanism() const;
  void set_mechanism(const ::std::string& value);
  #if LANG_CXX11
  void set_mechanism(::std::string&& value);
  #endif
  void set_mechanism(const char* value);
  void set_mechanism(const char* value, size_t size);
  ::std::string* mutable_mechanism();
  ::std::string* release_mechanism();
  void set_allocated_mechanism(::std::string* mechanism);

  // optional bytes data = 2;
  bool has_data() const;
  void clear_data();
  static const int kDataFieldNumber = 2;
  const ::std::string& data() const;
  void set_data(const ::std::string& value);
  #if LANG_CXX11
  void set_data(::std::string&& value);
  #endif
  void set_data(const char* value);
  void set_data(const void* value, size_t size);
  ::std::string* mutable_data();
  ::std::string* release_data();
  void set_allocated_data(::std::string* data);

  // optional .exec.shared.SaslStatus status = 3;
  bool has_status() const;
  void clear_status();
  static const int kStatusFieldNumber = 3;
  ::exec::shared::SaslStatus status() const;
  void set_status(::exec::shared::SaslStatus value);

  // @@protoc_insertion_point(class_scope:exec.shared.SaslMessage)
 private:
  void set_has_mechanism();
  void clear_has_mechanism();
  void set_has_data();
  void clear_has_data();
  void set_has_status();
  void clear_has_status();

  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
  ::google::protobuf::internal::HasBits<1> _has_bits_;
  mutable ::google::protobuf::internal::CachedSize _cached_size_;
  ::google::protobuf::internal::ArenaStringPtr mechanism_;
  ::google::protobuf::internal::ArenaStringPtr data_;
  int status_;
  friend struct ::protobuf_UserBitShared_2eproto::TableStruct;
};
// ===================================================================


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

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

// optional string user_name = 1;
inline bool UserCredentials::has_user_name() const {
  return (_has_bits_[0] & 0x00000001u) != 0;
}
inline void UserCredentials::set_has_user_name() {
  _has_bits_[0] |= 0x00000001u;
}
inline void UserCredentials::clear_has_user_name() {
  _has_bits_[0] &= ~0x00000001u;
}
inline void UserCredentials::clear_user_name() {
  user_name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  clear_has_user_name();
}
inline const ::std::string& UserCredentials::user_name() const {
  // @@protoc_insertion_point(field_get:exec.shared.UserCredentials.user_name)
  return user_name_.GetNoArena();
}
inline void UserCredentials::set_user_name(const ::std::string& value) {
  set_has_user_name();
  user_name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
  // @@protoc_insertion_point(field_set:exec.shared.UserCredentials.user_name)
}
#if LANG_CXX11
inline void UserCredentials::set_user_name(::std::string&& value) {
  set_has_user_name();
  user_name_.SetNoArena(
    &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
  // @@protoc_insertion_point(field_set_rvalue:exec.shared.UserCredentials.user_name)
}
#endif
inline void UserCredentials::set_user_name(const char* value) {
  GOOGLE_DCHECK(value != NULL);
  set_has_user_name();
  user_name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
  // @@protoc_insertion_point(field_set_char:exec.shared.UserCredentials.user_name)
}
inline void UserCredentials::set_user_name(const char* value, size_t size) {
  set_has_user_name();
  user_name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
      ::std::string(reinterpret_cast<const char*>(value), size));
  // @@protoc_insertion_point(field_set_pointer:exec.shared.UserCredentials.user_name)
}
inline ::std::string* UserCredentials::mutable_user_name() {
  set_has_user_name();
  // @@protoc_insertion_point(field_mutable:exec.shared.UserCredentials.user_name)
  return user_name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline ::std::string* UserCredentials::release_user_name() {
  // @@protoc_insertion_point(field_release:exec.shared.UserCredentials.user_name)
  if (!has_user_name()) {
    return NULL;
  }
  clear_has_user_name();
  return user_name_.ReleaseNonDefaultNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline void UserCredentials::set_allocated_user_name(::std::string* user_name) {
  if (user_name != NULL) {
    set_has_user_name();
  } else {
    clear_has_user_name();
  }
  user_name_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), user_name);
  // @@protoc_insertion_point(field_set_allocated:exec.shared.UserCredentials.user_name)
}

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

// QueryId

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

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

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

// DrillPBError

// optional string error_id = 1;
inline bool DrillPBError::has_error_id() const {
  return (_has_bits_[0] & 0x00000001u) != 0;
}
inline void DrillPBError::set_has_error_id() {
  _has_bits_[0] |= 0x00000001u;
}
inline void DrillPBError::clear_has_error_id() {
  _has_bits_[0] &= ~0x00000001u;
}
inline void DrillPBError::clear_error_id() {
  error_id_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  clear_has_error_id();
}
inline const ::std::string& DrillPBError::error_id() const {
  // @@protoc_insertion_point(field_get:exec.shared.DrillPBError.error_id)
  return error_id_.GetNoArena();
}
inline void DrillPBError::set_error_id(const ::std::string& value) {
  set_has_error_id();
  error_id_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
  // @@protoc_insertion_point(field_set:exec.shared.DrillPBError.error_id)
}
#if LANG_CXX11
inline void DrillPBError::set_error_id(::std::string&& value) {
  set_has_error_id();
  error_id_.SetNoArena(
    &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
  // @@protoc_insertion_point(field_set_rvalue:exec.shared.DrillPBError.error_id)
}
#endif
inline void DrillPBError::set_error_id(const char* value) {
  GOOGLE_DCHECK(value != NULL);
  set_has_error_id();
  error_id_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
  // @@protoc_insertion_point(field_set_char:exec.shared.DrillPBError.error_id)
}
inline void DrillPBError::set_error_id(const char* value, size_t size) {
  set_has_error_id();
  error_id_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
      ::std::string(reinterpret_cast<const char*>(value), size));
  // @@protoc_insertion_point(field_set_pointer:exec.shared.DrillPBError.error_id)
}
inline ::std::string* DrillPBError::mutable_error_id() {
  set_has_error_id();
  // @@protoc_insertion_point(field_mutable:exec.shared.DrillPBError.error_id)
  return error_id_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline ::std::string* DrillPBError::release_error_id() {
  // @@protoc_insertion_point(field_release:exec.shared.DrillPBError.error_id)
  if (!has_error_id()) {
    return NULL;
  }
  clear_has_error_id();
  return error_id_.ReleaseNonDefaultNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline void DrillPBError::set_allocated_error_id(::std::string* error_id) {
  if (error_id != NULL) {
    set_has_error_id();
  } else {
    clear_has_error_id();
  }
  error_id_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), error_id);
  // @@protoc_insertion_point(field_set_allocated:exec.shared.DrillPBError.error_id)
}

// optional .exec.DrillbitEndpoint endpoint = 2;
inline bool DrillPBError::has_endpoint() const {
  return (_has_bits_[0] & 0x00000004u) != 0;
}
inline void DrillPBError::set_has_endpoint() {
  _has_bits_[0] |= 0x00000004u;
}
inline void DrillPBError::clear_has_endpoint() {
  _has_bits_[0] &= ~0x00000004u;
}
inline const ::exec::DrillbitEndpoint& DrillPBError::_internal_endpoint() const {
  return *endpoint_;
}
inline const ::exec::DrillbitEndpoint& DrillPBError::endpoint() const {
  const ::exec::DrillbitEndpoint* p = endpoint_;
  // @@protoc_insertion_point(field_get:exec.shared.DrillPBError.endpoint)
  return p != NULL ? *p : *reinterpret_cast<const ::exec::DrillbitEndpoint*>(
      &::exec::_DrillbitEndpoint_default_instance_);
}
inline ::exec::DrillbitEndpoint* DrillPBError::release_endpoint() {
  // @@protoc_insertion_point(field_release:exec.shared.DrillPBError.endpoint)
  clear_has_endpoint();
  ::exec::DrillbitEndpoint* temp = endpoint_;
  endpoint_ = NULL;
  return temp;
}
inline ::exec::DrillbitEndpoint* DrillPBError::mutable_endpoint() {
  set_has_endpoint();
  if (endpoint_ == NULL) {
    auto* p = CreateMaybeMessage<::exec::DrillbitEndpoint>(GetArenaNoVirtual());
    endpoint_ = p;
  }
  // @@protoc_insertion_point(field_mutable:exec.shared.DrillPBError.endpoint)
  return endpoint_;
}
inline void DrillPBError::set_allocated_endpoint(::exec::DrillbitEndpoint* endpoint) {
  ::google::protobuf::Arena* message_arena = GetArenaNoVirtual();
  if (message_arena == NULL) {
    delete reinterpret_cast< ::google::protobuf::MessageLite*>(endpoint_);
  }
  if (endpoint) {
    ::google::protobuf::Arena* submessage_arena = NULL;
    if (message_arena != submessage_arena) {
      endpoint = ::google::protobuf::internal::GetOwnedMessage(
          message_arena, endpoint, submessage_arena);
    }
    set_has_endpoint();
  } else {
    clear_has_endpoint();
  }
  endpoint_ = endpoint;
  // @@protoc_insertion_point(field_set_allocated:exec.shared.DrillPBError.endpoint)
}

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

// optional string message = 4;
inline bool DrillPBError::has_message() const {
  return (_has_bits_[0] & 0x00000002u) != 0;
}
inline void DrillPBError::set_has_message() {
  _has_bits_[0] |= 0x00000002u;
}
inline void DrillPBError::clear_has_message() {
  _has_bits_[0] &= ~0x00000002u;
}
inline void DrillPBError::clear_message() {
  message_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  clear_has_message();
}
inline const ::std::string& DrillPBError::message() const {
  // @@protoc_insertion_point(field_get:exec.shared.DrillPBError.message)
  return message_.GetNoArena();
}
inline void DrillPBError::set_message(const ::std::string& value) {
  set_has_message();
  message_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
  // @@protoc_insertion_point(field_set:exec.shared.DrillPBError.message)
}
#if LANG_CXX11
inline void DrillPBError::set_message(::std::string&& value) {
  set_has_message();
  message_.SetNoArena(
    &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
  // @@protoc_insertion_point(field_set_rvalue:exec.shared.DrillPBError.message)
}
#endif
inline void DrillPBError::set_message(const char* value) {
  GOOGLE_DCHECK(value != NULL);
  set_has_message();
  message_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
  // @@protoc_insertion_point(field_set_char:exec.shared.DrillPBError.message)
}
inline void DrillPBError::set_message(const char* value, size_t size) {
  set_has_message();
  message_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
      ::std::string(reinterpret_cast<const char*>(value), size));
  // @@protoc_insertion_point(field_set_pointer:exec.shared.DrillPBError.message)
}
inline ::std::string* DrillPBError::mutable_message() {
  set_has_message();
  // @@protoc_insertion_point(field_mutable:exec.shared.DrillPBError.message)
  return message_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline ::std::string* DrillPBError::release_message() {
  // @@protoc_insertion_point(field_release:exec.shared.DrillPBError.message)
  if (!has_message()) {
    return NULL;
  }
  clear_has_message();
  return message_.ReleaseNonDefaultNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline void DrillPBError::set_allocated_message(::std::string* message) {
  if (message != NULL) {
    set_has_message();
  } else {
    clear_has_message();
  }
  message_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), message);
  // @@protoc_insertion_point(field_set_allocated:exec.shared.DrillPBError.message)
}

// optional .exec.shared.ExceptionWrapper exception = 5;
inline bool DrillPBError::has_exception() const {
  return (_has_bits_[0] & 0x00000008u) != 0;
}
inline void DrillPBError::set_has_exception() {
  _has_bits_[0] |= 0x00000008u;
}
inline void DrillPBError::clear_has_exception() {
  _has_bits_[0] &= ~0x00000008u;
}
inline void DrillPBError::clear_exception() {
  if (exception_ != NULL) exception_->Clear();
  clear_has_exception();
}
inline const ::exec::shared::ExceptionWrapper& DrillPBError::_internal_exception() const {
  return *exception_;
}
inline const ::exec::shared::ExceptionWrapper& DrillPBError::exception() const {
  const ::exec::shared::ExceptionWrapper* p = exception_;
  // @@protoc_insertion_point(field_get:exec.shared.DrillPBError.exception)
  return p != NULL ? *p : *reinterpret_cast<const ::exec::shared::ExceptionWrapper*>(
      &::exec::shared::_ExceptionWrapper_default_instance_);
}
inline ::exec::shared::ExceptionWrapper* DrillPBError::release_exception() {
  // @@protoc_insertion_point(field_release:exec.shared.DrillPBError.exception)
  clear_has_exception();
  ::exec::shared::ExceptionWrapper* temp = exception_;
  exception_ = NULL;
  return temp;
}
inline ::exec::shared::ExceptionWrapper* DrillPBError::mutable_exception() {
  set_has_exception();
  if (exception_ == NULL) {
    auto* p = CreateMaybeMessage<::exec::shared::ExceptionWrapper>(GetArenaNoVirtual());
    exception_ = p;
  }
  // @@protoc_insertion_point(field_mutable:exec.shared.DrillPBError.exception)
  return exception_;
}
inline void DrillPBError::set_allocated_exception(::exec::shared::ExceptionWrapper* exception) {
  ::google::protobuf::Arena* message_arena = GetArenaNoVirtual();
  if (message_arena == NULL) {
    delete exception_;
  }
  if (exception) {
    ::google::protobuf::Arena* submessage_arena = NULL;
    if (message_arena != submessage_arena) {
      exception = ::google::protobuf::internal::GetOwnedMessage(
          message_arena, exception, submessage_arena);
    }
    set_has_exception();
  } else {
    clear_has_exception();
  }
  exception_ = exception;
  // @@protoc_insertion_point(field_set_allocated:exec.shared.DrillPBError.exception)
}

// repeated .exec.shared.ParsingError parsing_error = 6;
inline int DrillPBError::parsing_error_size() const {
  return 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 ::google::protobuf::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::parsing_error(int index) const {
  // @@protoc_insertion_point(field_get:exec.shared.DrillPBError.parsing_error)
  return parsing_error_.Get(index);
}
inline ::exec::shared::ParsingError* DrillPBError::add_parsing_error() {
  // @@protoc_insertion_point(field_add:exec.shared.DrillPBError.parsing_error)
  return parsing_error_.Add();
}
inline const ::google::protobuf::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::has_exception_class() const {
  return (_has_bits_[0] & 0x00000001u) != 0;
}
inline void ExceptionWrapper::set_has_exception_class() {
  _has_bits_[0] |= 0x00000001u;
}
inline void ExceptionWrapper::clear_has_exception_class() {
  _has_bits_[0] &= ~0x00000001u;
}
inline void ExceptionWrapper::clear_exception_class() {
  exception_class_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  clear_has_exception_class();
}
inline const ::std::string& ExceptionWrapper::exception_class() const {
  // @@protoc_insertion_point(field_get:exec.shared.ExceptionWrapper.exception_class)
  return exception_class_.GetNoArena();
}
inline void ExceptionWrapper::set_exception_class(const ::std::string& value) {
  set_has_exception_class();
  exception_class_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
  // @@protoc_insertion_point(field_set:exec.shared.ExceptionWrapper.exception_class)
}
#if LANG_CXX11
inline void ExceptionWrapper::set_exception_class(::std::string&& value) {
  set_has_exception_class();
  exception_class_.SetNoArena(
    &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
  // @@protoc_insertion_point(field_set_rvalue:exec.shared.ExceptionWrapper.exception_class)
}
#endif
inline void ExceptionWrapper::set_exception_class(const char* value) {
  GOOGLE_DCHECK(value != NULL);
  set_has_exception_class();
  exception_class_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
  // @@protoc_insertion_point(field_set_char:exec.shared.ExceptionWrapper.exception_class)
}
inline void ExceptionWrapper::set_exception_class(const char* value, size_t size) {
  set_has_exception_class();
  exception_class_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
      ::std::string(reinterpret_cast<const char*>(value), size));
  // @@protoc_insertion_point(field_set_pointer:exec.shared.ExceptionWrapper.exception_class)
}
inline ::std::string* ExceptionWrapper::mutable_exception_class() {
  set_has_exception_class();
  // @@protoc_insertion_point(field_mutable:exec.shared.ExceptionWrapper.exception_class)
  return exception_class_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline ::std::string* ExceptionWrapper::release_exception_class() {
  // @@protoc_insertion_point(field_release:exec.shared.ExceptionWrapper.exception_class)
  if (!has_exception_class()) {
    return NULL;
  }
  clear_has_exception_class();
  return exception_class_.ReleaseNonDefaultNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline void ExceptionWrapper::set_allocated_exception_class(::std::string* exception_class) {
  if (exception_class != NULL) {
    set_has_exception_class();
  } else {
    clear_has_exception_class();
  }
  exception_class_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), exception_class);
  // @@protoc_insertion_point(field_set_allocated:exec.shared.ExceptionWrapper.exception_class)
}

// optional string message = 2;
inline bool ExceptionWrapper::has_message() const {
  return (_has_bits_[0] & 0x00000002u) != 0;
}
inline void ExceptionWrapper::set_has_message() {
  _has_bits_[0] |= 0x00000002u;
}
inline void ExceptionWrapper::clear_has_message() {
  _has_bits_[0] &= ~0x00000002u;
}
inline void ExceptionWrapper::clear_message() {
  message_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  clear_has_message();
}
inline const ::std::string& ExceptionWrapper::message() const {
  // @@protoc_insertion_point(field_get:exec.shared.ExceptionWrapper.message)
  return message_.GetNoArena();
}
inline void ExceptionWrapper::set_message(const ::std::string& value) {
  set_has_message();
  message_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
  // @@protoc_insertion_point(field_set:exec.shared.ExceptionWrapper.message)
}
#if LANG_CXX11
inline void ExceptionWrapper::set_message(::std::string&& value) {
  set_has_message();
  message_.SetNoArena(
    &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
  // @@protoc_insertion_point(field_set_rvalue:exec.shared.ExceptionWrapper.message)
}
#endif
inline void ExceptionWrapper::set_message(const char* value) {
  GOOGLE_DCHECK(value != NULL);
  set_has_message();
  message_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
  // @@protoc_insertion_point(field_set_char:exec.shared.ExceptionWrapper.message)
}
inline void ExceptionWrapper::set_message(const char* value, size_t size) {
  set_has_message();
  message_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
      ::std::string(reinterpret_cast<const char*>(value), size));
  // @@protoc_insertion_point(field_set_pointer:exec.shared.ExceptionWrapper.message)
}
inline ::std::string* ExceptionWrapper::mutable_message() {
  set_has_message();
  // @@protoc_insertion_point(field_mutable:exec.shared.ExceptionWrapper.message)
  return message_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline ::std::string* ExceptionWrapper::release_message() {
  // @@protoc_insertion_point(field_release:exec.shared.ExceptionWrapper.message)
  if (!has_message()) {
    return NULL;
  }
  clear_has_message();
  return message_.ReleaseNonDefaultNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline void ExceptionWrapper::set_allocated_message(::std::string* message) {
  if (message != NULL) {
    set_has_message();
  } else {
    clear_has_message();
  }
  message_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), message);
  // @@protoc_insertion_point(field_set_allocated:exec.shared.ExceptionWrapper.message)
}

// repeated .exec.shared.StackTraceElementWrapper stack_trace = 3;
inline int ExceptionWrapper::stack_trace_size() const {
  return 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 ::google::protobuf::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::stack_trace(int index) const {
  // @@protoc_insertion_point(field_get:exec.shared.ExceptionWrapper.stack_trace)
  return stack_trace_.Get(index);
}
inline ::exec::shared::StackTraceElementWrapper* ExceptionWrapper::add_stack_trace() {
  // @@protoc_insertion_point(field_add:exec.shared.ExceptionWrapper.stack_trace)
  return stack_trace_.Add();
}
inline const ::google::protobuf::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::has_cause() const {
  return (_has_bits_[0] & 0x00000004u) != 0;
}
inline void ExceptionWrapper::set_has_cause() {
  _has_bits_[0] |= 0x00000004u;
}
inline void ExceptionWrapper::clear_has_cause() {
  _has_bits_[0] &= ~0x00000004u;
}
inline void ExceptionWrapper::clear_cause() {
  if (cause_ != NULL) cause_->Clear();
  clear_has_cause();
}
inline const ::exec::shared::ExceptionWrapper& ExceptionWrapper::_internal_cause() const {
  return *cause_;
}
inline const ::exec::shared::ExceptionWrapper& ExceptionWrapper::cause() const {
  const ::exec::shared::ExceptionWrapper* p = cause_;
  // @@protoc_insertion_point(field_get:exec.shared.ExceptionWrapper.cause)
  return p != NULL ? *p : *reinterpret_cast<const ::exec::shared::ExceptionWrapper*>(
      &::exec::shared::_ExceptionWrapper_default_instance_);
}
inline ::exec::shared::ExceptionWrapper* ExceptionWrapper::release_cause() {
  // @@protoc_insertion_point(field_release:exec.shared.ExceptionWrapper.cause)
  clear_has_cause();
  ::exec::shared::ExceptionWrapper* temp = cause_;
  cause_ = NULL;
  return temp;
}
inline ::exec::shared::ExceptionWrapper* ExceptionWrapper::mutable_cause() {
  set_has_cause();
  if (cause_ == NULL) {
    auto* p = CreateMaybeMessage<::exec::shared::ExceptionWrapper>(GetArenaNoVirtual());
    cause_ = p;
  }
  // @@protoc_insertion_point(field_mutable:exec.shared.ExceptionWrapper.cause)
  return cause_;
}
inline void ExceptionWrapper::set_allocated_cause(::exec::shared::ExceptionWrapper* cause) {
  ::google::protobuf::Arena* message_arena = GetArenaNoVirtual();
  if (message_arena == NULL) {
    delete cause_;
  }
  if (cause) {
    ::google::protobuf::Arena* submessage_arena = NULL;
    if (message_arena != submessage_arena) {
      cause = ::google::protobuf::internal::GetOwnedMessage(
          message_arena, cause, submessage_arena);
    }
    set_has_cause();
  } else {
    clear_has_cause();
  }
  cause_ = cause;
  // @@protoc_insertion_point(field_set_allocated:exec.shared.ExceptionWrapper.cause)
}

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

// StackTraceElementWrapper

// optional string class_name = 1;
inline bool StackTraceElementWrapper::has_class_name() const {
  return (_has_bits_[0] & 0x00000001u) != 0;
}
inline void StackTraceElementWrapper::set_has_class_name() {
  _has_bits_[0] |= 0x00000001u;
}
inline void StackTraceElementWrapper::clear_has_class_name() {
  _has_bits_[0] &= ~0x00000001u;
}
inline void StackTraceElementWrapper::clear_class_name() {
  class_name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  clear_has_class_name();
}
inline const ::std::string& StackTraceElementWrapper::class_name() const {
  // @@protoc_insertion_point(field_get:exec.shared.StackTraceElementWrapper.class_name)
  return class_name_.GetNoArena();
}
inline void StackTraceElementWrapper::set_class_name(const ::std::string& value) {
  set_has_class_name();
  class_name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
  // @@protoc_insertion_point(field_set:exec.shared.StackTraceElementWrapper.class_name)
}
#if LANG_CXX11
inline void StackTraceElementWrapper::set_class_name(::std::string&& value) {
  set_has_class_name();
  class_name_.SetNoArena(
    &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
  // @@protoc_insertion_point(field_set_rvalue:exec.shared.StackTraceElementWrapper.class_name)
}
#endif
inline void StackTraceElementWrapper::set_class_name(const char* value) {
  GOOGLE_DCHECK(value != NULL);
  set_has_class_name();
  class_name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
  // @@protoc_insertion_point(field_set_char:exec.shared.StackTraceElementWrapper.class_name)
}
inline void StackTraceElementWrapper::set_class_name(const char* value, size_t size) {
  set_has_class_name();
  class_name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
      ::std::string(reinterpret_cast<const char*>(value), size));
  // @@protoc_insertion_point(field_set_pointer:exec.shared.StackTraceElementWrapper.class_name)
}
inline ::std::string* StackTraceElementWrapper::mutable_class_name() {
  set_has_class_name();
  // @@protoc_insertion_point(field_mutable:exec.shared.StackTraceElementWrapper.class_name)
  return class_name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline ::std::string* StackTraceElementWrapper::release_class_name() {
  // @@protoc_insertion_point(field_release:exec.shared.StackTraceElementWrapper.class_name)
  if (!has_class_name()) {
    return NULL;
  }
  clear_has_class_name();
  return class_name_.ReleaseNonDefaultNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline void StackTraceElementWrapper::set_allocated_class_name(::std::string* class_name) {
  if (class_name != NULL) {
    set_has_class_name();
  } else {
    clear_has_class_name();
  }
  class_name_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), class_name);
  // @@protoc_insertion_point(field_set_allocated:exec.shared.StackTraceElementWrapper.class_name)
}

// optional string file_name = 2;
inline bool StackTraceElementWrapper::has_file_name() const {
  return (_has_bits_[0] & 0x00000002u) != 0;
}
inline void StackTraceElementWrapper::set_has_file_name() {
  _has_bits_[0] |= 0x00000002u;
}
inline void StackTraceElementWrapper::clear_has_file_name() {
  _has_bits_[0] &= ~0x00000002u;
}
inline void StackTraceElementWrapper::clear_file_name() {
  file_name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  clear_has_file_name();
}
inline const ::std::string& StackTraceElementWrapper::file_name() const {
  // @@protoc_insertion_point(field_get:exec.shared.StackTraceElementWrapper.file_name)
  return file_name_.GetNoArena();
}
inline void StackTraceElementWrapper::set_file_name(const ::std::string& value) {
  set_has_file_name();
  file_name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
  // @@protoc_insertion_point(field_set:exec.shared.StackTraceElementWrapper.file_name)
}
#if LANG_CXX11
inline void StackTraceElementWrapper::set_file_name(::std::string&& value) {
  set_has_file_name();
  file_name_.SetNoArena(
    &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
  // @@protoc_insertion_point(field_set_rvalue:exec.shared.StackTraceElementWrapper.file_name)
}
#endif
inline void StackTraceElementWrapper::set_file_name(const char* value) {
  GOOGLE_DCHECK(value != NULL);
  set_has_file_name();
  file_name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
  // @@protoc_insertion_point(field_set_char:exec.shared.StackTraceElementWrapper.file_name)
}
inline void StackTraceElementWrapper::set_file_name(const char* value, size_t size) {
  set_has_file_name();
  file_name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
      ::std::string(reinterpret_cast<const char*>(value), size));
  // @@protoc_insertion_point(field_set_pointer:exec.shared.StackTraceElementWrapper.file_name)
}
inline ::std::string* StackTraceElementWrapper::mutable_file_name() {
  set_has_file_name();
  // @@protoc_insertion_point(field_mutable:exec.shared.StackTraceElementWrapper.file_name)
  return file_name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline ::std::string* StackTraceElementWrapper::release_file_name() {
  // @@protoc_insertion_point(field_release:exec.shared.StackTraceElementWrapper.file_name)
  if (!has_file_name()) {
    return NULL;
  }
  clear_has_file_name();
  return file_name_.ReleaseNonDefaultNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline void StackTraceElementWrapper::set_allocated_file_name(::std::string* file_name) {
  if (file_name != NULL) {
    set_has_file_name();
  } else {
    clear_has_file_name();
  }
  file_name_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), file_name);
  // @@protoc_insertion_point(field_set_allocated:exec.shared.StackTraceElementWrapper.file_name)
}

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

// optional string method_name = 4;
inline bool StackTraceElementWrapper::has_method_name() const {
  return (_has_bits_[0] & 0x00000004u) != 0;
}
inline void StackTraceElementWrapper::set_has_method_name() {
  _has_bits_[0] |= 0x00000004u;
}
inline void StackTraceElementWrapper::clear_has_method_name() {
  _has_bits_[0] &= ~0x00000004u;
}
inline void StackTraceElementWrapper::clear_method_name() {
  method_name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  clear_has_method_name();
}
inline const ::std::string& StackTraceElementWrapper::method_name() const {
  // @@protoc_insertion_point(field_get:exec.shared.StackTraceElementWrapper.method_name)
  return method_name_.GetNoArena();
}
inline void StackTraceElementWrapper::set_method_name(const ::std::string& value) {
  set_has_method_name();
  method_name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
  // @@protoc_insertion_point(field_set:exec.shared.StackTraceElementWrapper.method_name)
}
#if LANG_CXX11
inline void StackTraceElementWrapper::set_method_name(::std::string&& value) {
  set_has_method_name();
  method_name_.SetNoArena(
    &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
  // @@protoc_insertion_point(field_set_rvalue:exec.shared.StackTraceElementWrapper.method_name)
}
#endif
inline void StackTraceElementWrapper::set_method_name(const char* value) {
  GOOGLE_DCHECK(value != NULL);
  set_has_method_name();
  method_name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
  // @@protoc_insertion_point(field_set_char:exec.shared.StackTraceElementWrapper.method_name)
}
inline void StackTraceElementWrapper::set_method_name(const char* value, size_t size) {
  set_has_method_name();
  method_name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
      ::std::string(reinterpret_cast<const char*>(value), size));
  // @@protoc_insertion_point(field_set_pointer:exec.shared.StackTraceElementWrapper.method_name)
}
inline ::std::string* StackTraceElementWrapper::mutable_method_name() {
  set_has_method_name();
  // @@protoc_insertion_point(field_mutable:exec.shared.StackTraceElementWrapper.method_name)
  return method_name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline ::std::string* StackTraceElementWrapper::release_method_name() {
  // @@protoc_insertion_point(field_release:exec.shared.StackTraceElementWrapper.method_name)
  if (!has_method_name()) {
    return NULL;
  }
  clear_has_method_name();
  return method_name_.ReleaseNonDefaultNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline void StackTraceElementWrapper::set_allocated_method_name(::std::string* method_name) {
  if (method_name != NULL) {
    set_has_method_name();
  } else {
    clear_has_method_name();
  }
  method_name_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), method_name);
  // @@protoc_insertion_point(field_set_allocated:exec.shared.StackTraceElementWrapper.method_name)
}

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

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

// ParsingError

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

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

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

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

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

// RecordBatchDef

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

// repeated .exec.shared.SerializedField field = 2;
inline int RecordBatchDef::field_size() const {
  return 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 ::google::protobuf::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::field(int index) const {
  // @@protoc_insertion_point(field_get:exec.shared.RecordBatchDef.field)
  return field_.Get(index);
}
inline ::exec::shared::SerializedField* RecordBatchDef::add_field() {
  // @@protoc_insertion_point(field_add:exec.shared.RecordBatchDef.field)
  return field_.Add();
}
inline const ::google::protobuf::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::has_carries_two_byte_selection_vector() const {
  return (_has_bits_[0] & 0x00000002u) != 0;
}
inline void RecordBatchDef::set_has_carries_two_byte_selection_vector() {
  _has_bits_[0] |= 0x00000002u;
}
inline void RecordBatchDef::clear_has_carries_two_byte_selection_vector() {
  _has_bits_[0] &= ~0x00000002u;
}
inline void RecordBatchDef::clear_carries_two_byte_selection_vector() {
  carries_two_byte_selection_vector_ = false;
  clear_has_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 carries_two_byte_selection_vector_;
}
inline void RecordBatchDef::set_carries_two_byte_selection_vector(bool value) {
  set_has_carries_two_byte_selection_vector();
  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::has_affected_rows_count() const {
  return (_has_bits_[0] & 0x00000004u) != 0;
}
inline void RecordBatchDef::set_has_affected_rows_count() {
  _has_bits_[0] |= 0x00000004u;
}
inline void RecordBatchDef::clear_has_affected_rows_count() {
  _has_bits_[0] &= ~0x00000004u;
}
inline void RecordBatchDef::clear_affected_rows_count() {
  affected_rows_count_ = 0;
  clear_has_affected_rows_count();
}
inline ::google::protobuf::int32 RecordBatchDef::affected_rows_count() const {
  // @@protoc_insertion_point(field_get:exec.shared.RecordBatchDef.affected_rows_count)
  return affected_rows_count_;
}
inline void RecordBatchDef::set_affected_rows_count(::google::protobuf::int32 value) {
  set_has_affected_rows_count();
  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::has_type() const {
  return (_has_bits_[0] & 0x00000004u) != 0;
}
inline void NamePart::set_has_type() {
  _has_bits_[0] |= 0x00000004u;
}
inline void NamePart::clear_has_type() {
  _has_bits_[0] &= ~0x00000004u;
}
inline void NamePart::clear_type() {
  type_ = 0;
  clear_has_type();
}
inline ::exec::shared::NamePart_Type NamePart::type() const {
  // @@protoc_insertion_point(field_get:exec.shared.NamePart.type)
  return static_cast< ::exec::shared::NamePart_Type >(type_);
}
inline void NamePart::set_type(::exec::shared::NamePart_Type value) {
  assert(::exec::shared::NamePart_Type_IsValid(value));
  set_has_type();
  type_ = value;
  // @@protoc_insertion_point(field_set:exec.shared.NamePart.type)
}

// optional string name = 2;
inline bool NamePart::has_name() const {
  return (_has_bits_[0] & 0x00000001u) != 0;
}
inline void NamePart::set_has_name() {
  _has_bits_[0] |= 0x00000001u;
}
inline void NamePart::clear_has_name() {
  _has_bits_[0] &= ~0x00000001u;
}
inline void NamePart::clear_name() {
  name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  clear_has_name();
}
inline const ::std::string& NamePart::name() const {
  // @@protoc_insertion_point(field_get:exec.shared.NamePart.name)
  return name_.GetNoArena();
}
inline void NamePart::set_name(const ::std::string& value) {
  set_has_name();
  name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
  // @@protoc_insertion_point(field_set:exec.shared.NamePart.name)
}
#if LANG_CXX11
inline void NamePart::set_name(::std::string&& value) {
  set_has_name();
  name_.SetNoArena(
    &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
  // @@protoc_insertion_point(field_set_rvalue:exec.shared.NamePart.name)
}
#endif
inline void NamePart::set_name(const char* value) {
  GOOGLE_DCHECK(value != NULL);
  set_has_name();
  name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
  // @@protoc_insertion_point(field_set_char:exec.shared.NamePart.name)
}
inline void NamePart::set_name(const char* value, size_t size) {
  set_has_name();
  name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
      ::std::string(reinterpret_cast<const char*>(value), size));
  // @@protoc_insertion_point(field_set_pointer:exec.shared.NamePart.name)
}
inline ::std::string* NamePart::mutable_name() {
  set_has_name();
  // @@protoc_insertion_point(field_mutable:exec.shared.NamePart.name)
  return name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline ::std::string* NamePart::release_name() {
  // @@protoc_insertion_point(field_release:exec.shared.NamePart.name)
  if (!has_name()) {
    return NULL;
  }
  clear_has_name();
  return name_.ReleaseNonDefaultNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline void NamePart::set_allocated_name(::std::string* name) {
  if (name != NULL) {
    set_has_name();
  } else {
    clear_has_name();
  }
  name_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), name);
  // @@protoc_insertion_point(field_set_allocated:exec.shared.NamePart.name)
}

// optional .exec.shared.NamePart child = 3;
inline bool NamePart::has_child() const {
  return (_has_bits_[0] & 0x00000002u) != 0;
}
inline void NamePart::set_has_child() {
  _has_bits_[0] |= 0x00000002u;
}
inline void NamePart::clear_has_child() {
  _has_bits_[0] &= ~0x00000002u;
}
inline void NamePart::clear_child() {
  if (child_ != NULL) child_->Clear();
  clear_has_child();
}
inline const ::exec::shared::NamePart& NamePart::_internal_child() const {
  return *child_;
}
inline const ::exec::shared::NamePart& NamePart::child() const {
  const ::exec::shared::NamePart* p = child_;
  // @@protoc_insertion_point(field_get:exec.shared.NamePart.child)
  return p != NULL ? *p : *reinterpret_cast<const ::exec::shared::NamePart*>(
      &::exec::shared::_NamePart_default_instance_);
}
inline ::exec::shared::NamePart* NamePart::release_child() {
  // @@protoc_insertion_point(field_release:exec.shared.NamePart.child)
  clear_has_child();
  ::exec::shared::NamePart* temp = child_;
  child_ = NULL;
  return temp;
}
inline ::exec::shared::NamePart* NamePart::mutable_child() {
  set_has_child();
  if (child_ == NULL) {
    auto* p = CreateMaybeMessage<::exec::shared::NamePart>(GetArenaNoVirtual());
    child_ = p;
  }
  // @@protoc_insertion_point(field_mutable:exec.shared.NamePart.child)
  return child_;
}
inline void NamePart::set_allocated_child(::exec::shared::NamePart* child) {
  ::google::protobuf::Arena* message_arena = GetArenaNoVirtual();
  if (message_arena == NULL) {
    delete child_;
  }
  if (child) {
    ::google::protobuf::Arena* submessage_arena = NULL;
    if (message_arena != submessage_arena) {
      child = ::google::protobuf::internal::GetOwnedMessage(
          message_arena, child, submessage_arena);
    }
    set_has_child();
  } else {
    clear_has_child();
  }
  child_ = child;
  // @@protoc_insertion_point(field_set_allocated:exec.shared.NamePart.child)
}

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

// SerializedField

// optional .common.MajorType major_type = 1;
inline bool SerializedField::has_major_type() const {
  return (_has_bits_[0] & 0x00000001u) != 0;
}
inline void SerializedField::set_has_major_type() {
  _has_bits_[0] |= 0x00000001u;
}
inline void SerializedField::clear_has_major_type() {
  _has_bits_[0] &= ~0x00000001u;
}
inline const ::common::MajorType& SerializedField::_internal_major_type() const {
  return *major_type_;
}
inline const ::common::MajorType& SerializedField::major_type() const {
  const ::common::MajorType* p = major_type_;
  // @@protoc_insertion_point(field_get:exec.shared.SerializedField.major_type)
  return p != NULL ? *p : *reinterpret_cast<const ::common::MajorType*>(
      &::common::_MajorType_default_instance_);
}
inline ::common::MajorType* SerializedField::release_major_type() {
  // @@protoc_insertion_point(field_release:exec.shared.SerializedField.major_type)
  clear_has_major_type();
  ::common::MajorType* temp = major_type_;
  major_type_ = NULL;
  return temp;
}
inline ::common::MajorType* SerializedField::mutable_major_type() {
  set_has_major_type();
  if (major_type_ == NULL) {
    auto* p = CreateMaybeMessage<::common::MajorType>(GetArenaNoVirtual());
    major_type_ = p;
  }
  // @@protoc_insertion_point(field_mutable:exec.shared.SerializedField.major_type)
  return major_type_;
}
inline void SerializedField::set_allocated_major_type(::common::MajorType* major_type) {
  ::google::protobuf::Arena* message_arena = GetArenaNoVirtual();
  if (message_arena == NULL) {
    delete reinterpret_cast< ::google::protobuf::MessageLite*>(major_type_);
  }
  if (major_type) {
    ::google::protobuf::Arena* submessage_arena = NULL;
    if (message_arena != submessage_arena) {
      major_type = ::google::protobuf::internal::GetOwnedMessage(
          message_arena, major_type, submessage_arena);
    }
    set_has_major_type();
  } else {
    clear_has_major_type();
  }
  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::has_name_part() const {
  return (_has_bits_[0] & 0x00000002u) != 0;
}
inline void SerializedField::set_has_name_part() {
  _has_bits_[0] |= 0x00000002u;
}
inline void SerializedField::clear_has_name_part() {
  _has_bits_[0] &= ~0x00000002u;
}
inline void SerializedField::clear_name_part() {
  if (name_part_ != NULL) name_part_->Clear();
  clear_has_name_part();
}
inline const ::exec::shared::NamePart& SerializedField::_internal_name_part() const {
  return *name_part_;
}
inline const ::exec::shared::NamePart& SerializedField::name_part() const {
  const ::exec::shared::NamePart* p = name_part_;
  // @@protoc_insertion_point(field_get:exec.shared.SerializedField.name_part)
  return p != NULL ? *p : *reinterpret_cast<const ::exec::shared::NamePart*>(
      &::exec::shared::_NamePart_default_instance_);
}
inline ::exec::shared::NamePart* SerializedField::release_name_part() {
  // @@protoc_insertion_point(field_release:exec.shared.SerializedField.name_part)
  clear_has_name_part();
  ::exec::shared::NamePart* temp = name_part_;
  name_part_ = NULL;
  return temp;
}
inline ::exec::shared::NamePart* SerializedField::mutable_name_part() {
  set_has_name_part();
  if (name_part_ == NULL) {
    auto* p = CreateMaybeMessage<::exec::shared::NamePart>(GetArenaNoVirtual());
    name_part_ = p;
  }
  // @@protoc_insertion_point(field_mutable:exec.shared.SerializedField.name_part)
  return name_part_;
}
inline void SerializedField::set_allocated_name_part(::exec::shared::NamePart* name_part) {
  ::google::protobuf::Arena* message_arena = GetArenaNoVirtual();
  if (message_arena == NULL) {
    delete name_part_;
  }
  if (name_part) {
    ::google::protobuf::Arena* submessage_arena = NULL;
    if (message_arena != submessage_arena) {
      name_part = ::google::protobuf::internal::GetOwnedMessage(
          message_arena, name_part, submessage_arena);
    }
    set_has_name_part();
  } else {
    clear_has_name_part();
  }
  name_part_ = name_part;
  // @@protoc_insertion_point(field_set_allocated:exec.shared.SerializedField.name_part)
}

// repeated .exec.shared.SerializedField child = 3;
inline int SerializedField::child_size() const {
  return 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 ::google::protobuf::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::child(int index) const {
  // @@protoc_insertion_point(field_get:exec.shared.SerializedField.child)
  return child_.Get(index);
}
inline ::exec::shared::SerializedField* SerializedField::add_child() {
  // @@protoc_insertion_point(field_add:exec.shared.SerializedField.child)
  return child_.Add();
}
inline const ::google::protobuf::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::has_value_count() const {
  return (_has_bits_[0] & 0x00000004u) != 0;
}
inline void SerializedField::set_has_value_count() {
  _has_bits_[0] |= 0x00000004u;
}
inline void SerializedField::clear_has_value_count() {
  _has_bits_[0] &= ~0x00000004u;
}
inline void SerializedField::clear_value_count() {
  value_count_ = 0;
  clear_has_value_count();
}
inline ::google::protobuf::int32 SerializedField::value_count() const {
  // @@protoc_insertion_point(field_get:exec.shared.SerializedField.value_count)
  return value_count_;
}
inline void SerializedField::set_value_count(::google::protobuf::int32 value) {
  set_has_value_count();
  value_count_ = value;
  // @@protoc_insertion_point(field_set:exec.shared.SerializedField.value_count)
}

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

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

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

// NodeStatus

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

// optional int64 memory_footprint = 2;
inline bool NodeStatus::has_memory_footprint() const {
  return (_has_bits_[0] & 0x00000001u) != 0;
}
inline void NodeStatus::set_has_memory_footprint() {
  _has_bits_[0] |= 0x00000001u;
}
inline void NodeStatus::clear_has_memory_footprint() {
  _has_bits_[0] &= ~0x00000001u;
}
inline void NodeStatus::clear_memory_footprint() {
  memory_footprint_ = GOOGLE_LONGLONG(0);
  clear_has_memory_footprint();
}
inline ::google::protobuf::int64 NodeStatus::memory_footprint() const {
  // @@protoc_insertion_point(field_get:exec.shared.NodeStatus.memory_footprint)
  return memory_footprint_;
}
inline void NodeStatus::set_memory_footprint(::google::protobuf::int64 value) {
  set_has_memory_footprint();
  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::has_query_state() const {
  return (_has_bits_[0] & 0x00000002u) != 0;
}
inline void QueryResult::set_has_query_state() {
  _has_bits_[0] |= 0x00000002u;
}
inline void QueryResult::clear_has_query_state() {
  _has_bits_[0] &= ~0x00000002u;
}
inline void QueryResult::clear_query_state() {
  query_state_ = 0;
  clear_has_query_state();
}
inline ::exec::shared::QueryResult_QueryState QueryResult::query_state() const {
  // @@protoc_insertion_point(field_get:exec.shared.QueryResult.query_state)
  return static_cast< ::exec::shared::QueryResult_QueryState >(query_state_);
}
inline void QueryResult::set_query_state(::exec::shared::QueryResult_QueryState value) {
  assert(::exec::shared::QueryResult_QueryState_IsValid(value));
  set_has_query_state();
  query_state_ = value;
  // @@protoc_insertion_point(field_set:exec.shared.QueryResult.query_state)
}

// optional .exec.shared.QueryId query_id = 2;
inline bool QueryResult::has_query_id() const {
  return (_has_bits_[0] & 0x00000001u) != 0;
}
inline void QueryResult::set_has_query_id() {
  _has_bits_[0] |= 0x00000001u;
}
inline void QueryResult::clear_has_query_id() {
  _has_bits_[0] &= ~0x00000001u;
}
inline void QueryResult::clear_query_id() {
  if (query_id_ != NULL) query_id_->Clear();
  clear_has_query_id();
}
inline const ::exec::shared::QueryId& QueryResult::_internal_query_id() const {
  return *query_id_;
}
inline const ::exec::shared::QueryId& QueryResult::query_id() const {
  const ::exec::shared::QueryId* p = query_id_;
  // @@protoc_insertion_point(field_get:exec.shared.QueryResult.query_id)
  return p != NULL ? *p : *reinterpret_cast<const ::exec::shared::QueryId*>(
      &::exec::shared::_QueryId_default_instance_);
}
inline ::exec::shared::QueryId* QueryResult::release_query_id() {
  // @@protoc_insertion_point(field_release:exec.shared.QueryResult.query_id)
  clear_has_query_id();
  ::exec::shared::QueryId* temp = query_id_;
  query_id_ = NULL;
  return temp;
}
inline ::exec::shared::QueryId* QueryResult::mutable_query_id() {
  set_has_query_id();
  if (query_id_ == NULL) {
    auto* p = CreateMaybeMessage<::exec::shared::QueryId>(GetArenaNoVirtual());
    query_id_ = p;
  }
  // @@protoc_insertion_point(field_mutable:exec.shared.QueryResult.query_id)
  return query_id_;
}
inline void QueryResult::set_allocated_query_id(::exec::shared::QueryId* query_id) {
  ::google::protobuf::Arena* message_arena = GetArenaNoVirtual();
  if (message_arena == NULL) {
    delete query_id_;
  }
  if (query_id) {
    ::google::protobuf::Arena* submessage_arena = NULL;
    if (message_arena != submessage_arena) {
      query_id = ::google::protobuf::internal::GetOwnedMessage(
          message_arena, query_id, submessage_arena);
    }
    set_has_query_id();
  } else {
    clear_has_query_id();
  }
  query_id_ = query_id;
  // @@protoc_insertion_point(field_set_allocated:exec.shared.QueryResult.query_id)
}

// repeated .exec.shared.DrillPBError error = 3;
inline int QueryResult::error_size() const {
  return 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 ::google::protobuf::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::error(int index) const {
  // @@protoc_insertion_point(field_get:exec.shared.QueryResult.error)
  return error_.Get(index);
}
inline ::exec::shared::DrillPBError* QueryResult::add_error() {
  // @@protoc_insertion_point(field_add:exec.shared.QueryResult.error)
  return error_.Add();
}
inline const ::google::protobuf::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::has_query_id() const {
  return (_has_bits_[0] & 0x00000001u) != 0;
}
inline void QueryData::set_has_query_id() {
  _has_bits_[0] |= 0x00000001u;
}
inline void QueryData::clear_has_query_id() {
  _has_bits_[0] &= ~0x00000001u;
}
inline void QueryData::clear_query_id() {
  if (query_id_ != NULL) query_id_->Clear();
  clear_has_query_id();
}
inline const ::exec::shared::QueryId& QueryData::_internal_query_id() const {
  return *query_id_;
}
inline const ::exec::shared::QueryId& QueryData::query_id() const {
  const ::exec::shared::QueryId* p = query_id_;
  // @@protoc_insertion_point(field_get:exec.shared.QueryData.query_id)
  return p != NULL ? *p : *reinterpret_cast<const ::exec::shared::QueryId*>(
      &::exec::shared::_QueryId_default_instance_);
}
inline ::exec::shared::QueryId* QueryData::release_query_id() {
  // @@protoc_insertion_point(field_release:exec.shared.QueryData.query_id)
  clear_has_query_id();
  ::exec::shared::QueryId* temp = query_id_;
  query_id_ = NULL;
  return temp;
}
inline ::exec::shared::QueryId* QueryData::mutable_query_id() {
  set_has_query_id();
  if (query_id_ == NULL) {
    auto* p = CreateMaybeMessage<::exec::shared::QueryId>(GetArenaNoVirtual());
    query_id_ = p;
  }
  // @@protoc_insertion_point(field_mutable:exec.shared.QueryData.query_id)
  return query_id_;
}
inline void QueryData::set_allocated_query_id(::exec::shared::QueryId* query_id) {
  ::google::protobuf::Arena* message_arena = GetArenaNoVirtual();
  if (message_arena == NULL) {
    delete query_id_;
  }
  if (query_id) {
    ::google::protobuf::Arena* submessage_arena = NULL;
    if (message_arena != submessage_arena) {
      query_id = ::google::protobuf::internal::GetOwnedMessage(
          message_arena, query_id, submessage_arena);
    }
    set_has_query_id();
  } else {
    clear_has_query_id();
  }
  query_id_ = query_id;
  // @@protoc_insertion_point(field_set_allocated:exec.shared.QueryData.query_id)
}

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

// optional .exec.shared.RecordBatchDef def = 3;
inline bool QueryData::has_def() const {
  return (_has_bits_[0] & 0x00000002u) != 0;
}
inline void QueryData::set_has_def() {
  _has_bits_[0] |= 0x00000002u;
}
inline void QueryData::clear_has_def() {
  _has_bits_[0] &= ~0x00000002u;
}
inline void QueryData::clear_def() {
  if (def_ != NULL) def_->Clear();
  clear_has_def();
}
inline const ::exec::shared::RecordBatchDef& QueryData::_internal_def() const {
  return *def_;
}
inline const ::exec::shared::RecordBatchDef& QueryData::def() const {
  const ::exec::shared::RecordBatchDef* p = def_;
  // @@protoc_insertion_point(field_get:exec.shared.QueryData.def)
  return p != NULL ? *p : *reinterpret_cast<const ::exec::shared::RecordBatchDef*>(
      &::exec::shared::_RecordBatchDef_default_instance_);
}
inline ::exec::shared::RecordBatchDef* QueryData::release_def() {
  // @@protoc_insertion_point(field_release:exec.shared.QueryData.def)
  clear_has_def();
  ::exec::shared::RecordBatchDef* temp = def_;
  def_ = NULL;
  return temp;
}
inline ::exec::shared::RecordBatchDef* QueryData::mutable_def() {
  set_has_def();
  if (def_ == NULL) {
    auto* p = CreateMaybeMessage<::exec::shared::RecordBatchDef>(GetArenaNoVirtual());
    def_ = p;
  }
  // @@protoc_insertion_point(field_mutable:exec.shared.QueryData.def)
  return def_;
}
inline void QueryData::set_allocated_def(::exec::shared::RecordBatchDef* def) {
  ::google::protobuf::Arena* message_arena = GetArenaNoVirtual();
  if (message_arena == NULL) {
    delete def_;
  }
  if (def) {
    ::google::protobuf::Arena* submessage_arena = NULL;
    if (message_arena != submessage_arena) {
      def = ::google::protobuf::internal::GetOwnedMessage(
          message_arena, def, submessage_arena);
    }
    set_has_def();
  } else {
    clear_has_def();
  }
  def_ = def;
  // @@protoc_insertion_point(field_set_allocated:exec.shared.QueryData.def)
}

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

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

// QueryInfo

// optional string query = 1;
inline bool QueryInfo::has_query() const {
  return (_has_bits_[0] & 0x00000001u) != 0;
}
inline void QueryInfo::set_has_query() {
  _has_bits_[0] |= 0x00000001u;
}
inline void QueryInfo::clear_has_query() {
  _has_bits_[0] &= ~0x00000001u;
}
inline void QueryInfo::clear_query() {
  query_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  clear_has_query();
}
inline const ::std::string& QueryInfo::query() const {
  // @@protoc_insertion_point(field_get:exec.shared.QueryInfo.query)
  return query_.GetNoArena();
}
inline void QueryInfo::set_query(const ::std::string& value) {
  set_has_query();
  query_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
  // @@protoc_insertion_point(field_set:exec.shared.QueryInfo.query)
}
#if LANG_CXX11
inline void QueryInfo::set_query(::std::string&& value) {
  set_has_query();
  query_.SetNoArena(
    &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
  // @@protoc_insertion_point(field_set_rvalue:exec.shared.QueryInfo.query)
}
#endif
inline void QueryInfo::set_query(const char* value) {
  GOOGLE_DCHECK(value != NULL);
  set_has_query();
  query_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
  // @@protoc_insertion_point(field_set_char:exec.shared.QueryInfo.query)
}
inline void QueryInfo::set_query(const char* value, size_t size) {
  set_has_query();
  query_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
      ::std::string(reinterpret_cast<const char*>(value), size));
  // @@protoc_insertion_point(field_set_pointer:exec.shared.QueryInfo.query)
}
inline ::std::string* QueryInfo::mutable_query() {
  set_has_query();
  // @@protoc_insertion_point(field_mutable:exec.shared.QueryInfo.query)
  return query_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline ::std::string* QueryInfo::release_query() {
  // @@protoc_insertion_point(field_release:exec.shared.QueryInfo.query)
  if (!has_query()) {
    return NULL;
  }
  clear_has_query();
  return query_.ReleaseNonDefaultNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline void QueryInfo::set_allocated_query(::std::string* query) {
  if (query != NULL) {
    set_has_query();
  } else {
    clear_has_query();
  }
  query_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), query);
  // @@protoc_insertion_point(field_set_allocated:exec.shared.QueryInfo.query)
}

// optional int64 start = 2;
inline bool QueryInfo::has_start() const {
  return (_has_bits_[0] & 0x00000020u) != 0;
}
inline void QueryInfo::set_has_start() {
  _has_bits_[0] |= 0x00000020u;
}
inline void QueryInfo::clear_has_start() {
  _has_bits_[0] &= ~0x00000020u;
}
inline void QueryInfo::clear_start() {
  start_ = GOOGLE_LONGLONG(0);
  clear_has_start();
}
inline ::google::protobuf::int64 QueryInfo::start() const {
  // @@protoc_insertion_point(field_get:exec.shared.QueryInfo.start)
  return start_;
}
inline void QueryInfo::set_start(::google::protobuf::int64 value) {
  set_has_start();
  start_ = value;
  // @@protoc_insertion_point(field_set:exec.shared.QueryInfo.start)
}

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

// optional string user = 4 [default = "-"];
inline bool QueryInfo::has_user() const {
  return (_has_bits_[0] & 0x00000002u) != 0;
}
inline void QueryInfo::set_has_user() {
  _has_bits_[0] |= 0x00000002u;
}
inline void QueryInfo::clear_has_user() {
  _has_bits_[0] &= ~0x00000002u;
}
inline void QueryInfo::clear_user() {
  user_.ClearToDefaultNoArena(&::exec::shared::QueryInfo::_i_give_permission_to_break_this_code_default_user_.get());
  clear_has_user();
}
inline const ::std::string& QueryInfo::user() const {
  // @@protoc_insertion_point(field_get:exec.shared.QueryInfo.user)
  return user_.GetNoArena();
}
inline void QueryInfo::set_user(const ::std::string& value) {
  set_has_user();
  user_.SetNoArena(&::exec::shared::QueryInfo::_i_give_permission_to_break_this_code_default_user_.get(), value);
  // @@protoc_insertion_point(field_set:exec.shared.QueryInfo.user)
}
#if LANG_CXX11
inline void QueryInfo::set_user(::std::string&& value) {
  set_has_user();
  user_.SetNoArena(
    &::exec::shared::QueryInfo::_i_give_permission_to_break_this_code_default_user_.get(), ::std::move(value));
  // @@protoc_insertion_point(field_set_rvalue:exec.shared.QueryInfo.user)
}
#endif
inline void QueryInfo::set_user(const char* value) {
  GOOGLE_DCHECK(value != NULL);
  set_has_user();
  user_.SetNoArena(&::exec::shared::QueryInfo::_i_give_permission_to_break_this_code_default_user_.get(), ::std::string(value));
  // @@protoc_insertion_point(field_set_char:exec.shared.QueryInfo.user)
}
inline void QueryInfo::set_user(const char* value, size_t size) {
  set_has_user();
  user_.SetNoArena(&::exec::shared::QueryInfo::_i_give_permission_to_break_this_code_default_user_.get(),
      ::std::string(reinterpret_cast<const char*>(value), size));
  // @@protoc_insertion_point(field_set_pointer:exec.shared.QueryInfo.user)
}
inline ::std::string* QueryInfo::mutable_user() {
  set_has_user();
  // @@protoc_insertion_point(field_mutable:exec.shared.QueryInfo.user)
  return user_.MutableNoArena(&::exec::shared::QueryInfo::_i_give_permission_to_break_this_code_default_user_.get());
}
inline ::std::string* QueryInfo::release_user() {
  // @@protoc_insertion_point(field_release:exec.shared.QueryInfo.user)
  if (!has_user()) {
    return NULL;
  }
  clear_has_user();
  return user_.ReleaseNonDefaultNoArena(&::exec::shared::QueryInfo::_i_give_permission_to_break_this_code_default_user_.get());
}
inline void QueryInfo::set_allocated_user(::std::string* user) {
  if (user != NULL) {
    set_has_user();
  } else {
    clear_has_user();
  }
  user_.SetAllocatedNoArena(&::exec::shared::QueryInfo::_i_give_permission_to_break_this_code_default_user_.get(), user);
  // @@protoc_insertion_point(field_set_allocated:exec.shared.QueryInfo.user)
}

// optional .exec.DrillbitEndpoint foreman = 5;
inline bool QueryInfo::has_foreman() const {
  return (_has_bits_[0] & 0x00000010u) != 0;
}
inline void QueryInfo::set_has_foreman() {
  _has_bits_[0] |= 0x00000010u;
}
inline void QueryInfo::clear_has_foreman() {
  _has_bits_[0] &= ~0x00000010u;
}
inline const ::exec::DrillbitEndpoint& QueryInfo::_internal_foreman() const {
  return *foreman_;
}
inline const ::exec::DrillbitEndpoint& QueryInfo::foreman() const {
  const ::exec::DrillbitEndpoint* p = foreman_;
  // @@protoc_insertion_point(field_get:exec.shared.QueryInfo.foreman)
  return p != NULL ? *p : *reinterpret_cast<const ::exec::DrillbitEndpoint*>(
      &::exec::_DrillbitEndpoint_default_instance_);
}
inline ::exec::DrillbitEndpoint* QueryInfo::release_foreman() {
  // @@protoc_insertion_point(field_release:exec.shared.QueryInfo.foreman)
  clear_has_foreman();
  ::exec::DrillbitEndpoint* temp = foreman_;
  foreman_ = NULL;
  return temp;
}
inline ::exec::DrillbitEndpoint* QueryInfo::mutable_foreman() {
  set_has_foreman();
  if (foreman_ == NULL) {
    auto* p = CreateMaybeMessage<::exec::DrillbitEndpoint>(GetArenaNoVirtual());
    foreman_ = p;
  }
  // @@protoc_insertion_point(field_mutable:exec.shared.QueryInfo.foreman)
  return foreman_;
}
inline void QueryInfo::set_allocated_foreman(::exec::DrillbitEndpoint* foreman) {
  ::google::protobuf::Arena* message_arena = GetArenaNoVirtual();
  if (message_arena == NULL) {
    delete reinterpret_cast< ::google::protobuf::MessageLite*>(foreman_);
  }
  if (foreman) {
    ::google::protobuf::Arena* submessage_arena = NULL;
    if (message_arena != submessage_arena) {
      foreman = ::google::protobuf::internal::GetOwnedMessage(
          message_arena, foreman, submessage_arena);
    }
    set_has_foreman();
  } else {
    clear_has_foreman();
  }
  foreman_ = foreman;
  // @@protoc_insertion_point(field_set_allocated:exec.shared.QueryInfo.foreman)
}

// optional string options_json = 6;
inline bool QueryInfo::has_options_json() const {
  return (_has_bits_[0] & 0x00000004u) != 0;
}
inline void QueryInfo::set_has_options_json() {
  _has_bits_[0] |= 0x00000004u;
}
inline void QueryInfo::clear_has_options_json() {
  _has_bits_[0] &= ~0x00000004u;
}
inline void QueryInfo::clear_options_json() {
  options_json_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  clear_has_options_json();
}
inline const ::std::string& QueryInfo::options_json() const {
  // @@protoc_insertion_point(field_get:exec.shared.QueryInfo.options_json)
  return options_json_.GetNoArena();
}
inline void QueryInfo::set_options_json(const ::std::string& value) {
  set_has_options_json();
  options_json_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
  // @@protoc_insertion_point(field_set:exec.shared.QueryInfo.options_json)
}
#if LANG_CXX11
inline void QueryInfo::set_options_json(::std::string&& value) {
  set_has_options_json();
  options_json_.SetNoArena(
    &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
  // @@protoc_insertion_point(field_set_rvalue:exec.shared.QueryInfo.options_json)
}
#endif
inline void QueryInfo::set_options_json(const char* value) {
  GOOGLE_DCHECK(value != NULL);
  set_has_options_json();
  options_json_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
  // @@protoc_insertion_point(field_set_char:exec.shared.QueryInfo.options_json)
}
inline void QueryInfo::set_options_json(const char* value, size_t size) {
  set_has_options_json();
  options_json_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
      ::std::string(reinterpret_cast<const char*>(value), size));
  // @@protoc_insertion_point(field_set_pointer:exec.shared.QueryInfo.options_json)
}
inline ::std::string* QueryInfo::mutable_options_json() {
  set_has_options_json();
  // @@protoc_insertion_point(field_mutable:exec.shared.QueryInfo.options_json)
  return options_json_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline ::std::string* QueryInfo::release_options_json() {
  // @@protoc_insertion_point(field_release:exec.shared.QueryInfo.options_json)
  if (!has_options_json()) {
    return NULL;
  }
  clear_has_options_json();
  return options_json_.ReleaseNonDefaultNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline void QueryInfo::set_allocated_options_json(::std::string* options_json) {
  if (options_json != NULL) {
    set_has_options_json();
  } else {
    clear_has_options_json();
  }
  options_json_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), options_json);
  // @@protoc_insertion_point(field_set_allocated:exec.shared.QueryInfo.options_json)
}

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

// optional string queue_name = 8 [default = "-"];
inline bool QueryInfo::has_queue_name() const {
  return (_has_bits_[0] & 0x00000008u) != 0;
}
inline void QueryInfo::set_has_queue_name() {
  _has_bits_[0] |= 0x00000008u;
}
inline void QueryInfo::clear_has_queue_name() {
  _has_bits_[0] &= ~0x00000008u;
}
inline void QueryInfo::clear_queue_name() {
  queue_name_.ClearToDefaultNoArena(&::exec::shared::QueryInfo::_i_give_permission_to_break_this_code_default_queue_name_.get());
  clear_has_queue_name();
}
inline const ::std::string& QueryInfo::queue_name() const {
  // @@protoc_insertion_point(field_get:exec.shared.QueryInfo.queue_name)
  return queue_name_.GetNoArena();
}
inline void QueryInfo::set_queue_name(const ::std::string& value) {
  set_has_queue_name();
  queue_name_.SetNoArena(&::exec::shared::QueryInfo::_i_give_permission_to_break_this_code_default_queue_name_.get(), value);
  // @@protoc_insertion_point(field_set:exec.shared.QueryInfo.queue_name)
}
#if LANG_CXX11
inline void QueryInfo::set_queue_name(::std::string&& value) {
  set_has_queue_name();
  queue_name_.SetNoArena(
    &::exec::shared::QueryInfo::_i_give_permission_to_break_this_code_default_queue_name_.get(), ::std::move(value));
  // @@protoc_insertion_point(field_set_rvalue:exec.shared.QueryInfo.queue_name)
}
#endif
inline void QueryInfo::set_queue_name(const char* value) {
  GOOGLE_DCHECK(value != NULL);
  set_has_queue_name();
  queue_name_.SetNoArena(&::exec::shared::QueryInfo::_i_give_permission_to_break_this_code_default_queue_name_.get(), ::std::string(value));
  // @@protoc_insertion_point(field_set_char:exec.shared.QueryInfo.queue_name)
}
inline void QueryInfo::set_queue_name(const char* value, size_t size) {
  set_has_queue_name();
  queue_name_.SetNoArena(&::exec::shared::QueryInfo::_i_give_permission_to_break_this_code_default_queue_name_.get(),
      ::std::string(reinterpret_cast<const char*>(value), size));
  // @@protoc_insertion_point(field_set_pointer:exec.shared.QueryInfo.queue_name)
}
inline ::std::string* QueryInfo::mutable_queue_name() {
  set_has_queue_name();
  // @@protoc_insertion_point(field_mutable:exec.shared.QueryInfo.queue_name)
  return queue_name_.MutableNoArena(&::exec::shared::QueryInfo::_i_give_permission_to_break_this_code_default_queue_name_.get());
}
inline ::std::string* QueryInfo::release_queue_name() {
  // @@protoc_insertion_point(field_release:exec.shared.QueryInfo.queue_name)
  if (!has_queue_name()) {
    return NULL;
  }
  clear_has_queue_name();
  return queue_name_.ReleaseNonDefaultNoArena(&::exec::shared::QueryInfo::_i_give_permission_to_break_this_code_default_queue_name_.get());
}
inline void QueryInfo::set_allocated_queue_name(::std::string* queue_name) {
  if (queue_name != NULL) {
    set_has_queue_name();
  } else {
    clear_has_queue_name();
  }
  queue_name_.SetAllocatedNoArena(&::exec::shared::QueryInfo::_i_give_permission_to_break_this_code_default_queue_name_.get(), queue_name);
  // @@protoc_insertion_point(field_set_allocated:exec.shared.QueryInfo.queue_name)
}

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

// QueryProfile

// optional .exec.shared.QueryId id = 1;
inline bool QueryProfile::has_id() const {
  return (_has_bits_[0] & 0x00000400u) != 0;
}
inline void QueryProfile::set_has_id() {
  _has_bits_[0] |= 0x00000400u;
}
inline void QueryProfile::clear_has_id() {
  _has_bits_[0] &= ~0x00000400u;
}
inline void QueryProfile::clear_id() {
  if (id_ != NULL) id_->Clear();
  clear_has_id();
}
inline const ::exec::shared::QueryId& QueryProfile::_internal_id() const {
  return *id_;
}
inline const ::exec::shared::QueryId& QueryProfile::id() const {
  const ::exec::shared::QueryId* p = id_;
  // @@protoc_insertion_point(field_get:exec.shared.QueryProfile.id)
  return p != NULL ? *p : *reinterpret_cast<const ::exec::shared::QueryId*>(
      &::exec::shared::_QueryId_default_instance_);
}
inline ::exec::shared::QueryId* QueryProfile::release_id() {
  // @@protoc_insertion_point(field_release:exec.shared.QueryProfile.id)
  clear_has_id();
  ::exec::shared::QueryId* temp = id_;
  id_ = NULL;
  return temp;
}
inline ::exec::shared::QueryId* QueryProfile::mutable_id() {
  set_has_id();
  if (id_ == NULL) {
    auto* p = CreateMaybeMessage<::exec::shared::QueryId>(GetArenaNoVirtual());
    id_ = p;
  }
  // @@protoc_insertion_point(field_mutable:exec.shared.QueryProfile.id)
  return id_;
}
inline void QueryProfile::set_allocated_id(::exec::shared::QueryId* id) {
  ::google::protobuf::Arena* message_arena = GetArenaNoVirtual();
  if (message_arena == NULL) {
    delete id_;
  }
  if (id) {
    ::google::protobuf::Arena* submessage_arena = NULL;
    if (message_arena != submessage_arena) {
      id = ::google::protobuf::internal::GetOwnedMessage(
          message_arena, id, submessage_arena);
    }
    set_has_id();
  } else {
    clear_has_id();
  }
  id_ = id;
  // @@protoc_insertion_point(field_set_allocated:exec.shared.QueryProfile.id)
}

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

// optional int64 start = 3;
inline bool QueryProfile::has_start() const {
  return (_has_bits_[0] & 0x00001000u) != 0;
}
inline void QueryProfile::set_has_start() {
  _has_bits_[0] |= 0x00001000u;
}
inline void QueryProfile::clear_has_start() {
  _has_bits_[0] &= ~0x00001000u;
}
inline void QueryProfile::clear_start() {
  start_ = GOOGLE_LONGLONG(0);
  clear_has_start();
}
inline ::google::protobuf::int64 QueryProfile::start() const {
  // @@protoc_insertion_point(field_get:exec.shared.QueryProfile.start)
  return start_;
}
inline void QueryProfile::set_start(::google::protobuf::int64 value) {
  set_has_start();
  start_ = value;
  // @@protoc_insertion_point(field_set:exec.shared.QueryProfile.start)
}

// optional int64 end = 4;
inline bool QueryProfile::has_end() const {
  return (_has_bits_[0] & 0x00002000u) != 0;
}
inline void QueryProfile::set_has_end() {
  _has_bits_[0] |= 0x00002000u;
}
inline void QueryProfile::clear_has_end() {
  _has_bits_[0] &= ~0x00002000u;
}
inline void QueryProfile::clear_end() {
  end_ = GOOGLE_LONGLONG(0);
  clear_has_end();
}
inline ::google::protobuf::int64 QueryProfile::end() const {
  // @@protoc_insertion_point(field_get:exec.shared.QueryProfile.end)
  return end_;
}
inline void QueryProfile::set_end(::google::protobuf::int64 value) {
  set_has_end();
  end_ = value;
  // @@protoc_insertion_point(field_set:exec.shared.QueryProfile.end)
}

// optional string query = 5;
inline bool QueryProfile::has_query() const {
  return (_has_bits_[0] & 0x00000001u) != 0;
}
inline void QueryProfile::set_has_query() {
  _has_bits_[0] |= 0x00000001u;
}
inline void QueryProfile::clear_has_query() {
  _has_bits_[0] &= ~0x00000001u;
}
inline void QueryProfile::clear_query() {
  query_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  clear_has_query();
}
inline const ::std::string& QueryProfile::query() const {
  // @@protoc_insertion_point(field_get:exec.shared.QueryProfile.query)
  return query_.GetNoArena();
}
inline void QueryProfile::set_query(const ::std::string& value) {
  set_has_query();
  query_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
  // @@protoc_insertion_point(field_set:exec.shared.QueryProfile.query)
}
#if LANG_CXX11
inline void QueryProfile::set_query(::std::string&& value) {
  set_has_query();
  query_.SetNoArena(
    &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
  // @@protoc_insertion_point(field_set_rvalue:exec.shared.QueryProfile.query)
}
#endif
inline void QueryProfile::set_query(const char* value) {
  GOOGLE_DCHECK(value != NULL);
  set_has_query();
  query_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
  // @@protoc_insertion_point(field_set_char:exec.shared.QueryProfile.query)
}
inline void QueryProfile::set_query(const char* value, size_t size) {
  set_has_query();
  query_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
      ::std::string(reinterpret_cast<const char*>(value), size));
  // @@protoc_insertion_point(field_set_pointer:exec.shared.QueryProfile.query)
}
inline ::std::string* QueryProfile::mutable_query() {
  set_has_query();
  // @@protoc_insertion_point(field_mutable:exec.shared.QueryProfile.query)
  return query_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline ::std::string* QueryProfile::release_query() {
  // @@protoc_insertion_point(field_release:exec.shared.QueryProfile.query)
  if (!has_query()) {
    return NULL;
  }
  clear_has_query();
  return query_.ReleaseNonDefaultNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline void QueryProfile::set_allocated_query(::std::string* query) {
  if (query != NULL) {
    set_has_query();
  } else {
    clear_has_query();
  }
  query_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), query);
  // @@protoc_insertion_point(field_set_allocated:exec.shared.QueryProfile.query)
}

// optional string plan = 6;
inline bool QueryProfile::has_plan() const {
  return (_has_bits_[0] & 0x00000002u) != 0;
}
inline void QueryProfile::set_has_plan() {
  _has_bits_[0] |= 0x00000002u;
}
inline void QueryProfile::clear_has_plan() {
  _has_bits_[0] &= ~0x00000002u;
}
inline void QueryProfile::clear_plan() {
  plan_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  clear_has_plan();
}
inline const ::std::string& QueryProfile::plan() const {
  // @@protoc_insertion_point(field_get:exec.shared.QueryProfile.plan)
  return plan_.GetNoArena();
}
inline void QueryProfile::set_plan(const ::std::string& value) {
  set_has_plan();
  plan_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
  // @@protoc_insertion_point(field_set:exec.shared.QueryProfile.plan)
}
#if LANG_CXX11
inline void QueryProfile::set_plan(::std::string&& value) {
  set_has_plan();
  plan_.SetNoArena(
    &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
  // @@protoc_insertion_point(field_set_rvalue:exec.shared.QueryProfile.plan)
}
#endif
inline void QueryProfile::set_plan(const char* value) {
  GOOGLE_DCHECK(value != NULL);
  set_has_plan();
  plan_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
  // @@protoc_insertion_point(field_set_char:exec.shared.QueryProfile.plan)
}
inline void QueryProfile::set_plan(const char* value, size_t size) {
  set_has_plan();
  plan_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
      ::std::string(reinterpret_cast<const char*>(value), size));
  // @@protoc_insertion_point(field_set_pointer:exec.shared.QueryProfile.plan)
}
inline ::std::string* QueryProfile::mutable_plan() {
  set_has_plan();
  // @@protoc_insertion_point(field_mutable:exec.shared.QueryProfile.plan)
  return plan_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline ::std::string* QueryProfile::release_plan() {
  // @@protoc_insertion_point(field_release:exec.shared.QueryProfile.plan)
  if (!has_plan()) {
    return NULL;
  }
  clear_has_plan();
  return plan_.ReleaseNonDefaultNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline void QueryProfile::set_allocated_plan(::std::string* plan) {
  if (plan != NULL) {
    set_has_plan();
  } else {
    clear_has_plan();
  }
  plan_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), plan);
  // @@protoc_insertion_point(field_set_allocated:exec.shared.QueryProfile.plan)
}

// optional .exec.DrillbitEndpoint foreman = 7;
inline bool QueryProfile::has_foreman() const {
  return (_has_bits_[0] & 0x00000800u) != 0;
}
inline void QueryProfile::set_has_foreman() {
  _has_bits_[0] |= 0x00000800u;
}
inline void QueryProfile::clear_has_foreman() {
  _has_bits_[0] &= ~0x00000800u;
}
inline const ::exec::DrillbitEndpoint& QueryProfile::_internal_foreman() const {
  return *foreman_;
}
inline const ::exec::DrillbitEndpoint& QueryProfile::foreman() const {
  const ::exec::DrillbitEndpoint* p = foreman_;
  // @@protoc_insertion_point(field_get:exec.shared.QueryProfile.foreman)
  return p != NULL ? *p : *reinterpret_cast<const ::exec::DrillbitEndpoint*>(
      &::exec::_DrillbitEndpoint_default_instance_);
}
inline ::exec::DrillbitEndpoint* QueryProfile::release_foreman() {
  // @@protoc_insertion_point(field_release:exec.shared.QueryProfile.foreman)
  clear_has_foreman();
  ::exec::DrillbitEndpoint* temp = foreman_;
  foreman_ = NULL;
  return temp;
}
inline ::exec::DrillbitEndpoint* QueryProfile::mutable_foreman() {
  set_has_foreman();
  if (foreman_ == NULL) {
    auto* p = CreateMaybeMessage<::exec::DrillbitEndpoint>(GetArenaNoVirtual());
    foreman_ = p;
  }
  // @@protoc_insertion_point(field_mutable:exec.shared.QueryProfile.foreman)
  return foreman_;
}
inline void QueryProfile::set_allocated_foreman(::exec::DrillbitEndpoint* foreman) {
  ::google::protobuf::Arena* message_arena = GetArenaNoVirtual();
  if (message_arena == NULL) {
    delete reinterpret_cast< ::google::protobuf::MessageLite*>(foreman_);
  }
  if (foreman) {
    ::google::protobuf::Arena* submessage_arena = NULL;
    if (message_arena != submessage_arena) {
      foreman = ::google::protobuf::internal::GetOwnedMessage(
          message_arena, foreman, submessage_arena);
    }
    set_has_foreman();
  } else {
    clear_has_foreman();
  }
  foreman_ = foreman;
  // @@protoc_insertion_point(field_set_allocated:exec.shared.QueryProfile.foreman)
}

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

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

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

// repeated .exec.shared.MajorFragmentProfile fragment_profile = 11;
inline int QueryProfile::fragment_profile_size() const {
  return 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 ::google::protobuf::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::fragment_profile(int index) const {
  // @@protoc_insertion_point(field_get:exec.shared.QueryProfile.fragment_profile)
  return fragment_profile_.Get(index);
}
inline ::exec::shared::MajorFragmentProfile* QueryProfile::add_fragment_profile() {
  // @@protoc_insertion_point(field_add:exec.shared.QueryProfile.fragment_profile)
  return fragment_profile_.Add();
}
inline const ::google::protobuf::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::has_user() const {
  return (_has_bits_[0] & 0x00000004u) != 0;
}
inline void QueryProfile::set_has_user() {
  _has_bits_[0] |= 0x00000004u;
}
inline void QueryProfile::clear_has_user() {
  _has_bits_[0] &= ~0x00000004u;
}
inline void QueryProfile::clear_user() {
  user_.ClearToDefaultNoArena(&::exec::shared::QueryProfile::_i_give_permission_to_break_this_code_default_user_.get());
  clear_has_user();
}
inline const ::std::string& QueryProfile::user() const {
  // @@protoc_insertion_point(field_get:exec.shared.QueryProfile.user)
  return user_.GetNoArena();
}
inline void QueryProfile::set_user(const ::std::string& value) {
  set_has_user();
  user_.SetNoArena(&::exec::shared::QueryProfile::_i_give_permission_to_break_this_code_default_user_.get(), value);
  // @@protoc_insertion_point(field_set:exec.shared.QueryProfile.user)
}
#if LANG_CXX11
inline void QueryProfile::set_user(::std::string&& value) {
  set_has_user();
  user_.SetNoArena(
    &::exec::shared::QueryProfile::_i_give_permission_to_break_this_code_default_user_.get(), ::std::move(value));
  // @@protoc_insertion_point(field_set_rvalue:exec.shared.QueryProfile.user)
}
#endif
inline void QueryProfile::set_user(const char* value) {
  GOOGLE_DCHECK(value != NULL);
  set_has_user();
  user_.SetNoArena(&::exec::shared::QueryProfile::_i_give_permission_to_break_this_code_default_user_.get(), ::std::string(value));
  // @@protoc_insertion_point(field_set_char:exec.shared.QueryProfile.user)
}
inline void QueryProfile::set_user(const char* value, size_t size) {
  set_has_user();
  user_.SetNoArena(&::exec::shared::QueryProfile::_i_give_permission_to_break_this_code_default_user_.get(),
      ::std::string(reinterpret_cast<const char*>(value), size));
  // @@protoc_insertion_point(field_set_pointer:exec.shared.QueryProfile.user)
}
inline ::std::string* QueryProfile::mutable_user() {
  set_has_user();
  // @@protoc_insertion_point(field_mutable:exec.shared.QueryProfile.user)
  return user_.MutableNoArena(&::exec::shared::QueryProfile::_i_give_permission_to_break_this_code_default_user_.get());
}
inline ::std::string* QueryProfile::release_user() {
  // @@protoc_insertion_point(field_release:exec.shared.QueryProfile.user)
  if (!has_user()) {
    return NULL;
  }
  clear_has_user();
  return user_.ReleaseNonDefaultNoArena(&::exec::shared::QueryProfile::_i_give_permission_to_break_this_code_default_user_.get());
}
inline void QueryProfile::set_allocated_user(::std::string* user) {
  if (user != NULL) {
    set_has_user();
  } else {
    clear_has_user();
  }
  user_.SetAllocatedNoArena(&::exec::shared::QueryProfile::_i_give_permission_to_break_this_code_default_user_.get(), user);
  // @@protoc_insertion_point(field_set_allocated:exec.shared.QueryProfile.user)
}

// optional string error = 13;
inline bool QueryProfile::has_error() const {
  return (_has_bits_[0] & 0x00000008u) != 0;
}
inline void QueryProfile::set_has_error() {
  _has_bits_[0] |= 0x00000008u;
}
inline void QueryProfile::clear_has_error() {
  _has_bits_[0] &= ~0x00000008u;
}
inline void QueryProfile::clear_error() {
  error_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  clear_has_error();
}
inline const ::std::string& QueryProfile::error() const {
  // @@protoc_insertion_point(field_get:exec.shared.QueryProfile.error)
  return error_.GetNoArena();
}
inline void QueryProfile::set_error(const ::std::string& value) {
  set_has_error();
  error_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
  // @@protoc_insertion_point(field_set:exec.shared.QueryProfile.error)
}
#if LANG_CXX11
inline void QueryProfile::set_error(::std::string&& value) {
  set_has_error();
  error_.SetNoArena(
    &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
  // @@protoc_insertion_point(field_set_rvalue:exec.shared.QueryProfile.error)
}
#endif
inline void QueryProfile::set_error(const char* value) {
  GOOGLE_DCHECK(value != NULL);
  set_has_error();
  error_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
  // @@protoc_insertion_point(field_set_char:exec.shared.QueryProfile.error)
}
inline void QueryProfile::set_error(const char* value, size_t size) {
  set_has_error();
  error_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
      ::std::string(reinterpret_cast<const char*>(value), size));
  // @@protoc_insertion_point(field_set_pointer:exec.shared.QueryProfile.error)
}
inline ::std::string* QueryProfile::mutable_error() {
  set_has_error();
  // @@protoc_insertion_point(field_mutable:exec.shared.QueryProfile.error)
  return error_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline ::std::string* QueryProfile::release_error() {
  // @@protoc_insertion_point(field_release:exec.shared.QueryProfile.error)
  if (!has_error()) {
    return NULL;
  }
  clear_has_error();
  return error_.ReleaseNonDefaultNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline void QueryProfile::set_allocated_error(::std::string* error) {
  if (error != NULL) {
    set_has_error();
  } else {
    clear_has_error();
  }
  error_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), error);
  // @@protoc_insertion_point(field_set_allocated:exec.shared.QueryProfile.error)
}

// optional string verboseError = 14;
inline bool QueryProfile::has_verboseerror() const {
  return (_has_bits_[0] & 0x00000010u) != 0;
}
inline void QueryProfile::set_has_verboseerror() {
  _has_bits_[0] |= 0x00000010u;
}
inline void QueryProfile::clear_has_verboseerror() {
  _has_bits_[0] &= ~0x00000010u;
}
inline void QueryProfile::clear_verboseerror() {
  verboseerror_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  clear_has_verboseerror();
}
inline const ::std::string& QueryProfile::verboseerror() const {
  // @@protoc_insertion_point(field_get:exec.shared.QueryProfile.verboseError)
  return verboseerror_.GetNoArena();
}
inline void QueryProfile::set_verboseerror(const ::std::string& value) {
  set_has_verboseerror();
  verboseerror_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
  // @@protoc_insertion_point(field_set:exec.shared.QueryProfile.verboseError)
}
#if LANG_CXX11
inline void QueryProfile::set_verboseerror(::std::string&& value) {
  set_has_verboseerror();
  verboseerror_.SetNoArena(
    &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
  // @@protoc_insertion_point(field_set_rvalue:exec.shared.QueryProfile.verboseError)
}
#endif
inline void QueryProfile::set_verboseerror(const char* value) {
  GOOGLE_DCHECK(value != NULL);
  set_has_verboseerror();
  verboseerror_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
  // @@protoc_insertion_point(field_set_char:exec.shared.QueryProfile.verboseError)
}
inline void QueryProfile::set_verboseerror(const char* value, size_t size) {
  set_has_verboseerror();
  verboseerror_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
      ::std::string(reinterpret_cast<const char*>(value), size));
  // @@protoc_insertion_point(field_set_pointer:exec.shared.QueryProfile.verboseError)
}
inline ::std::string* QueryProfile::mutable_verboseerror() {
  set_has_verboseerror();
  // @@protoc_insertion_point(field_mutable:exec.shared.QueryProfile.verboseError)
  return verboseerror_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline ::std::string* QueryProfile::release_verboseerror() {
  // @@protoc_insertion_point(field_release:exec.shared.QueryProfile.verboseError)
  if (!has_verboseerror()) {
    return NULL;
  }
  clear_has_verboseerror();
  return verboseerror_.ReleaseNonDefaultNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline void QueryProfile::set_allocated_verboseerror(::std::string* verboseerror) {
  if (verboseerror != NULL) {
    set_has_verboseerror();
  } else {
    clear_has_verboseerror();
  }
  verboseerror_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), verboseerror);
  // @@protoc_insertion_point(field_set_allocated:exec.shared.QueryProfile.verboseError)
}

// optional string error_id = 15;
inline bool QueryProfile::has_error_id() const {
  return (_has_bits_[0] & 0x00000020u) != 0;
}
inline void QueryProfile::set_has_error_id() {
  _has_bits_[0] |= 0x00000020u;
}
inline void QueryProfile::clear_has_error_id() {
  _has_bits_[0] &= ~0x00000020u;
}
inline void QueryProfile::clear_error_id() {
  error_id_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  clear_has_error_id();
}
inline const ::std::string& QueryProfile::error_id() const {
  // @@protoc_insertion_point(field_get:exec.shared.QueryProfile.error_id)
  return error_id_.GetNoArena();
}
inline void QueryProfile::set_error_id(const ::std::string& value) {
  set_has_error_id();
  error_id_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
  // @@protoc_insertion_point(field_set:exec.shared.QueryProfile.error_id)
}
#if LANG_CXX11
inline void QueryProfile::set_error_id(::std::string&& value) {
  set_has_error_id();
  error_id_.SetNoArena(
    &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
  // @@protoc_insertion_point(field_set_rvalue:exec.shared.QueryProfile.error_id)
}
#endif
inline void QueryProfile::set_error_id(const char* value) {
  GOOGLE_DCHECK(value != NULL);
  set_has_error_id();
  error_id_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
  // @@protoc_insertion_point(field_set_char:exec.shared.QueryProfile.error_id)
}
inline void QueryProfile::set_error_id(const char* value, size_t size) {
  set_has_error_id();
  error_id_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
      ::std::string(reinterpret_cast<const char*>(value), size));
  // @@protoc_insertion_point(field_set_pointer:exec.shared.QueryProfile.error_id)
}
inline ::std::string* QueryProfile::mutable_error_id() {
  set_has_error_id();
  // @@protoc_insertion_point(field_mutable:exec.shared.QueryProfile.error_id)
  return error_id_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline ::std::string* QueryProfile::release_error_id() {
  // @@protoc_insertion_point(field_release:exec.shared.QueryProfile.error_id)
  if (!has_error_id()) {
    return NULL;
  }
  clear_has_error_id();
  return error_id_.ReleaseNonDefaultNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline void QueryProfile::set_allocated_error_id(::std::string* error_id) {
  if (error_id != NULL) {
    set_has_error_id();
  } else {
    clear_has_error_id();
  }
  error_id_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), error_id);
  // @@protoc_insertion_point(field_set_allocated:exec.shared.QueryProfile.error_id)
}

// optional string error_node = 16;
inline bool QueryProfile::has_error_node() const {
  return (_has_bits_[0] & 0x00000040u) != 0;
}
inline void QueryProfile::set_has_error_node() {
  _has_bits_[0] |= 0x00000040u;
}
inline void QueryProfile::clear_has_error_node() {
  _has_bits_[0] &= ~0x00000040u;
}
inline void QueryProfile::clear_error_node() {
  error_node_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  clear_has_error_node();
}
inline const ::std::string& QueryProfile::error_node() const {
  // @@protoc_insertion_point(field_get:exec.shared.QueryProfile.error_node)
  return error_node_.GetNoArena();
}
inline void QueryProfile::set_error_node(const ::std::string& value) {
  set_has_error_node();
  error_node_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
  // @@protoc_insertion_point(field_set:exec.shared.QueryProfile.error_node)
}
#if LANG_CXX11
inline void QueryProfile::set_error_node(::std::string&& value) {
  set_has_error_node();
  error_node_.SetNoArena(
    &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
  // @@protoc_insertion_point(field_set_rvalue:exec.shared.QueryProfile.error_node)
}
#endif
inline void QueryProfile::set_error_node(const char* value) {
  GOOGLE_DCHECK(value != NULL);
  set_has_error_node();
  error_node_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
  // @@protoc_insertion_point(field_set_char:exec.shared.QueryProfile.error_node)
}
inline void QueryProfile::set_error_node(const char* value, size_t size) {
  set_has_error_node();
  error_node_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
      ::std::string(reinterpret_cast<const char*>(value), size));
  // @@protoc_insertion_point(field_set_pointer:exec.shared.QueryProfile.error_node)
}
inline ::std::string* QueryProfile::mutable_error_node() {
  set_has_error_node();
  // @@protoc_insertion_point(field_mutable:exec.shared.QueryProfile.error_node)
  return error_node_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline ::std::string* QueryProfile::release_error_node() {
  // @@protoc_insertion_point(field_release:exec.shared.QueryProfile.error_node)
  if (!has_error_node()) {
    return NULL;
  }
  clear_has_error_node();
  return error_node_.ReleaseNonDefaultNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline void QueryProfile::set_allocated_error_node(::std::string* error_node) {
  if (error_node != NULL) {
    set_has_error_node();
  } else {
    clear_has_error_node();
  }
  error_node_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), error_node);
  // @@protoc_insertion_point(field_set_allocated:exec.shared.QueryProfile.error_node)
}

// optional string options_json = 17;
inline bool QueryProfile::has_options_json() const {
  return (_has_bits_[0] & 0x00000080u) != 0;
}
inline void QueryProfile::set_has_options_json() {
  _has_bits_[0] |= 0x00000080u;
}
inline void QueryProfile::clear_has_options_json() {
  _has_bits_[0] &= ~0x00000080u;
}
inline void QueryProfile::clear_options_json() {
  options_json_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  clear_has_options_json();
}
inline const ::std::string& QueryProfile::options_json() const {
  // @@protoc_insertion_point(field_get:exec.shared.QueryProfile.options_json)
  return options_json_.GetNoArena();
}
inline void QueryProfile::set_options_json(const ::std::string& value) {
  set_has_options_json();
  options_json_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
  // @@protoc_insertion_point(field_set:exec.shared.QueryProfile.options_json)
}
#if LANG_CXX11
inline void QueryProfile::set_options_json(::std::string&& value) {
  set_has_options_json();
  options_json_.SetNoArena(
    &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
  // @@protoc_insertion_point(field_set_rvalue:exec.shared.QueryProfile.options_json)
}
#endif
inline void QueryProfile::set_options_json(const char* value) {
  GOOGLE_DCHECK(value != NULL);
  set_has_options_json();
  options_json_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
  // @@protoc_insertion_point(field_set_char:exec.shared.QueryProfile.options_json)
}
inline void QueryProfile::set_options_json(const char* value, size_t size) {
  set_has_options_json();
  options_json_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
      ::std::string(reinterpret_cast<const char*>(value), size));
  // @@protoc_insertion_point(field_set_pointer:exec.shared.QueryProfile.options_json)
}
inline ::std::string* QueryProfile::mutable_options_json() {
  set_has_options_json();
  // @@protoc_insertion_point(field_mutable:exec.shared.QueryProfile.options_json)
  return options_json_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline ::std::string* QueryProfile::release_options_json() {
  // @@protoc_insertion_point(field_release:exec.shared.QueryProfile.options_json)
  if (!has_options_json()) {
    return NULL;
  }
  clear_has_options_json();
  return options_json_.ReleaseNonDefaultNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline void QueryProfile::set_allocated_options_json(::std::string* options_json) {
  if (options_json != NULL) {
    set_has_options_json();
  } else {
    clear_has_options_json();
  }
  options_json_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), options_json);
  // @@protoc_insertion_point(field_set_allocated:exec.shared.QueryProfile.options_json)
}

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

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

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

// optional string queue_name = 21 [default = "-"];
inline bool QueryProfile::has_queue_name() const {
  return (_has_bits_[0] & 0x00000100u) != 0;
}
inline void QueryProfile::set_has_queue_name() {
  _has_bits_[0] |= 0x00000100u;
}
inline void QueryProfile::clear_has_queue_name() {
  _has_bits_[0] &= ~0x00000100u;
}
inline void QueryProfile::clear_queue_name() {
  queue_name_.ClearToDefaultNoArena(&::exec::shared::QueryProfile::_i_give_permission_to_break_this_code_default_queue_name_.get());
  clear_has_queue_name();
}
inline const ::std::string& QueryProfile::queue_name() const {
  // @@protoc_insertion_point(field_get:exec.shared.QueryProfile.queue_name)
  return queue_name_.GetNoArena();
}
inline void QueryProfile::set_queue_name(const ::std::string& value) {
  set_has_queue_name();
  queue_name_.SetNoArena(&::exec::shared::QueryProfile::_i_give_permission_to_break_this_code_default_queue_name_.get(), value);
  // @@protoc_insertion_point(field_set:exec.shared.QueryProfile.queue_name)
}
#if LANG_CXX11
inline void QueryProfile::set_queue_name(::std::string&& value) {
  set_has_queue_name();
  queue_name_.SetNoArena(
    &::exec::shared::QueryProfile::_i_give_permission_to_break_this_code_default_queue_name_.get(), ::std::move(value));
  // @@protoc_insertion_point(field_set_rvalue:exec.shared.QueryProfile.queue_name)
}
#endif
inline void QueryProfile::set_queue_name(const char* value) {
  GOOGLE_DCHECK(value != NULL);
  set_has_queue_name();
  queue_name_.SetNoArena(&::exec::shared::QueryProfile::_i_give_permission_to_break_this_code_default_queue_name_.get(), ::std::string(value));
  // @@protoc_insertion_point(field_set_char:exec.shared.QueryProfile.queue_name)
}
inline void QueryProfile::set_queue_name(const char* value, size_t size) {
  set_has_queue_name();
  queue_name_.SetNoArena(&::exec::shared::QueryProfile::_i_give_permission_to_break_this_code_default_queue_name_.get(),
      ::std::string(reinterpret_cast<const char*>(value), size));
  // @@protoc_insertion_point(field_set_pointer:exec.shared.QueryProfile.queue_name)
}
inline ::std::string* QueryProfile::mutable_queue_name() {
  set_has_queue_name();
  // @@protoc_insertion_point(field_mutable:exec.shared.QueryProfile.queue_name)
  return queue_name_.MutableNoArena(&::exec::shared::QueryProfile::_i_give_permission_to_break_this_code_default_queue_name_.get());
}
inline ::std::string* QueryProfile::release_queue_name() {
  // @@protoc_insertion_point(field_release:exec.shared.QueryProfile.queue_name)
  if (!has_queue_name()) {
    return NULL;
  }
  clear_has_queue_name();
  return queue_name_.ReleaseNonDefaultNoArena(&::exec::shared::QueryProfile::_i_give_permission_to_break_this_code_default_queue_name_.get());
}
inline void QueryProfile::set_allocated_queue_name(::std::string* queue_name) {
  if (queue_name != NULL) {
    set_has_queue_name();
  } else {
    clear_has_queue_name();
  }
  queue_name_.SetAllocatedNoArena(&::exec::shared::QueryProfile::_i_give_permission_to_break_this_code_default_queue_name_.get(), queue_name);
  // @@protoc_insertion_point(field_set_allocated:exec.shared.QueryProfile.queue_name)
}

// optional string queryId = 22;
inline bool QueryProfile::has_queryid() const {
  return (_has_bits_[0] & 0x00000200u) != 0;
}
inline void QueryProfile::set_has_queryid() {
  _has_bits_[0] |= 0x00000200u;
}
inline void QueryProfile::clear_has_queryid() {
  _has_bits_[0] &= ~0x00000200u;
}
inline void QueryProfile::clear_queryid() {
  queryid_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  clear_has_queryid();
}
inline const ::std::string& QueryProfile::queryid() const {
  // @@protoc_insertion_point(field_get:exec.shared.QueryProfile.queryId)
  return queryid_.GetNoArena();
}
inline void QueryProfile::set_queryid(const ::std::string& value) {
  set_has_queryid();
  queryid_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
  // @@protoc_insertion_point(field_set:exec.shared.QueryProfile.queryId)
}
#if LANG_CXX11
inline void QueryProfile::set_queryid(::std::string&& value) {
  set_has_queryid();
  queryid_.SetNoArena(
    &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
  // @@protoc_insertion_point(field_set_rvalue:exec.shared.QueryProfile.queryId)
}
#endif
inline void QueryProfile::set_queryid(const char* value) {
  GOOGLE_DCHECK(value != NULL);
  set_has_queryid();
  queryid_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
  // @@protoc_insertion_point(field_set_char:exec.shared.QueryProfile.queryId)
}
inline void QueryProfile::set_queryid(const char* value, size_t size) {
  set_has_queryid();
  queryid_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
      ::std::string(reinterpret_cast<const char*>(value), size));
  // @@protoc_insertion_point(field_set_pointer:exec.shared.QueryProfile.queryId)
}
inline ::std::string* QueryProfile::mutable_queryid() {
  set_has_queryid();
  // @@protoc_insertion_point(field_mutable:exec.shared.QueryProfile.queryId)
  return queryid_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline ::std::string* QueryProfile::release_queryid() {
  // @@protoc_insertion_point(field_release:exec.shared.QueryProfile.queryId)
  if (!has_queryid()) {
    return NULL;
  }
  clear_has_queryid();
  return queryid_.ReleaseNonDefaultNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline void QueryProfile::set_allocated_queryid(::std::string* queryid) {
  if (queryid != NULL) {
    set_has_queryid();
  } else {
    clear_has_queryid();
  }
  queryid_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), queryid);
  // @@protoc_insertion_point(field_set_allocated:exec.shared.QueryProfile.queryId)
}

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

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

// MajorFragmentProfile

// optional int32 major_fragment_id = 1;
inline bool MajorFragmentProfile::has_major_fragment_id() const {
  return (_has_bits_[0] & 0x00000001u) != 0;
}
inline void MajorFragmentProfile::set_has_major_fragment_id() {
  _has_bits_[0] |= 0x00000001u;
}
inline void MajorFragmentProfile::clear_has_major_fragment_id() {
  _has_bits_[0] &= ~0x00000001u;
}
inline void MajorFragmentProfile::clear_major_fragment_id() {
  major_fragment_id_ = 0;
  clear_has_major_fragment_id();
}
inline ::google::protobuf::int32 MajorFragmentProfile::major_fragment_id() const {
  // @@protoc_insertion_point(field_get:exec.shared.MajorFragmentProfile.major_fragment_id)
  return major_fragment_id_;
}
inline void MajorFragmentProfile::set_major_fragment_id(::google::protobuf::int32 value) {
  set_has_major_fragment_id();
  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::minor_fragment_profile_size() const {
  return 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 ::google::protobuf::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::minor_fragment_profile(int index) const {
  // @@protoc_insertion_point(field_get:exec.shared.MajorFragmentProfile.minor_fragment_profile)
  return minor_fragment_profile_.Get(index);
}
inline ::exec::shared::MinorFragmentProfile* MajorFragmentProfile::add_minor_fragment_profile() {
  // @@protoc_insertion_point(field_add:exec.shared.MajorFragmentProfile.minor_fragment_profile)
  return minor_fragment_profile_.Add();
}
inline const ::google::protobuf::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::has_state() const {
  return (_has_bits_[0] & 0x00000004u) != 0;
}
inline void MinorFragmentProfile::set_has_state() {
  _has_bits_[0] |= 0x00000004u;
}
inline void MinorFragmentProfile::clear_has_state() {
  _has_bits_[0] &= ~0x00000004u;
}
inline void MinorFragmentProfile::clear_state() {
  state_ = 0;
  clear_has_state();
}
inline ::exec::shared::FragmentState MinorFragmentProfile::state() const {
  // @@protoc_insertion_point(field_get:exec.shared.MinorFragmentProfile.state)
  return static_cast< ::exec::shared::FragmentState >(state_);
}
inline void MinorFragmentProfile::set_state(::exec::shared::FragmentState value) {
  assert(::exec::shared::FragmentState_IsValid(value));
  set_has_state();
  state_ = value;
  // @@protoc_insertion_point(field_set:exec.shared.MinorFragmentProfile.state)
}

// optional .exec.shared.DrillPBError error = 2;
inline bool MinorFragmentProfile::has_error() const {
  return (_has_bits_[0] & 0x00000001u) != 0;
}
inline void MinorFragmentProfile::set_has_error() {
  _has_bits_[0] |= 0x00000001u;
}
inline void MinorFragmentProfile::clear_has_error() {
  _has_bits_[0] &= ~0x00000001u;
}
inline void MinorFragmentProfile::clear_error() {
  if (error_ != NULL) error_->Clear();
  clear_has_error();
}
inline const ::exec::shared::DrillPBError& MinorFragmentProfile::_internal_error() const {
  return *error_;
}
inline const ::exec::shared::DrillPBError& MinorFragmentProfile::error() const {
  const ::exec::shared::DrillPBError* p = error_;
  // @@protoc_insertion_point(field_get:exec.shared.MinorFragmentProfile.error)
  return p != NULL ? *p : *reinterpret_cast<const ::exec::shared::DrillPBError*>(
      &::exec::shared::_DrillPBError_default_instance_);
}
inline ::exec::shared::DrillPBError* MinorFragmentProfile::release_error() {
  // @@protoc_insertion_point(field_release:exec.shared.MinorFragmentProfile.error)
  clear_has_error();
  ::exec::shared::DrillPBError* temp = error_;
  error_ = NULL;
  return temp;
}
inline ::exec::shared::DrillPBError* MinorFragmentProfile::mutable_error() {
  set_has_error();
  if (error_ == NULL) {
    auto* p = CreateMaybeMessage<::exec::shared::DrillPBError>(GetArenaNoVirtual());
    error_ = p;
  }
  // @@protoc_insertion_point(field_mutable:exec.shared.MinorFragmentProfile.error)
  return error_;
}
inline void MinorFragmentProfile::set_allocated_error(::exec::shared::DrillPBError* error) {
  ::google::protobuf::Arena* message_arena = GetArenaNoVirtual();
  if (message_arena == NULL) {
    delete error_;
  }
  if (error) {
    ::google::protobuf::Arena* submessage_arena = NULL;
    if (message_arena != submessage_arena) {
      error = ::google::protobuf::internal::GetOwnedMessage(
          message_arena, error, submessage_arena);
    }
    set_has_error();
  } else {
    clear_has_error();
  }
  error_ = error;
  // @@protoc_insertion_point(field_set_allocated:exec.shared.MinorFragmentProfile.error)
}

// optional int32 minor_fragment_id = 3;
inline bool MinorFragmentProfile::has_minor_fragment_id() const {
  return (_has_bits_[0] & 0x00000008u) != 0;
}
inline void MinorFragmentProfile::set_has_minor_fragment_id() {
  _has_bits_[0] |= 0x00000008u;
}
inline void MinorFragmentProfile::clear_has_minor_fragment_id() {
  _has_bits_[0] &= ~0x00000008u;
}
inline void MinorFragmentProfile::clear_minor_fragment_id() {
  minor_fragment_id_ = 0;
  clear_has_minor_fragment_id();
}
inline ::google::protobuf::int32 MinorFragmentProfile::minor_fragment_id() const {
  // @@protoc_insertion_point(field_get:exec.shared.MinorFragmentProfile.minor_fragment_id)
  return minor_fragment_id_;
}
inline void MinorFragmentProfile::set_minor_fragment_id(::google::protobuf::int32 value) {
  set_has_minor_fragment_id();
  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::operator_profile_size() const {
  return 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 ::google::protobuf::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::operator_profile(int index) const {
  // @@protoc_insertion_point(field_get:exec.shared.MinorFragmentProfile.operator_profile)
  return operator_profile_.Get(index);
}
inline ::exec::shared::OperatorProfile* MinorFragmentProfile::add_operator_profile() {
  // @@protoc_insertion_point(field_add:exec.shared.MinorFragmentProfile.operator_profile)
  return operator_profile_.Add();
}
inline const ::google::protobuf::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::has_start_time() const {
  return (_has_bits_[0] & 0x00000010u) != 0;
}
inline void MinorFragmentProfile::set_has_start_time() {
  _has_bits_[0] |= 0x00000010u;
}
inline void MinorFragmentProfile::clear_has_start_time() {
  _has_bits_[0] &= ~0x00000010u;
}
inline void MinorFragmentProfile::clear_start_time() {
  start_time_ = GOOGLE_LONGLONG(0);
  clear_has_start_time();
}
inline ::google::protobuf::int64 MinorFragmentProfile::start_time() const {
  // @@protoc_insertion_point(field_get:exec.shared.MinorFragmentProfile.start_time)
  return start_time_;
}
inline void MinorFragmentProfile::set_start_time(::google::protobuf::int64 value) {
  set_has_start_time();
  start_time_ = value;
  // @@protoc_insertion_point(field_set:exec.shared.MinorFragmentProfile.start_time)
}

// optional int64 end_time = 6;
inline bool MinorFragmentProfile::has_end_time() const {
  return (_has_bits_[0] & 0x00000020u) != 0;
}
inline void MinorFragmentProfile::set_has_end_time() {
  _has_bits_[0] |= 0x00000020u;
}
inline void MinorFragmentProfile::clear_has_end_time() {
  _has_bits_[0] &= ~0x00000020u;
}
inline void MinorFragmentProfile::clear_end_time() {
  end_time_ = GOOGLE_LONGLONG(0);
  clear_has_end_time();
}
inline ::google::protobuf::int64 MinorFragmentProfile::end_time() const {
  // @@protoc_insertion_point(field_get:exec.shared.MinorFragmentProfile.end_time)
  return end_time_;
}
inline void MinorFragmentProfile::set_end_time(::google::protobuf::int64 value) {
  set_has_end_time();
  end_time_ = value;
  // @@protoc_insertion_point(field_set:exec.shared.MinorFragmentProfile.end_time)
}

// optional int64 memory_used = 7;
inline bool MinorFragmentProfile::has_memory_used() const {
  return (_has_bits_[0] & 0x00000040u) != 0;
}
inline void MinorFragmentProfile::set_has_memory_used() {
  _has_bits_[0] |= 0x00000040u;
}
inline void MinorFragmentProfile::clear_has_memory_used() {
  _has_bits_[0] &= ~0x00000040u;
}
inline void MinorFragmentProfile::clear_memory_used() {
  memory_used_ = GOOGLE_LONGLONG(0);
  clear_has_memory_used();
}
inline ::google::protobuf::int64 MinorFragmentProfile::memory_used() const {
  // @@protoc_insertion_point(field_get:exec.shared.MinorFragmentProfile.memory_used)
  return memory_used_;
}
inline void MinorFragmentProfile::set_memory_used(::google::protobuf::int64 value) {
  set_has_memory_used();
  memory_used_ = value;
  // @@protoc_insertion_point(field_set:exec.shared.MinorFragmentProfile.memory_used)
}

// optional int64 max_memory_used = 8;
inline bool MinorFragmentProfile::has_max_memory_used() const {
  return (_has_bits_[0] & 0x00000080u) != 0;
}
inline void MinorFragmentProfile::set_has_max_memory_used() {
  _has_bits_[0] |= 0x00000080u;
}
inline void MinorFragmentProfile::clear_has_max_memory_used() {
  _has_bits_[0] &= ~0x00000080u;
}
inline void MinorFragmentProfile::clear_max_memory_used() {
  max_memory_used_ = GOOGLE_LONGLONG(0);
  clear_has_max_memory_used();
}
inline ::google::protobuf::int64 MinorFragmentProfile::max_memory_used() const {
  // @@protoc_insertion_point(field_get:exec.shared.MinorFragmentProfile.max_memory_used)
  return max_memory_used_;
}
inline void MinorFragmentProfile::set_max_memory_used(::google::protobuf::int64 value) {
  set_has_max_memory_used();
  max_memory_used_ = value;
  // @@protoc_insertion_point(field_set:exec.shared.MinorFragmentProfile.max_memory_used)
}

// optional .exec.DrillbitEndpoint endpoint = 9;
inline bool MinorFragmentProfile::has_endpoint() const {
  return (_has_bits_[0] & 0x00000002u) != 0;
}
inline void MinorFragmentProfile::set_has_endpoint() {
  _has_bits_[0] |= 0x00000002u;
}
inline void MinorFragmentProfile::clear_has_endpoint() {
  _has_bits_[0] &= ~0x00000002u;
}
inline const ::exec::DrillbitEndpoint& MinorFragmentProfile::_internal_endpoint() const {
  return *endpoint_;
}
inline const ::exec::DrillbitEndpoint& MinorFragmentProfile::endpoint() const {
  const ::exec::DrillbitEndpoint* p = endpoint_;
  // @@protoc_insertion_point(field_get:exec.shared.MinorFragmentProfile.endpoint)
  return p != NULL ? *p : *reinterpret_cast<const ::exec::DrillbitEndpoint*>(
      &::exec::_DrillbitEndpoint_default_instance_);
}
inline ::exec::DrillbitEndpoint* MinorFragmentProfile::release_endpoint() {
  // @@protoc_insertion_point(field_release:exec.shared.MinorFragmentProfile.endpoint)
  clear_has_endpoint();
  ::exec::DrillbitEndpoint* temp = endpoint_;
  endpoint_ = NULL;
  return temp;
}
inline ::exec::DrillbitEndpoint* MinorFragmentProfile::mutable_endpoint() {
  set_has_endpoint();
  if (endpoint_ == NULL) {
    auto* p = CreateMaybeMessage<::exec::DrillbitEndpoint>(GetArenaNoVirtual());
    endpoint_ = p;
  }
  // @@protoc_insertion_point(field_mutable:exec.shared.MinorFragmentProfile.endpoint)
  return endpoint_;
}
inline void MinorFragmentProfile::set_allocated_endpoint(::exec::DrillbitEndpoint* endpoint) {
  ::google::protobuf::Arena* message_arena = GetArenaNoVirtual();
  if (message_arena == NULL) {
    delete reinterpret_cast< ::google::protobuf::MessageLite*>(endpoint_);
  }
  if (endpoint) {
    ::google::protobuf::Arena* submessage_arena = NULL;
    if (message_arena != submessage_arena) {
      endpoint = ::google::protobuf::internal::GetOwnedMessage(
          message_arena, endpoint, submessage_arena);
    }
    set_has_endpoint();
  } else {
    clear_has_endpoint();
  }
  endpoint_ = endpoint;
  // @@protoc_insertion_point(field_set_allocated:exec.shared.MinorFragmentProfile.endpoint)
}

// optional int64 last_update = 10;
inline bool MinorFragmentProfile::has_last_update() const {
  return (_has_bits_[0] & 0x00000100u) != 0;
}
inline void MinorFragmentProfile::set_has_last_update() {
  _has_bits_[0] |= 0x00000100u;
}
inline void MinorFragmentProfile::clear_has_last_update() {
  _has_bits_[0] &= ~0x00000100u;
}
inline void MinorFragmentProfile::clear_last_update() {
  last_update_ = GOOGLE_LONGLONG(0);
  clear_has_last_update();
}
inline ::google::protobuf::int64 MinorFragmentProfile::last_update() const {
  // @@protoc_insertion_point(field_get:exec.shared.MinorFragmentProfile.last_update)
  return last_update_;
}
inline void MinorFragmentProfile::set_last_update(::google::protobuf::int64 value) {
  set_has_last_update();
  last_update_ = value;
  // @@protoc_insertion_point(field_set:exec.shared.MinorFragmentProfile.last_update)
}

// optional int64 last_progress = 11;
inline bool MinorFragmentProfile::has_last_progress() const {
  return (_has_bits_[0] & 0x00000200u) != 0;
}
inline void MinorFragmentProfile::set_has_last_progress() {
  _has_bits_[0] |= 0x00000200u;
}
inline void MinorFragmentProfile::clear_has_last_progress() {
  _has_bits_[0] &= ~0x00000200u;
}
inline void MinorFragmentProfile::clear_last_progress() {
  last_progress_ = GOOGLE_LONGLONG(0);
  clear_has_last_progress();
}
inline ::google::protobuf::int64 MinorFragmentProfile::last_progress() const {
  // @@protoc_insertion_point(field_get:exec.shared.MinorFragmentProfile.last_progress)
  return last_progress_;
}
inline void MinorFragmentProfile::set_last_progress(::google::protobuf::int64 value) {
  set_has_last_progress();
  last_progress_ = value;
  // @@protoc_insertion_point(field_set:exec.shared.MinorFragmentProfile.last_progress)
}

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

// OperatorProfile

// repeated .exec.shared.StreamProfile input_profile = 1;
inline int OperatorProfile::input_profile_size() const {
  return 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 ::google::protobuf::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::input_profile(int index) const {
  // @@protoc_insertion_point(field_get:exec.shared.OperatorProfile.input_profile)
  return input_profile_.Get(index);
}
inline ::exec::shared::StreamProfile* OperatorProfile::add_input_profile() {
  // @@protoc_insertion_point(field_add:exec.shared.OperatorProfile.input_profile)
  return input_profile_.Add();
}
inline const ::google::protobuf::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::has_operator_id() const {
  return (_has_bits_[0] & 0x00000001u) != 0;
}
inline void OperatorProfile::set_has_operator_id() {
  _has_bits_[0] |= 0x00000001u;
}
inline void OperatorProfile::clear_has_operator_id() {
  _has_bits_[0] &= ~0x00000001u;
}
inline void OperatorProfile::clear_operator_id() {
  operator_id_ = 0;
  clear_has_operator_id();
}
inline ::google::protobuf::int32 OperatorProfile::operator_id() const {
  // @@protoc_insertion_point(field_get:exec.shared.OperatorProfile.operator_id)
  return operator_id_;
}
inline void OperatorProfile::set_operator_id(::google::protobuf::int32 value) {
  set_has_operator_id();
  operator_id_ = value;
  // @@protoc_insertion_point(field_set:exec.shared.OperatorProfile.operator_id)
}

// optional int32 operator_type = 4;
inline bool OperatorProfile::has_operator_type() const {
  return (_has_bits_[0] & 0x00000002u) != 0;
}
inline void OperatorProfile::set_has_operator_type() {
  _has_bits_[0] |= 0x00000002u;
}
inline void OperatorProfile::clear_has_operator_type() {
  _has_bits_[0] &= ~0x00000002u;
}
inline void OperatorProfile::clear_operator_type() {
  operator_type_ = 0;
  clear_has_operator_type();
}
inline ::google::protobuf::int32 OperatorProfile::operator_type() const {
  // @@protoc_insertion_point(field_get:exec.shared.OperatorProfile.operator_type)
  return operator_type_;
}
inline void OperatorProfile::set_operator_type(::google::protobuf::int32 value) {
  set_has_operator_type();
  operator_type_ = value;
  // @@protoc_insertion_point(field_set:exec.shared.OperatorProfile.operator_type)
}

// optional int64 setup_nanos = 5;
inline bool OperatorProfile::has_setup_nanos() const {
  return (_has_bits_[0] & 0x00000004u) != 0;
}
inline void OperatorProfile::set_has_setup_nanos() {
  _has_bits_[0] |= 0x00000004u;
}
inline void OperatorProfile::clear_has_setup_nanos() {
  _has_bits_[0] &= ~0x00000004u;
}
inline void OperatorProfile::clear_setup_nanos() {
  setup_nanos_ = GOOGLE_LONGLONG(0);
  clear_has_setup_nanos();
}
inline ::google::protobuf::int64 OperatorProfile::setup_nanos() const {
  // @@protoc_insertion_point(field_get:exec.shared.OperatorProfile.setup_nanos)
  return setup_nanos_;
}
inline void OperatorProfile::set_setup_nanos(::google::protobuf::int64 value) {
  set_has_setup_nanos();
  setup_nanos_ = value;
  // @@protoc_insertion_point(field_set:exec.shared.OperatorProfile.setup_nanos)
}

// optional int64 process_nanos = 6;
inline bool OperatorProfile::has_process_nanos() const {
  return (_has_bits_[0] & 0x00000008u) != 0;
}
inline void OperatorProfile::set_has_process_nanos() {
  _has_bits_[0] |= 0x00000008u;
}
inline void OperatorProfile::clear_has_process_nanos() {
  _has_bits_[0] &= ~0x00000008u;
}
inline void OperatorProfile::clear_process_nanos() {
  process_nanos_ = GOOGLE_LONGLONG(0);
  clear_has_process_nanos();
}
inline ::google::protobuf::int64 OperatorProfile::process_nanos() const {
  // @@protoc_insertion_point(field_get:exec.shared.OperatorProfile.process_nanos)
  return process_nanos_;
}
inline void OperatorProfile::set_process_nanos(::google::protobuf::int64 value) {
  set_has_process_nanos();
  process_nanos_ = value;
  // @@protoc_insertion_point(field_set:exec.shared.OperatorProfile.process_nanos)
}

// optional int64 peak_local_memory_allocated = 7;
inline bool OperatorProfile::has_peak_local_memory_allocated() const {
  return (_has_bits_[0] & 0x00000010u) != 0;
}
inline void OperatorProfile::set_has_peak_local_memory_allocated() {
  _has_bits_[0] |= 0x00000010u;
}
inline void OperatorProfile::clear_has_peak_local_memory_allocated() {
  _has_bits_[0] &= ~0x00000010u;
}
inline void OperatorProfile::clear_peak_local_memory_allocated() {
  peak_local_memory_allocated_ = GOOGLE_LONGLONG(0);
  clear_has_peak_local_memory_allocated();
}
inline ::google::protobuf::int64 OperatorProfile::peak_local_memory_allocated() const {
  // @@protoc_insertion_point(field_get:exec.shared.OperatorProfile.peak_local_memory_allocated)
  return peak_local_memory_allocated_;
}
inline void OperatorProfile::set_peak_local_memory_allocated(::google::protobuf::int64 value) {
  set_has_peak_local_memory_allocated();
  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::metric_size() const {
  return 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 ::google::protobuf::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::metric(int index) const {
  // @@protoc_insertion_point(field_get:exec.shared.OperatorProfile.metric)
  return metric_.Get(index);
}
inline ::exec::shared::MetricValue* OperatorProfile::add_metric() {
  // @@protoc_insertion_point(field_add:exec.shared.OperatorProfile.metric)
  return metric_.Add();
}
inline const ::google::protobuf::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::has_wait_nanos() const {
  return (_has_bits_[0] & 0x00000020u) != 0;
}
inline void OperatorProfile::set_has_wait_nanos() {
  _has_bits_[0] |= 0x00000020u;
}
inline void OperatorProfile::clear_has_wait_nanos() {
  _has_bits_[0] &= ~0x00000020u;
}
inline void OperatorProfile::clear_wait_nanos() {
  wait_nanos_ = GOOGLE_LONGLONG(0);
  clear_has_wait_nanos();
}
inline ::google::protobuf::int64 OperatorProfile::wait_nanos() const {
  // @@protoc_insertion_point(field_get:exec.shared.OperatorProfile.wait_nanos)
  return wait_nanos_;
}
inline void OperatorProfile::set_wait_nanos(::google::protobuf::int64 value) {
  set_has_wait_nanos();
  wait_nanos_ = value;
  // @@protoc_insertion_point(field_set:exec.shared.OperatorProfile.wait_nanos)
}

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

// StreamProfile

// optional int64 records = 1;
inline bool StreamProfile::has_records() const {
  return (_has_bits_[0] & 0x00000001u) != 0;
}
inline void StreamProfile::set_has_records() {
  _has_bits_[0] |= 0x00000001u;
}
inline void StreamProfile::clear_has_records() {
  _has_bits_[0] &= ~0x00000001u;
}
inline void StreamProfile::clear_records() {
  records_ = GOOGLE_LONGLONG(0);
  clear_has_records();
}
inline ::google::protobuf::int64 StreamProfile::records() const {
  // @@protoc_insertion_point(field_get:exec.shared.StreamProfile.records)
  return records_;
}
inline void StreamProfile::set_records(::google::protobuf::int64 value) {
  set_has_records();
  records_ = value;
  // @@protoc_insertion_point(field_set:exec.shared.StreamProfile.records)
}

// optional int64 batches = 2;
inline bool StreamProfile::has_batches() const {
  return (_has_bits_[0] & 0x00000002u) != 0;
}
inline void StreamProfile::set_has_batches() {
  _has_bits_[0] |= 0x00000002u;
}
inline void StreamProfile::clear_has_batches() {
  _has_bits_[0] &= ~0x00000002u;
}
inline void StreamProfile::clear_batches() {
  batches_ = GOOGLE_LONGLONG(0);
  clear_has_batches();
}
inline ::google::protobuf::int64 StreamProfile::batches() const {
  // @@protoc_insertion_point(field_get:exec.shared.StreamProfile.batches)
  return batches_;
}
inline void StreamProfile::set_batches(::google::protobuf::int64 value) {
  set_has_batches();
  batches_ = value;
  // @@protoc_insertion_point(field_set:exec.shared.StreamProfile.batches)
}

// optional int64 schemas = 3;
inline bool StreamProfile::has_schemas() const {
  return (_has_bits_[0] & 0x00000004u) != 0;
}
inline void StreamProfile::set_has_schemas() {
  _has_bits_[0] |= 0x00000004u;
}
inline void StreamProfile::clear_has_schemas() {
  _has_bits_[0] &= ~0x00000004u;
}
inline void StreamProfile::clear_schemas() {
  schemas_ = GOOGLE_LONGLONG(0);
  clear_has_schemas();
}
inline ::google::protobuf::int64 StreamProfile::schemas() const {
  // @@protoc_insertion_point(field_get:exec.shared.StreamProfile.schemas)
  return schemas_;
}
inline void StreamProfile::set_schemas(::google::protobuf::int64 value) {
  set_has_schemas();
  schemas_ = value;
  // @@protoc_insertion_point(field_set:exec.shared.StreamProfile.schemas)
}

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

// MetricValue

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

// optional int64 long_value = 2;
inline bool MetricValue::has_long_value() const {
  return (_has_bits_[0] & 0x00000001u) != 0;
}
inline void MetricValue::set_has_long_value() {
  _has_bits_[0] |= 0x00000001u;
}
inline void MetricValue::clear_has_long_value() {
  _has_bits_[0] &= ~0x00000001u;
}
inline void MetricValue::clear_long_value() {
  long_value_ = GOOGLE_LONGLONG(0);
  clear_has_long_value();
}
inline ::google::protobuf::int64 MetricValue::long_value() const {
  // @@protoc_insertion_point(field_get:exec.shared.MetricValue.long_value)
  return long_value_;
}
inline void MetricValue::set_long_value(::google::protobuf::int64 value) {
  set_has_long_value();
  long_value_ = value;
  // @@protoc_insertion_point(field_set:exec.shared.MetricValue.long_value)
}

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

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

// Registry

// repeated .exec.shared.Jar jar = 1;
inline int Registry::jar_size() const {
  return 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 ::google::protobuf::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::jar(int index) const {
  // @@protoc_insertion_point(field_get:exec.shared.Registry.jar)
  return jar_.Get(index);
}
inline ::exec::shared::Jar* Registry::add_jar() {
  // @@protoc_insertion_point(field_add:exec.shared.Registry.jar)
  return jar_.Add();
}
inline const ::google::protobuf::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::has_name() const {
  return (_has_bits_[0] & 0x00000001u) != 0;
}
inline void Jar::set_has_name() {
  _has_bits_[0] |= 0x00000001u;
}
inline void Jar::clear_has_name() {
  _has_bits_[0] &= ~0x00000001u;
}
inline void Jar::clear_name() {
  name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  clear_has_name();
}
inline const ::std::string& Jar::name() const {
  // @@protoc_insertion_point(field_get:exec.shared.Jar.name)
  return name_.GetNoArena();
}
inline void Jar::set_name(const ::std::string& value) {
  set_has_name();
  name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
  // @@protoc_insertion_point(field_set:exec.shared.Jar.name)
}
#if LANG_CXX11
inline void Jar::set_name(::std::string&& value) {
  set_has_name();
  name_.SetNoArena(
    &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
  // @@protoc_insertion_point(field_set_rvalue:exec.shared.Jar.name)
}
#endif
inline void Jar::set_name(const char* value) {
  GOOGLE_DCHECK(value != NULL);
  set_has_name();
  name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
  // @@protoc_insertion_point(field_set_char:exec.shared.Jar.name)
}
inline void Jar::set_name(const char* value, size_t size) {
  set_has_name();
  name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
      ::std::string(reinterpret_cast<const char*>(value), size));
  // @@protoc_insertion_point(field_set_pointer:exec.shared.Jar.name)
}
inline ::std::string* Jar::mutable_name() {
  set_has_name();
  // @@protoc_insertion_point(field_mutable:exec.shared.Jar.name)
  return name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline ::std::string* Jar::release_name() {
  // @@protoc_insertion_point(field_release:exec.shared.Jar.name)
  if (!has_name()) {
    return NULL;
  }
  clear_has_name();
  return name_.ReleaseNonDefaultNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline void Jar::set_allocated_name(::std::string* name) {
  if (name != NULL) {
    set_has_name();
  } else {
    clear_has_name();
  }
  name_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), name);
  // @@protoc_insertion_point(field_set_allocated:exec.shared.Jar.name)
}

// repeated string function_signature = 2;
inline int Jar::function_signature_size() const {
  return function_signature_.size();
}
inline void Jar::clear_function_signature() {
  function_signature_.Clear();
}
inline const ::std::string& Jar::function_signature(int index) const {
  // @@protoc_insertion_point(field_get:exec.shared.Jar.function_signature)
  return function_signature_.Get(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);
}
#if LANG_CXX11
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));
}
#endif
inline void Jar::set_function_signature(int index, const char* value) {
  GOOGLE_DCHECK(value != NULL);
  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::add_function_signature() {
  // @@protoc_insertion_point(field_add_mutable:exec.shared.Jar.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)
}
#if LANG_CXX11
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)
}
#endif
inline void Jar::add_function_signature(const char* value) {
  GOOGLE_DCHECK(value != NULL);
  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 ::google::protobuf::RepeatedPtrField< ::std::string>&
Jar::function_signature() const {
  // @@protoc_insertion_point(field_list:exec.shared.Jar.function_signature)
  return function_signature_;
}
inline ::google::protobuf::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::has_mechanism() const {
  return (_has_bits_[0] & 0x00000001u) != 0;
}
inline void SaslMessage::set_has_mechanism() {
  _has_bits_[0] |= 0x00000001u;
}
inline void SaslMessage::clear_has_mechanism() {
  _has_bits_[0] &= ~0x00000001u;
}
inline void SaslMessage::clear_mechanism() {
  mechanism_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  clear_has_mechanism();
}
inline const ::std::string& SaslMessage::mechanism() const {
  // @@protoc_insertion_point(field_get:exec.shared.SaslMessage.mechanism)
  return mechanism_.GetNoArena();
}
inline void SaslMessage::set_mechanism(const ::std::string& value) {
  set_has_mechanism();
  mechanism_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
  // @@protoc_insertion_point(field_set:exec.shared.SaslMessage.mechanism)
}
#if LANG_CXX11
inline void SaslMessage::set_mechanism(::std::string&& value) {
  set_has_mechanism();
  mechanism_.SetNoArena(
    &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
  // @@protoc_insertion_point(field_set_rvalue:exec.shared.SaslMessage.mechanism)
}
#endif
inline void SaslMessage::set_mechanism(const char* value) {
  GOOGLE_DCHECK(value != NULL);
  set_has_mechanism();
  mechanism_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
  // @@protoc_insertion_point(field_set_char:exec.shared.SaslMessage.mechanism)
}
inline void SaslMessage::set_mechanism(const char* value, size_t size) {
  set_has_mechanism();
  mechanism_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
      ::std::string(reinterpret_cast<const char*>(value), size));
  // @@protoc_insertion_point(field_set_pointer:exec.shared.SaslMessage.mechanism)
}
inline ::std::string* SaslMessage::mutable_mechanism() {
  set_has_mechanism();
  // @@protoc_insertion_point(field_mutable:exec.shared.SaslMessage.mechanism)
  return mechanism_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline ::std::string* SaslMessage::release_mechanism() {
  // @@protoc_insertion_point(field_release:exec.shared.SaslMessage.mechanism)
  if (!has_mechanism()) {
    return NULL;
  }
  clear_has_mechanism();
  return mechanism_.ReleaseNonDefaultNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline void SaslMessage::set_allocated_mechanism(::std::string* mechanism) {
  if (mechanism != NULL) {
    set_has_mechanism();
  } else {
    clear_has_mechanism();
  }
  mechanism_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), mechanism);
  // @@protoc_insertion_point(field_set_allocated:exec.shared.SaslMessage.mechanism)
}

// optional bytes data = 2;
inline bool SaslMessage::has_data() const {
  return (_has_bits_[0] & 0x00000002u) != 0;
}
inline void SaslMessage::set_has_data() {
  _has_bits_[0] |= 0x00000002u;
}
inline void SaslMessage::clear_has_data() {
  _has_bits_[0] &= ~0x00000002u;
}
inline void SaslMessage::clear_data() {
  data_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  clear_has_data();
}
inline const ::std::string& SaslMessage::data() const {
  // @@protoc_insertion_point(field_get:exec.shared.SaslMessage.data)
  return data_.GetNoArena();
}
inline void SaslMessage::set_data(const ::std::string& value) {
  set_has_data();
  data_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
  // @@protoc_insertion_point(field_set:exec.shared.SaslMessage.data)
}
#if LANG_CXX11
inline void SaslMessage::set_data(::std::string&& value) {
  set_has_data();
  data_.SetNoArena(
    &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
  // @@protoc_insertion_point(field_set_rvalue:exec.shared.SaslMessage.data)
}
#endif
inline void SaslMessage::set_data(const char* value) {
  GOOGLE_DCHECK(value != NULL);
  set_has_data();
  data_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
  // @@protoc_insertion_point(field_set_char:exec.shared.SaslMessage.data)
}
inline void SaslMessage::set_data(const void* value, size_t size) {
  set_has_data();
  data_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
      ::std::string(reinterpret_cast<const char*>(value), size));
  // @@protoc_insertion_point(field_set_pointer:exec.shared.SaslMessage.data)
}
inline ::std::string* SaslMessage::mutable_data() {
  set_has_data();
  // @@protoc_insertion_point(field_mutable:exec.shared.SaslMessage.data)
  return data_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline ::std::string* SaslMessage::release_data() {
  // @@protoc_insertion_point(field_release:exec.shared.SaslMessage.data)
  if (!has_data()) {
    return NULL;
  }
  clear_has_data();
  return data_.ReleaseNonDefaultNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline void SaslMessage::set_allocated_data(::std::string* data) {
  if (data != NULL) {
    set_has_data();
  } else {
    clear_has_data();
  }
  data_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), data);
  // @@protoc_insertion_point(field_set_allocated:exec.shared.SaslMessage.data)
}

// optional .exec.shared.SaslStatus status = 3;
inline bool SaslMessage::has_status() const {
  return (_has_bits_[0] & 0x00000004u) != 0;
}
inline void SaslMessage::set_has_status() {
  _has_bits_[0] |= 0x00000004u;
}
inline void SaslMessage::clear_has_status() {
  _has_bits_[0] &= ~0x00000004u;
}
inline void SaslMessage::clear_status() {
  status_ = 0;
  clear_has_status();
}
inline ::exec::shared::SaslStatus SaslMessage::status() const {
  // @@protoc_insertion_point(field_get:exec.shared.SaslMessage.status)
  return static_cast< ::exec::shared::SaslStatus >(status_);
}
inline void SaslMessage::set_status(::exec::shared::SaslStatus value) {
  assert(::exec::shared::SaslStatus_IsValid(value));
  set_has_status();
  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

namespace google {
namespace protobuf {

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::CoreOperatorType> : ::std::true_type {};
template <>
inline const EnumDescriptor* GetEnumDescriptor< ::exec::shared::CoreOperatorType>() {
  return ::exec::shared::CoreOperatorType_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();
}

}  // namespace protobuf
}  // namespace google

// @@protoc_insertion_point(global_scope)

#endif  // PROTOBUF_INCLUDED_UserBitShared_2eproto
