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

#ifndef GOOGLE_PROTOBUF_INCLUDED_Coordination_2eproto
#define GOOGLE_PROTOBUF_INCLUDED_Coordination_2eproto

#include <limits>
#include <string>

#include <google/protobuf/port_def.inc>
#if PROTOBUF_VERSION < 3011000
#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 3011001 < PROTOBUF_MIN_PROTOC_VERSION
#error This file was generated by an older version of protoc which is
#error incompatible with your Protocol Buffer headers. Please
#error regenerate this file with a newer version of protoc.
#endif

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

// Internal implementation detail -- do not use these members.
struct TableStruct_Coordination_2eproto {
  static const ::PROTOBUF_NAMESPACE_ID::internal::ParseTableField entries[]
    PROTOBUF_SECTION_VARIABLE(protodesc_cold);
  static const ::PROTOBUF_NAMESPACE_ID::internal::AuxillaryParseTableField aux[]
    PROTOBUF_SECTION_VARIABLE(protodesc_cold);
  static const ::PROTOBUF_NAMESPACE_ID::internal::ParseTable schema[3]
    PROTOBUF_SECTION_VARIABLE(protodesc_cold);
  static const ::PROTOBUF_NAMESPACE_ID::internal::FieldMetadata field_metadata[];
  static const ::PROTOBUF_NAMESPACE_ID::internal::SerializationTable serialization_table[];
  static const ::PROTOBUF_NAMESPACE_ID::uint32 offsets[];
};
extern const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable descriptor_table_Coordination_2eproto;
namespace exec {
class DrillServiceInstance;
class DrillServiceInstanceDefaultTypeInternal;
extern DrillServiceInstanceDefaultTypeInternal _DrillServiceInstance_default_instance_;
class DrillbitEndpoint;
class DrillbitEndpointDefaultTypeInternal;
extern DrillbitEndpointDefaultTypeInternal _DrillbitEndpoint_default_instance_;
class Roles;
class RolesDefaultTypeInternal;
extern RolesDefaultTypeInternal _Roles_default_instance_;
}  // namespace exec
PROTOBUF_NAMESPACE_OPEN
template<> ::exec::DrillServiceInstance* Arena::CreateMaybeMessage<::exec::DrillServiceInstance>(Arena*);
template<> ::exec::DrillbitEndpoint* Arena::CreateMaybeMessage<::exec::DrillbitEndpoint>(Arena*);
template<> ::exec::Roles* Arena::CreateMaybeMessage<::exec::Roles>(Arena*);
PROTOBUF_NAMESPACE_CLOSE
namespace exec {

enum DrillbitEndpoint_State : int {
  DrillbitEndpoint_State_STARTUP = 0,
  DrillbitEndpoint_State_ONLINE = 1,
  DrillbitEndpoint_State_QUIESCENT = 2,
  DrillbitEndpoint_State_OFFLINE = 3
};
bool DrillbitEndpoint_State_IsValid(int value);
constexpr DrillbitEndpoint_State DrillbitEndpoint_State_State_MIN = DrillbitEndpoint_State_STARTUP;
constexpr DrillbitEndpoint_State DrillbitEndpoint_State_State_MAX = DrillbitEndpoint_State_OFFLINE;
constexpr int DrillbitEndpoint_State_State_ARRAYSIZE = DrillbitEndpoint_State_State_MAX + 1;

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

class DrillbitEndpoint :
    public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:exec.DrillbitEndpoint) */ {
 public:
  DrillbitEndpoint();
  virtual ~DrillbitEndpoint();

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

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

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

  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() {
    return GetDescriptor();
  }
  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() {
    return GetMetadataStatic().descriptor;
  }
  static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() {
    return GetMetadataStatic().reflection;
  }
  static const DrillbitEndpoint& default_instance();

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

  friend void swap(DrillbitEndpoint& a, DrillbitEndpoint& b) {
    a.Swap(&b);
  }
  inline void Swap(DrillbitEndpoint* other) {
    if (other == this) return;
    InternalSwap(other);
  }

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

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

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

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

  private:
  inline void SharedCtor();
  inline void SharedDtor();
  void SetCachedSize(int size) const final;
  void InternalSwap(DrillbitEndpoint* other);
  friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
  static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
    return "exec.DrillbitEndpoint";
  }
  private:
  inline ::PROTOBUF_NAMESPACE_ID::Arena* GetArenaNoVirtual() const {
    return nullptr;
  }
  inline void* MaybeArenaPtr() const {
    return nullptr;
  }
  public:

  ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final;
  private:
  static ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadataStatic() {
    ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors(&::descriptor_table_Coordination_2eproto);
    return ::descriptor_table_Coordination_2eproto.file_level_metadata[kIndexInFileMessages];
  }

  public:

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

  typedef DrillbitEndpoint_State State;
  static constexpr State STARTUP =
    DrillbitEndpoint_State_STARTUP;
  static constexpr State ONLINE =
    DrillbitEndpoint_State_ONLINE;
  static constexpr State QUIESCENT =
    DrillbitEndpoint_State_QUIESCENT;
  static constexpr State OFFLINE =
    DrillbitEndpoint_State_OFFLINE;
  static inline bool State_IsValid(int value) {
    return DrillbitEndpoint_State_IsValid(value);
  }
  static constexpr State State_MIN =
    DrillbitEndpoint_State_State_MIN;
  static constexpr State State_MAX =
    DrillbitEndpoint_State_State_MAX;
  static constexpr int State_ARRAYSIZE =
    DrillbitEndpoint_State_State_ARRAYSIZE;
  static inline const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor*
  State_descriptor() {
    return DrillbitEndpoint_State_descriptor();
  }
  template<typename T>
  static inline const std::string& State_Name(T enum_t_value) {
    static_assert(::std::is_same<T, State>::value ||
      ::std::is_integral<T>::value,
      "Incorrect type passed to function State_Name.");
    return DrillbitEndpoint_State_Name(enum_t_value);
  }
  static inline bool State_Parse(const std::string& name,
      State* value) {
    return DrillbitEndpoint_State_Parse(name, value);
  }

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

  enum : int {
    kAddressFieldNumber = 1,
    kVersionFieldNumber = 6,
    kRolesFieldNumber = 5,
    kUserPortFieldNumber = 2,
    kControlPortFieldNumber = 3,
    kDataPortFieldNumber = 4,
    kStateFieldNumber = 7,
    kHttpPortFieldNumber = 8,
  };
  // optional string address = 1;
  bool has_address() const;
  private:
  bool _internal_has_address() const;
  public:
  void clear_address();
  const std::string& address() const;
  void set_address(const std::string& value);
  void set_address(std::string&& value);
  void set_address(const char* value);
  void set_address(const char* value, size_t size);
  std::string* mutable_address();
  std::string* release_address();
  void set_allocated_address(std::string* address);
  private:
  const std::string& _internal_address() const;
  void _internal_set_address(const std::string& value);
  std::string* _internal_mutable_address();
  public:

  // optional string version = 6;
  bool has_version() const;
  private:
  bool _internal_has_version() const;
  public:
  void clear_version();
  const std::string& version() const;
  void set_version(const std::string& value);
  void set_version(std::string&& value);
  void set_version(const char* value);
  void set_version(const char* value, size_t size);
  std::string* mutable_version();
  std::string* release_version();
  void set_allocated_version(std::string* version);
  private:
  const std::string& _internal_version() const;
  void _internal_set_version(const std::string& value);
  std::string* _internal_mutable_version();
  public:

  // optional .exec.Roles roles = 5;
  bool has_roles() const;
  private:
  bool _internal_has_roles() const;
  public:
  void clear_roles();
  const ::exec::Roles& roles() const;
  ::exec::Roles* release_roles();
  ::exec::Roles* mutable_roles();
  void set_allocated_roles(::exec::Roles* roles);
  private:
  const ::exec::Roles& _internal_roles() const;
  ::exec::Roles* _internal_mutable_roles();
  public:

  // optional int32 user_port = 2;
  bool has_user_port() const;
  private:
  bool _internal_has_user_port() const;
  public:
  void clear_user_port();
  ::PROTOBUF_NAMESPACE_ID::int32 user_port() const;
  void set_user_port(::PROTOBUF_NAMESPACE_ID::int32 value);
  private:
  ::PROTOBUF_NAMESPACE_ID::int32 _internal_user_port() const;
  void _internal_set_user_port(::PROTOBUF_NAMESPACE_ID::int32 value);
  public:

  // optional int32 control_port = 3;
  bool has_control_port() const;
  private:
  bool _internal_has_control_port() const;
  public:
  void clear_control_port();
  ::PROTOBUF_NAMESPACE_ID::int32 control_port() const;
  void set_control_port(::PROTOBUF_NAMESPACE_ID::int32 value);
  private:
  ::PROTOBUF_NAMESPACE_ID::int32 _internal_control_port() const;
  void _internal_set_control_port(::PROTOBUF_NAMESPACE_ID::int32 value);
  public:

  // optional int32 data_port = 4;
  bool has_data_port() const;
  private:
  bool _internal_has_data_port() const;
  public:
  void clear_data_port();
  ::PROTOBUF_NAMESPACE_ID::int32 data_port() const;
  void set_data_port(::PROTOBUF_NAMESPACE_ID::int32 value);
  private:
  ::PROTOBUF_NAMESPACE_ID::int32 _internal_data_port() const;
  void _internal_set_data_port(::PROTOBUF_NAMESPACE_ID::int32 value);
  public:

  // optional .exec.DrillbitEndpoint.State state = 7;
  bool has_state() const;
  private:
  bool _internal_has_state() const;
  public:
  void clear_state();
  ::exec::DrillbitEndpoint_State state() const;
  void set_state(::exec::DrillbitEndpoint_State value);
  private:
  ::exec::DrillbitEndpoint_State _internal_state() const;
  void _internal_set_state(::exec::DrillbitEndpoint_State value);
  public:

  // optional int32 http_port = 8;
  bool has_http_port() const;
  private:
  bool _internal_has_http_port() const;
  public:
  void clear_http_port();
  ::PROTOBUF_NAMESPACE_ID::int32 http_port() const;
  void set_http_port(::PROTOBUF_NAMESPACE_ID::int32 value);
  private:
  ::PROTOBUF_NAMESPACE_ID::int32 _internal_http_port() const;
  void _internal_set_http_port(::PROTOBUF_NAMESPACE_ID::int32 value);
  public:

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

  ::PROTOBUF_NAMESPACE_ID::internal::InternalMetadataWithArena _internal_metadata_;
  ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_;
  mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
  ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr address_;
  ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr version_;
  ::exec::Roles* roles_;
  ::PROTOBUF_NAMESPACE_ID::int32 user_port_;
  ::PROTOBUF_NAMESPACE_ID::int32 control_port_;
  ::PROTOBUF_NAMESPACE_ID::int32 data_port_;
  int state_;
  ::PROTOBUF_NAMESPACE_ID::int32 http_port_;
  friend struct ::TableStruct_Coordination_2eproto;
};
// -------------------------------------------------------------------

