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

#ifndef GOOGLE_PROTOBUF_INCLUDED_GeneralRPC_2eproto
#define GOOGLE_PROTOBUF_INCLUDED_GeneralRPC_2eproto

#include <limits>
#include <string>

#include <google/protobuf/port_def.inc>
#if PROTOBUF_VERSION < 3016000
#error This file was generated by a newer version of protoc which is
#error incompatible with your Protocol Buffer headers. Please update
#error your headers.
#endif
#if 3016003 < PROTOBUF_MIN_PROTOC_VERSION
#error This file was generated by an older version of protoc which is
#error incompatible with your Protocol Buffer headers. Please
#error regenerate this file with a newer version of protoc.
#endif

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

// Internal implementation detail -- do not use these members.
struct TableStruct_GeneralRPC_2eproto {
  static const ::PROTOBUF_NAMESPACE_ID::internal::ParseTableField entries[]
    PROTOBUF_SECTION_VARIABLE(protodesc_cold);
  static const ::PROTOBUF_NAMESPACE_ID::internal::AuxiliaryParseTableField aux[]
    PROTOBUF_SECTION_VARIABLE(protodesc_cold);
  static const ::PROTOBUF_NAMESPACE_ID::internal::ParseTable schema[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_GeneralRPC_2eproto;
namespace exec {
namespace rpc {
class Ack;
struct AckDefaultTypeInternal;
extern AckDefaultTypeInternal _Ack_default_instance_;
class CompleteRpcMessage;
struct CompleteRpcMessageDefaultTypeInternal;
extern CompleteRpcMessageDefaultTypeInternal _CompleteRpcMessage_default_instance_;
class RpcHeader;
struct RpcHeaderDefaultTypeInternal;
extern RpcHeaderDefaultTypeInternal _RpcHeader_default_instance_;
}  // namespace rpc
}  // namespace exec
PROTOBUF_NAMESPACE_OPEN
template<> ::exec::rpc::Ack* Arena::CreateMaybeMessage<::exec::rpc::Ack>(Arena*);
template<> ::exec::rpc::CompleteRpcMessage* Arena::CreateMaybeMessage<::exec::rpc::CompleteRpcMessage>(Arena*);
template<> ::exec::rpc::RpcHeader* Arena::CreateMaybeMessage<::exec::rpc::RpcHeader>(Arena*);
PROTOBUF_NAMESPACE_CLOSE
namespace exec {
namespace rpc {

enum RpcMode : int {
  REQUEST = 0,
  RESPONSE = 1,
  RESPONSE_FAILURE = 2,
  PING = 3,
  PONG = 4
};
bool RpcMode_IsValid(int value);
constexpr RpcMode RpcMode_MIN = REQUEST;
constexpr RpcMode RpcMode_MAX = PONG;
constexpr int RpcMode_ARRAYSIZE = RpcMode_MAX + 1;

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

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

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

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

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

  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() {
    return GetDescriptor();
  }
  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() {
    return default_instance().GetMetadata().descriptor;
  }
  static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() {
    return default_instance().GetMetadata().reflection;
  }
  static const Ack& default_instance() {
    return *internal_default_instance();
  }
  static inline const Ack* internal_default_instance() {
    return reinterpret_cast<const Ack*>(
               &_Ack_default_instance_);
  }
  static constexpr int kIndexInFileMessages =
    0;

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

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

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

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

  ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final;

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

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

  enum : int {
    kOkFieldNumber = 1,
  };
  // optional bool ok = 1;
  bool has_ok() const;
  private:
  bool _internal_has_ok() const;
  public:
  void clear_ok();
  bool ok() const;
  void set_ok(bool value);
  private:
  bool _internal_ok() const;
  void _internal_set_ok(bool value);
  public:

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

  template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper;
  typedef void InternalArenaConstructable_;
  typedef void DestructorSkippable_;
  ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_;
  mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
  bool ok_;
  friend struct ::TableStruct_GeneralRPC_2eproto;
};
// -------------------------------------------------------------------

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

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

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

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

  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() {
    return GetDescriptor();
  }
  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() {
    return default_instance().GetMetadata().descriptor;
  }
  static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() {
    return default_instance().GetMetadata().reflection;
  }
  static const RpcHeader& default_instance() {
    return *internal_default_instance();
  }
  static inline const RpcHeader* internal_default_instance() {
    return reinterpret_cast<const RpcHeader*>(
               &_RpcHeader_default_instance_);
  }
  static constexpr int kIndexInFileMessages =
    1;

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

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

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

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

  ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final;

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

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

  enum : int {
    kModeFieldNumber = 1,
    kCoordinationIdFieldNumber = 2,
    kRpcTypeFieldNumber = 3,
  };
  // optional .exec.rpc.RpcMode mode = 1;
  bool has_mode() const;
  private:
  bool _internal_has_mode() const;
  public:
  void clear_mode();
  ::exec::rpc::RpcMode mode() const;
  void set_mode(::exec::rpc::RpcMode value);
  private:
  ::exec::rpc::RpcMode _internal_mode() const;
  void _internal_set_mode(::exec::rpc::RpcMode value);
  public:

  // optional int32 coordination_id = 2;
  bool has_coordination_id() const;
  private:
  bool _internal_has_coordination_id() const;
  public:
  void clear_coordination_id();
  ::PROTOBUF_NAMESPACE_ID::int32 coordination_id() const;
  void set_coordination_id(::PROTOBUF_NAMESPACE_ID::int32 value);
  private:
  ::PROTOBUF_NAMESPACE_ID::int32 _internal_coordination_id() const;
  void _internal_set_coordination_id(::PROTOBUF_NAMESPACE_ID::int32 value);
  public:

  // optional int32 rpc_type = 3;
  bool has_rpc_type() const;
  private:
  bool _internal_has_rpc_type() const;
  public:
  void clear_rpc_type();
  ::PROTOBUF_NAMESPACE_ID::int32 rpc_type() const;
  void set_rpc_type(::PROTOBUF_NAMESPACE_ID::int32 value);
  private:
  ::PROTOBUF_NAMESPACE_ID::int32 _internal_rpc_type() const;
  void _internal_set_rpc_type(::PROTOBUF_NAMESPACE_ID::int32 value);
  public:

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

  template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper;
  typedef void InternalArenaConstructable_;
  typedef void DestructorSkippable_;
  ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_;
  mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
  int mode_;
  ::PROTOBUF_NAMESPACE_ID::int32 coordination_id_;
  ::PROTOBUF_NAMESPACE_ID::int32 rpc_type_;
  friend struct ::TableStruct_GeneralRPC_2eproto;
};
// -------------------------------------------------------------------

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

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

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

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

  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() {
    return GetDescriptor();
  }
  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() {
    return default_instance().GetMetadata().descriptor;
  }
  static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() {
    return default_instance().GetMetadata().reflection;
  }
  static const CompleteRpcMessage& default_instance() {
    return *internal_default_instance();
  }
  static inline const CompleteRpcMessage* internal_default_instance() {
    return reinterpret_cast<const CompleteRpcMessage*>(
               &_CompleteRpcMessage_default_instance_);
  }
  static constexpr int kIndexInFileMessages =
    2;

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

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

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

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

  ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final;

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

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

  enum : int {
    kProtobufBodyFieldNumber = 2,
    kRawBodyFieldNumber = 3,
    kHeaderFieldNumber = 1,
  };
  // optional bytes protobuf_body = 2;
  bool has_protobuf_body() const;
  private:
  bool _internal_has_protobuf_body() const;
  public:
  void clear_protobuf_body();
  const std::string& protobuf_body() const;
  template <typename ArgT0 = const std::string&, typename... ArgT>
  void set_protobuf_body(ArgT0&& arg0, ArgT... args);
  std::string* mutable_protobuf_body();
  std::string* release_protobuf_body();
  void set_allocated_protobuf_body(std::string* protobuf_body);
  private:
  const std::string& _internal_protobuf_body() const;
  void _internal_set_protobuf_body(const std::string& value);
  std::string* _internal_mutable_protobuf_body();
  public:

  // optional bytes raw_body = 3;
  bool has_raw_body() const;
  private:
  bool _internal_has_raw_body() const;
  public:
  void clear_raw_body();
  const std::string& raw_body() const;
  template <typename ArgT0 = const std::string&, typename... ArgT>
  void set_raw_body(ArgT0&& arg0, ArgT... args);
  std::string* mutable_raw_body();
  std::string* release_raw_body();
  void set_allocated_raw_body(std::string* raw_body);
  private:
  const std::string& _internal_raw_body() const;
  void _internal_set_raw_body(const std::string& value);
  std::string* _internal_mutable_raw_body();
  public:

  // optional .exec.rpc.RpcHeader header = 1;
  bool has_header() const;
  private:
  bool _internal_has_header() const;
  public:
  void clear_header();
  const ::exec::rpc::RpcHeader& header() const;
  ::exec::rpc::RpcHeader* release_header();
  ::exec::rpc::RpcHeader* mutable_header();
  void set_allocated_header(::exec::rpc::RpcHeader* header);
  private:
  const ::exec::rpc::RpcHeader& _internal_header() const;
  ::exec::rpc::RpcHeader* _internal_mutable_header();
  public:
  void unsafe_arena_set_allocated_header(
      ::exec::rpc::RpcHeader* header);
  ::exec::rpc::RpcHeader* unsafe_arena_release_header();

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

  template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper;
  typedef void InternalArenaConstructable_;
  typedef void DestructorSkippable_;
  ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_;
  mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
  ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr protobuf_body_;
  ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr raw_body_;
  ::exec::rpc::RpcHeader* header_;
  friend struct ::TableStruct_GeneralRPC_2eproto;
};
// ===================================================================


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

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

// optional bool ok = 1;
inline bool Ack::_internal_has_ok() const {
  bool value = (_has_bits_[0] & 0x00000001u) != 0;
  return value;
}
inline bool Ack::has_ok() const {
  return _internal_has_ok();
}
inline void Ack::clear_ok() {
  ok_ = false;
  _has_bits_[0] &= ~0x00000001u;
}
inline bool Ack::_internal_ok() const {
  return ok_;
}
inline bool Ack::ok() const {
  // @@protoc_insertion_point(field_get:exec.rpc.Ack.ok)
  return _internal_ok();
}
inline void Ack::_internal_set_ok(bool value) {
  _has_bits_[0] |= 0x00000001u;
  ok_ = value;
}
inline void Ack::set_ok(bool value) {
  _internal_set_ok(value);
  // @@protoc_insertion_point(field_set:exec.rpc.Ack.ok)
}

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

// RpcHeader

// optional .exec.rpc.RpcMode mode = 1;
inline bool RpcHeader::_internal_has_mode() const {
  bool value = (_has_bits_[0] & 0x00000001u) != 0;
  return value;
}
inline bool RpcHeader::has_mode() const {
  return _internal_has_mode();
}
inline void RpcHeader::clear_mode() {
  mode_ = 0;
  _has_bits_[0] &= ~0x00000001u;
}
inline ::exec::rpc::RpcMode RpcHeader::_internal_mode() const {
  return static_cast< ::exec::rpc::RpcMode >(mode_);
}
inline ::exec::rpc::RpcMode RpcHeader::mode() const {
  // @@protoc_insertion_point(field_get:exec.rpc.RpcHeader.mode)
  return _internal_mode();
}
inline void RpcHeader::_internal_set_mode(::exec::rpc::RpcMode value) {
  assert(::exec::rpc::RpcMode_IsValid(value));
  _has_bits_[0] |= 0x00000001u;
  mode_ = value;
}
inline void RpcHeader::set_mode(::exec::rpc::RpcMode value) {
  _internal_set_mode(value);
  // @@protoc_insertion_point(field_set:exec.rpc.RpcHeader.mode)
}

// optional int32 coordination_id = 2;
inline bool RpcHeader::_internal_has_coordination_id() const {
  bool value = (_has_bits_[0] & 0x00000002u) != 0;
  return value;
}
inline bool RpcHeader::has_coordination_id() const {
  return _internal_has_coordination_id();
}
inline void RpcHeader::clear_coordination_id() {
  coordination_id_ = 0;
  _has_bits_[0] &= ~0x00000002u;
}
inline ::PROTOBUF_NAMESPACE_ID::int32 RpcHeader::_internal_coordination_id() const {
  return coordination_id_;
}
inline ::PROTOBUF_NAMESPACE_ID::int32 RpcHeader::coordination_id() const {
  // @@protoc_insertion_point(field_get:exec.rpc.RpcHeader.coordination_id)
  return _internal_coordination_id();
}
inline void RpcHeader::_internal_set_coordination_id(::PROTOBUF_NAMESPACE_ID::int32 value) {
  _has_bits_[0] |= 0x00000002u;
  coordination_id_ = value;
}
inline void RpcHeader::set_coordination_id(::PROTOBUF_NAMESPACE_ID::int32 value) {
  _internal_set_coordination_id(value);
  // @@protoc_insertion_point(field_set:exec.rpc.RpcHeader.coordination_id)
}

// optional int32 rpc_type = 3;
inline bool RpcHeader::_internal_has_rpc_type() const {
  bool value = (_has_bits_[0] & 0x00000004u) != 0;
  return value;
}
inline bool RpcHeader::has_rpc_type() const {
  return _internal_has_rpc_type();
}
inline void RpcHeader::clear_rpc_type() {
  rpc_type_ = 0;
  _has_bits_[0] &= ~0x00000004u;
}
inline ::PROTOBUF_NAMESPACE_ID::int32 RpcHeader::_internal_rpc_type() const {
  return rpc_type_;
}
inline ::PROTOBUF_NAMESPACE_ID::int32 RpcHeader::rpc_type() const {
  // @@protoc_insertion_point(field_get:exec.rpc.RpcHeader.rpc_type)
  return _internal_rpc_type();
}
inline void RpcHeader::_internal_set_rpc_type(::PROTOBUF_NAMESPACE_ID::int32 value) {
  _has_bits_[0] |= 0x00000004u;
  rpc_type_ = value;
}
inline void RpcHeader::set_rpc_type(::PROTOBUF_NAMESPACE_ID::int32 value) {
  _internal_set_rpc_type(value);
  // @@protoc_insertion_point(field_set:exec.rpc.RpcHeader.rpc_type)
}

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

// CompleteRpcMessage

// optional .exec.rpc.RpcHeader header = 1;
inline bool CompleteRpcMessage::_internal_has_header() const {
  bool value = (_has_bits_[0] & 0x00000004u) != 0;
  PROTOBUF_ASSUME(!value || header_ != nullptr);
  return value;
}
inline bool CompleteRpcMessage::has_header() const {
  return _internal_has_header();
}
inline void CompleteRpcMessage::clear_header() {
  if (header_ != nullptr) header_->Clear();
  _has_bits_[0] &= ~0x00000004u;
}
inline const ::exec::rpc::RpcHeader& CompleteRpcMessage::_internal_header() const {
  const ::exec::rpc::RpcHeader* p = header_;
  return p != nullptr ? *p : reinterpret_cast<const ::exec::rpc::RpcHeader&>(
      ::exec::rpc::_RpcHeader_default_instance_);
}
inline const ::exec::rpc::RpcHeader& CompleteRpcMessage::header() const {
  // @@protoc_insertion_point(field_get:exec.rpc.CompleteRpcMessage.header)
  return _internal_header();
}
inline void CompleteRpcMessage::unsafe_arena_set_allocated_header(
    ::exec::rpc::RpcHeader* header) {
  if (GetArena() == nullptr) {
    delete reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(header_);
  }
  header_ = header;
  if (header) {
    _has_bits_[0] |= 0x00000004u;
  } else {
    _has_bits_[0] &= ~0x00000004u;
  }
  // @@protoc_insertion_point(field_unsafe_arena_set_allocated:exec.rpc.CompleteRpcMessage.header)
}
inline ::exec::rpc::RpcHeader* CompleteRpcMessage::release_header() {
  _has_bits_[0] &= ~0x00000004u;
  ::exec::rpc::RpcHeader* temp = header_;
  header_ = nullptr;
  if (GetArena() != nullptr) {
    temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp);
  }
  return temp;
}
inline ::exec::rpc::RpcHeader* CompleteRpcMessage::unsafe_arena_release_header() {
  // @@protoc_insertion_point(field_release:exec.rpc.CompleteRpcMessage.header)
  _has_bits_[0] &= ~0x00000004u;
  ::exec::rpc::RpcHeader* temp = header_;
  header_ = nullptr;
  return temp;
}
inline ::exec::rpc::RpcHeader* CompleteRpcMessage::_internal_mutable_header() {
  _has_bits_[0] |= 0x00000004u;
  if (header_ == nullptr) {
    auto* p = CreateMaybeMessage<::exec::rpc::RpcHeader>(GetArena());
    header_ = p;
  }
  return header_;
}
inline ::exec::rpc::RpcHeader* CompleteRpcMessage::mutable_header() {
  // @@protoc_insertion_point(field_mutable:exec.rpc.CompleteRpcMessage.header)
  return _internal_mutable_header();
}
inline void CompleteRpcMessage::set_allocated_header(::exec::rpc::RpcHeader* header) {
  ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArena();
  if (message_arena == nullptr) {
    delete header_;
  }
  if (header) {
    ::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena =
      ::PROTOBUF_NAMESPACE_ID::Arena::GetArena(header);
    if (message_arena != submessage_arena) {
      header = ::PROTOBUF_NAMESPACE_ID::internal::GetOwnedMessage(
          message_arena, header, submessage_arena);
    }
    _has_bits_[0] |= 0x00000004u;
  } else {
    _has_bits_[0] &= ~0x00000004u;
  }
  header_ = header;
  // @@protoc_insertion_point(field_set_allocated:exec.rpc.CompleteRpcMessage.header)
}

