// 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
};
bool CoreOperatorType_IsValid(int value);
const CoreOperatorType CoreOperatorType_MIN = SINGLE_SENDER;
const CoreOperatorType CoreOperatorType_MAX = METADATA_CONTROLLER;
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