class DrillServiceInstance :
    public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:exec.DrillServiceInstance) */ {
 public:
  DrillServiceInstance();
  virtual ~DrillServiceInstance();

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

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

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

  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() {
    return GetDescriptor();
  }
  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() {
    return GetMetadataStatic().descriptor;
  }
  static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() {
    return GetMetadataStatic().reflection;
  }
  static const DrillServiceInstance& default_instance();

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

  friend void swap(DrillServiceInstance& a, DrillServiceInstance& b) {
    a.Swap(&b);
  }
  inline void Swap(DrillServiceInstance* other) {
    if (other == this) return;
    InternalSwap(other);
  }

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

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

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

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

  private:
  inline void SharedCtor();
  inline void SharedDtor();
  void SetCachedSize(int size) const final;
  void InternalSwap(DrillServiceInstance* other);
  friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
  static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
    return "exec.DrillServiceInstance";
  }
  private:
  inline ::PROTOBUF_NAMESPACE_ID::Arena* GetArenaNoVirtual() const {
    return nullptr;
  }
  inline void* MaybeArenaPtr() const {
    return nullptr;
  }
  public:

  ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final;
  private:
  static ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadataStatic() {
    ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors(&::descriptor_table_Coordination_2eproto);
    return ::descriptor_table_Coordination_2eproto.file_level_metadata[kIndexInFileMessages];
  }

  public:

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

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

  enum : int {
    kIdFieldNumber = 1,
    kEndpointFieldNumber = 3,
    kRegistrationTimeUTCFieldNumber = 2,
  };
  // optional string id = 1;
  bool has_id() const;
  private:
  bool _internal_has_id() const;
  public:
  void clear_id();
  const std::string& id() const;
  void set_id(const std::string& value);
  void set_id(std::string&& value);
  void set_id(const char* value);
  void set_id(const char* value, size_t size);
  std::string* mutable_id();
  std::string* release_id();
  void set_allocated_id(std::string* id);
  private:
  const std::string& _internal_id() const;
  void _internal_set_id(const std::string& value);
  std::string* _internal_mutable_id();
  public:

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

  // optional int64 registrationTimeUTC = 2;
  bool has_registrationtimeutc() const;
  private:
  bool _internal_has_registrationtimeutc() const;
  public:
  void clear_registrationtimeutc();
  ::PROTOBUF_NAMESPACE_ID::int64 registrationtimeutc() const;
  void set_registrationtimeutc(::PROTOBUF_NAMESPACE_ID::int64 value);
  private:
  ::PROTOBUF_NAMESPACE_ID::int64 _internal_registrationtimeutc() const;
  void _internal_set_registrationtimeutc(::PROTOBUF_NAMESPACE_ID::int64 value);
  public:

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

  ::PROTOBUF_NAMESPACE_ID::internal::InternalMetadataWithArena _internal_metadata_;
  ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_;
  mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
  ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr id_;
  ::exec::DrillbitEndpoint* endpoint_;
  ::PROTOBUF_NAMESPACE_ID::int64 registrationtimeutc_;
  friend struct ::TableStruct_Coordination_2eproto;
};
// -------------------------------------------------------------------