// optional bytes protobuf_body = 2;
inline bool CompleteRpcMessage::_internal_has_protobuf_body() const {
  bool value = (_has_bits_[0] & 0x00000001u) != 0;
  return value;
}
inline bool CompleteRpcMessage::has_protobuf_body() const {
  return _internal_has_protobuf_body();
}
inline void CompleteRpcMessage::clear_protobuf_body() {
  protobuf_body_.ClearToEmpty();
  _has_bits_[0] &= ~0x00000001u;
}
inline const std::string& CompleteRpcMessage::protobuf_body() const {
  // @@protoc_insertion_point(field_get:exec.rpc.CompleteRpcMessage.protobuf_body)
  return _internal_protobuf_body();
}
template <typename ArgT0, typename... ArgT>
PROTOBUF_ALWAYS_INLINE
inline void CompleteRpcMessage::set_protobuf_body(ArgT0&& arg0, ArgT... args) {
 _has_bits_[0] |= 0x00000001u;
 protobuf_body_.SetBytes(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArena());
  // @@protoc_insertion_point(field_set:exec.rpc.CompleteRpcMessage.protobuf_body)
}
inline std::string* CompleteRpcMessage::mutable_protobuf_body() {
  // @@protoc_insertion_point(field_mutable:exec.rpc.CompleteRpcMessage.protobuf_body)
  return _internal_mutable_protobuf_body();
}
inline const std::string& CompleteRpcMessage::_internal_protobuf_body() const {
  return protobuf_body_.Get();
}
inline void CompleteRpcMessage::_internal_set_protobuf_body(const std::string& value) {
  _has_bits_[0] |= 0x00000001u;
  protobuf_body_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena());
}
inline std::string* CompleteRpcMessage::_internal_mutable_protobuf_body() {
  _has_bits_[0] |= 0x00000001u;
  return protobuf_body_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena());
}
inline std::string* CompleteRpcMessage::release_protobuf_body() {
  // @@protoc_insertion_point(field_release:exec.rpc.CompleteRpcMessage.protobuf_body)
  if (!_internal_has_protobuf_body()) {
    return nullptr;
  }
  _has_bits_[0] &= ~0x00000001u;
  return protobuf_body_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena());
}
inline void CompleteRpcMessage::set_allocated_protobuf_body(std::string* protobuf_body) {
  if (protobuf_body != nullptr) {
    _has_bits_[0] |= 0x00000001u;
  } else {
    _has_bits_[0] &= ~0x00000001u;
  }
  protobuf_body_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), protobuf_body,
      GetArena());
  // @@protoc_insertion_point(field_set_allocated:exec.rpc.CompleteRpcMessage.protobuf_body)
}