class Roles :
    public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:exec.Roles) */ {
 public:
  Roles();
  virtual ~Roles();

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

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

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

  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() {
    return GetDescriptor();
  }
  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() {
    return GetMetadataStatic().descriptor;
  }
  static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() {
    return GetMetadataStatic().reflection;
  }
  static const Roles& default_instance();

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

  friend void swap(Roles& a, Roles& b) {
    a.Swap(&b);
  }
  inline void Swap(Roles* other) {
    if (other == this) return;
    InternalSwap(other);
  }

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

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

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

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

  private:
  inline void SharedCtor();
  inline void SharedDtor();
  void SetCachedSize(int size) const final;
  void InternalSwap(Roles* other);
  friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
  static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
    return "exec.Roles";
  }
  private:
  inline ::PROTOBUF_NAMESPACE_ID::Arena* GetArenaNoVirtual() const {
    return nullptr;
  }
  inline void* MaybeArenaPtr() const {
    return nullptr;
  }
  public:

  ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final;
  private:
  static ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadataStatic() {
    ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors(&::descriptor_table_Coordination_2eproto);
    return ::descriptor_table_Coordination_2eproto.file_level_metadata[kIndexInFileMessages];
  }

  public:

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

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

  enum : int {
    kSqlQueryFieldNumber = 1,
    kLogicalPlanFieldNumber = 2,
    kPhysicalPlanFieldNumber = 3,
    kJavaExecutorFieldNumber = 4,
    kDistributedCacheFieldNumber = 5,
  };
  // optional bool sql_query = 1 [default = true];
  bool has_sql_query() const;
  private:
  bool _internal_has_sql_query() const;
  public:
  void clear_sql_query();
  bool sql_query() const;
  void set_sql_query(bool value);
  private:
  bool _internal_sql_query() const;
  void _internal_set_sql_query(bool value);
  public:

  // optional bool logical_plan = 2 [default = true];
  bool has_logical_plan() const;
  private:
  bool _internal_has_logical_plan() const;
  public:
  void clear_logical_plan();
  bool logical_plan() const;
  void set_logical_plan(bool value);
  private:
  bool _internal_logical_plan() const;
  void _internal_set_logical_plan(bool value);
  public:

  // optional bool physical_plan = 3 [default = true];
  bool has_physical_plan() const;
  private:
  bool _internal_has_physical_plan() const;
  public:
  void clear_physical_plan();
  bool physical_plan() const;
  void set_physical_plan(bool value);
  private:
  bool _internal_physical_plan() const;
  void _internal_set_physical_plan(bool value);
  public:

  // optional bool java_executor = 4 [default = true];
  bool has_java_executor() const;
  private:
  bool _internal_has_java_executor() const;
  public:
  void clear_java_executor();
  bool java_executor() const;
  void set_java_executor(bool value);
  private:
  bool _internal_java_executor() const;
  void _internal_set_java_executor(bool value);
  public:

  // optional bool distributed_cache = 5 [default = true];
  bool has_distributed_cache() const;
  private:
  bool _internal_has_distributed_cache() const;
  public:
  void clear_distributed_cache();
  bool distributed_cache() const;
  void set_distributed_cache(bool value);
  private:
  bool _internal_distributed_cache() const;
  void _internal_set_distributed_cache(bool value);
  public:

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

  ::PROTOBUF_NAMESPACE_ID::internal::InternalMetadataWithArena _internal_metadata_;
  ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_;
  mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
  bool sql_query_;
  bool logical_plan_;
  bool physical_plan_;
  bool java_executor_;
  bool distributed_cache_;
  friend struct ::TableStruct_Coordination_2eproto;
};
// ===================================================================


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

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

// optional string address = 1;
inline bool DrillbitEndpoint::_internal_has_address() const {
  bool value = (_has_bits_[0] & 0x00000001u) != 0;
  return value;
}
inline bool DrillbitEndpoint::has_address() const {
  return _internal_has_address();
}
inline void DrillbitEndpoint::clear_address() {
  address_.ClearToEmptyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
  _has_bits_[0] &= ~0x00000001u;
}
inline const std::string& DrillbitEndpoint::address() const {
  // @@protoc_insertion_point(field_get:exec.DrillbitEndpoint.address)
  return _internal_address();
}
inline void DrillbitEndpoint::set_address(const std::string& value) {
  _internal_set_address(value);
  // @@protoc_insertion_point(field_set:exec.DrillbitEndpoint.address)
}
inline std::string* DrillbitEndpoint::mutable_address() {
  // @@protoc_insertion_point(field_mutable:exec.DrillbitEndpoint.address)
  return _internal_mutable_address();
}
inline const std::string& DrillbitEndpoint::_internal_address() const {
  return address_.GetNoArena();
}
inline void DrillbitEndpoint::_internal_set_address(const std::string& value) {
  _has_bits_[0] |= 0x00000001u;
  address_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value);
}
inline void DrillbitEndpoint::set_address(std::string&& value) {
  _has_bits_[0] |= 0x00000001u;
  address_.SetNoArena(
    &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
  // @@protoc_insertion_point(field_set_rvalue:exec.DrillbitEndpoint.address)
}
inline void DrillbitEndpoint::set_address(const char* value) {
  GOOGLE_DCHECK(value != nullptr);
  _has_bits_[0] |= 0x00000001u;
  address_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
  // @@protoc_insertion_point(field_set_char:exec.DrillbitEndpoint.address)
}
inline void DrillbitEndpoint::set_address(const char* value, size_t size) {
  _has_bits_[0] |= 0x00000001u;
  address_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(),
      ::std::string(reinterpret_cast<const char*>(value), size));
  // @@protoc_insertion_point(field_set_pointer:exec.DrillbitEndpoint.address)
}
inline std::string* DrillbitEndpoint::_internal_mutable_address() {
  _has_bits_[0] |= 0x00000001u;
  return address_.MutableNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
}
inline std::string* DrillbitEndpoint::release_address() {
  // @@protoc_insertion_point(field_release:exec.DrillbitEndpoint.address)
  if (!_internal_has_address()) {
    return nullptr;
  }
  _has_bits_[0] &= ~0x00000001u;
  return address_.ReleaseNonDefaultNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
}
inline void DrillbitEndpoint::set_allocated_address(std::string* address) {
  if (address != nullptr) {
    _has_bits_[0] |= 0x00000001u;
  } else {
    _has_bits_[0] &= ~0x00000001u;
  }
  address_.SetAllocatedNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), address);
  // @@protoc_insertion_point(field_set_allocated:exec.DrillbitEndpoint.address)
}