// optional bytes raw_body = 3;
inline bool CompleteRpcMessage::_internal_has_raw_body() const {
  bool value = (_has_bits_[0] & 0x00000002u) != 0;
  return value;
}
inline bool CompleteRpcMessage::has_raw_body() const {
  return _internal_has_raw_body();
}
inline void CompleteRpcMessage::clear_raw_body() {
  raw_body_.ClearToEmpty();
  _has_bits_[0] &= ~0x00000002u;
}
inline const std::string& CompleteRpcMessage::raw_body() const {
  // @@protoc_insertion_point(field_get:exec.rpc.CompleteRpcMessage.raw_body)
  return _internal_raw_body();
}
template <typename ArgT0, typename... ArgT>
PROTOBUF_ALWAYS_INLINE
inline void CompleteRpcMessage::set_raw_body(ArgT0&& arg0, ArgT... args) {
 _has_bits_[0] |= 0x00000002u;
 raw_body_.SetBytes(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArena());
  // @@protoc_insertion_point(field_set:exec.rpc.CompleteRpcMessage.raw_body)
}
inline std::string* CompleteRpcMessage::mutable_raw_body() {
  // @@protoc_insertion_point(field_mutable:exec.rpc.CompleteRpcMessage.raw_body)
  return _internal_mutable_raw_body();
}
inline const std::string& CompleteRpcMessage::_internal_raw_body() const {
  return raw_body_.Get();
}
inline void CompleteRpcMessage::_internal_set_raw_body(const std::string& value) {
  _has_bits_[0] |= 0x00000002u;
  raw_body_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena());
}
inline std::string* CompleteRpcMessage::_internal_mutable_raw_body() {
  _has_bits_[0] |= 0x00000002u;
  return raw_body_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena());
}
inline std::string* CompleteRpcMessage::release_raw_body() {
  // @@protoc_insertion_point(field_release:exec.rpc.CompleteRpcMessage.raw_body)
  if (!_internal_has_raw_body()) {
    return nullptr;
  }
  _has_bits_[0] &= ~0x00000002u;
  return raw_body_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena());
}
inline void CompleteRpcMessage::set_allocated_raw_body(std::string* raw_body) {
  if (raw_body != nullptr) {
    _has_bits_[0] |= 0x00000002u;
  } else {
    _has_bits_[0] &= ~0x00000002u;
  }
  raw_body_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), raw_body,
      GetArena());
  // @@protoc_insertion_point(field_set_allocated:exec.rpc.CompleteRpcMessage.raw_body)
}

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

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


// @@protoc_insertion_point(namespace_scope)

}  // namespace rpc
}  // namespace exec

PROTOBUF_NAMESPACE_OPEN

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

PROTOBUF_NAMESPACE_CLOSE

// @@protoc_insertion_point(global_scope)

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