// optional int32 user_port = 2;
inline bool DrillbitEndpoint::_internal_has_user_port() const {
  bool value = (_has_bits_[0] & 0x00000008u) != 0;
  return value;
}
inline bool DrillbitEndpoint::has_user_port() const {
  return _internal_has_user_port();
}
inline void DrillbitEndpoint::clear_user_port() {
  user_port_ = 0;
  _has_bits_[0] &= ~0x00000008u;
}
inline ::PROTOBUF_NAMESPACE_ID::int32 DrillbitEndpoint::_internal_user_port() const {
  return user_port_;
}
inline ::PROTOBUF_NAMESPACE_ID::int32 DrillbitEndpoint::user_port() const {
  // @@protoc_insertion_point(field_get:exec.DrillbitEndpoint.user_port)
  return _internal_user_port();
}
inline void DrillbitEndpoint::_internal_set_user_port(::PROTOBUF_NAMESPACE_ID::int32 value) {
  _has_bits_[0] |= 0x00000008u;
  user_port_ = value;
}
inline void DrillbitEndpoint::set_user_port(::PROTOBUF_NAMESPACE_ID::int32 value) {
  _internal_set_user_port(value);
  // @@protoc_insertion_point(field_set:exec.DrillbitEndpoint.user_port)
}

// optional int32 control_port = 3;
inline bool DrillbitEndpoint::_internal_has_control_port() const {
  bool value = (_has_bits_[0] & 0x00000010u) != 0;
  return value;
}
inline bool DrillbitEndpoint::has_control_port() const {
  return _internal_has_control_port();
}
inline void DrillbitEndpoint::clear_control_port() {
  control_port_ = 0;
  _has_bits_[0] &= ~0x00000010u;
}
inline ::PROTOBUF_NAMESPACE_ID::int32 DrillbitEndpoint::_internal_control_port() const {
  return control_port_;
}
inline ::PROTOBUF_NAMESPACE_ID::int32 DrillbitEndpoint::control_port() const {
  // @@protoc_insertion_point(field_get:exec.DrillbitEndpoint.control_port)
  return _internal_control_port();
}
inline void DrillbitEndpoint::_internal_set_control_port(::PROTOBUF_NAMESPACE_ID::int32 value) {
  _has_bits_[0] |= 0x00000010u;
  control_port_ = value;
}
inline void DrillbitEndpoint::set_control_port(::PROTOBUF_NAMESPACE_ID::int32 value) {
  _internal_set_control_port(value);
  // @@protoc_insertion_point(field_set:exec.DrillbitEndpoint.control_port)
}

// optional int32 data_port = 4;
inline bool DrillbitEndpoint::_internal_has_data_port() const {
  bool value = (_has_bits_[0] & 0x00000020u) != 0;
  return value;
}
inline bool DrillbitEndpoint::has_data_port() const {
  return _internal_has_data_port();
}
inline void DrillbitEndpoint::clear_data_port() {
  data_port_ = 0;
  _has_bits_[0] &= ~0x00000020u;
}
inline ::PROTOBUF_NAMESPACE_ID::int32 DrillbitEndpoint::_internal_data_port() const {
  return data_port_;
}
inline ::PROTOBUF_NAMESPACE_ID::int32 DrillbitEndpoint::data_port() const {
  // @@protoc_insertion_point(field_get:exec.DrillbitEndpoint.data_port)
  return _internal_data_port();
}
inline void DrillbitEndpoint::_internal_set_data_port(::PROTOBUF_NAMESPACE_ID::int32 value) {
  _has_bits_[0] |= 0x00000020u;
  data_port_ = value;
}
inline void DrillbitEndpoint::set_data_port(::PROTOBUF_NAMESPACE_ID::int32 value) {
  _internal_set_data_port(value);
  // @@protoc_insertion_point(field_set:exec.DrillbitEndpoint.data_port)
}

// optional .exec.Roles roles = 5;
inline bool DrillbitEndpoint::_internal_has_roles() const {
  bool value = (_has_bits_[0] & 0x00000004u) != 0;
  PROTOBUF_ASSUME(!value || roles_ != nullptr);
  return value;
}
inline bool DrillbitEndpoint::has_roles() const {
  return _internal_has_roles();
}
inline void DrillbitEndpoint::clear_roles() {
  if (roles_ != nullptr) roles_->Clear();
  _has_bits_[0] &= ~0x00000004u;
}
inline const ::exec::Roles& DrillbitEndpoint::_internal_roles() const {
  const ::exec::Roles* p = roles_;
  return p != nullptr ? *p : *reinterpret_cast<const ::exec::Roles*>(
      &::exec::_Roles_default_instance_);
}
inline const ::exec::Roles& DrillbitEndpoint::roles() const {
  // @@protoc_insertion_point(field_get:exec.DrillbitEndpoint.roles)
  return _internal_roles();
}
inline ::exec::Roles* DrillbitEndpoint::release_roles() {
  // @@protoc_insertion_point(field_release:exec.DrillbitEndpoint.roles)
  _has_bits_[0] &= ~0x00000004u;
  ::exec::Roles* temp = roles_;
  roles_ = nullptr;
  return temp;
}
inline ::exec::Roles* DrillbitEndpoint::_internal_mutable_roles() {
  _has_bits_[0] |= 0x00000004u;
  if (roles_ == nullptr) {
    auto* p = CreateMaybeMessage<::exec::Roles>(GetArenaNoVirtual());
    roles_ = p;
  }
  return roles_;
}
inline ::exec::Roles* DrillbitEndpoint::mutable_roles() {
  // @@protoc_insertion_point(field_mutable:exec.DrillbitEndpoint.roles)
  return _internal_mutable_roles();
}
inline void DrillbitEndpoint::set_allocated_roles(::exec::Roles* roles) {
  ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArenaNoVirtual();
  if (message_arena == nullptr) {
    delete roles_;
  }
  if (roles) {
    ::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena = nullptr;
    if (message_arena != submessage_arena) {
      roles = ::PROTOBUF_NAMESPACE_ID::internal::GetOwnedMessage(
          message_arena, roles, submessage_arena);
    }
    _has_bits_[0] |= 0x00000004u;
  } else {
    _has_bits_[0] &= ~0x00000004u;
  }
  roles_ = roles;
  // @@protoc_insertion_point(field_set_allocated:exec.DrillbitEndpoint.roles)
}

// optional string version = 6;
inline bool DrillbitEndpoint::_internal_has_version() const {
  bool value = (_has_bits_[0] & 0x00000002u) != 0;
  return value;
}
inline bool DrillbitEndpoint::has_version() const {
  return _internal_has_version();
}
inline void DrillbitEndpoint::clear_version() {
  version_.ClearToEmptyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
  _has_bits_[0] &= ~0x00000002u;
}
inline const std::string& DrillbitEndpoint::version() const {
  // @@protoc_insertion_point(field_get:exec.DrillbitEndpoint.version)
  return _internal_version();
}
inline void DrillbitEndpoint::set_version(const std::string& value) {
  _internal_set_version(value);
  // @@protoc_insertion_point(field_set:exec.DrillbitEndpoint.version)
}
inline std::string* DrillbitEndpoint::mutable_version() {
  // @@protoc_insertion_point(field_mutable:exec.DrillbitEndpoint.version)
  return _internal_mutable_version();
}
inline const std::string& DrillbitEndpoint::_internal_version() const {
  return version_.GetNoArena();
}
inline void DrillbitEndpoint::_internal_set_version(const std::string& value) {
  _has_bits_[0] |= 0x00000002u;
  version_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value);
}
inline void DrillbitEndpoint::set_version(std::string&& value) {
  _has_bits_[0] |= 0x00000002u;
  version_.SetNoArena(
    &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
  // @@protoc_insertion_point(field_set_rvalue:exec.DrillbitEndpoint.version)
}
inline void DrillbitEndpoint::set_version(const char* value) {
  GOOGLE_DCHECK(value != nullptr);
  _has_bits_[0] |= 0x00000002u;
  version_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
  // @@protoc_insertion_point(field_set_char:exec.DrillbitEndpoint.version)
}
inline void DrillbitEndpoint::set_version(const char* value, size_t size) {
  _has_bits_[0] |= 0x00000002u;
  version_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(),
      ::std::string(reinterpret_cast<const char*>(value), size));
  // @@protoc_insertion_point(field_set_pointer:exec.DrillbitEndpoint.version)
}
inline std::string* DrillbitEndpoint::_internal_mutable_version() {
  _has_bits_[0] |= 0x00000002u;
  return version_.MutableNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
}
inline std::string* DrillbitEndpoint::release_version() {
  // @@protoc_insertion_point(field_release:exec.DrillbitEndpoint.version)
  if (!_internal_has_version()) {
    return nullptr;
  }
  _has_bits_[0] &= ~0x00000002u;
  return version_.ReleaseNonDefaultNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
}
inline void DrillbitEndpoint::set_allocated_version(std::string* version) {
  if (version != nullptr) {
    _has_bits_[0] |= 0x00000002u;
  } else {
    _has_bits_[0] &= ~0x00000002u;
  }
  version_.SetAllocatedNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), version);
  // @@protoc_insertion_point(field_set_allocated:exec.DrillbitEndpoint.version)
}

// optional .exec.DrillbitEndpoint.State state = 7;
inline bool DrillbitEndpoint::_internal_has_state() const {
  bool value = (_has_bits_[0] & 0x00000040u) != 0;
  return value;
}
inline bool DrillbitEndpoint::has_state() const {
  return _internal_has_state();
}
inline void DrillbitEndpoint::clear_state() {
  state_ = 0;
  _has_bits_[0] &= ~0x00000040u;
}
inline ::exec::DrillbitEndpoint_State DrillbitEndpoint::_internal_state() const {
  return static_cast< ::exec::DrillbitEndpoint_State >(state_);
}
inline ::exec::DrillbitEndpoint_State DrillbitEndpoint::state() const {
  // @@protoc_insertion_point(field_get:exec.DrillbitEndpoint.state)
  return _internal_state();
}
inline void DrillbitEndpoint::_internal_set_state(::exec::DrillbitEndpoint_State value) {
  assert(::exec::DrillbitEndpoint_State_IsValid(value));
  _has_bits_[0] |= 0x00000040u;
  state_ = value;
}
inline void DrillbitEndpoint::set_state(::exec::DrillbitEndpoint_State value) {
  _internal_set_state(value);
  // @@protoc_insertion_point(field_set:exec.DrillbitEndpoint.state)
}

// optional int32 http_port = 8;
inline bool DrillbitEndpoint::_internal_has_http_port() const {
  bool value = (_has_bits_[0] & 0x00000080u) != 0;
  return value;
}
inline bool DrillbitEndpoint::has_http_port() const {
  return _internal_has_http_port();
}
inline void DrillbitEndpoint::clear_http_port() {
  http_port_ = 0;
  _has_bits_[0] &= ~0x00000080u;
}
inline ::PROTOBUF_NAMESPACE_ID::int32 DrillbitEndpoint::_internal_http_port() const {
  return http_port_;
}
inline ::PROTOBUF_NAMESPACE_ID::int32 DrillbitEndpoint::http_port() const {
  // @@protoc_insertion_point(field_get:exec.DrillbitEndpoint.http_port)
  return _internal_http_port();
}
inline void DrillbitEndpoint::_internal_set_http_port(::PROTOBUF_NAMESPACE_ID::int32 value) {
  _has_bits_[0] |= 0x00000080u;
  http_port_ = value;
}
inline void DrillbitEndpoint::set_http_port(::PROTOBUF_NAMESPACE_ID::int32 value) {
  _internal_set_http_port(value);
  // @@protoc_insertion_point(field_set:exec.DrillbitEndpoint.http_port)
}

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

// DrillServiceInstance

// optional string id = 1;
inline bool DrillServiceInstance::_internal_has_id() const {
  bool value = (_has_bits_[0] & 0x00000001u) != 0;
  return value;
}
inline bool DrillServiceInstance::has_id() const {
  return _internal_has_id();
}
inline void DrillServiceInstance::clear_id() {
  id_.ClearToEmptyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
  _has_bits_[0] &= ~0x00000001u;
}
inline const std::string& DrillServiceInstance::id() const {
  // @@protoc_insertion_point(field_get:exec.DrillServiceInstance.id)
  return _internal_id();
}
inline void DrillServiceInstance::set_id(const std::string& value) {
  _internal_set_id(value);
  // @@protoc_insertion_point(field_set:exec.DrillServiceInstance.id)
}
inline std::string* DrillServiceInstance::mutable_id() {
  // @@protoc_insertion_point(field_mutable:exec.DrillServiceInstance.id)
  return _internal_mutable_id();
}
inline const std::string& DrillServiceInstance::_internal_id() const {
  return id_.GetNoArena();
}
inline void DrillServiceInstance::_internal_set_id(const std::string& value) {
  _has_bits_[0] |= 0x00000001u;
  id_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value);
}
inline void DrillServiceInstance::set_id(std::string&& value) {
  _has_bits_[0] |= 0x00000001u;
  id_.SetNoArena(
    &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
  // @@protoc_insertion_point(field_set_rvalue:exec.DrillServiceInstance.id)
}
inline void DrillServiceInstance::set_id(const char* value) {
  GOOGLE_DCHECK(value != nullptr);
  _has_bits_[0] |= 0x00000001u;
  id_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
  // @@protoc_insertion_point(field_set_char:exec.DrillServiceInstance.id)
}
inline void DrillServiceInstance::set_id(const char* value, size_t size) {
  _has_bits_[0] |= 0x00000001u;
  id_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(),
      ::std::string(reinterpret_cast<const char*>(value), size));
  // @@protoc_insertion_point(field_set_pointer:exec.DrillServiceInstance.id)
}
inline std::string* DrillServiceInstance::_internal_mutable_id() {
  _has_bits_[0] |= 0x00000001u;
  return id_.MutableNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
}
inline std::string* DrillServiceInstance::release_id() {
  // @@protoc_insertion_point(field_release:exec.DrillServiceInstance.id)
  if (!_internal_has_id()) {
    return nullptr;
  }
  _has_bits_[0] &= ~0x00000001u;
  return id_.ReleaseNonDefaultNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
}
inline void DrillServiceInstance::set_allocated_id(std::string* id) {
  if (id != nullptr) {
    _has_bits_[0] |= 0x00000001u;
  } else {
    _has_bits_[0] &= ~0x00000001u;
  }
  id_.SetAllocatedNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), id);
  // @@protoc_insertion_point(field_set_allocated:exec.DrillServiceInstance.id)
}

// optional int64 registrationTimeUTC = 2;
inline bool DrillServiceInstance::_internal_has_registrationtimeutc() const {
  bool value = (_has_bits_[0] & 0x00000004u) != 0;
  return value;
}
inline bool DrillServiceInstance::has_registrationtimeutc() const {
  return _internal_has_registrationtimeutc();
}
inline void DrillServiceInstance::clear_registrationtimeutc() {
  registrationtimeutc_ = PROTOBUF_LONGLONG(0);
  _has_bits_[0] &= ~0x00000004u;
}
inline ::PROTOBUF_NAMESPACE_ID::int64 DrillServiceInstance::_internal_registrationtimeutc() const {
  return registrationtimeutc_;
}
inline ::PROTOBUF_NAMESPACE_ID::int64 DrillServiceInstance::registrationtimeutc() const {
  // @@protoc_insertion_point(field_get:exec.DrillServiceInstance.registrationTimeUTC)
  return _internal_registrationtimeutc();
}
inline void DrillServiceInstance::_internal_set_registrationtimeutc(::PROTOBUF_NAMESPACE_ID::int64 value) {
  _has_bits_[0] |= 0x00000004u;
  registrationtimeutc_ = value;
}
inline void DrillServiceInstance::set_registrationtimeutc(::PROTOBUF_NAMESPACE_ID::int64 value) {
  _internal_set_registrationtimeutc(value);
  // @@protoc_insertion_point(field_set:exec.DrillServiceInstance.registrationTimeUTC)
}

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

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

// Roles

// optional bool sql_query = 1 [default = true];
inline bool Roles::_internal_has_sql_query() const {
  bool value = (_has_bits_[0] & 0x00000001u) != 0;
  return value;
}
inline bool Roles::has_sql_query() const {
  return _internal_has_sql_query();
}
inline void Roles::clear_sql_query() {
  sql_query_ = true;
  _has_bits_[0] &= ~0x00000001u;
}
inline bool Roles::_internal_sql_query() const {
  return sql_query_;
}
inline bool Roles::sql_query() const {
  // @@protoc_insertion_point(field_get:exec.Roles.sql_query)
  return _internal_sql_query();
}
inline void Roles::_internal_set_sql_query(bool value) {
  _has_bits_[0] |= 0x00000001u;
  sql_query_ = value;
}
inline void Roles::set_sql_query(bool value) {
  _internal_set_sql_query(value);
  // @@protoc_insertion_point(field_set:exec.Roles.sql_query)
}

// optional bool logical_plan = 2 [default = true];
inline bool Roles::_internal_has_logical_plan() const {
  bool value = (_has_bits_[0] & 0x00000002u) != 0;
  return value;
}
inline bool Roles::has_logical_plan() const {
  return _internal_has_logical_plan();
}
inline void Roles::clear_logical_plan() {
  logical_plan_ = true;
  _has_bits_[0] &= ~0x00000002u;
}
inline bool Roles::_internal_logical_plan() const {
  return logical_plan_;
}
inline bool Roles::logical_plan() const {
  // @@protoc_insertion_point(field_get:exec.Roles.logical_plan)
  return _internal_logical_plan();
}
inline void Roles::_internal_set_logical_plan(bool value) {
  _has_bits_[0] |= 0x00000002u;
  logical_plan_ = value;
}
inline void Roles::set_logical_plan(bool value) {
  _internal_set_logical_plan(value);
  // @@protoc_insertion_point(field_set:exec.Roles.logical_plan)
}

// optional bool physical_plan = 3 [default = true];
inline bool Roles::_internal_has_physical_plan() const {
  bool value = (_has_bits_[0] & 0x00000004u) != 0;
  return value;
}
inline bool Roles::has_physical_plan() const {
  return _internal_has_physical_plan();
}
inline void Roles::clear_physical_plan() {
  physical_plan_ = true;
  _has_bits_[0] &= ~0x00000004u;
}
inline bool Roles::_internal_physical_plan() const {
  return physical_plan_;
}
inline bool Roles::physical_plan() const {
  // @@protoc_insertion_point(field_get:exec.Roles.physical_plan)
  return _internal_physical_plan();
}
inline void Roles::_internal_set_physical_plan(bool value) {
  _has_bits_[0] |= 0x00000004u;
  physical_plan_ = value;
}
inline void Roles::set_physical_plan(bool value) {
  _internal_set_physical_plan(value);
  // @@protoc_insertion_point(field_set:exec.Roles.physical_plan)
}

// optional bool java_executor = 4 [default = true];
inline bool Roles::_internal_has_java_executor() const {
  bool value = (_has_bits_[0] & 0x00000008u) != 0;
  return value;
}
inline bool Roles::has_java_executor() const {
  return _internal_has_java_executor();
}
inline void Roles::clear_java_executor() {
  java_executor_ = true;
  _has_bits_[0] &= ~0x00000008u;
}
inline bool Roles::_internal_java_executor() const {
  return java_executor_;
}
inline bool Roles::java_executor() const {
  // @@protoc_insertion_point(field_get:exec.Roles.java_executor)
  return _internal_java_executor();
}
inline void Roles::_internal_set_java_executor(bool value) {
  _has_bits_[0] |= 0x00000008u;
  java_executor_ = value;
}
inline void Roles::set_java_executor(bool value) {
  _internal_set_java_executor(value);
  // @@protoc_insertion_point(field_set:exec.Roles.java_executor)
}

// optional bool distributed_cache = 5 [default = true];
inline bool Roles::_internal_has_distributed_cache() const {
  bool value = (_has_bits_[0] & 0x00000010u) != 0;
  return value;
}
inline bool Roles::has_distributed_cache() const {
  return _internal_has_distributed_cache();
}
inline void Roles::clear_distributed_cache() {
  distributed_cache_ = true;
  _has_bits_[0] &= ~0x00000010u;
}
inline bool Roles::_internal_distributed_cache() const {
  return distributed_cache_;
}
inline bool Roles::distributed_cache() const {
  // @@protoc_insertion_point(field_get:exec.Roles.distributed_cache)
  return _internal_distributed_cache();
}
inline void Roles::_internal_set_distributed_cache(bool value) {
  _has_bits_[0] |= 0x00000010u;
  distributed_cache_ = value;
}
inline void Roles::set_distributed_cache(bool value) {
  _internal_set_distributed_cache(value);
  // @@protoc_insertion_point(field_set:exec.Roles.distributed_cache)
}

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

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


// @@protoc_insertion_point(namespace_scope)

}  // namespace exec

PROTOBUF_NAMESPACE_OPEN

template <> struct is_proto_enum< ::exec::DrillbitEndpoint_State> : ::std::true_type {};
template <>
inline const EnumDescriptor* GetEnumDescriptor< ::exec::DrillbitEndpoint_State>() {
  return ::exec::DrillbitEndpoint_State_descriptor();
}

PROTOBUF_NAMESPACE_CLOSE

// @@protoc_insertion_point(global_scope)

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