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

#ifndef PROTOBUF_PulsarApi_2eproto__INCLUDED
#define PROTOBUF_PulsarApi_2eproto__INCLUDED

#include <string>

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

#if GOOGLE_PROTOBUF_VERSION < 2006000
#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 2006001 < 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/generated_message_util.h>
#include <google/protobuf/message_lite.h>
#include <google/protobuf/repeated_field.h>
#include <google/protobuf/extension_set.h>
// @@protoc_insertion_point(includes)

namespace pulsar {
namespace proto {

// Internal implementation detail -- do not call these.
void  protobuf_AddDesc_PulsarApi_2eproto();
void protobuf_AssignDesc_PulsarApi_2eproto();
void protobuf_ShutdownFile_PulsarApi_2eproto();

class MessageIdData;
class KeyValue;
class MessageMetadata;
class SingleMessageMetadata;
class CommandConnect;
class CommandConnected;
class CommandSubscribe;
class CommandPartitionedTopicMetadata;
class CommandPartitionedTopicMetadataResponse;
class CommandLookupTopic;
class CommandLookupTopicResponse;
class CommandProducer;
class CommandSend;
class CommandSendReceipt;
class CommandSendError;
class CommandMessage;
class CommandAck;
class CommandFlow;
class CommandUnsubscribe;
class CommandCloseProducer;
class CommandCloseConsumer;
class CommandRedeliverUnacknowledgedMessages;
class CommandSuccess;
class CommandProducerSuccess;
class CommandError;
class CommandPing;
class CommandPong;
class CommandConsumerStats;
class CommandConsumerStatsResponse;
class BaseCommand;

enum CommandSubscribe_SubType {
  CommandSubscribe_SubType_Exclusive = 0,
  CommandSubscribe_SubType_Shared = 1,
  CommandSubscribe_SubType_Failover = 2
};
bool CommandSubscribe_SubType_IsValid(int value);
const CommandSubscribe_SubType CommandSubscribe_SubType_SubType_MIN = CommandSubscribe_SubType_Exclusive;
const CommandSubscribe_SubType CommandSubscribe_SubType_SubType_MAX = CommandSubscribe_SubType_Failover;
const int CommandSubscribe_SubType_SubType_ARRAYSIZE = CommandSubscribe_SubType_SubType_MAX + 1;

enum CommandPartitionedTopicMetadataResponse_LookupType {
  CommandPartitionedTopicMetadataResponse_LookupType_Success = 0,
  CommandPartitionedTopicMetadataResponse_LookupType_Failed = 1
};
bool CommandPartitionedTopicMetadataResponse_LookupType_IsValid(int value);
const CommandPartitionedTopicMetadataResponse_LookupType CommandPartitionedTopicMetadataResponse_LookupType_LookupType_MIN = CommandPartitionedTopicMetadataResponse_LookupType_Success;
const CommandPartitionedTopicMetadataResponse_LookupType CommandPartitionedTopicMetadataResponse_LookupType_LookupType_MAX = CommandPartitionedTopicMetadataResponse_LookupType_Failed;
const int CommandPartitionedTopicMetadataResponse_LookupType_LookupType_ARRAYSIZE = CommandPartitionedTopicMetadataResponse_LookupType_LookupType_MAX + 1;

enum CommandLookupTopicResponse_LookupType {
  CommandLookupTopicResponse_LookupType_Redirect = 0,
  CommandLookupTopicResponse_LookupType_Connect = 1,
  CommandLookupTopicResponse_LookupType_Failed = 2
};
bool CommandLookupTopicResponse_LookupType_IsValid(int value);
const CommandLookupTopicResponse_LookupType CommandLookupTopicResponse_LookupType_LookupType_MIN = CommandLookupTopicResponse_LookupType_Redirect;
const CommandLookupTopicResponse_LookupType CommandLookupTopicResponse_LookupType_LookupType_MAX = CommandLookupTopicResponse_LookupType_Failed;
const int CommandLookupTopicResponse_LookupType_LookupType_ARRAYSIZE = CommandLookupTopicResponse_LookupType_LookupType_MAX + 1;

enum CommandAck_AckType {
  CommandAck_AckType_Individual = 0,
  CommandAck_AckType_Cumulative = 1
};
bool CommandAck_AckType_IsValid(int value);
const CommandAck_AckType CommandAck_AckType_AckType_MIN = CommandAck_AckType_Individual;
const CommandAck_AckType CommandAck_AckType_AckType_MAX = CommandAck_AckType_Cumulative;
const int CommandAck_AckType_AckType_ARRAYSIZE = CommandAck_AckType_AckType_MAX + 1;

enum CommandAck_ValidationError {
  CommandAck_ValidationError_UncompressedSizeCorruption = 0,
  CommandAck_ValidationError_DecompressionError = 1,
  CommandAck_ValidationError_ChecksumMismatch = 2,
  CommandAck_ValidationError_BatchDeSerializeError = 3
};
bool CommandAck_ValidationError_IsValid(int value);
const CommandAck_ValidationError CommandAck_ValidationError_ValidationError_MIN = CommandAck_ValidationError_UncompressedSizeCorruption;
const CommandAck_ValidationError CommandAck_ValidationError_ValidationError_MAX = CommandAck_ValidationError_BatchDeSerializeError;
const int CommandAck_ValidationError_ValidationError_ARRAYSIZE = CommandAck_ValidationError_ValidationError_MAX + 1;

enum BaseCommand_Type {
  BaseCommand_Type_CONNECT = 2,
  BaseCommand_Type_CONNECTED = 3,
  BaseCommand_Type_SUBSCRIBE = 4,
  BaseCommand_Type_PRODUCER = 5,
  BaseCommand_Type_SEND = 6,
  BaseCommand_Type_SEND_RECEIPT = 7,
  BaseCommand_Type_SEND_ERROR = 8,
  BaseCommand_Type_MESSAGE = 9,
  BaseCommand_Type_ACK = 10,
  BaseCommand_Type_FLOW = 11,
  BaseCommand_Type_UNSUBSCRIBE = 12,
  BaseCommand_Type_SUCCESS = 13,
  BaseCommand_Type_ERROR = 14,
  BaseCommand_Type_CLOSE_PRODUCER = 15,
  BaseCommand_Type_CLOSE_CONSUMER = 16,
  BaseCommand_Type_PRODUCER_SUCCESS = 17,
  BaseCommand_Type_PING = 18,
  BaseCommand_Type_PONG = 19,
  BaseCommand_Type_REDELIVER_UNACKNOWLEDGED_MESSAGES = 20,
  BaseCommand_Type_PARTITIONED_METADATA = 21,
  BaseCommand_Type_PARTITIONED_METADATA_RESPONSE = 22,
  BaseCommand_Type_LOOKUP = 23,
  BaseCommand_Type_LOOKUP_RESPONSE = 24,
  BaseCommand_Type_CONSUMER_STATS = 25,
  BaseCommand_Type_CONSUMER_STATS_RESPONSE = 26
};
bool BaseCommand_Type_IsValid(int value);
const BaseCommand_Type BaseCommand_Type_Type_MIN = BaseCommand_Type_CONNECT;
const BaseCommand_Type BaseCommand_Type_Type_MAX = BaseCommand_Type_CONSUMER_STATS_RESPONSE;
const int BaseCommand_Type_Type_ARRAYSIZE = BaseCommand_Type_Type_MAX + 1;

enum CompressionType {
  NONE = 0,
  LZ4 = 1,
  ZLIB = 2
};
bool CompressionType_IsValid(int value);
const CompressionType CompressionType_MIN = NONE;
const CompressionType CompressionType_MAX = ZLIB;
const int CompressionType_ARRAYSIZE = CompressionType_MAX + 1;

enum ServerError {
  UnknownError = 0,
  MetadataError = 1,
  PersistenceError = 2,
  AuthenticationError = 3,
  AuthorizationError = 4,
  ConsumerBusy = 5,
  ServiceNotReady = 6,
  ProducerBlockedQuotaExceededError = 7,
  ProducerBlockedQuotaExceededException = 8,
  ChecksumError = 9,
  UnsupportedVersionError = 10,
  TopicNotFound = 11,
  SubscriptionNotFound = 12,
  ConsumerNotFound = 13
};
bool ServerError_IsValid(int value);
const ServerError ServerError_MIN = UnknownError;
const ServerError ServerError_MAX = ConsumerNotFound;
const int ServerError_ARRAYSIZE = ServerError_MAX + 1;

enum AuthMethod {
  AuthMethodNone = 0,
  AuthMethodYcaV1 = 1,
  AuthMethodAthens = 2
};
bool AuthMethod_IsValid(int value);
const AuthMethod AuthMethod_MIN = AuthMethodNone;
const AuthMethod AuthMethod_MAX = AuthMethodAthens;
const int AuthMethod_ARRAYSIZE = AuthMethod_MAX + 1;

enum ProtocolVersion {
  v0 = 0,
  v1 = 1,
  v2 = 2,
  v3 = 3,
  v4 = 4,
  v5 = 5,
  v6 = 6,
  v7 = 7
};
bool ProtocolVersion_IsValid(int value);
const ProtocolVersion ProtocolVersion_MIN = v0;
const ProtocolVersion ProtocolVersion_MAX = v7;
const int ProtocolVersion_ARRAYSIZE = ProtocolVersion_MAX + 1;

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

class MessageIdData : public ::google::protobuf::MessageLite {
 public:
  MessageIdData();
  virtual ~MessageIdData();

  MessageIdData(const MessageIdData& from);

  inline MessageIdData& operator=(const MessageIdData& from) {
    CopyFrom(from);
    return *this;
  }

  inline const ::std::string& unknown_fields() const {
    return _unknown_fields_;
  }

  inline ::std::string* mutable_unknown_fields() {
    return &_unknown_fields_;
  }

  static const MessageIdData& default_instance();

  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
  // Returns the internal default instance pointer. This function can
  // return NULL thus should not be used by the user. This is intended
  // for Protobuf internal code. Please use default_instance() declared
  // above instead.
  static inline const MessageIdData* internal_default_instance() {
    return default_instance_;
  }
  #endif

  void Swap(MessageIdData* other);

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

  MessageIdData* New() const;
  void CheckTypeAndMergeFrom(const ::google::protobuf::MessageLite& from);
  void CopyFrom(const MessageIdData& from);
  void MergeFrom(const MessageIdData& from);
  void Clear();
  bool IsInitialized() const;

  int ByteSize() const;
  bool MergePartialFromCodedStream(
      ::google::protobuf::io::CodedInputStream* input);
  void SerializeWithCachedSizes(
      ::google::protobuf::io::CodedOutputStream* output) const;
  void DiscardUnknownFields();
  int GetCachedSize() const { return _cached_size_; }
  private:
  void SharedCtor();
  void SharedDtor();
  void SetCachedSize(int size) const;
  public:
  ::std::string GetTypeName() const;

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

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

  // required uint64 ledgerId = 1;
  inline bool has_ledgerid() const;
  inline void clear_ledgerid();
  static const int kLedgerIdFieldNumber = 1;
  inline ::google::protobuf::uint64 ledgerid() const;
  inline void set_ledgerid(::google::protobuf::uint64 value);

  // required uint64 entryId = 2;
  inline bool has_entryid() const;
  inline void clear_entryid();
  static const int kEntryIdFieldNumber = 2;
  inline ::google::protobuf::uint64 entryid() const;
  inline void set_entryid(::google::protobuf::uint64 value);

  // optional int32 partition = 3 [default = -1];
  inline bool has_partition() const;
  inline void clear_partition();
  static const int kPartitionFieldNumber = 3;
  inline ::google::protobuf::int32 partition() const;
  inline void set_partition(::google::protobuf::int32 value);

  // optional int32 batch_index = 4 [default = -1];
  inline bool has_batch_index() const;
  inline void clear_batch_index();
  static const int kBatchIndexFieldNumber = 4;
  inline ::google::protobuf::int32 batch_index() const;
  inline void set_batch_index(::google::protobuf::int32 value);

  // @@protoc_insertion_point(class_scope:pulsar.proto.MessageIdData)
 private:
  inline void set_has_ledgerid();
  inline void clear_has_ledgerid();
  inline void set_has_entryid();
  inline void clear_has_entryid();
  inline void set_has_partition();
  inline void clear_has_partition();
  inline void set_has_batch_index();
  inline void clear_has_batch_index();

  ::std::string _unknown_fields_;

  ::google::protobuf::uint32 _has_bits_[1];
  mutable int _cached_size_;
  ::google::protobuf::uint64 ledgerid_;
  ::google::protobuf::uint64 entryid_;
  ::google::protobuf::int32 partition_;
  ::google::protobuf::int32 batch_index_;
  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
  friend void  protobuf_AddDesc_PulsarApi_2eproto_impl();
  #else
  friend void  protobuf_AddDesc_PulsarApi_2eproto();
  #endif
  friend void protobuf_AssignDesc_PulsarApi_2eproto();
  friend void protobuf_ShutdownFile_PulsarApi_2eproto();

  void InitAsDefaultInstance();
  static MessageIdData* default_instance_;
};
// -------------------------------------------------------------------

class KeyValue : public ::google::protobuf::MessageLite {
 public:
  KeyValue();
  virtual ~KeyValue();

  KeyValue(const KeyValue& from);

  inline KeyValue& operator=(const KeyValue& from) {
    CopyFrom(from);
    return *this;
  }

  inline const ::std::string& unknown_fields() const {
    return _unknown_fields_;
  }

  inline ::std::string* mutable_unknown_fields() {
    return &_unknown_fields_;
  }

  static const KeyValue& default_instance();

  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
  // Returns the internal default instance pointer. This function can
  // return NULL thus should not be used by the user. This is intended
  // for Protobuf internal code. Please use default_instance() declared
  // above instead.
  static inline const KeyValue* internal_default_instance() {
    return default_instance_;
  }
  #endif

  void Swap(KeyValue* other);

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

  KeyValue* New() const;
  void CheckTypeAndMergeFrom(const ::google::protobuf::MessageLite& from);
  void CopyFrom(const KeyValue& from);
  void MergeFrom(const KeyValue& from);
  void Clear();
  bool IsInitialized() const;

  int ByteSize() const;
  bool MergePartialFromCodedStream(
      ::google::protobuf::io::CodedInputStream* input);
  void SerializeWithCachedSizes(
      ::google::protobuf::io::CodedOutputStream* output) const;
  void DiscardUnknownFields();
  int GetCachedSize() const { return _cached_size_; }
  private:
  void SharedCtor();
  void SharedDtor();
  void SetCachedSize(int size) const;
  public:
  ::std::string GetTypeName() const;

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

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

  // required string key = 1;
  inline bool has_key() const;
  inline void clear_key();
  static const int kKeyFieldNumber = 1;
  inline const ::std::string& key() const;
  inline void set_key(const ::std::string& value);
  inline void set_key(const char* value);
  inline void set_key(const char* value, size_t size);
  inline ::std::string* mutable_key();
  inline ::std::string* release_key();
  inline void set_allocated_key(::std::string* key);

  // required string value = 2;
  inline bool has_value() const;
  inline void clear_value();
  static const int kValueFieldNumber = 2;
  inline const ::std::string& value() const;
  inline void set_value(const ::std::string& value);
  inline void set_value(const char* value);
  inline void set_value(const char* value, size_t size);
  inline ::std::string* mutable_value();
  inline ::std::string* release_value();
  inline void set_allocated_value(::std::string* value);

  // @@protoc_insertion_point(class_scope:pulsar.proto.KeyValue)
 private:
  inline void set_has_key();
  inline void clear_has_key();
  inline void set_has_value();
  inline void clear_has_value();

  ::std::string _unknown_fields_;

  ::google::protobuf::uint32 _has_bits_[1];
  mutable int _cached_size_;
  ::std::string* key_;
  ::std::string* value_;
  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
  friend void  protobuf_AddDesc_PulsarApi_2eproto_impl();
  #else
  friend void  protobuf_AddDesc_PulsarApi_2eproto();
  #endif
  friend void protobuf_AssignDesc_PulsarApi_2eproto();
  friend void protobuf_ShutdownFile_PulsarApi_2eproto();

  void InitAsDefaultInstance();
  static KeyValue* default_instance_;
};
// -------------------------------------------------------------------

class MessageMetadata : public ::google::protobuf::MessageLite {
 public:
  MessageMetadata();
  virtual ~MessageMetadata();

  MessageMetadata(const MessageMetadata& from);

  inline MessageMetadata& operator=(const MessageMetadata& from) {
    CopyFrom(from);
    return *this;
  }

  inline const ::std::string& unknown_fields() const {
    return _unknown_fields_;
  }

  inline ::std::string* mutable_unknown_fields() {
    return &_unknown_fields_;
  }

  static const MessageMetadata& default_instance();

  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
  // Returns the internal default instance pointer. This function can
  // return NULL thus should not be used by the user. This is intended
  // for Protobuf internal code. Please use default_instance() declared
  // above instead.
  static inline const MessageMetadata* internal_default_instance() {
    return default_instance_;
  }
  #endif

  void Swap(MessageMetadata* other);

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

  MessageMetadata* New() const;
  void CheckTypeAndMergeFrom(const ::google::protobuf::MessageLite& from);
  void CopyFrom(const MessageMetadata& from);
  void MergeFrom(const MessageMetadata& from);
  void Clear();
  bool IsInitialized() const;

  int ByteSize() const;
  bool MergePartialFromCodedStream(
      ::google::protobuf::io::CodedInputStream* input);
  void SerializeWithCachedSizes(
      ::google::protobuf::io::CodedOutputStream* output) const;
  void DiscardUnknownFields();
  int GetCachedSize() const { return _cached_size_; }
  private:
  void SharedCtor();
  void SharedDtor();
  void SetCachedSize(int size) const;
  public:
  ::std::string GetTypeName() const;

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

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

  // required string producer_name = 1;
  inline bool has_producer_name() const;
  inline void clear_producer_name();
  static const int kProducerNameFieldNumber = 1;
  inline const ::std::string& producer_name() const;
  inline void set_producer_name(const ::std::string& value);
  inline void set_producer_name(const char* value);
  inline void set_producer_name(const char* value, size_t size);
  inline ::std::string* mutable_producer_name();
  inline ::std::string* release_producer_name();
  inline void set_allocated_producer_name(::std::string* producer_name);

  // required uint64 sequence_id = 2;
  inline bool has_sequence_id() const;
  inline void clear_sequence_id();
  static const int kSequenceIdFieldNumber = 2;
  inline ::google::protobuf::uint64 sequence_id() const;
  inline void set_sequence_id(::google::protobuf::uint64 value);

  // required uint64 publish_time = 3;
  inline bool has_publish_time() const;
  inline void clear_publish_time();
  static const int kPublishTimeFieldNumber = 3;
  inline ::google::protobuf::uint64 publish_time() const;
  inline void set_publish_time(::google::protobuf::uint64 value);

  // repeated .pulsar.proto.KeyValue properties = 4;
  inline int properties_size() const;
  inline void clear_properties();
  static const int kPropertiesFieldNumber = 4;
  inline const ::pulsar::proto::KeyValue& properties(int index) const;
  inline ::pulsar::proto::KeyValue* mutable_properties(int index);
  inline ::pulsar::proto::KeyValue* add_properties();
  inline const ::google::protobuf::RepeatedPtrField< ::pulsar::proto::KeyValue >&
      properties() const;
  inline ::google::protobuf::RepeatedPtrField< ::pulsar::proto::KeyValue >*
      mutable_properties();

  // optional string replicated_from = 5;
  inline bool has_replicated_from() const;
  inline void clear_replicated_from();
  static const int kReplicatedFromFieldNumber = 5;
  inline const ::std::string& replicated_from() const;
  inline void set_replicated_from(const ::std::string& value);
  inline void set_replicated_from(const char* value);
  inline void set_replicated_from(const char* value, size_t size);
  inline ::std::string* mutable_replicated_from();
  inline ::std::string* release_replicated_from();
  inline void set_allocated_replicated_from(::std::string* replicated_from);

  // optional string partition_key = 6;
  inline bool has_partition_key() const;
  inline void clear_partition_key();
  static const int kPartitionKeyFieldNumber = 6;
  inline const ::std::string& partition_key() const;
  inline void set_partition_key(const ::std::string& value);
  inline void set_partition_key(const char* value);
  inline void set_partition_key(const char* value, size_t size);
  inline ::std::string* mutable_partition_key();
  inline ::std::string* release_partition_key();
  inline void set_allocated_partition_key(::std::string* partition_key);

  // repeated string replicate_to = 7;
  inline int replicate_to_size() const;
  inline void clear_replicate_to();
  static const int kReplicateToFieldNumber = 7;
  inline const ::std::string& replicate_to(int index) const;
  inline ::std::string* mutable_replicate_to(int index);
  inline void set_replicate_to(int index, const ::std::string& value);
  inline void set_replicate_to(int index, const char* value);
  inline void set_replicate_to(int index, const char* value, size_t size);
  inline ::std::string* add_replicate_to();
  inline void add_replicate_to(const ::std::string& value);
  inline void add_replicate_to(const char* value);
  inline void add_replicate_to(const char* value, size_t size);
  inline const ::google::protobuf::RepeatedPtrField< ::std::string>& replicate_to() const;
  inline ::google::protobuf::RepeatedPtrField< ::std::string>* mutable_replicate_to();

  // optional .pulsar.proto.CompressionType compression = 8 [default = NONE];
  inline bool has_compression() const;
  inline void clear_compression();
  static const int kCompressionFieldNumber = 8;
  inline ::pulsar::proto::CompressionType compression() const;
  inline void set_compression(::pulsar::proto::CompressionType value);

  // optional uint32 uncompressed_size = 9 [default = 0];
  inline bool has_uncompressed_size() const;
  inline void clear_uncompressed_size();
  static const int kUncompressedSizeFieldNumber = 9;
  inline ::google::protobuf::uint32 uncompressed_size() const;
  inline void set_uncompressed_size(::google::protobuf::uint32 value);

  // optional int32 num_messages_in_batch = 11 [default = 1];
  inline bool has_num_messages_in_batch() const;
  inline void clear_num_messages_in_batch();
  static const int kNumMessagesInBatchFieldNumber = 11;
  inline ::google::protobuf::int32 num_messages_in_batch() const;
  inline void set_num_messages_in_batch(::google::protobuf::int32 value);

  // @@protoc_insertion_point(class_scope:pulsar.proto.MessageMetadata)
 private:
  inline void set_has_producer_name();
  inline void clear_has_producer_name();
  inline void set_has_sequence_id();
  inline void clear_has_sequence_id();
  inline void set_has_publish_time();
  inline void clear_has_publish_time();
  inline void set_has_replicated_from();
  inline void clear_has_replicated_from();
  inline void set_has_partition_key();
  inline void clear_has_partition_key();
  inline void set_has_compression();
  inline void clear_has_compression();
  inline void set_has_uncompressed_size();
  inline void clear_has_uncompressed_size();
  inline void set_has_num_messages_in_batch();
  inline void clear_has_num_messages_in_batch();

  ::std::string _unknown_fields_;

  ::google::protobuf::uint32 _has_bits_[1];
  mutable int _cached_size_;
  ::std::string* producer_name_;
  ::google::protobuf::uint64 sequence_id_;
  ::google::protobuf::uint64 publish_time_;
  ::google::protobuf::RepeatedPtrField< ::pulsar::proto::KeyValue > properties_;
  ::std::string* replicated_from_;
  ::std::string* partition_key_;
  ::google::protobuf::RepeatedPtrField< ::std::string> replicate_to_;
  int compression_;
  ::google::protobuf::uint32 uncompressed_size_;
  ::google::protobuf::int32 num_messages_in_batch_;
  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
  friend void  protobuf_AddDesc_PulsarApi_2eproto_impl();
  #else
  friend void  protobuf_AddDesc_PulsarApi_2eproto();
  #endif
  friend void protobuf_AssignDesc_PulsarApi_2eproto();
  friend void protobuf_ShutdownFile_PulsarApi_2eproto();

  void InitAsDefaultInstance();
  static MessageMetadata* default_instance_;
};
// -------------------------------------------------------------------

class SingleMessageMetadata : public ::google::protobuf::MessageLite {
 public:
  SingleMessageMetadata();
  virtual ~SingleMessageMetadata();

  SingleMessageMetadata(const SingleMessageMetadata& from);

  inline SingleMessageMetadata& operator=(const SingleMessageMetadata& from) {
    CopyFrom(from);
    return *this;
  }

  inline const ::std::string& unknown_fields() const {
    return _unknown_fields_;
  }

  inline ::std::string* mutable_unknown_fields() {
    return &_unknown_fields_;
  }

  static const SingleMessageMetadata& default_instance();

  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
  // Returns the internal default instance pointer. This function can
  // return NULL thus should not be used by the user. This is intended
  // for Protobuf internal code. Please use default_instance() declared
  // above instead.
  static inline const SingleMessageMetadata* internal_default_instance() {
    return default_instance_;
  }
  #endif

  void Swap(SingleMessageMetadata* other);

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

  SingleMessageMetadata* New() const;
  void CheckTypeAndMergeFrom(const ::google::protobuf::MessageLite& from);
  void CopyFrom(const SingleMessageMetadata& from);
  void MergeFrom(const SingleMessageMetadata& from);
  void Clear();
  bool IsInitialized() const;

  int ByteSize() const;
  bool MergePartialFromCodedStream(
      ::google::protobuf::io::CodedInputStream* input);
  void SerializeWithCachedSizes(
      ::google::protobuf::io::CodedOutputStream* output) const;
  void DiscardUnknownFields();
  int GetCachedSize() const { return _cached_size_; }
  private:
  void SharedCtor();
  void SharedDtor();
  void SetCachedSize(int size) const;
  public:
  ::std::string GetTypeName() const;

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

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

  // repeated .pulsar.proto.KeyValue properties = 1;
  inline int properties_size() const;
  inline void clear_properties();
  static const int kPropertiesFieldNumber = 1;
  inline const ::pulsar::proto::KeyValue& properties(int index) const;
  inline ::pulsar::proto::KeyValue* mutable_properties(int index);
  inline ::pulsar::proto::KeyValue* add_properties();
  inline const ::google::protobuf::RepeatedPtrField< ::pulsar::proto::KeyValue >&
      properties() const;
  inline ::google::protobuf::RepeatedPtrField< ::pulsar::proto::KeyValue >*
      mutable_properties();

  // optional string partition_key = 2;
  inline bool has_partition_key() const;
  inline void clear_partition_key();
  static const int kPartitionKeyFieldNumber = 2;
  inline const ::std::string& partition_key() const;
  inline void set_partition_key(const ::std::string& value);
  inline void set_partition_key(const char* value);
  inline void set_partition_key(const char* value, size_t size);
  inline ::std::string* mutable_partition_key();
  inline ::std::string* release_partition_key();
  inline void set_allocated_partition_key(::std::string* partition_key);

  // required int32 payload_size = 3;
  inline bool has_payload_size() const;
  inline void clear_payload_size();
  static const int kPayloadSizeFieldNumber = 3;
  inline ::google::protobuf::int32 payload_size() const;
  inline void set_payload_size(::google::protobuf::int32 value);

  // @@protoc_insertion_point(class_scope:pulsar.proto.SingleMessageMetadata)
 private:
  inline void set_has_partition_key();
  inline void clear_has_partition_key();
  inline void set_has_payload_size();
  inline void clear_has_payload_size();

  ::std::string _unknown_fields_;

  ::google::protobuf::uint32 _has_bits_[1];
  mutable int _cached_size_;
  ::google::protobuf::RepeatedPtrField< ::pulsar::proto::KeyValue > properties_;
  ::std::string* partition_key_;
  ::google::protobuf::int32 payload_size_;
  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
  friend void  protobuf_AddDesc_PulsarApi_2eproto_impl();
  #else
  friend void  protobuf_AddDesc_PulsarApi_2eproto();
  #endif
  friend void protobuf_AssignDesc_PulsarApi_2eproto();
  friend void protobuf_ShutdownFile_PulsarApi_2eproto();

  void InitAsDefaultInstance();
  static SingleMessageMetadata* default_instance_;
};
// -------------------------------------------------------------------

class CommandConnect : public ::google::protobuf::MessageLite {
 public:
  CommandConnect();
  virtual ~CommandConnect();

  CommandConnect(const CommandConnect& from);

  inline CommandConnect& operator=(const CommandConnect& from) {
    CopyFrom(from);
    return *this;
  }

  inline const ::std::string& unknown_fields() const {
    return _unknown_fields_;
  }

  inline ::std::string* mutable_unknown_fields() {
    return &_unknown_fields_;
  }

  static const CommandConnect& default_instance();

  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
  // Returns the internal default instance pointer. This function can
  // return NULL thus should not be used by the user. This is intended
  // for Protobuf internal code. Please use default_instance() declared
  // above instead.
  static inline const CommandConnect* internal_default_instance() {
    return default_instance_;
  }
  #endif

  void Swap(CommandConnect* other);

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

  CommandConnect* New() const;
  void CheckTypeAndMergeFrom(const ::google::protobuf::MessageLite& from);
  void CopyFrom(const CommandConnect& from);
  void MergeFrom(const CommandConnect& from);
  void Clear();
  bool IsInitialized() const;

  int ByteSize() const;
  bool MergePartialFromCodedStream(
      ::google::protobuf::io::CodedInputStream* input);
  void SerializeWithCachedSizes(
      ::google::protobuf::io::CodedOutputStream* output) const;
  void DiscardUnknownFields();
  int GetCachedSize() const { return _cached_size_; }
  private:
  void SharedCtor();
  void SharedDtor();
  void SetCachedSize(int size) const;
  public:
  ::std::string GetTypeName() const;

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

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

  // required string client_version = 1;
  inline bool has_client_version() const;
  inline void clear_client_version();
  static const int kClientVersionFieldNumber = 1;
  inline const ::std::string& client_version() const;
  inline void set_client_version(const ::std::string& value);
  inline void set_client_version(const char* value);
  inline void set_client_version(const char* value, size_t size);
  inline ::std::string* mutable_client_version();
  inline ::std::string* release_client_version();
  inline void set_allocated_client_version(::std::string* client_version);

  // optional .pulsar.proto.AuthMethod auth_method = 2;
  inline bool has_auth_method() const;
  inline void clear_auth_method();
  static const int kAuthMethodFieldNumber = 2;
  inline ::pulsar::proto::AuthMethod auth_method() const;
  inline void set_auth_method(::pulsar::proto::AuthMethod value);

  // optional string auth_method_name = 5;
  inline bool has_auth_method_name() const;
  inline void clear_auth_method_name();
  static const int kAuthMethodNameFieldNumber = 5;
  inline const ::std::string& auth_method_name() const;
  inline void set_auth_method_name(const ::std::string& value);
  inline void set_auth_method_name(const char* value);
  inline void set_auth_method_name(const char* value, size_t size);
  inline ::std::string* mutable_auth_method_name();
  inline ::std::string* release_auth_method_name();
  inline void set_allocated_auth_method_name(::std::string* auth_method_name);

  // optional bytes auth_data = 3;
  inline bool has_auth_data() const;
  inline void clear_auth_data();
  static const int kAuthDataFieldNumber = 3;
  inline const ::std::string& auth_data() const;
  inline void set_auth_data(const ::std::string& value);
  inline void set_auth_data(const char* value);
  inline void set_auth_data(const void* value, size_t size);
  inline ::std::string* mutable_auth_data();
  inline ::std::string* release_auth_data();
  inline void set_allocated_auth_data(::std::string* auth_data);

  // optional int32 protocol_version = 4 [default = 0];
  inline bool has_protocol_version() const;
  inline void clear_protocol_version();
  static const int kProtocolVersionFieldNumber = 4;
  inline ::google::protobuf::int32 protocol_version() const;
  inline void set_protocol_version(::google::protobuf::int32 value);

  // @@protoc_insertion_point(class_scope:pulsar.proto.CommandConnect)
 private:
  inline void set_has_client_version();
  inline void clear_has_client_version();
  inline void set_has_auth_method();
  inline void clear_has_auth_method();
  inline void set_has_auth_method_name();
  inline void clear_has_auth_method_name();
  inline void set_has_auth_data();
  inline void clear_has_auth_data();
  inline void set_has_protocol_version();
  inline void clear_has_protocol_version();

  ::std::string _unknown_fields_;

  ::google::protobuf::uint32 _has_bits_[1];
  mutable int _cached_size_;
  ::std::string* client_version_;
  ::std::string* auth_method_name_;
  int auth_method_;
  ::google::protobuf::int32 protocol_version_;
  ::std::string* auth_data_;
  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
  friend void  protobuf_AddDesc_PulsarApi_2eproto_impl();
  #else
  friend void  protobuf_AddDesc_PulsarApi_2eproto();
  #endif
  friend void protobuf_AssignDesc_PulsarApi_2eproto();
  friend void protobuf_ShutdownFile_PulsarApi_2eproto();

  void InitAsDefaultInstance();
  static CommandConnect* default_instance_;
};
// -------------------------------------------------------------------

class CommandConnected : public ::google::protobuf::MessageLite {
 public:
  CommandConnected();
  virtual ~CommandConnected();

  CommandConnected(const CommandConnected& from);

  inline CommandConnected& operator=(const CommandConnected& from) {
    CopyFrom(from);
    return *this;
  }

  inline const ::std::string& unknown_fields() const {
    return _unknown_fields_;
  }

  inline ::std::string* mutable_unknown_fields() {
    return &_unknown_fields_;
  }

  static const CommandConnected& default_instance();

  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
  // Returns the internal default instance pointer. This function can
  // return NULL thus should not be used by the user. This is intended
  // for Protobuf internal code. Please use default_instance() declared
  // above instead.
  static inline const CommandConnected* internal_default_instance() {
    return default_instance_;
  }
  #endif

  void Swap(CommandConnected* other);

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

  CommandConnected* New() const;
  void CheckTypeAndMergeFrom(const ::google::protobuf::MessageLite& from);
  void CopyFrom(const CommandConnected& from);
  void MergeFrom(const CommandConnected& from);
  void Clear();
  bool IsInitialized() const;

  int ByteSize() const;
  bool MergePartialFromCodedStream(
      ::google::protobuf::io::CodedInputStream* input);
  void SerializeWithCachedSizes(
      ::google::protobuf::io::CodedOutputStream* output) const;
  void DiscardUnknownFields();
  int GetCachedSize() const { return _cached_size_; }
  private:
  void SharedCtor();
  void SharedDtor();
  void SetCachedSize(int size) const;
  public:
  ::std::string GetTypeName() const;

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

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

  // required string server_version = 1;
  inline bool has_server_version() const;
  inline void clear_server_version();
  static const int kServerVersionFieldNumber = 1;
  inline const ::std::string& server_version() const;
  inline void set_server_version(const ::std::string& value);
  inline void set_server_version(const char* value);
  inline void set_server_version(const char* value, size_t size);
  inline ::std::string* mutable_server_version();
  inline ::std::string* release_server_version();
  inline void set_allocated_server_version(::std::string* server_version);

  // optional int32 protocol_version = 2 [default = 0];
  inline bool has_protocol_version() const;
  inline void clear_protocol_version();
  static const int kProtocolVersionFieldNumber = 2;
  inline ::google::protobuf::int32 protocol_version() const;
  inline void set_protocol_version(::google::protobuf::int32 value);

  // @@protoc_insertion_point(class_scope:pulsar.proto.CommandConnected)
 private:
  inline void set_has_server_version();
  inline void clear_has_server_version();
  inline void set_has_protocol_version();
  inline void clear_has_protocol_version();

  ::std::string _unknown_fields_;

  ::google::protobuf::uint32 _has_bits_[1];
  mutable int _cached_size_;
  ::std::string* server_version_;
  ::google::protobuf::int32 protocol_version_;
  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
  friend void  protobuf_AddDesc_PulsarApi_2eproto_impl();
  #else
  friend void  protobuf_AddDesc_PulsarApi_2eproto();
  #endif
  friend void protobuf_AssignDesc_PulsarApi_2eproto();
  friend void protobuf_ShutdownFile_PulsarApi_2eproto();

  void InitAsDefaultInstance();
  static CommandConnected* default_instance_;
};
// -------------------------------------------------------------------

class CommandSubscribe : public ::google::protobuf::MessageLite {
 public:
  CommandSubscribe();
  virtual ~CommandSubscribe();

  CommandSubscribe(const CommandSubscribe& from);

  inline CommandSubscribe& operator=(const CommandSubscribe& from) {
    CopyFrom(from);
    return *this;
  }

  inline const ::std::string& unknown_fields() const {
    return _unknown_fields_;
  }

  inline ::std::string* mutable_unknown_fields() {
    return &_unknown_fields_;
  }

  static const CommandSubscribe& default_instance();

  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
  // Returns the internal default instance pointer. This function can
  // return NULL thus should not be used by the user. This is intended
  // for Protobuf internal code. Please use default_instance() declared
  // above instead.
  static inline const CommandSubscribe* internal_default_instance() {
    return default_instance_;
  }
  #endif

  void Swap(CommandSubscribe* other);

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

  CommandSubscribe* New() const;
  void CheckTypeAndMergeFrom(const ::google::protobuf::MessageLite& from);
  void CopyFrom(const CommandSubscribe& from);
  void MergeFrom(const CommandSubscribe& from);
  void Clear();
  bool IsInitialized() const;

  int ByteSize() const;
  bool MergePartialFromCodedStream(
      ::google::protobuf::io::CodedInputStream* input);
  void SerializeWithCachedSizes(
      ::google::protobuf::io::CodedOutputStream* output) const;
  void DiscardUnknownFields();
  int GetCachedSize() const { return _cached_size_; }
  private:
  void SharedCtor();
  void SharedDtor();
  void SetCachedSize(int size) const;
  public:
  ::std::string GetTypeName() const;

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

  typedef CommandSubscribe_SubType SubType;
  static const SubType Exclusive = CommandSubscribe_SubType_Exclusive;
  static const SubType Shared = CommandSubscribe_SubType_Shared;
  static const SubType Failover = CommandSubscribe_SubType_Failover;
  static inline bool SubType_IsValid(int value) {
    return CommandSubscribe_SubType_IsValid(value);
  }
  static const SubType SubType_MIN =
    CommandSubscribe_SubType_SubType_MIN;
  static const SubType SubType_MAX =
    CommandSubscribe_SubType_SubType_MAX;
  static const int SubType_ARRAYSIZE =
    CommandSubscribe_SubType_SubType_ARRAYSIZE;

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

  // required string topic = 1;
  inline bool has_topic() const;
  inline void clear_topic();
  static const int kTopicFieldNumber = 1;
  inline const ::std::string& topic() const;
  inline void set_topic(const ::std::string& value);
  inline void set_topic(const char* value);
  inline void set_topic(const char* value, size_t size);
  inline ::std::string* mutable_topic();
  inline ::std::string* release_topic();
  inline void set_allocated_topic(::std::string* topic);

  // required string subscription = 2;
  inline bool has_subscription() const;
  inline void clear_subscription();
  static const int kSubscriptionFieldNumber = 2;
  inline const ::std::string& subscription() const;
  inline void set_subscription(const ::std::string& value);
  inline void set_subscription(const char* value);
  inline void set_subscription(const char* value, size_t size);
  inline ::std::string* mutable_subscription();
  inline ::std::string* release_subscription();
  inline void set_allocated_subscription(::std::string* subscription);

  // required .pulsar.proto.CommandSubscribe.SubType subType = 3;
  inline bool has_subtype() const;
  inline void clear_subtype();
  static const int kSubTypeFieldNumber = 3;
  inline ::pulsar::proto::CommandSubscribe_SubType subtype() const;
  inline void set_subtype(::pulsar::proto::CommandSubscribe_SubType value);

  // required uint64 consumer_id = 4;
  inline bool has_consumer_id() const;
  inline void clear_consumer_id();
  static const int kConsumerIdFieldNumber = 4;
  inline ::google::protobuf::uint64 consumer_id() const;
  inline void set_consumer_id(::google::protobuf::uint64 value);

  // required uint64 request_id = 5;
  inline bool has_request_id() const;
  inline void clear_request_id();
  static const int kRequestIdFieldNumber = 5;
  inline ::google::protobuf::uint64 request_id() const;
  inline void set_request_id(::google::protobuf::uint64 value);

  // optional string consumer_name = 6;
  inline bool has_consumer_name() const;
  inline void clear_consumer_name();
  static const int kConsumerNameFieldNumber = 6;
  inline const ::std::string& consumer_name() const;
  inline void set_consumer_name(const ::std::string& value);
  inline void set_consumer_name(const char* value);
  inline void set_consumer_name(const char* value, size_t size);
  inline ::std::string* mutable_consumer_name();
  inline ::std::string* release_consumer_name();
  inline void set_allocated_consumer_name(::std::string* consumer_name);

  // @@protoc_insertion_point(class_scope:pulsar.proto.CommandSubscribe)
 private:
  inline void set_has_topic();
  inline void clear_has_topic();
  inline void set_has_subscription();
  inline void clear_has_subscription();
  inline void set_has_subtype();
  inline void clear_has_subtype();
  inline void set_has_consumer_id();
  inline void clear_has_consumer_id();
  inline void set_has_request_id();
  inline void clear_has_request_id();
  inline void set_has_consumer_name();
  inline void clear_has_consumer_name();

  ::std::string _unknown_fields_;

  ::google::protobuf::uint32 _has_bits_[1];
  mutable int _cached_size_;
  ::std::string* topic_;
  ::std::string* subscription_;
  ::google::protobuf::uint64 consumer_id_;
  ::google::protobuf::uint64 request_id_;
  ::std::string* consumer_name_;
  int subtype_;
  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
  friend void  protobuf_AddDesc_PulsarApi_2eproto_impl();
  #else
  friend void  protobuf_AddDesc_PulsarApi_2eproto();
  #endif
  friend void protobuf_AssignDesc_PulsarApi_2eproto();
  friend void protobuf_ShutdownFile_PulsarApi_2eproto();

  void InitAsDefaultInstance();
  static CommandSubscribe* default_instance_;
};
// -------------------------------------------------------------------

class CommandPartitionedTopicMetadata : public ::google::protobuf::MessageLite {
 public:
  CommandPartitionedTopicMetadata();
  virtual ~CommandPartitionedTopicMetadata();

  CommandPartitionedTopicMetadata(const CommandPartitionedTopicMetadata& from);

  inline CommandPartitionedTopicMetadata& operator=(const CommandPartitionedTopicMetadata& from) {
    CopyFrom(from);
    return *this;
  }

  inline const ::std::string& unknown_fields() const {
    return _unknown_fields_;
  }

  inline ::std::string* mutable_unknown_fields() {
    return &_unknown_fields_;
  }

  static const CommandPartitionedTopicMetadata& default_instance();

  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
  // Returns the internal default instance pointer. This function can
  // return NULL thus should not be used by the user. This is intended
  // for Protobuf internal code. Please use default_instance() declared
  // above instead.
  static inline const CommandPartitionedTopicMetadata* internal_default_instance() {
    return default_instance_;
  }
  #endif

  void Swap(CommandPartitionedTopicMetadata* other);

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

  CommandPartitionedTopicMetadata* New() const;
  void CheckTypeAndMergeFrom(const ::google::protobuf::MessageLite& from);
  void CopyFrom(const CommandPartitionedTopicMetadata& from);
  void MergeFrom(const CommandPartitionedTopicMetadata& from);
  void Clear();
  bool IsInitialized() const;

  int ByteSize() const;
  bool MergePartialFromCodedStream(
      ::google::protobuf::io::CodedInputStream* input);
  void SerializeWithCachedSizes(
      ::google::protobuf::io::CodedOutputStream* output) const;
  void DiscardUnknownFields();
  int GetCachedSize() const { return _cached_size_; }
  private:
  void SharedCtor();
  void SharedDtor();
  void SetCachedSize(int size) const;
  public:
  ::std::string GetTypeName() const;

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

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

  // required string topic = 1;
  inline bool has_topic() const;
  inline void clear_topic();
  static const int kTopicFieldNumber = 1;
  inline const ::std::string& topic() const;
  inline void set_topic(const ::std::string& value);
  inline void set_topic(const char* value);
  inline void set_topic(const char* value, size_t size);
  inline ::std::string* mutable_topic();
  inline ::std::string* release_topic();
  inline void set_allocated_topic(::std::string* topic);

  // required uint64 request_id = 2;
  inline bool has_request_id() const;
  inline void clear_request_id();
  static const int kRequestIdFieldNumber = 2;
  inline ::google::protobuf::uint64 request_id() const;
  inline void set_request_id(::google::protobuf::uint64 value);

  // @@protoc_insertion_point(class_scope:pulsar.proto.CommandPartitionedTopicMetadata)
 private:
  inline void set_has_topic();
  inline void clear_has_topic();
  inline void set_has_request_id();
  inline void clear_has_request_id();

  ::std::string _unknown_fields_;

  ::google::protobuf::uint32 _has_bits_[1];
  mutable int _cached_size_;
  ::std::string* topic_;
  ::google::protobuf::uint64 request_id_;
  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
  friend void  protobuf_AddDesc_PulsarApi_2eproto_impl();
  #else
  friend void  protobuf_AddDesc_PulsarApi_2eproto();
  #endif
  friend void protobuf_AssignDesc_PulsarApi_2eproto();
  friend void protobuf_ShutdownFile_PulsarApi_2eproto();

  void InitAsDefaultInstance();
  static CommandPartitionedTopicMetadata* default_instance_;
};
// -------------------------------------------------------------------

class CommandPartitionedTopicMetadataResponse : public ::google::protobuf::MessageLite {
 public:
  CommandPartitionedTopicMetadataResponse();
  virtual ~CommandPartitionedTopicMetadataResponse();

  CommandPartitionedTopicMetadataResponse(const CommandPartitionedTopicMetadataResponse& from);

  inline CommandPartitionedTopicMetadataResponse& operator=(const CommandPartitionedTopicMetadataResponse& from) {
    CopyFrom(from);
    return *this;
  }

  inline const ::std::string& unknown_fields() const {
    return _unknown_fields_;
  }

  inline ::std::string* mutable_unknown_fields() {
    return &_unknown_fields_;
  }

  static const CommandPartitionedTopicMetadataResponse& default_instance();

  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
  // Returns the internal default instance pointer. This function can
  // return NULL thus should not be used by the user. This is intended
  // for Protobuf internal code. Please use default_instance() declared
  // above instead.
  static inline const CommandPartitionedTopicMetadataResponse* internal_default_instance() {
    return default_instance_;
  }
  #endif

  void Swap(CommandPartitionedTopicMetadataResponse* other);

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

  CommandPartitionedTopicMetadataResponse* New() const;
  void CheckTypeAndMergeFrom(const ::google::protobuf::MessageLite& from);
  void CopyFrom(const CommandPartitionedTopicMetadataResponse& from);
  void MergeFrom(const CommandPartitionedTopicMetadataResponse& from);
  void Clear();
  bool IsInitialized() const;

  int ByteSize() const;
  bool MergePartialFromCodedStream(
      ::google::protobuf::io::CodedInputStream* input);
  void SerializeWithCachedSizes(
      ::google::protobuf::io::CodedOutputStream* output) const;
  void DiscardUnknownFields();
  int GetCachedSize() const { return _cached_size_; }
  private:
  void SharedCtor();
  void SharedDtor();
  void SetCachedSize(int size) const;
  public:
  ::std::string GetTypeName() const;

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

  typedef CommandPartitionedTopicMetadataResponse_LookupType LookupType;
  static const LookupType Success = CommandPartitionedTopicMetadataResponse_LookupType_Success;
  static const LookupType Failed = CommandPartitionedTopicMetadataResponse_LookupType_Failed;
  static inline bool LookupType_IsValid(int value) {
    return CommandPartitionedTopicMetadataResponse_LookupType_IsValid(value);
  }
  static const LookupType LookupType_MIN =
    CommandPartitionedTopicMetadataResponse_LookupType_LookupType_MIN;
  static const LookupType LookupType_MAX =
    CommandPartitionedTopicMetadataResponse_LookupType_LookupType_MAX;
  static const int LookupType_ARRAYSIZE =
    CommandPartitionedTopicMetadataResponse_LookupType_LookupType_ARRAYSIZE;

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

  // optional uint32 partitions = 1;
  inline bool has_partitions() const;
  inline void clear_partitions();
  static const int kPartitionsFieldNumber = 1;
  inline ::google::protobuf::uint32 partitions() const;
  inline void set_partitions(::google::protobuf::uint32 value);

  // required uint64 request_id = 2;
  inline bool has_request_id() const;
  inline void clear_request_id();
  static const int kRequestIdFieldNumber = 2;
  inline ::google::protobuf::uint64 request_id() const;
  inline void set_request_id(::google::protobuf::uint64 value);

  // optional .pulsar.proto.CommandPartitionedTopicMetadataResponse.LookupType response = 3;
  inline bool has_response() const;
  inline void clear_response();
  static const int kResponseFieldNumber = 3;
  inline ::pulsar::proto::CommandPartitionedTopicMetadataResponse_LookupType response() const;
  inline void set_response(::pulsar::proto::CommandPartitionedTopicMetadataResponse_LookupType value);

  // optional .pulsar.proto.ServerError error = 4;
  inline bool has_error() const;
  inline void clear_error();
  static const int kErrorFieldNumber = 4;
  inline ::pulsar::proto::ServerError error() const;
  inline void set_error(::pulsar::proto::ServerError value);

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

  // @@protoc_insertion_point(class_scope:pulsar.proto.CommandPartitionedTopicMetadataResponse)
 private:
  inline void set_has_partitions();
  inline void clear_has_partitions();
  inline void set_has_request_id();
  inline void clear_has_request_id();
  inline void set_has_response();
  inline void clear_has_response();
  inline void set_has_error();
  inline void clear_has_error();
  inline void set_has_message();
  inline void clear_has_message();

  ::std::string _unknown_fields_;

  ::google::protobuf::uint32 _has_bits_[1];
  mutable int _cached_size_;
  ::google::protobuf::uint64 request_id_;
  ::google::protobuf::uint32 partitions_;
  int response_;
  ::std::string* message_;
  int error_;
  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
  friend void  protobuf_AddDesc_PulsarApi_2eproto_impl();
  #else
  friend void  protobuf_AddDesc_PulsarApi_2eproto();
  #endif
  friend void protobuf_AssignDesc_PulsarApi_2eproto();
  friend void protobuf_ShutdownFile_PulsarApi_2eproto();

  void InitAsDefaultInstance();
  static CommandPartitionedTopicMetadataResponse* default_instance_;
};
// -------------------------------------------------------------------

class CommandLookupTopic : public ::google::protobuf::MessageLite {
 public:
  CommandLookupTopic();
  virtual ~CommandLookupTopic();

  CommandLookupTopic(const CommandLookupTopic& from);

  inline CommandLookupTopic& operator=(const CommandLookupTopic& from) {
    CopyFrom(from);
    return *this;
  }

  inline const ::std::string& unknown_fields() const {
    return _unknown_fields_;
  }

  inline ::std::string* mutable_unknown_fields() {
    return &_unknown_fields_;
  }

  static const CommandLookupTopic& default_instance();

  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
  // Returns the internal default instance pointer. This function can
  // return NULL thus should not be used by the user. This is intended
  // for Protobuf internal code. Please use default_instance() declared
  // above instead.
  static inline const CommandLookupTopic* internal_default_instance() {
    return default_instance_;
  }
  #endif

  void Swap(CommandLookupTopic* other);

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

  CommandLookupTopic* New() const;
  void CheckTypeAndMergeFrom(const ::google::protobuf::MessageLite& from);
  void CopyFrom(const CommandLookupTopic& from);
  void MergeFrom(const CommandLookupTopic& from);
  void Clear();
  bool IsInitialized() const;

  int ByteSize() const;
  bool MergePartialFromCodedStream(
      ::google::protobuf::io::CodedInputStream* input);
  void SerializeWithCachedSizes(
      ::google::protobuf::io::CodedOutputStream* output) const;
  void DiscardUnknownFields();
  int GetCachedSize() const { return _cached_size_; }
  private:
  void SharedCtor();
  void SharedDtor();
  void SetCachedSize(int size) const;
  public:
  ::std::string GetTypeName() const;

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

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

  // required string topic = 1;
  inline bool has_topic() const;
  inline void clear_topic();
  static const int kTopicFieldNumber = 1;
  inline const ::std::string& topic() const;
  inline void set_topic(const ::std::string& value);
  inline void set_topic(const char* value);
  inline void set_topic(const char* value, size_t size);
  inline ::std::string* mutable_topic();
  inline ::std::string* release_topic();
  inline void set_allocated_topic(::std::string* topic);

  // required uint64 request_id = 2;
  inline bool has_request_id() const;
  inline void clear_request_id();
  static const int kRequestIdFieldNumber = 2;
  inline ::google::protobuf::uint64 request_id() const;
  inline void set_request_id(::google::protobuf::uint64 value);

  // optional bool authoritative = 3 [default = false];
  inline bool has_authoritative() const;
  inline void clear_authoritative();
  static const int kAuthoritativeFieldNumber = 3;
  inline bool authoritative() const;
  inline void set_authoritative(bool value);

  // @@protoc_insertion_point(class_scope:pulsar.proto.CommandLookupTopic)
 private:
  inline void set_has_topic();
  inline void clear_has_topic();
  inline void set_has_request_id();
  inline void clear_has_request_id();
  inline void set_has_authoritative();
  inline void clear_has_authoritative();

  ::std::string _unknown_fields_;

  ::google::protobuf::uint32 _has_bits_[1];
  mutable int _cached_size_;
  ::std::string* topic_;
  ::google::protobuf::uint64 request_id_;
  bool authoritative_;
  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
  friend void  protobuf_AddDesc_PulsarApi_2eproto_impl();
  #else
  friend void  protobuf_AddDesc_PulsarApi_2eproto();
  #endif
  friend void protobuf_AssignDesc_PulsarApi_2eproto();
  friend void protobuf_ShutdownFile_PulsarApi_2eproto();

  void InitAsDefaultInstance();
  static CommandLookupTopic* default_instance_;
};
// -------------------------------------------------------------------

class CommandLookupTopicResponse : public ::google::protobuf::MessageLite {
 public:
  CommandLookupTopicResponse();
  virtual ~CommandLookupTopicResponse();

  CommandLookupTopicResponse(const CommandLookupTopicResponse& from);

  inline CommandLookupTopicResponse& operator=(const CommandLookupTopicResponse& from) {
    CopyFrom(from);
    return *this;
  }

  inline const ::std::string& unknown_fields() const {
    return _unknown_fields_;
  }

  inline ::std::string* mutable_unknown_fields() {
    return &_unknown_fields_;
  }

  static const CommandLookupTopicResponse& default_instance();

  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
  // Returns the internal default instance pointer. This function can
  // return NULL thus should not be used by the user. This is intended
  // for Protobuf internal code. Please use default_instance() declared
  // above instead.
  static inline const CommandLookupTopicResponse* internal_default_instance() {
    return default_instance_;
  }
  #endif

  void Swap(CommandLookupTopicResponse* other);

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

  CommandLookupTopicResponse* New() const;
  void CheckTypeAndMergeFrom(const ::google::protobuf::MessageLite& from);
  void CopyFrom(const CommandLookupTopicResponse& from);
  void MergeFrom(const CommandLookupTopicResponse& from);
  void Clear();
  bool IsInitialized() const;

  int ByteSize() const;
  bool MergePartialFromCodedStream(
      ::google::protobuf::io::CodedInputStream* input);
  void SerializeWithCachedSizes(
      ::google::protobuf::io::CodedOutputStream* output) const;
  void DiscardUnknownFields();
  int GetCachedSize() const { return _cached_size_; }
  private:
  void SharedCtor();
  void SharedDtor();
  void SetCachedSize(int size) const;
  public:
  ::std::string GetTypeName() const;

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

  typedef CommandLookupTopicResponse_LookupType LookupType;
  static const LookupType Redirect = CommandLookupTopicResponse_LookupType_Redirect;
  static const LookupType Connect = CommandLookupTopicResponse_LookupType_Connect;
  static const LookupType Failed = CommandLookupTopicResponse_LookupType_Failed;
  static inline bool LookupType_IsValid(int value) {
    return CommandLookupTopicResponse_LookupType_IsValid(value);
  }
  static const LookupType LookupType_MIN =
    CommandLookupTopicResponse_LookupType_LookupType_MIN;
  static const LookupType LookupType_MAX =
    CommandLookupTopicResponse_LookupType_LookupType_MAX;
  static const int LookupType_ARRAYSIZE =
    CommandLookupTopicResponse_LookupType_LookupType_ARRAYSIZE;

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

  // optional string brokerServiceUrl = 1;
  inline bool has_brokerserviceurl() const;
  inline void clear_brokerserviceurl();
  static const int kBrokerServiceUrlFieldNumber = 1;
  inline const ::std::string& brokerserviceurl() const;
  inline void set_brokerserviceurl(const ::std::string& value);
  inline void set_brokerserviceurl(const char* value);
  inline void set_brokerserviceurl(const char* value, size_t size);
  inline ::std::string* mutable_brokerserviceurl();
  inline ::std::string* release_brokerserviceurl();
  inline void set_allocated_brokerserviceurl(::std::string* brokerserviceurl);

  // optional string brokerServiceUrlTls = 2;
  inline bool has_brokerserviceurltls() const;
  inline void clear_brokerserviceurltls();
  static const int kBrokerServiceUrlTlsFieldNumber = 2;
  inline const ::std::string& brokerserviceurltls() const;
  inline void set_brokerserviceurltls(const ::std::string& value);
  inline void set_brokerserviceurltls(const char* value);
  inline void set_brokerserviceurltls(const char* value, size_t size);
  inline ::std::string* mutable_brokerserviceurltls();
  inline ::std::string* release_brokerserviceurltls();
  inline void set_allocated_brokerserviceurltls(::std::string* brokerserviceurltls);

  // optional .pulsar.proto.CommandLookupTopicResponse.LookupType response = 3;
  inline bool has_response() const;
  inline void clear_response();
  static const int kResponseFieldNumber = 3;
  inline ::pulsar::proto::CommandLookupTopicResponse_LookupType response() const;
  inline void set_response(::pulsar::proto::CommandLookupTopicResponse_LookupType value);

  // required uint64 request_id = 4;
  inline bool has_request_id() const;
  inline void clear_request_id();
  static const int kRequestIdFieldNumber = 4;
  inline ::google::protobuf::uint64 request_id() const;
  inline void set_request_id(::google::protobuf::uint64 value);

  // optional bool authoritative = 5 [default = false];
  inline bool has_authoritative() const;
  inline void clear_authoritative();
  static const int kAuthoritativeFieldNumber = 5;
  inline bool authoritative() const;
  inline void set_authoritative(bool value);

  // optional .pulsar.proto.ServerError error = 6;
  inline bool has_error() const;
  inline void clear_error();
  static const int kErrorFieldNumber = 6;
  inline ::pulsar::proto::ServerError error() const;
  inline void set_error(::pulsar::proto::ServerError value);

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

  // @@protoc_insertion_point(class_scope:pulsar.proto.CommandLookupTopicResponse)
 private:
  inline void set_has_brokerserviceurl();
  inline void clear_has_brokerserviceurl();
  inline void set_has_brokerserviceurltls();
  inline void clear_has_brokerserviceurltls();
  inline void set_has_response();
  inline void clear_has_response();
  inline void set_has_request_id();
  inline void clear_has_request_id();
  inline void set_has_authoritative();
  inline void clear_has_authoritative();
  inline void set_has_error();
  inline void clear_has_error();
  inline void set_has_message();
  inline void clear_has_message();

  ::std::string _unknown_fields_;

  ::google::protobuf::uint32 _has_bits_[1];
  mutable int _cached_size_;
  ::std::string* brokerserviceurl_;
  ::std::string* brokerserviceurltls_;
  ::google::protobuf::uint64 request_id_;
  int response_;
  bool authoritative_;
  ::std::string* message_;
  int error_;
  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
  friend void  protobuf_AddDesc_PulsarApi_2eproto_impl();
  #else
  friend void  protobuf_AddDesc_PulsarApi_2eproto();
  #endif
  friend void protobuf_AssignDesc_PulsarApi_2eproto();
  friend void protobuf_ShutdownFile_PulsarApi_2eproto();

  void InitAsDefaultInstance();
  static CommandLookupTopicResponse* default_instance_;
};
// -------------------------------------------------------------------

class CommandProducer : public ::google::protobuf::MessageLite {
 public:
  CommandProducer();
  virtual ~CommandProducer();

  CommandProducer(const CommandProducer& from);

  inline CommandProducer& operator=(const CommandProducer& from) {
    CopyFrom(from);
    return *this;
  }

  inline const ::std::string& unknown_fields() const {
    return _unknown_fields_;
  }

  inline ::std::string* mutable_unknown_fields() {
    return &_unknown_fields_;
  }

  static const CommandProducer& default_instance();

  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
  // Returns the internal default instance pointer. This function can
  // return NULL thus should not be used by the user. This is intended
  // for Protobuf internal code. Please use default_instance() declared
  // above instead.
  static inline const CommandProducer* internal_default_instance() {
    return default_instance_;
  }
  #endif

  void Swap(CommandProducer* other);

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

  CommandProducer* New() const;
  void CheckTypeAndMergeFrom(const ::google::protobuf::MessageLite& from);
  void CopyFrom(const CommandProducer& from);
  void MergeFrom(const CommandProducer& from);
  void Clear();
  bool IsInitialized() const;

  int ByteSize() const;
  bool MergePartialFromCodedStream(
      ::google::protobuf::io::CodedInputStream* input);
  void SerializeWithCachedSizes(
      ::google::protobuf::io::CodedOutputStream* output) const;
  void DiscardUnknownFields();
  int GetCachedSize() const { return _cached_size_; }
  private:
  void SharedCtor();
  void SharedDtor();
  void SetCachedSize(int size) const;
  public:
  ::std::string GetTypeName() const;

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

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

  // required string topic = 1;
  inline bool has_topic() const;
  inline void clear_topic();
  static const int kTopicFieldNumber = 1;
  inline const ::std::string& topic() const;
  inline void set_topic(const ::std::string& value);
  inline void set_topic(const char* value);
  inline void set_topic(const char* value, size_t size);
  inline ::std::string* mutable_topic();
  inline ::std::string* release_topic();
  inline void set_allocated_topic(::std::string* topic);

  // required uint64 producer_id = 2;
  inline bool has_producer_id() const;
  inline void clear_producer_id();
  static const int kProducerIdFieldNumber = 2;
  inline ::google::protobuf::uint64 producer_id() const;
  inline void set_producer_id(::google::protobuf::uint64 value);

  // required uint64 request_id = 3;
  inline bool has_request_id() const;
  inline void clear_request_id();
  static const int kRequestIdFieldNumber = 3;
  inline ::google::protobuf::uint64 request_id() const;
  inline void set_request_id(::google::protobuf::uint64 value);

  // optional string producer_name = 4;
  inline bool has_producer_name() const;
  inline void clear_producer_name();
  static const int kProducerNameFieldNumber = 4;
  inline const ::std::string& producer_name() const;
  inline void set_producer_name(const ::std::string& value);
  inline void set_producer_name(const char* value);
  inline void set_producer_name(const char* value, size_t size);
  inline ::std::string* mutable_producer_name();
  inline ::std::string* release_producer_name();
  inline void set_allocated_producer_name(::std::string* producer_name);

  // @@protoc_insertion_point(class_scope:pulsar.proto.CommandProducer)
 private:
  inline void set_has_topic();
  inline void clear_has_topic();
  inline void set_has_producer_id();
  inline void clear_has_producer_id();
  inline void set_has_request_id();
  inline void clear_has_request_id();
  inline void set_has_producer_name();
  inline void clear_has_producer_name();

  ::std::string _unknown_fields_;

  ::google::protobuf::uint32 _has_bits_[1];
  mutable int _cached_size_;
  ::std::string* topic_;
  ::google::protobuf::uint64 producer_id_;
  ::google::protobuf::uint64 request_id_;
  ::std::string* producer_name_;
  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
  friend void  protobuf_AddDesc_PulsarApi_2eproto_impl();
  #else
  friend void  protobuf_AddDesc_PulsarApi_2eproto();
  #endif
  friend void protobuf_AssignDesc_PulsarApi_2eproto();
  friend void protobuf_ShutdownFile_PulsarApi_2eproto();

  void InitAsDefaultInstance();
  static CommandProducer* default_instance_;
};
// -------------------------------------------------------------------

class CommandSend : public ::google::protobuf::MessageLite {
 public:
  CommandSend();
  virtual ~CommandSend();

  CommandSend(const CommandSend& from);

  inline CommandSend& operator=(const CommandSend& from) {
    CopyFrom(from);
    return *this;
  }

  inline const ::std::string& unknown_fields() const {
    return _unknown_fields_;
  }

  inline ::std::string* mutable_unknown_fields() {
    return &_unknown_fields_;
  }

  static const CommandSend& default_instance();

  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
  // Returns the internal default instance pointer. This function can
  // return NULL thus should not be used by the user. This is intended
  // for Protobuf internal code. Please use default_instance() declared
  // above instead.
  static inline const CommandSend* internal_default_instance() {
    return default_instance_;
  }
  #endif

  void Swap(CommandSend* other);

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

  CommandSend* New() const;
  void CheckTypeAndMergeFrom(const ::google::protobuf::MessageLite& from);
  void CopyFrom(const CommandSend& from);
  void MergeFrom(const CommandSend& from);
  void Clear();
  bool IsInitialized() const;

  int ByteSize() const;
  bool MergePartialFromCodedStream(
      ::google::protobuf::io::CodedInputStream* input);
  void SerializeWithCachedSizes(
      ::google::protobuf::io::CodedOutputStream* output) const;
  void DiscardUnknownFields();
  int GetCachedSize() const { return _cached_size_; }
  private:
  void SharedCtor();
  void SharedDtor();
  void SetCachedSize(int size) const;
  public:
  ::std::string GetTypeName() const;

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

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

  // required uint64 producer_id = 1;
  inline bool has_producer_id() const;
  inline void clear_producer_id();
  static const int kProducerIdFieldNumber = 1;
  inline ::google::protobuf::uint64 producer_id() const;
  inline void set_producer_id(::google::protobuf::uint64 value);

  // required uint64 sequence_id = 2;
  inline bool has_sequence_id() const;
  inline void clear_sequence_id();
  static const int kSequenceIdFieldNumber = 2;
  inline ::google::protobuf::uint64 sequence_id() const;
  inline void set_sequence_id(::google::protobuf::uint64 value);

  // optional int32 num_messages = 3 [default = 1];
  inline bool has_num_messages() const;
  inline void clear_num_messages();
  static const int kNumMessagesFieldNumber = 3;
  inline ::google::protobuf::int32 num_messages() const;
  inline void set_num_messages(::google::protobuf::int32 value);

  // @@protoc_insertion_point(class_scope:pulsar.proto.CommandSend)
 private:
  inline void set_has_producer_id();
  inline void clear_has_producer_id();
  inline void set_has_sequence_id();
  inline void clear_has_sequence_id();
  inline void set_has_num_messages();
  inline void clear_has_num_messages();

  ::std::string _unknown_fields_;

  ::google::protobuf::uint32 _has_bits_[1];
  mutable int _cached_size_;
  ::google::protobuf::uint64 producer_id_;
  ::google::protobuf::uint64 sequence_id_;
  ::google::protobuf::int32 num_messages_;
  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
  friend void  protobuf_AddDesc_PulsarApi_2eproto_impl();
  #else
  friend void  protobuf_AddDesc_PulsarApi_2eproto();
  #endif
  friend void protobuf_AssignDesc_PulsarApi_2eproto();
  friend void protobuf_ShutdownFile_PulsarApi_2eproto();

  void InitAsDefaultInstance();
  static CommandSend* default_instance_;
};
// -------------------------------------------------------------------

class CommandSendReceipt : public ::google::protobuf::MessageLite {
 public:
  CommandSendReceipt();
  virtual ~CommandSendReceipt();

  CommandSendReceipt(const CommandSendReceipt& from);

  inline CommandSendReceipt& operator=(const CommandSendReceipt& from) {
    CopyFrom(from);
    return *this;
  }

  inline const ::std::string& unknown_fields() const {
    return _unknown_fields_;
  }

  inline ::std::string* mutable_unknown_fields() {
    return &_unknown_fields_;
  }

  static const CommandSendReceipt& default_instance();

  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
  // Returns the internal default instance pointer. This function can
  // return NULL thus should not be used by the user. This is intended
  // for Protobuf internal code. Please use default_instance() declared
  // above instead.
  static inline const CommandSendReceipt* internal_default_instance() {
    return default_instance_;
  }
  #endif

  void Swap(CommandSendReceipt* other);

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

  CommandSendReceipt* New() const;
  void CheckTypeAndMergeFrom(const ::google::protobuf::MessageLite& from);
  void CopyFrom(const CommandSendReceipt& from);
  void MergeFrom(const CommandSendReceipt& from);
  void Clear();
  bool IsInitialized() const;

  int ByteSize() const;
  bool MergePartialFromCodedStream(
      ::google::protobuf::io::CodedInputStream* input);
  void SerializeWithCachedSizes(
      ::google::protobuf::io::CodedOutputStream* output) const;
  void DiscardUnknownFields();
  int GetCachedSize() const { return _cached_size_; }
  private:
  void SharedCtor();
  void SharedDtor();
  void SetCachedSize(int size) const;
  public:
  ::std::string GetTypeName() const;

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

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

  // required uint64 producer_id = 1;
  inline bool has_producer_id() const;
  inline void clear_producer_id();
  static const int kProducerIdFieldNumber = 1;
  inline ::google::protobuf::uint64 producer_id() const;
  inline void set_producer_id(::google::protobuf::uint64 value);

  // required uint64 sequence_id = 2;
  inline bool has_sequence_id() const;
  inline void clear_sequence_id();
  static const int kSequenceIdFieldNumber = 2;
  inline ::google::protobuf::uint64 sequence_id() const;
  inline void set_sequence_id(::google::protobuf::uint64 value);

  // optional .pulsar.proto.MessageIdData message_id = 3;
  inline bool has_message_id() const;
  inline void clear_message_id();
  static const int kMessageIdFieldNumber = 3;
  inline const ::pulsar::proto::MessageIdData& message_id() const;
  inline ::pulsar::proto::MessageIdData* mutable_message_id();
  inline ::pulsar::proto::MessageIdData* release_message_id();
  inline void set_allocated_message_id(::pulsar::proto::MessageIdData* message_id);

  // @@protoc_insertion_point(class_scope:pulsar.proto.CommandSendReceipt)
 private:
  inline void set_has_producer_id();
  inline void clear_has_producer_id();
  inline void set_has_sequence_id();
  inline void clear_has_sequence_id();
  inline void set_has_message_id();
  inline void clear_has_message_id();

  ::std::string _unknown_fields_;

  ::google::protobuf::uint32 _has_bits_[1];
  mutable int _cached_size_;
  ::google::protobuf::uint64 producer_id_;
  ::google::protobuf::uint64 sequence_id_;
  ::pulsar::proto::MessageIdData* message_id_;
  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
  friend void  protobuf_AddDesc_PulsarApi_2eproto_impl();
  #else
  friend void  protobuf_AddDesc_PulsarApi_2eproto();
  #endif
  friend void protobuf_AssignDesc_PulsarApi_2eproto();
  friend void protobuf_ShutdownFile_PulsarApi_2eproto();

  void InitAsDefaultInstance();
  static CommandSendReceipt* default_instance_;
};
// -------------------------------------------------------------------

class CommandSendError : public ::google::protobuf::MessageLite {
 public:
  CommandSendError();
  virtual ~CommandSendError();

  CommandSendError(const CommandSendError& from);

  inline CommandSendError& operator=(const CommandSendError& from) {
    CopyFrom(from);
    return *this;
  }

  inline const ::std::string& unknown_fields() const {
    return _unknown_fields_;
  }

  inline ::std::string* mutable_unknown_fields() {
    return &_unknown_fields_;
  }

  static const CommandSendError& default_instance();

  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
  // Returns the internal default instance pointer. This function can
  // return NULL thus should not be used by the user. This is intended
  // for Protobuf internal code. Please use default_instance() declared
  // above instead.
  static inline const CommandSendError* internal_default_instance() {
    return default_instance_;
  }
  #endif

  void Swap(CommandSendError* other);

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

  CommandSendError* New() const;
  void CheckTypeAndMergeFrom(const ::google::protobuf::MessageLite& from);
  void CopyFrom(const CommandSendError& from);
  void MergeFrom(const CommandSendError& from);
  void Clear();
  bool IsInitialized() const;

  int ByteSize() const;
  bool MergePartialFromCodedStream(
      ::google::protobuf::io::CodedInputStream* input);
  void SerializeWithCachedSizes(
      ::google::protobuf::io::CodedOutputStream* output) const;
  void DiscardUnknownFields();
  int GetCachedSize() const { return _cached_size_; }
  private:
  void SharedCtor();
  void SharedDtor();
  void SetCachedSize(int size) const;
  public:
  ::std::string GetTypeName() const;

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

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

  // required uint64 producer_id = 1;
  inline bool has_producer_id() const;
  inline void clear_producer_id();
  static const int kProducerIdFieldNumber = 1;
  inline ::google::protobuf::uint64 producer_id() const;
  inline void set_producer_id(::google::protobuf::uint64 value);

  // required uint64 sequence_id = 2;
  inline bool has_sequence_id() const;
  inline void clear_sequence_id();
  static const int kSequenceIdFieldNumber = 2;
  inline ::google::protobuf::uint64 sequence_id() const;
  inline void set_sequence_id(::google::protobuf::uint64 value);

  // required .pulsar.proto.ServerError error = 3;
  inline bool has_error() const;
  inline void clear_error();
  static const int kErrorFieldNumber = 3;
  inline ::pulsar::proto::ServerError error() const;
  inline void set_error(::pulsar::proto::ServerError value);

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

  // @@protoc_insertion_point(class_scope:pulsar.proto.CommandSendError)
 private:
  inline void set_has_producer_id();
  inline void clear_has_producer_id();
  inline void set_has_sequence_id();
  inline void clear_has_sequence_id();
  inline void set_has_error();
  inline void clear_has_error();
  inline void set_has_message();
  inline void clear_has_message();

  ::std::string _unknown_fields_;

  ::google::protobuf::uint32 _has_bits_[1];
  mutable int _cached_size_;
  ::google::protobuf::uint64 producer_id_;
  ::google::protobuf::uint64 sequence_id_;
  ::std::string* message_;
  int error_;
  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
  friend void  protobuf_AddDesc_PulsarApi_2eproto_impl();
  #else
  friend void  protobuf_AddDesc_PulsarApi_2eproto();
  #endif
  friend void protobuf_AssignDesc_PulsarApi_2eproto();
  friend void protobuf_ShutdownFile_PulsarApi_2eproto();

  void InitAsDefaultInstance();
  static CommandSendError* default_instance_;
};
// -------------------------------------------------------------------

class CommandMessage : public ::google::protobuf::MessageLite {
 public:
  CommandMessage();
  virtual ~CommandMessage();

  CommandMessage(const CommandMessage& from);

  inline CommandMessage& operator=(const CommandMessage& from) {
    CopyFrom(from);
    return *this;
  }

  inline const ::std::string& unknown_fields() const {
    return _unknown_fields_;
  }

  inline ::std::string* mutable_unknown_fields() {
    return &_unknown_fields_;
  }

  static const CommandMessage& default_instance();

  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
  // Returns the internal default instance pointer. This function can
  // return NULL thus should not be used by the user. This is intended
  // for Protobuf internal code. Please use default_instance() declared
  // above instead.
  static inline const CommandMessage* internal_default_instance() {
    return default_instance_;
  }
  #endif

  void Swap(CommandMessage* other);

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

  CommandMessage* New() const;
  void CheckTypeAndMergeFrom(const ::google::protobuf::MessageLite& from);
  void CopyFrom(const CommandMessage& from);
  void MergeFrom(const CommandMessage& from);
  void Clear();
  bool IsInitialized() const;

  int ByteSize() const;
  bool MergePartialFromCodedStream(
      ::google::protobuf::io::CodedInputStream* input);
  void SerializeWithCachedSizes(
      ::google::protobuf::io::CodedOutputStream* output) const;
  void DiscardUnknownFields();
  int GetCachedSize() const { return _cached_size_; }
  private:
  void SharedCtor();
  void SharedDtor();
  void SetCachedSize(int size) const;
  public:
  ::std::string GetTypeName() const;

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

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

  // required uint64 consumer_id = 1;
  inline bool has_consumer_id() const;
  inline void clear_consumer_id();
  static const int kConsumerIdFieldNumber = 1;
  inline ::google::protobuf::uint64 consumer_id() const;
  inline void set_consumer_id(::google::protobuf::uint64 value);

  // required .pulsar.proto.MessageIdData message_id = 2;
  inline bool has_message_id() const;
  inline void clear_message_id();
  static const int kMessageIdFieldNumber = 2;
  inline const ::pulsar::proto::MessageIdData& message_id() const;
  inline ::pulsar::proto::MessageIdData* mutable_message_id();
  inline ::pulsar::proto::MessageIdData* release_message_id();
  inline void set_allocated_message_id(::pulsar::proto::MessageIdData* message_id);

  // @@protoc_insertion_point(class_scope:pulsar.proto.CommandMessage)
 private:
  inline void set_has_consumer_id();
  inline void clear_has_consumer_id();
  inline void set_has_message_id();
  inline void clear_has_message_id();

  ::std::string _unknown_fields_;

  ::google::protobuf::uint32 _has_bits_[1];
  mutable int _cached_size_;
  ::google::protobuf::uint64 consumer_id_;
  ::pulsar::proto::MessageIdData* message_id_;
  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
  friend void  protobuf_AddDesc_PulsarApi_2eproto_impl();
  #else
  friend void  protobuf_AddDesc_PulsarApi_2eproto();
  #endif
  friend void protobuf_AssignDesc_PulsarApi_2eproto();
  friend void protobuf_ShutdownFile_PulsarApi_2eproto();

  void InitAsDefaultInstance();
  static CommandMessage* default_instance_;
};
// -------------------------------------------------------------------

class CommandAck : public ::google::protobuf::MessageLite {
 public:
  CommandAck();
  virtual ~CommandAck();

  CommandAck(const CommandAck& from);

  inline CommandAck& operator=(const CommandAck& from) {
    CopyFrom(from);
    return *this;
  }

  inline const ::std::string& unknown_fields() const {
    return _unknown_fields_;
  }

  inline ::std::string* mutable_unknown_fields() {
    return &_unknown_fields_;
  }

  static const CommandAck& default_instance();

  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
  // Returns the internal default instance pointer. This function can
  // return NULL thus should not be used by the user. This is intended
  // for Protobuf internal code. Please use default_instance() declared
  // above instead.
  static inline const CommandAck* internal_default_instance() {
    return default_instance_;
  }
  #endif

  void Swap(CommandAck* other);

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

  CommandAck* New() const;
  void CheckTypeAndMergeFrom(const ::google::protobuf::MessageLite& from);
  void CopyFrom(const CommandAck& from);
  void MergeFrom(const CommandAck& from);
  void Clear();
  bool IsInitialized() const;

  int ByteSize() const;
  bool MergePartialFromCodedStream(
      ::google::protobuf::io::CodedInputStream* input);
  void SerializeWithCachedSizes(
      ::google::protobuf::io::CodedOutputStream* output) const;
  void DiscardUnknownFields();
  int GetCachedSize() const { return _cached_size_; }
  private:
  void SharedCtor();
  void SharedDtor();
  void SetCachedSize(int size) const;
  public:
  ::std::string GetTypeName() const;

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

  typedef CommandAck_AckType AckType;
  static const AckType Individual = CommandAck_AckType_Individual;
  static const AckType Cumulative = CommandAck_AckType_Cumulative;
  static inline bool AckType_IsValid(int value) {
    return CommandAck_AckType_IsValid(value);
  }
  static const AckType AckType_MIN =
    CommandAck_AckType_AckType_MIN;
  static const AckType AckType_MAX =
    CommandAck_AckType_AckType_MAX;
  static const int AckType_ARRAYSIZE =
    CommandAck_AckType_AckType_ARRAYSIZE;

  typedef CommandAck_ValidationError ValidationError;
  static const ValidationError UncompressedSizeCorruption = CommandAck_ValidationError_UncompressedSizeCorruption;
  static const ValidationError DecompressionError = CommandAck_ValidationError_DecompressionError;
  static const ValidationError ChecksumMismatch = CommandAck_ValidationError_ChecksumMismatch;
  static const ValidationError BatchDeSerializeError = CommandAck_ValidationError_BatchDeSerializeError;
  static inline bool ValidationError_IsValid(int value) {
    return CommandAck_ValidationError_IsValid(value);
  }
  static const ValidationError ValidationError_MIN =
    CommandAck_ValidationError_ValidationError_MIN;
  static const ValidationError ValidationError_MAX =
    CommandAck_ValidationError_ValidationError_MAX;
  static const int ValidationError_ARRAYSIZE =
    CommandAck_ValidationError_ValidationError_ARRAYSIZE;

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

  // required uint64 consumer_id = 1;
  inline bool has_consumer_id() const;
  inline void clear_consumer_id();
  static const int kConsumerIdFieldNumber = 1;
  inline ::google::protobuf::uint64 consumer_id() const;
  inline void set_consumer_id(::google::protobuf::uint64 value);

  // required .pulsar.proto.CommandAck.AckType ack_type = 2;
  inline bool has_ack_type() const;
  inline void clear_ack_type();
  static const int kAckTypeFieldNumber = 2;
  inline ::pulsar::proto::CommandAck_AckType ack_type() const;
  inline void set_ack_type(::pulsar::proto::CommandAck_AckType value);

  // required .pulsar.proto.MessageIdData message_id = 3;
  inline bool has_message_id() const;
  inline void clear_message_id();
  static const int kMessageIdFieldNumber = 3;
  inline const ::pulsar::proto::MessageIdData& message_id() const;
  inline ::pulsar::proto::MessageIdData* mutable_message_id();
  inline ::pulsar::proto::MessageIdData* release_message_id();
  inline void set_allocated_message_id(::pulsar::proto::MessageIdData* message_id);

  // optional .pulsar.proto.CommandAck.ValidationError validation_error = 4;
  inline bool has_validation_error() const;
  inline void clear_validation_error();
  static const int kValidationErrorFieldNumber = 4;
  inline ::pulsar::proto::CommandAck_ValidationError validation_error() const;
  inline void set_validation_error(::pulsar::proto::CommandAck_ValidationError value);

  // @@protoc_insertion_point(class_scope:pulsar.proto.CommandAck)
 private:
  inline void set_has_consumer_id();
  inline void clear_has_consumer_id();
  inline void set_has_ack_type();
  inline void clear_has_ack_type();
  inline void set_has_message_id();
  inline void clear_has_message_id();
  inline void set_has_validation_error();
  inline void clear_has_validation_error();

  ::std::string _unknown_fields_;

  ::google::protobuf::uint32 _has_bits_[1];
  mutable int _cached_size_;
  ::google::protobuf::uint64 consumer_id_;
  ::pulsar::proto::MessageIdData* message_id_;
  int ack_type_;
  int validation_error_;
  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
  friend void  protobuf_AddDesc_PulsarApi_2eproto_impl();
  #else
  friend void  protobuf_AddDesc_PulsarApi_2eproto();
  #endif
  friend void protobuf_AssignDesc_PulsarApi_2eproto();
  friend void protobuf_ShutdownFile_PulsarApi_2eproto();

  void InitAsDefaultInstance();
  static CommandAck* default_instance_;
};
// -------------------------------------------------------------------

class CommandFlow : public ::google::protobuf::MessageLite {
 public:
  CommandFlow();
  virtual ~CommandFlow();

  CommandFlow(const CommandFlow& from);

  inline CommandFlow& operator=(const CommandFlow& from) {
    CopyFrom(from);
    return *this;
  }

  inline const ::std::string& unknown_fields() const {
    return _unknown_fields_;
  }

  inline ::std::string* mutable_unknown_fields() {
    return &_unknown_fields_;
  }

  static const CommandFlow& default_instance();

  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
  // Returns the internal default instance pointer. This function can
  // return NULL thus should not be used by the user. This is intended
  // for Protobuf internal code. Please use default_instance() declared
  // above instead.
  static inline const CommandFlow* internal_default_instance() {
    return default_instance_;
  }
  #endif

  void Swap(CommandFlow* other);

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

  CommandFlow* New() const;
  void CheckTypeAndMergeFrom(const ::google::protobuf::MessageLite& from);
  void CopyFrom(const CommandFlow& from);
  void MergeFrom(const CommandFlow& from);
  void Clear();
  bool IsInitialized() const;

  int ByteSize() const;
  bool MergePartialFromCodedStream(
      ::google::protobuf::io::CodedInputStream* input);
  void SerializeWithCachedSizes(
      ::google::protobuf::io::CodedOutputStream* output) const;
  void DiscardUnknownFields();
  int GetCachedSize() const { return _cached_size_; }
  private:
  void SharedCtor();
  void SharedDtor();
  void SetCachedSize(int size) const;
  public:
  ::std::string GetTypeName() const;

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

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

  // required uint64 consumer_id = 1;
  inline bool has_consumer_id() const;
  inline void clear_consumer_id();
  static const int kConsumerIdFieldNumber = 1;
  inline ::google::protobuf::uint64 consumer_id() const;
  inline void set_consumer_id(::google::protobuf::uint64 value);

  // required uint32 messagePermits = 2;
  inline bool has_messagepermits() const;
  inline void clear_messagepermits();
  static const int kMessagePermitsFieldNumber = 2;
  inline ::google::protobuf::uint32 messagepermits() const;
  inline void set_messagepermits(::google::protobuf::uint32 value);

  // @@protoc_insertion_point(class_scope:pulsar.proto.CommandFlow)
 private:
  inline void set_has_consumer_id();
  inline void clear_has_consumer_id();
  inline void set_has_messagepermits();
  inline void clear_has_messagepermits();

  ::std::string _unknown_fields_;

  ::google::protobuf::uint32 _has_bits_[1];
  mutable int _cached_size_;
  ::google::protobuf::uint64 consumer_id_;
  ::google::protobuf::uint32 messagepermits_;
  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
  friend void  protobuf_AddDesc_PulsarApi_2eproto_impl();
  #else
  friend void  protobuf_AddDesc_PulsarApi_2eproto();
  #endif
  friend void protobuf_AssignDesc_PulsarApi_2eproto();
  friend void protobuf_ShutdownFile_PulsarApi_2eproto();

  void InitAsDefaultInstance();
  static CommandFlow* default_instance_;
};
// -------------------------------------------------------------------

class CommandUnsubscribe : public ::google::protobuf::MessageLite {
 public:
  CommandUnsubscribe();
  virtual ~CommandUnsubscribe();

  CommandUnsubscribe(const CommandUnsubscribe& from);

  inline CommandUnsubscribe& operator=(const CommandUnsubscribe& from) {
    CopyFrom(from);
    return *this;
  }

  inline const ::std::string& unknown_fields() const {
    return _unknown_fields_;
  }

  inline ::std::string* mutable_unknown_fields() {
    return &_unknown_fields_;
  }

  static const CommandUnsubscribe& default_instance();

  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
  // Returns the internal default instance pointer. This function can
  // return NULL thus should not be used by the user. This is intended
  // for Protobuf internal code. Please use default_instance() declared
  // above instead.
  static inline const CommandUnsubscribe* internal_default_instance() {
    return default_instance_;
  }
  #endif

  void Swap(CommandUnsubscribe* other);

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

  CommandUnsubscribe* New() const;
  void CheckTypeAndMergeFrom(const ::google::protobuf::MessageLite& from);
  void CopyFrom(const CommandUnsubscribe& from);
  void MergeFrom(const CommandUnsubscribe& from);
  void Clear();
  bool IsInitialized() const;

  int ByteSize() const;
  bool MergePartialFromCodedStream(
      ::google::protobuf::io::CodedInputStream* input);
  void SerializeWithCachedSizes(
      ::google::protobuf::io::CodedOutputStream* output) const;
  void DiscardUnknownFields();
  int GetCachedSize() const { return _cached_size_; }
  private:
  void SharedCtor();
  void SharedDtor();
  void SetCachedSize(int size) const;
  public:
  ::std::string GetTypeName() const;

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

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

  // required uint64 consumer_id = 1;
  inline bool has_consumer_id() const;
  inline void clear_consumer_id();
  static const int kConsumerIdFieldNumber = 1;
  inline ::google::protobuf::uint64 consumer_id() const;
  inline void set_consumer_id(::google::protobuf::uint64 value);

  // required uint64 request_id = 2;
  inline bool has_request_id() const;
  inline void clear_request_id();
  static const int kRequestIdFieldNumber = 2;
  inline ::google::protobuf::uint64 request_id() const;
  inline void set_request_id(::google::protobuf::uint64 value);

  // @@protoc_insertion_point(class_scope:pulsar.proto.CommandUnsubscribe)
 private:
  inline void set_has_consumer_id();
  inline void clear_has_consumer_id();
  inline void set_has_request_id();
  inline void clear_has_request_id();

  ::std::string _unknown_fields_;

  ::google::protobuf::uint32 _has_bits_[1];
  mutable int _cached_size_;
  ::google::protobuf::uint64 consumer_id_;
  ::google::protobuf::uint64 request_id_;
  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
  friend void  protobuf_AddDesc_PulsarApi_2eproto_impl();
  #else
  friend void  protobuf_AddDesc_PulsarApi_2eproto();
  #endif
  friend void protobuf_AssignDesc_PulsarApi_2eproto();
  friend void protobuf_ShutdownFile_PulsarApi_2eproto();

  void InitAsDefaultInstance();
  static CommandUnsubscribe* default_instance_;
};
// -------------------------------------------------------------------

class CommandCloseProducer : public ::google::protobuf::MessageLite {
 public:
  CommandCloseProducer();
  virtual ~CommandCloseProducer();

  CommandCloseProducer(const CommandCloseProducer& from);

  inline CommandCloseProducer& operator=(const CommandCloseProducer& from) {
    CopyFrom(from);
    return *this;
  }

  inline const ::std::string& unknown_fields() const {
    return _unknown_fields_;
  }

  inline ::std::string* mutable_unknown_fields() {
    return &_unknown_fields_;
  }

  static const CommandCloseProducer& default_instance();

  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
  // Returns the internal default instance pointer. This function can
  // return NULL thus should not be used by the user. This is intended
  // for Protobuf internal code. Please use default_instance() declared
  // above instead.
  static inline const CommandCloseProducer* internal_default_instance() {
    return default_instance_;
  }
  #endif

  void Swap(CommandCloseProducer* other);

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

  CommandCloseProducer* New() const;
  void CheckTypeAndMergeFrom(const ::google::protobuf::MessageLite& from);
  void CopyFrom(const CommandCloseProducer& from);
  void MergeFrom(const CommandCloseProducer& from);
  void Clear();
  bool IsInitialized() const;

  int ByteSize() const;
  bool MergePartialFromCodedStream(
      ::google::protobuf::io::CodedInputStream* input);
  void SerializeWithCachedSizes(
      ::google::protobuf::io::CodedOutputStream* output) const;
  void DiscardUnknownFields();
  int GetCachedSize() const { return _cached_size_; }
  private:
  void SharedCtor();
  void SharedDtor();
  void SetCachedSize(int size) const;
  public:
  ::std::string GetTypeName() const;

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

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

  // required uint64 producer_id = 1;
  inline bool has_producer_id() const;
  inline void clear_producer_id();
  static const int kProducerIdFieldNumber = 1;
  inline ::google::protobuf::uint64 producer_id() const;
  inline void set_producer_id(::google::protobuf::uint64 value);

  // required uint64 request_id = 2;
  inline bool has_request_id() const;
  inline void clear_request_id();
  static const int kRequestIdFieldNumber = 2;
  inline ::google::protobuf::uint64 request_id() const;
  inline void set_request_id(::google::protobuf::uint64 value);

  // @@protoc_insertion_point(class_scope:pulsar.proto.CommandCloseProducer)
 private:
  inline void set_has_producer_id();
  inline void clear_has_producer_id();
  inline void set_has_request_id();
  inline void clear_has_request_id();

  ::std::string _unknown_fields_;

  ::google::protobuf::uint32 _has_bits_[1];
  mutable int _cached_size_;
  ::google::protobuf::uint64 producer_id_;
  ::google::protobuf::uint64 request_id_;
  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
  friend void  protobuf_AddDesc_PulsarApi_2eproto_impl();
  #else
  friend void  protobuf_AddDesc_PulsarApi_2eproto();
  #endif
  friend void protobuf_AssignDesc_PulsarApi_2eproto();
  friend void protobuf_ShutdownFile_PulsarApi_2eproto();

  void InitAsDefaultInstance();
  static CommandCloseProducer* default_instance_;
};
// -------------------------------------------------------------------

class CommandCloseConsumer : public ::google::protobuf::MessageLite {
 public:
  CommandCloseConsumer();
  virtual ~CommandCloseConsumer();

  CommandCloseConsumer(const CommandCloseConsumer& from);

  inline CommandCloseConsumer& operator=(const CommandCloseConsumer& from) {
    CopyFrom(from);
    return *this;
  }

  inline const ::std::string& unknown_fields() const {
    return _unknown_fields_;
  }

  inline ::std::string* mutable_unknown_fields() {
    return &_unknown_fields_;
  }

  static const CommandCloseConsumer& default_instance();

  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
  // Returns the internal default instance pointer. This function can
  // return NULL thus should not be used by the user. This is intended
  // for Protobuf internal code. Please use default_instance() declared
  // above instead.
  static inline const CommandCloseConsumer* internal_default_instance() {
    return default_instance_;
  }
  #endif

  void Swap(CommandCloseConsumer* other);

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

  CommandCloseConsumer* New() const;
  void CheckTypeAndMergeFrom(const ::google::protobuf::MessageLite& from);
  void CopyFrom(const CommandCloseConsumer& from);
  void MergeFrom(const CommandCloseConsumer& from);
  void Clear();
  bool IsInitialized() const;

  int ByteSize() const;
  bool MergePartialFromCodedStream(
      ::google::protobuf::io::CodedInputStream* input);
  void SerializeWithCachedSizes(
      ::google::protobuf::io::CodedOutputStream* output) const;
  void DiscardUnknownFields();
  int GetCachedSize() const { return _cached_size_; }
  private:
  void SharedCtor();
  void SharedDtor();
  void SetCachedSize(int size) const;
  public:
  ::std::string GetTypeName() const;

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

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

  // required uint64 consumer_id = 1;
  inline bool has_consumer_id() const;
  inline void clear_consumer_id();
  static const int kConsumerIdFieldNumber = 1;
  inline ::google::protobuf::uint64 consumer_id() const;
  inline void set_consumer_id(::google::protobuf::uint64 value);

  // required uint64 request_id = 2;
  inline bool has_request_id() const;
  inline void clear_request_id();
  static const int kRequestIdFieldNumber = 2;
  inline ::google::protobuf::uint64 request_id() const;
  inline void set_request_id(::google::protobuf::uint64 value);

  // @@protoc_insertion_point(class_scope:pulsar.proto.CommandCloseConsumer)
 private:
  inline void set_has_consumer_id();
  inline void clear_has_consumer_id();
  inline void set_has_request_id();
  inline void clear_has_request_id();

  ::std::string _unknown_fields_;

  ::google::protobuf::uint32 _has_bits_[1];
  mutable int _cached_size_;
  ::google::protobuf::uint64 consumer_id_;
  ::google::protobuf::uint64 request_id_;
  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
  friend void  protobuf_AddDesc_PulsarApi_2eproto_impl();
  #else
  friend void  protobuf_AddDesc_PulsarApi_2eproto();
  #endif
  friend void protobuf_AssignDesc_PulsarApi_2eproto();
  friend void protobuf_ShutdownFile_PulsarApi_2eproto();

  void InitAsDefaultInstance();
  static CommandCloseConsumer* default_instance_;
};
// -------------------------------------------------------------------

class CommandRedeliverUnacknowledgedMessages : public ::google::protobuf::MessageLite {
 public:
  CommandRedeliverUnacknowledgedMessages();
  virtual ~CommandRedeliverUnacknowledgedMessages();

  CommandRedeliverUnacknowledgedMessages(const CommandRedeliverUnacknowledgedMessages& from);

  inline CommandRedeliverUnacknowledgedMessages& operator=(const CommandRedeliverUnacknowledgedMessages& from) {
    CopyFrom(from);
    return *this;
  }

  inline const ::std::string& unknown_fields() const {
    return _unknown_fields_;
  }

  inline ::std::string* mutable_unknown_fields() {
    return &_unknown_fields_;
  }

  static const CommandRedeliverUnacknowledgedMessages& default_instance();

  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
  // Returns the internal default instance pointer. This function can
  // return NULL thus should not be used by the user. This is intended
  // for Protobuf internal code. Please use default_instance() declared
  // above instead.
  static inline const CommandRedeliverUnacknowledgedMessages* internal_default_instance() {
    return default_instance_;
  }
  #endif

  void Swap(CommandRedeliverUnacknowledgedMessages* other);

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

  CommandRedeliverUnacknowledgedMessages* New() const;
  void CheckTypeAndMergeFrom(const ::google::protobuf::MessageLite& from);
  void CopyFrom(const CommandRedeliverUnacknowledgedMessages& from);
  void MergeFrom(const CommandRedeliverUnacknowledgedMessages& from);
  void Clear();
  bool IsInitialized() const;

  int ByteSize() const;
  bool MergePartialFromCodedStream(
      ::google::protobuf::io::CodedInputStream* input);
  void SerializeWithCachedSizes(
      ::google::protobuf::io::CodedOutputStream* output) const;
  void DiscardUnknownFields();
  int GetCachedSize() const { return _cached_size_; }
  private:
  void SharedCtor();
  void SharedDtor();
  void SetCachedSize(int size) const;
  public:
  ::std::string GetTypeName() const;

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

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

  // required uint64 consumer_id = 1;
  inline bool has_consumer_id() const;
  inline void clear_consumer_id();
  static const int kConsumerIdFieldNumber = 1;
  inline ::google::protobuf::uint64 consumer_id() const;
  inline void set_consumer_id(::google::protobuf::uint64 value);

  // repeated .pulsar.proto.MessageIdData message_ids = 2;
  inline int message_ids_size() const;
  inline void clear_message_ids();
  static const int kMessageIdsFieldNumber = 2;
  inline const ::pulsar::proto::MessageIdData& message_ids(int index) const;
  inline ::pulsar::proto::MessageIdData* mutable_message_ids(int index);
  inline ::pulsar::proto::MessageIdData* add_message_ids();
  inline const ::google::protobuf::RepeatedPtrField< ::pulsar::proto::MessageIdData >&
      message_ids() const;
  inline ::google::protobuf::RepeatedPtrField< ::pulsar::proto::MessageIdData >*
      mutable_message_ids();

  // @@protoc_insertion_point(class_scope:pulsar.proto.CommandRedeliverUnacknowledgedMessages)
 private:
  inline void set_has_consumer_id();
  inline void clear_has_consumer_id();

  ::std::string _unknown_fields_;

  ::google::protobuf::uint32 _has_bits_[1];
  mutable int _cached_size_;
  ::google::protobuf::uint64 consumer_id_;
  ::google::protobuf::RepeatedPtrField< ::pulsar::proto::MessageIdData > message_ids_;
  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
  friend void  protobuf_AddDesc_PulsarApi_2eproto_impl();
  #else
  friend void  protobuf_AddDesc_PulsarApi_2eproto();
  #endif
  friend void protobuf_AssignDesc_PulsarApi_2eproto();
  friend void protobuf_ShutdownFile_PulsarApi_2eproto();

  void InitAsDefaultInstance();
  static CommandRedeliverUnacknowledgedMessages* default_instance_;
};
// -------------------------------------------------------------------

class CommandSuccess : public ::google::protobuf::MessageLite {
 public:
  CommandSuccess();
  virtual ~CommandSuccess();

  CommandSuccess(const CommandSuccess& from);

  inline CommandSuccess& operator=(const CommandSuccess& from) {
    CopyFrom(from);
    return *this;
  }

  inline const ::std::string& unknown_fields() const {
    return _unknown_fields_;
  }

  inline ::std::string* mutable_unknown_fields() {
    return &_unknown_fields_;
  }

  static const CommandSuccess& default_instance();

  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
  // Returns the internal default instance pointer. This function can
  // return NULL thus should not be used by the user. This is intended
  // for Protobuf internal code. Please use default_instance() declared
  // above instead.
  static inline const CommandSuccess* internal_default_instance() {
    return default_instance_;
  }
  #endif

  void Swap(CommandSuccess* other);

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

  CommandSuccess* New() const;
  void CheckTypeAndMergeFrom(const ::google::protobuf::MessageLite& from);
  void CopyFrom(const CommandSuccess& from);
  void MergeFrom(const CommandSuccess& from);
  void Clear();
  bool IsInitialized() const;

  int ByteSize() const;
  bool MergePartialFromCodedStream(
      ::google::protobuf::io::CodedInputStream* input);
  void SerializeWithCachedSizes(
      ::google::protobuf::io::CodedOutputStream* output) const;
  void DiscardUnknownFields();
  int GetCachedSize() const { return _cached_size_; }
  private:
  void SharedCtor();
  void SharedDtor();
  void SetCachedSize(int size) const;
  public:
  ::std::string GetTypeName() const;

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

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

  // required uint64 request_id = 1;
  inline bool has_request_id() const;
  inline void clear_request_id();
  static const int kRequestIdFieldNumber = 1;
  inline ::google::protobuf::uint64 request_id() const;
  inline void set_request_id(::google::protobuf::uint64 value);

  // @@protoc_insertion_point(class_scope:pulsar.proto.CommandSuccess)
 private:
  inline void set_has_request_id();
  inline void clear_has_request_id();

  ::std::string _unknown_fields_;

  ::google::protobuf::uint32 _has_bits_[1];
  mutable int _cached_size_;
  ::google::protobuf::uint64 request_id_;
  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
  friend void  protobuf_AddDesc_PulsarApi_2eproto_impl();
  #else
  friend void  protobuf_AddDesc_PulsarApi_2eproto();
  #endif
  friend void protobuf_AssignDesc_PulsarApi_2eproto();
  friend void protobuf_ShutdownFile_PulsarApi_2eproto();

  void InitAsDefaultInstance();
  static CommandSuccess* default_instance_;
};
// -------------------------------------------------------------------

class CommandProducerSuccess : public ::google::protobuf::MessageLite {
 public:
  CommandProducerSuccess();
  virtual ~CommandProducerSuccess();

  CommandProducerSuccess(const CommandProducerSuccess& from);

  inline CommandProducerSuccess& operator=(const CommandProducerSuccess& from) {
    CopyFrom(from);
    return *this;
  }

  inline const ::std::string& unknown_fields() const {
    return _unknown_fields_;
  }

  inline ::std::string* mutable_unknown_fields() {
    return &_unknown_fields_;
  }

  static const CommandProducerSuccess& default_instance();

  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
  // Returns the internal default instance pointer. This function can
  // return NULL thus should not be used by the user. This is intended
  // for Protobuf internal code. Please use default_instance() declared
  // above instead.
  static inline const CommandProducerSuccess* internal_default_instance() {
    return default_instance_;
  }
  #endif

  void Swap(CommandProducerSuccess* other);

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

  CommandProducerSuccess* New() const;
  void CheckTypeAndMergeFrom(const ::google::protobuf::MessageLite& from);
  void CopyFrom(const CommandProducerSuccess& from);
  void MergeFrom(const CommandProducerSuccess& from);
  void Clear();
  bool IsInitialized() const;

  int ByteSize() const;
  bool MergePartialFromCodedStream(
      ::google::protobuf::io::CodedInputStream* input);
  void SerializeWithCachedSizes(
      ::google::protobuf::io::CodedOutputStream* output) const;
  void DiscardUnknownFields();
  int GetCachedSize() const { return _cached_size_; }
  private:
  void SharedCtor();
  void SharedDtor();
  void SetCachedSize(int size) const;
  public:
  ::std::string GetTypeName() const;

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

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

  // required uint64 request_id = 1;
  inline bool has_request_id() const;
  inline void clear_request_id();
  static const int kRequestIdFieldNumber = 1;
  inline ::google::protobuf::uint64 request_id() const;
  inline void set_request_id(::google::protobuf::uint64 value);

  // required string producer_name = 2;
  inline bool has_producer_name() const;
  inline void clear_producer_name();
  static const int kProducerNameFieldNumber = 2;
  inline const ::std::string& producer_name() const;
  inline void set_producer_name(const ::std::string& value);
  inline void set_producer_name(const char* value);
  inline void set_producer_name(const char* value, size_t size);
  inline ::std::string* mutable_producer_name();
  inline ::std::string* release_producer_name();
  inline void set_allocated_producer_name(::std::string* producer_name);

  // @@protoc_insertion_point(class_scope:pulsar.proto.CommandProducerSuccess)
 private:
  inline void set_has_request_id();
  inline void clear_has_request_id();
  inline void set_has_producer_name();
  inline void clear_has_producer_name();

  ::std::string _unknown_fields_;

  ::google::protobuf::uint32 _has_bits_[1];
  mutable int _cached_size_;
  ::google::protobuf::uint64 request_id_;
  ::std::string* producer_name_;
  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
  friend void  protobuf_AddDesc_PulsarApi_2eproto_impl();
  #else
  friend void  protobuf_AddDesc_PulsarApi_2eproto();
  #endif
  friend void protobuf_AssignDesc_PulsarApi_2eproto();
  friend void protobuf_ShutdownFile_PulsarApi_2eproto();

  void InitAsDefaultInstance();
  static CommandProducerSuccess* default_instance_;
};
// -------------------------------------------------------------------

class CommandError : public ::google::protobuf::MessageLite {
 public:
  CommandError();
  virtual ~CommandError();

  CommandError(const CommandError& from);

  inline CommandError& operator=(const CommandError& from) {
    CopyFrom(from);
    return *this;
  }

  inline const ::std::string& unknown_fields() const {
    return _unknown_fields_;
  }

  inline ::std::string* mutable_unknown_fields() {
    return &_unknown_fields_;
  }

  static const CommandError& default_instance();

  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
  // Returns the internal default instance pointer. This function can
  // return NULL thus should not be used by the user. This is intended
  // for Protobuf internal code. Please use default_instance() declared
  // above instead.
  static inline const CommandError* internal_default_instance() {
    return default_instance_;
  }
  #endif

  void Swap(CommandError* other);

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

  CommandError* New() const;
  void CheckTypeAndMergeFrom(const ::google::protobuf::MessageLite& from);
  void CopyFrom(const CommandError& from);
  void MergeFrom(const CommandError& from);
  void Clear();
  bool IsInitialized() const;

  int ByteSize() const;
  bool MergePartialFromCodedStream(
      ::google::protobuf::io::CodedInputStream* input);
  void SerializeWithCachedSizes(
      ::google::protobuf::io::CodedOutputStream* output) const;
  void DiscardUnknownFields();
  int GetCachedSize() const { return _cached_size_; }
  private:
  void SharedCtor();
  void SharedDtor();
  void SetCachedSize(int size) const;
  public:
  ::std::string GetTypeName() const;

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

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

  // required uint64 request_id = 1;
  inline bool has_request_id() const;
  inline void clear_request_id();
  static const int kRequestIdFieldNumber = 1;
  inline ::google::protobuf::uint64 request_id() const;
  inline void set_request_id(::google::protobuf::uint64 value);

  // required .pulsar.proto.ServerError error = 2;
  inline bool has_error() const;
  inline void clear_error();
  static const int kErrorFieldNumber = 2;
  inline ::pulsar::proto::ServerError error() const;
  inline void set_error(::pulsar::proto::ServerError value);

  // required string message = 3;
  inline bool has_message() const;
  inline void clear_message();
  static const int kMessageFieldNumber = 3;
  inline const ::std::string& message() const;
  inline void set_message(const ::std::string& value);
  inline void set_message(const char* value);
  inline void set_message(const char* value, size_t size);
  inline ::std::string* mutable_message();
  inline ::std::string* release_message();
  inline void set_allocated_message(::std::string* message);

  // @@protoc_insertion_point(class_scope:pulsar.proto.CommandError)
 private:
  inline void set_has_request_id();
  inline void clear_has_request_id();
  inline void set_has_error();
  inline void clear_has_error();
  inline void set_has_message();
  inline void clear_has_message();

  ::std::string _unknown_fields_;

  ::google::protobuf::uint32 _has_bits_[1];
  mutable int _cached_size_;
  ::google::protobuf::uint64 request_id_;
  ::std::string* message_;
  int error_;
  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
  friend void  protobuf_AddDesc_PulsarApi_2eproto_impl();
  #else
  friend void  protobuf_AddDesc_PulsarApi_2eproto();
  #endif
  friend void protobuf_AssignDesc_PulsarApi_2eproto();
  friend void protobuf_ShutdownFile_PulsarApi_2eproto();

  void InitAsDefaultInstance();
  static CommandError* default_instance_;
};
// -------------------------------------------------------------------

class CommandPing : public ::google::protobuf::MessageLite {
 public:
  CommandPing();
  virtual ~CommandPing();

  CommandPing(const CommandPing& from);

  inline CommandPing& operator=(const CommandPing& from) {
    CopyFrom(from);
    return *this;
  }

  inline const ::std::string& unknown_fields() const {
    return _unknown_fields_;
  }

  inline ::std::string* mutable_unknown_fields() {
    return &_unknown_fields_;
  }

  static const CommandPing& default_instance();

  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
  // Returns the internal default instance pointer. This function can
  // return NULL thus should not be used by the user. This is intended
  // for Protobuf internal code. Please use default_instance() declared
  // above instead.
  static inline const CommandPing* internal_default_instance() {
    return default_instance_;
  }
  #endif

  void Swap(CommandPing* other);

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

  CommandPing* New() const;
  void CheckTypeAndMergeFrom(const ::google::protobuf::MessageLite& from);
  void CopyFrom(const CommandPing& from);
  void MergeFrom(const CommandPing& from);
  void Clear();
  bool IsInitialized() const;

  int ByteSize() const;
  bool MergePartialFromCodedStream(
      ::google::protobuf::io::CodedInputStream* input);
  void SerializeWithCachedSizes(
      ::google::protobuf::io::CodedOutputStream* output) const;
  void DiscardUnknownFields();
  int GetCachedSize() const { return _cached_size_; }
  private:
  void SharedCtor();
  void SharedDtor();
  void SetCachedSize(int size) const;
  public:
  ::std::string GetTypeName() const;

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

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

  // @@protoc_insertion_point(class_scope:pulsar.proto.CommandPing)
 private:

  ::std::string _unknown_fields_;

  ::google::protobuf::uint32 _has_bits_[1];
  mutable int _cached_size_;
  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
  friend void  protobuf_AddDesc_PulsarApi_2eproto_impl();
  #else
  friend void  protobuf_AddDesc_PulsarApi_2eproto();
  #endif
  friend void protobuf_AssignDesc_PulsarApi_2eproto();
  friend void protobuf_ShutdownFile_PulsarApi_2eproto();

  void InitAsDefaultInstance();
  static CommandPing* default_instance_;
};
// -------------------------------------------------------------------

class CommandPong : public ::google::protobuf::MessageLite {
 public:
  CommandPong();
  virtual ~CommandPong();

  CommandPong(const CommandPong& from);

  inline CommandPong& operator=(const CommandPong& from) {
    CopyFrom(from);
    return *this;
  }

  inline const ::std::string& unknown_fields() const {
    return _unknown_fields_;
  }

  inline ::std::string* mutable_unknown_fields() {
    return &_unknown_fields_;
  }

  static const CommandPong& default_instance();

  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
  // Returns the internal default instance pointer. This function can
  // return NULL thus should not be used by the user. This is intended
  // for Protobuf internal code. Please use default_instance() declared
  // above instead.
  static inline const CommandPong* internal_default_instance() {
    return default_instance_;
  }
  #endif

  void Swap(CommandPong* other);

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

  CommandPong* New() const;
  void CheckTypeAndMergeFrom(const ::google::protobuf::MessageLite& from);
  void CopyFrom(const CommandPong& from);
  void MergeFrom(const CommandPong& from);
  void Clear();
  bool IsInitialized() const;

  int ByteSize() const;
  bool MergePartialFromCodedStream(
      ::google::protobuf::io::CodedInputStream* input);
  void SerializeWithCachedSizes(
      ::google::protobuf::io::CodedOutputStream* output) const;
  void DiscardUnknownFields();
  int GetCachedSize() const { return _cached_size_; }
  private:
  void SharedCtor();
  void SharedDtor();
  void SetCachedSize(int size) const;
  public:
  ::std::string GetTypeName() const;

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

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

  // @@protoc_insertion_point(class_scope:pulsar.proto.CommandPong)
 private:

  ::std::string _unknown_fields_;

  ::google::protobuf::uint32 _has_bits_[1];
  mutable int _cached_size_;
  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
  friend void  protobuf_AddDesc_PulsarApi_2eproto_impl();
  #else
  friend void  protobuf_AddDesc_PulsarApi_2eproto();
  #endif
  friend void protobuf_AssignDesc_PulsarApi_2eproto();
  friend void protobuf_ShutdownFile_PulsarApi_2eproto();

  void InitAsDefaultInstance();
  static CommandPong* default_instance_;
};
// -------------------------------------------------------------------

class CommandConsumerStats : public ::google::protobuf::MessageLite {
 public:
  CommandConsumerStats();
  virtual ~CommandConsumerStats();

  CommandConsumerStats(const CommandConsumerStats& from);

  inline CommandConsumerStats& operator=(const CommandConsumerStats& from) {
    CopyFrom(from);
    return *this;
  }

  inline const ::std::string& unknown_fields() const {
    return _unknown_fields_;
  }

  inline ::std::string* mutable_unknown_fields() {
    return &_unknown_fields_;
  }

  static const CommandConsumerStats& default_instance();

  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
  // Returns the internal default instance pointer. This function can
  // return NULL thus should not be used by the user. This is intended
  // for Protobuf internal code. Please use default_instance() declared
  // above instead.
  static inline const CommandConsumerStats* internal_default_instance() {
    return default_instance_;
  }
  #endif

  void Swap(CommandConsumerStats* other);

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

  CommandConsumerStats* New() const;
  void CheckTypeAndMergeFrom(const ::google::protobuf::MessageLite& from);
  void CopyFrom(const CommandConsumerStats& from);
  void MergeFrom(const CommandConsumerStats& from);
  void Clear();
  bool IsInitialized() const;

  int ByteSize() const;
  bool MergePartialFromCodedStream(
      ::google::protobuf::io::CodedInputStream* input);
  void SerializeWithCachedSizes(
      ::google::protobuf::io::CodedOutputStream* output) const;
  void DiscardUnknownFields();
  int GetCachedSize() const { return _cached_size_; }
  private:
  void SharedCtor();
  void SharedDtor();
  void SetCachedSize(int size) const;
  public:
  ::std::string GetTypeName() const;

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

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

  // required uint64 request_id = 1;
  inline bool has_request_id() const;
  inline void clear_request_id();
  static const int kRequestIdFieldNumber = 1;
  inline ::google::protobuf::uint64 request_id() const;
  inline void set_request_id(::google::protobuf::uint64 value);

  // required string topic_name = 2;
  inline bool has_topic_name() const;
  inline void clear_topic_name();
  static const int kTopicNameFieldNumber = 2;
  inline const ::std::string& topic_name() const;
  inline void set_topic_name(const ::std::string& value);
  inline void set_topic_name(const char* value);
  inline void set_topic_name(const char* value, size_t size);
  inline ::std::string* mutable_topic_name();
  inline ::std::string* release_topic_name();
  inline void set_allocated_topic_name(::std::string* topic_name);

  // required string subscription_name = 3;
  inline bool has_subscription_name() const;
  inline void clear_subscription_name();
  static const int kSubscriptionNameFieldNumber = 3;
  inline const ::std::string& subscription_name() const;
  inline void set_subscription_name(const ::std::string& value);
  inline void set_subscription_name(const char* value);
  inline void set_subscription_name(const char* value, size_t size);
  inline ::std::string* mutable_subscription_name();
  inline ::std::string* release_subscription_name();
  inline void set_allocated_subscription_name(::std::string* subscription_name);

  // required uint64 consumer_id = 4;
  inline bool has_consumer_id() const;
  inline void clear_consumer_id();
  static const int kConsumerIdFieldNumber = 4;
  inline ::google::protobuf::uint64 consumer_id() const;
  inline void set_consumer_id(::google::protobuf::uint64 value);

  // @@protoc_insertion_point(class_scope:pulsar.proto.CommandConsumerStats)
 private:
  inline void set_has_request_id();
  inline void clear_has_request_id();
  inline void set_has_topic_name();
  inline void clear_has_topic_name();
  inline void set_has_subscription_name();
  inline void clear_has_subscription_name();
  inline void set_has_consumer_id();
  inline void clear_has_consumer_id();

  ::std::string _unknown_fields_;

  ::google::protobuf::uint32 _has_bits_[1];
  mutable int _cached_size_;
  ::google::protobuf::uint64 request_id_;
  ::std::string* topic_name_;
  ::std::string* subscription_name_;
  ::google::protobuf::uint64 consumer_id_;
  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
  friend void  protobuf_AddDesc_PulsarApi_2eproto_impl();
  #else
  friend void  protobuf_AddDesc_PulsarApi_2eproto();
  #endif
  friend void protobuf_AssignDesc_PulsarApi_2eproto();
  friend void protobuf_ShutdownFile_PulsarApi_2eproto();

  void InitAsDefaultInstance();
  static CommandConsumerStats* default_instance_;
};
// -------------------------------------------------------------------

class CommandConsumerStatsResponse : public ::google::protobuf::MessageLite {
 public:
  CommandConsumerStatsResponse();
  virtual ~CommandConsumerStatsResponse();

  CommandConsumerStatsResponse(const CommandConsumerStatsResponse& from);

  inline CommandConsumerStatsResponse& operator=(const CommandConsumerStatsResponse& from) {
    CopyFrom(from);
    return *this;
  }

  inline const ::std::string& unknown_fields() const {
    return _unknown_fields_;
  }

  inline ::std::string* mutable_unknown_fields() {
    return &_unknown_fields_;
  }

  static const CommandConsumerStatsResponse& default_instance();

  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
  // Returns the internal default instance pointer. This function can
  // return NULL thus should not be used by the user. This is intended
  // for Protobuf internal code. Please use default_instance() declared
  // above instead.
  static inline const CommandConsumerStatsResponse* internal_default_instance() {
    return default_instance_;
  }
  #endif

  void Swap(CommandConsumerStatsResponse* other);

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

  CommandConsumerStatsResponse* New() const;
  void CheckTypeAndMergeFrom(const ::google::protobuf::MessageLite& from);
  void CopyFrom(const CommandConsumerStatsResponse& from);
  void MergeFrom(const CommandConsumerStatsResponse& from);
  void Clear();
  bool IsInitialized() const;

  int ByteSize() const;
  bool MergePartialFromCodedStream(
      ::google::protobuf::io::CodedInputStream* input);
  void SerializeWithCachedSizes(
      ::google::protobuf::io::CodedOutputStream* output) const;
  void DiscardUnknownFields();
  int GetCachedSize() const { return _cached_size_; }
  private:
  void SharedCtor();
  void SharedDtor();
  void SetCachedSize(int size) const;
  public:
  ::std::string GetTypeName() const;

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

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

  // required uint64 request_id = 1;
  inline bool has_request_id() const;
  inline void clear_request_id();
  static const int kRequestIdFieldNumber = 1;
  inline ::google::protobuf::uint64 request_id() const;
  inline void set_request_id(::google::protobuf::uint64 value);

  // optional .pulsar.proto.ServerError error_code = 2;
  inline bool has_error_code() const;
  inline void clear_error_code();
  static const int kErrorCodeFieldNumber = 2;
  inline ::pulsar::proto::ServerError error_code() const;
  inline void set_error_code(::pulsar::proto::ServerError value);

  // optional string error_message = 3;
  inline bool has_error_message() const;
  inline void clear_error_message();
  static const int kErrorMessageFieldNumber = 3;
  inline const ::std::string& error_message() const;
  inline void set_error_message(const ::std::string& value);
  inline void set_error_message(const char* value);
  inline void set_error_message(const char* value, size_t size);
  inline ::std::string* mutable_error_message();
  inline ::std::string* release_error_message();
  inline void set_allocated_error_message(::std::string* error_message);

  // optional double msgRateOut = 4;
  inline bool has_msgrateout() const;
  inline void clear_msgrateout();
  static const int kMsgRateOutFieldNumber = 4;
  inline double msgrateout() const;
  inline void set_msgrateout(double value);

  // optional double msgThroughputOut = 5;
  inline bool has_msgthroughputout() const;
  inline void clear_msgthroughputout();
  static const int kMsgThroughputOutFieldNumber = 5;
  inline double msgthroughputout() const;
  inline void set_msgthroughputout(double value);

  // optional double msgRateRedeliver = 6;
  inline bool has_msgrateredeliver() const;
  inline void clear_msgrateredeliver();
  static const int kMsgRateRedeliverFieldNumber = 6;
  inline double msgrateredeliver() const;
  inline void set_msgrateredeliver(double value);

  // optional string consumerName = 7;
  inline bool has_consumername() const;
  inline void clear_consumername();
  static const int kConsumerNameFieldNumber = 7;
  inline const ::std::string& consumername() const;
  inline void set_consumername(const ::std::string& value);
  inline void set_consumername(const char* value);
  inline void set_consumername(const char* value, size_t size);
  inline ::std::string* mutable_consumername();
  inline ::std::string* release_consumername();
  inline void set_allocated_consumername(::std::string* consumername);

  // optional uint64 availablePermits = 8;
  inline bool has_availablepermits() const;
  inline void clear_availablepermits();
  static const int kAvailablePermitsFieldNumber = 8;
  inline ::google::protobuf::uint64 availablepermits() const;
  inline void set_availablepermits(::google::protobuf::uint64 value);

  // optional uint64 unackedMessages = 9;
  inline bool has_unackedmessages() const;
  inline void clear_unackedmessages();
  static const int kUnackedMessagesFieldNumber = 9;
  inline ::google::protobuf::uint64 unackedmessages() const;
  inline void set_unackedmessages(::google::protobuf::uint64 value);

  // optional bool blockedConsumerOnUnackedMsgs = 10;
  inline bool has_blockedconsumeronunackedmsgs() const;
  inline void clear_blockedconsumeronunackedmsgs();
  static const int kBlockedConsumerOnUnackedMsgsFieldNumber = 10;
  inline bool blockedconsumeronunackedmsgs() const;
  inline void set_blockedconsumeronunackedmsgs(bool value);

  // optional string address = 11;
  inline bool has_address() const;
  inline void clear_address();
  static const int kAddressFieldNumber = 11;
  inline const ::std::string& address() const;
  inline void set_address(const ::std::string& value);
  inline void set_address(const char* value);
  inline void set_address(const char* value, size_t size);
  inline ::std::string* mutable_address();
  inline ::std::string* release_address();
  inline void set_allocated_address(::std::string* address);

  // optional string connectedSince = 12;
  inline bool has_connectedsince() const;
  inline void clear_connectedsince();
  static const int kConnectedSinceFieldNumber = 12;
  inline const ::std::string& connectedsince() const;
  inline void set_connectedsince(const ::std::string& value);
  inline void set_connectedsince(const char* value);
  inline void set_connectedsince(const char* value, size_t size);
  inline ::std::string* mutable_connectedsince();
  inline ::std::string* release_connectedsince();
  inline void set_allocated_connectedsince(::std::string* connectedsince);

  // optional string type = 13;
  inline bool has_type() const;
  inline void clear_type();
  static const int kTypeFieldNumber = 13;
  inline const ::std::string& type() const;
  inline void set_type(const ::std::string& value);
  inline void set_type(const char* value);
  inline void set_type(const char* value, size_t size);
  inline ::std::string* mutable_type();
  inline ::std::string* release_type();
  inline void set_allocated_type(::std::string* type);

  // optional double msgRateExpired = 14;
  inline bool has_msgrateexpired() const;
  inline void clear_msgrateexpired();
  static const int kMsgRateExpiredFieldNumber = 14;
  inline double msgrateexpired() const;
  inline void set_msgrateexpired(double value);

  // optional uint64 msgBacklog = 15;
  inline bool has_msgbacklog() const;
  inline void clear_msgbacklog();
  static const int kMsgBacklogFieldNumber = 15;
  inline ::google::protobuf::uint64 msgbacklog() const;
  inline void set_msgbacklog(::google::protobuf::uint64 value);

  // @@protoc_insertion_point(class_scope:pulsar.proto.CommandConsumerStatsResponse)
 private:
  inline void set_has_request_id();
  inline void clear_has_request_id();
  inline void set_has_error_code();
  inline void clear_has_error_code();
  inline void set_has_error_message();
  inline void clear_has_error_message();
  inline void set_has_msgrateout();
  inline void clear_has_msgrateout();
  inline void set_has_msgthroughputout();
  inline void clear_has_msgthroughputout();
  inline void set_has_msgrateredeliver();
  inline void clear_has_msgrateredeliver();
  inline void set_has_consumername();
  inline void clear_has_consumername();
  inline void set_has_availablepermits();
  inline void clear_has_availablepermits();
  inline void set_has_unackedmessages();
  inline void clear_has_unackedmessages();
  inline void set_has_blockedconsumeronunackedmsgs();
  inline void clear_has_blockedconsumeronunackedmsgs();
  inline void set_has_address();
  inline void clear_has_address();
  inline void set_has_connectedsince();
  inline void clear_has_connectedsince();
  inline void set_has_type();
  inline void clear_has_type();
  inline void set_has_msgrateexpired();
  inline void clear_has_msgrateexpired();
  inline void set_has_msgbacklog();
  inline void clear_has_msgbacklog();

  ::std::string _unknown_fields_;

  ::google::protobuf::uint32 _has_bits_[1];
  mutable int _cached_size_;
  ::google::protobuf::uint64 request_id_;
  ::std::string* error_message_;
  double msgrateout_;
  double msgthroughputout_;
  double msgrateredeliver_;
  int error_code_;
  bool blockedconsumeronunackedmsgs_;
  ::std::string* consumername_;
  ::google::protobuf::uint64 availablepermits_;
  ::google::protobuf::uint64 unackedmessages_;
  ::std::string* address_;
  ::std::string* connectedsince_;
  ::std::string* type_;
  double msgrateexpired_;
  ::google::protobuf::uint64 msgbacklog_;
  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
  friend void  protobuf_AddDesc_PulsarApi_2eproto_impl();
  #else
  friend void  protobuf_AddDesc_PulsarApi_2eproto();
  #endif
  friend void protobuf_AssignDesc_PulsarApi_2eproto();
  friend void protobuf_ShutdownFile_PulsarApi_2eproto();

  void InitAsDefaultInstance();
  static CommandConsumerStatsResponse* default_instance_;
};
// -------------------------------------------------------------------

class BaseCommand : public ::google::protobuf::MessageLite {
 public:
  BaseCommand();
  virtual ~BaseCommand();

  BaseCommand(const BaseCommand& from);

  inline BaseCommand& operator=(const BaseCommand& from) {
    CopyFrom(from);
    return *this;
  }

  inline const ::std::string& unknown_fields() const {
    return _unknown_fields_;
  }

  inline ::std::string* mutable_unknown_fields() {
    return &_unknown_fields_;
  }

  static const BaseCommand& default_instance();

  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
  // Returns the internal default instance pointer. This function can
  // return NULL thus should not be used by the user. This is intended
  // for Protobuf internal code. Please use default_instance() declared
  // above instead.
  static inline const BaseCommand* internal_default_instance() {
    return default_instance_;
  }
  #endif

  void Swap(BaseCommand* other);

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

  BaseCommand* New() const;
  void CheckTypeAndMergeFrom(const ::google::protobuf::MessageLite& from);
  void CopyFrom(const BaseCommand& from);
  void MergeFrom(const BaseCommand& from);
  void Clear();
  bool IsInitialized() const;

  int ByteSize() const;
  bool MergePartialFromCodedStream(
      ::google::protobuf::io::CodedInputStream* input);
  void SerializeWithCachedSizes(
      ::google::protobuf::io::CodedOutputStream* output) const;
  void DiscardUnknownFields();
  int GetCachedSize() const { return _cached_size_; }
  private:
  void SharedCtor();
  void SharedDtor();
  void SetCachedSize(int size) const;
  public:
  ::std::string GetTypeName() const;

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

  typedef BaseCommand_Type Type;
  static const Type CONNECT = BaseCommand_Type_CONNECT;
  static const Type CONNECTED = BaseCommand_Type_CONNECTED;
  static const Type SUBSCRIBE = BaseCommand_Type_SUBSCRIBE;
  static const Type PRODUCER = BaseCommand_Type_PRODUCER;
  static const Type SEND = BaseCommand_Type_SEND;
  static const Type SEND_RECEIPT = BaseCommand_Type_SEND_RECEIPT;
  static const Type SEND_ERROR = BaseCommand_Type_SEND_ERROR;
  static const Type MESSAGE = BaseCommand_Type_MESSAGE;
  static const Type ACK = BaseCommand_Type_ACK;
  static const Type FLOW = BaseCommand_Type_FLOW;
  static const Type UNSUBSCRIBE = BaseCommand_Type_UNSUBSCRIBE;
  static const Type SUCCESS = BaseCommand_Type_SUCCESS;
  static const Type ERROR = BaseCommand_Type_ERROR;
  static const Type CLOSE_PRODUCER = BaseCommand_Type_CLOSE_PRODUCER;
  static const Type CLOSE_CONSUMER = BaseCommand_Type_CLOSE_CONSUMER;
  static const Type PRODUCER_SUCCESS = BaseCommand_Type_PRODUCER_SUCCESS;
  static const Type PING = BaseCommand_Type_PING;
  static const Type PONG = BaseCommand_Type_PONG;
  static const Type REDELIVER_UNACKNOWLEDGED_MESSAGES = BaseCommand_Type_REDELIVER_UNACKNOWLEDGED_MESSAGES;
  static const Type PARTITIONED_METADATA = BaseCommand_Type_PARTITIONED_METADATA;
  static const Type PARTITIONED_METADATA_RESPONSE = BaseCommand_Type_PARTITIONED_METADATA_RESPONSE;
  static const Type LOOKUP = BaseCommand_Type_LOOKUP;
  static const Type LOOKUP_RESPONSE = BaseCommand_Type_LOOKUP_RESPONSE;
  static const Type CONSUMER_STATS = BaseCommand_Type_CONSUMER_STATS;
  static const Type CONSUMER_STATS_RESPONSE = BaseCommand_Type_CONSUMER_STATS_RESPONSE;
  static inline bool Type_IsValid(int value) {
    return BaseCommand_Type_IsValid(value);
  }
  static const Type Type_MIN =
    BaseCommand_Type_Type_MIN;
  static const Type Type_MAX =
    BaseCommand_Type_Type_MAX;
  static const int Type_ARRAYSIZE =
    BaseCommand_Type_Type_ARRAYSIZE;

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

  // required .pulsar.proto.BaseCommand.Type type = 1;
  inline bool has_type() const;
  inline void clear_type();
  static const int kTypeFieldNumber = 1;
  inline ::pulsar::proto::BaseCommand_Type type() const;
  inline void set_type(::pulsar::proto::BaseCommand_Type value);

  // optional .pulsar.proto.CommandConnect connect = 2;
  inline bool has_connect() const;
  inline void clear_connect();
  static const int kConnectFieldNumber = 2;
  inline const ::pulsar::proto::CommandConnect& connect() const;
  inline ::pulsar::proto::CommandConnect* mutable_connect();
  inline ::pulsar::proto::CommandConnect* release_connect();
  inline void set_allocated_connect(::pulsar::proto::CommandConnect* connect);

  // optional .pulsar.proto.CommandConnected connected = 3;
  inline bool has_connected() const;
  inline void clear_connected();
  static const int kConnectedFieldNumber = 3;
  inline const ::pulsar::proto::CommandConnected& connected() const;
  inline ::pulsar::proto::CommandConnected* mutable_connected();
  inline ::pulsar::proto::CommandConnected* release_connected();
  inline void set_allocated_connected(::pulsar::proto::CommandConnected* connected);

  // optional .pulsar.proto.CommandSubscribe subscribe = 4;
  inline bool has_subscribe() const;
  inline void clear_subscribe();
  static const int kSubscribeFieldNumber = 4;
  inline const ::pulsar::proto::CommandSubscribe& subscribe() const;
  inline ::pulsar::proto::CommandSubscribe* mutable_subscribe();
  inline ::pulsar::proto::CommandSubscribe* release_subscribe();
  inline void set_allocated_subscribe(::pulsar::proto::CommandSubscribe* subscribe);

  // optional .pulsar.proto.CommandProducer producer = 5;
  inline bool has_producer() const;
  inline void clear_producer();
  static const int kProducerFieldNumber = 5;
  inline const ::pulsar::proto::CommandProducer& producer() const;
  inline ::pulsar::proto::CommandProducer* mutable_producer();
  inline ::pulsar::proto::CommandProducer* release_producer();
  inline void set_allocated_producer(::pulsar::proto::CommandProducer* producer);

  // optional .pulsar.proto.CommandSend send = 6;
  inline bool has_send() const;
  inline void clear_send();
  static const int kSendFieldNumber = 6;
  inline const ::pulsar::proto::CommandSend& send() const;
  inline ::pulsar::proto::CommandSend* mutable_send();
  inline ::pulsar::proto::CommandSend* release_send();
  inline void set_allocated_send(::pulsar::proto::CommandSend* send);

  // optional .pulsar.proto.CommandSendReceipt send_receipt = 7;
  inline bool has_send_receipt() const;
  inline void clear_send_receipt();
  static const int kSendReceiptFieldNumber = 7;
  inline const ::pulsar::proto::CommandSendReceipt& send_receipt() const;
  inline ::pulsar::proto::CommandSendReceipt* mutable_send_receipt();
  inline ::pulsar::proto::CommandSendReceipt* release_send_receipt();
  inline void set_allocated_send_receipt(::pulsar::proto::CommandSendReceipt* send_receipt);

  // optional .pulsar.proto.CommandSendError send_error = 8;
  inline bool has_send_error() const;
  inline void clear_send_error();
  static const int kSendErrorFieldNumber = 8;
  inline const ::pulsar::proto::CommandSendError& send_error() const;
  inline ::pulsar::proto::CommandSendError* mutable_send_error();
  inline ::pulsar::proto::CommandSendError* release_send_error();
  inline void set_allocated_send_error(::pulsar::proto::CommandSendError* send_error);

  // optional .pulsar.proto.CommandMessage message = 9;
  inline bool has_message() const;
  inline void clear_message();
  static const int kMessageFieldNumber = 9;
  inline const ::pulsar::proto::CommandMessage& message() const;
  inline ::pulsar::proto::CommandMessage* mutable_message();
  inline ::pulsar::proto::CommandMessage* release_message();
  inline void set_allocated_message(::pulsar::proto::CommandMessage* message);

  // optional .pulsar.proto.CommandAck ack = 10;
  inline bool has_ack() const;
  inline void clear_ack();
  static const int kAckFieldNumber = 10;
  inline const ::pulsar::proto::CommandAck& ack() const;
  inline ::pulsar::proto::CommandAck* mutable_ack();
  inline ::pulsar::proto::CommandAck* release_ack();
  inline void set_allocated_ack(::pulsar::proto::CommandAck* ack);

  // optional .pulsar.proto.CommandFlow flow = 11;
  inline bool has_flow() const;
  inline void clear_flow();
  static const int kFlowFieldNumber = 11;
  inline const ::pulsar::proto::CommandFlow& flow() const;
  inline ::pulsar::proto::CommandFlow* mutable_flow();
  inline ::pulsar::proto::CommandFlow* release_flow();
  inline void set_allocated_flow(::pulsar::proto::CommandFlow* flow);

  // optional .pulsar.proto.CommandUnsubscribe unsubscribe = 12;
  inline bool has_unsubscribe() const;
  inline void clear_unsubscribe();
  static const int kUnsubscribeFieldNumber = 12;
  inline const ::pulsar::proto::CommandUnsubscribe& unsubscribe() const;
  inline ::pulsar::proto::CommandUnsubscribe* mutable_unsubscribe();
  inline ::pulsar::proto::CommandUnsubscribe* release_unsubscribe();
  inline void set_allocated_unsubscribe(::pulsar::proto::CommandUnsubscribe* unsubscribe);

  // optional .pulsar.proto.CommandSuccess success = 13;
  inline bool has_success() const;
  inline void clear_success();
  static const int kSuccessFieldNumber = 13;
  inline const ::pulsar::proto::CommandSuccess& success() const;
  inline ::pulsar::proto::CommandSuccess* mutable_success();
  inline ::pulsar::proto::CommandSuccess* release_success();
  inline void set_allocated_success(::pulsar::proto::CommandSuccess* success);

  // optional .pulsar.proto.CommandError error = 14;
  inline bool has_error() const;
  inline void clear_error();
  static const int kErrorFieldNumber = 14;
  inline const ::pulsar::proto::CommandError& error() const;
  inline ::pulsar::proto::CommandError* mutable_error();
  inline ::pulsar::proto::CommandError* release_error();
  inline void set_allocated_error(::pulsar::proto::CommandError* error);

  // optional .pulsar.proto.CommandCloseProducer close_producer = 15;
  inline bool has_close_producer() const;
  inline void clear_close_producer();
  static const int kCloseProducerFieldNumber = 15;
  inline const ::pulsar::proto::CommandCloseProducer& close_producer() const;
  inline ::pulsar::proto::CommandCloseProducer* mutable_close_producer();
  inline ::pulsar::proto::CommandCloseProducer* release_close_producer();
  inline void set_allocated_close_producer(::pulsar::proto::CommandCloseProducer* close_producer);

  // optional .pulsar.proto.CommandCloseConsumer close_consumer = 16;
  inline bool has_close_consumer() const;
  inline void clear_close_consumer();
  static const int kCloseConsumerFieldNumber = 16;
  inline const ::pulsar::proto::CommandCloseConsumer& close_consumer() const;
  inline ::pulsar::proto::CommandCloseConsumer* mutable_close_consumer();
  inline ::pulsar::proto::CommandCloseConsumer* release_close_consumer();
  inline void set_allocated_close_consumer(::pulsar::proto::CommandCloseConsumer* close_consumer);

  // optional .pulsar.proto.CommandProducerSuccess producer_success = 17;
  inline bool has_producer_success() const;
  inline void clear_producer_success();
  static const int kProducerSuccessFieldNumber = 17;
  inline const ::pulsar::proto::CommandProducerSuccess& producer_success() const;
  inline ::pulsar::proto::CommandProducerSuccess* mutable_producer_success();
  inline ::pulsar::proto::CommandProducerSuccess* release_producer_success();
  inline void set_allocated_producer_success(::pulsar::proto::CommandProducerSuccess* producer_success);

  // optional .pulsar.proto.CommandPing ping = 18;
  inline bool has_ping() const;
  inline void clear_ping();
  static const int kPingFieldNumber = 18;
  inline const ::pulsar::proto::CommandPing& ping() const;
  inline ::pulsar::proto::CommandPing* mutable_ping();
  inline ::pulsar::proto::CommandPing* release_ping();
  inline void set_allocated_ping(::pulsar::proto::CommandPing* ping);

  // optional .pulsar.proto.CommandPong pong = 19;
  inline bool has_pong() const;
  inline void clear_pong();
  static const int kPongFieldNumber = 19;
  inline const ::pulsar::proto::CommandPong& pong() const;
  inline ::pulsar::proto::CommandPong* mutable_pong();
  inline ::pulsar::proto::CommandPong* release_pong();
  inline void set_allocated_pong(::pulsar::proto::CommandPong* pong);

  // optional .pulsar.proto.CommandRedeliverUnacknowledgedMessages redeliverUnacknowledgedMessages = 20;
  inline bool has_redeliverunacknowledgedmessages() const;
  inline void clear_redeliverunacknowledgedmessages();
  static const int kRedeliverUnacknowledgedMessagesFieldNumber = 20;
  inline const ::pulsar::proto::CommandRedeliverUnacknowledgedMessages& redeliverunacknowledgedmessages() const;
  inline ::pulsar::proto::CommandRedeliverUnacknowledgedMessages* mutable_redeliverunacknowledgedmessages();
  inline ::pulsar::proto::CommandRedeliverUnacknowledgedMessages* release_redeliverunacknowledgedmessages();
  inline void set_allocated_redeliverunacknowledgedmessages(::pulsar::proto::CommandRedeliverUnacknowledgedMessages* redeliverunacknowledgedmessages);

  // optional .pulsar.proto.CommandPartitionedTopicMetadata partitionMetadata = 21;
  inline bool has_partitionmetadata() const;
  inline void clear_partitionmetadata();
  static const int kPartitionMetadataFieldNumber = 21;
  inline const ::pulsar::proto::CommandPartitionedTopicMetadata& partitionmetadata() const;
  inline ::pulsar::proto::CommandPartitionedTopicMetadata* mutable_partitionmetadata();
  inline ::pulsar::proto::CommandPartitionedTopicMetadata* release_partitionmetadata();
  inline void set_allocated_partitionmetadata(::pulsar::proto::CommandPartitionedTopicMetadata* partitionmetadata);

  // optional .pulsar.proto.CommandPartitionedTopicMetadataResponse partitionMetadataResponse = 22;
  inline bool has_partitionmetadataresponse() const;
  inline void clear_partitionmetadataresponse();
  static const int kPartitionMetadataResponseFieldNumber = 22;
  inline const ::pulsar::proto::CommandPartitionedTopicMetadataResponse& partitionmetadataresponse() const;
  inline ::pulsar::proto::CommandPartitionedTopicMetadataResponse* mutable_partitionmetadataresponse();
  inline ::pulsar::proto::CommandPartitionedTopicMetadataResponse* release_partitionmetadataresponse();
  inline void set_allocated_partitionmetadataresponse(::pulsar::proto::CommandPartitionedTopicMetadataResponse* partitionmetadataresponse);

  // optional .pulsar.proto.CommandLookupTopic lookupTopic = 23;
  inline bool has_lookuptopic() const;
  inline void clear_lookuptopic();
  static const int kLookupTopicFieldNumber = 23;
  inline const ::pulsar::proto::CommandLookupTopic& lookuptopic() const;
  inline ::pulsar::proto::CommandLookupTopic* mutable_lookuptopic();
  inline ::pulsar::proto::CommandLookupTopic* release_lookuptopic();
  inline void set_allocated_lookuptopic(::pulsar::proto::CommandLookupTopic* lookuptopic);

  // optional .pulsar.proto.CommandLookupTopicResponse lookupTopicResponse = 24;
  inline bool has_lookuptopicresponse() const;
  inline void clear_lookuptopicresponse();
  static const int kLookupTopicResponseFieldNumber = 24;
  inline const ::pulsar::proto::CommandLookupTopicResponse& lookuptopicresponse() const;
  inline ::pulsar::proto::CommandLookupTopicResponse* mutable_lookuptopicresponse();
  inline ::pulsar::proto::CommandLookupTopicResponse* release_lookuptopicresponse();
  inline void set_allocated_lookuptopicresponse(::pulsar::proto::CommandLookupTopicResponse* lookuptopicresponse);

  // optional .pulsar.proto.CommandConsumerStats consumerStats = 25;
  inline bool has_consumerstats() const;
  inline void clear_consumerstats();
  static const int kConsumerStatsFieldNumber = 25;
  inline const ::pulsar::proto::CommandConsumerStats& consumerstats() const;
  inline ::pulsar::proto::CommandConsumerStats* mutable_consumerstats();
  inline ::pulsar::proto::CommandConsumerStats* release_consumerstats();
  inline void set_allocated_consumerstats(::pulsar::proto::CommandConsumerStats* consumerstats);

  // optional .pulsar.proto.CommandConsumerStatsResponse consumerStatsResponse = 26;
  inline bool has_consumerstatsresponse() const;
  inline void clear_consumerstatsresponse();
  static const int kConsumerStatsResponseFieldNumber = 26;
  inline const ::pulsar::proto::CommandConsumerStatsResponse& consumerstatsresponse() const;
  inline ::pulsar::proto::CommandConsumerStatsResponse* mutable_consumerstatsresponse();
  inline ::pulsar::proto::CommandConsumerStatsResponse* release_consumerstatsresponse();
  inline void set_allocated_consumerstatsresponse(::pulsar::proto::CommandConsumerStatsResponse* consumerstatsresponse);

  // @@protoc_insertion_point(class_scope:pulsar.proto.BaseCommand)
 private:
  inline void set_has_type();
  inline void clear_has_type();
  inline void set_has_connect();
  inline void clear_has_connect();
  inline void set_has_connected();
  inline void clear_has_connected();
  inline void set_has_subscribe();
  inline void clear_has_subscribe();
  inline void set_has_producer();
  inline void clear_has_producer();
  inline void set_has_send();
  inline void clear_has_send();
  inline void set_has_send_receipt();
  inline void clear_has_send_receipt();
  inline void set_has_send_error();
  inline void clear_has_send_error();
  inline void set_has_message();
  inline void clear_has_message();
  inline void set_has_ack();
  inline void clear_has_ack();
  inline void set_has_flow();
  inline void clear_has_flow();
  inline void set_has_unsubscribe();
  inline void clear_has_unsubscribe();
  inline void set_has_success();
  inline void clear_has_success();
  inline void set_has_error();
  inline void clear_has_error();
  inline void set_has_close_producer();
  inline void clear_has_close_producer();
  inline void set_has_close_consumer();
  inline void clear_has_close_consumer();
  inline void set_has_producer_success();
  inline void clear_has_producer_success();
  inline void set_has_ping();
  inline void clear_has_ping();
  inline void set_has_pong();
  inline void clear_has_pong();
  inline void set_has_redeliverunacknowledgedmessages();
  inline void clear_has_redeliverunacknowledgedmessages();
  inline void set_has_partitionmetadata();
  inline void clear_has_partitionmetadata();
  inline void set_has_partitionmetadataresponse();
  inline void clear_has_partitionmetadataresponse();
  inline void set_has_lookuptopic();
  inline void clear_has_lookuptopic();
  inline void set_has_lookuptopicresponse();
  inline void clear_has_lookuptopicresponse();
  inline void set_has_consumerstats();
  inline void clear_has_consumerstats();
  inline void set_has_consumerstatsresponse();
  inline void clear_has_consumerstatsresponse();

  ::std::string _unknown_fields_;

  ::google::protobuf::uint32 _has_bits_[1];
  mutable int _cached_size_;
  ::pulsar::proto::CommandConnect* connect_;
  ::pulsar::proto::CommandConnected* connected_;
  ::pulsar::proto::CommandSubscribe* subscribe_;
  ::pulsar::proto::CommandProducer* producer_;
  ::pulsar::proto::CommandSend* send_;
  ::pulsar::proto::CommandSendReceipt* send_receipt_;
  ::pulsar::proto::CommandSendError* send_error_;
  ::pulsar::proto::CommandMessage* message_;
  ::pulsar::proto::CommandAck* ack_;
  ::pulsar::proto::CommandFlow* flow_;
  ::pulsar::proto::CommandUnsubscribe* unsubscribe_;
  ::pulsar::proto::CommandSuccess* success_;
  ::pulsar::proto::CommandError* error_;
  ::pulsar::proto::CommandCloseProducer* close_producer_;
  ::pulsar::proto::CommandCloseConsumer* close_consumer_;
  ::pulsar::proto::CommandProducerSuccess* producer_success_;
  ::pulsar::proto::CommandPing* ping_;
  ::pulsar::proto::CommandPong* pong_;
  ::pulsar::proto::CommandRedeliverUnacknowledgedMessages* redeliverunacknowledgedmessages_;
  ::pulsar::proto::CommandPartitionedTopicMetadata* partitionmetadata_;
  ::pulsar::proto::CommandPartitionedTopicMetadataResponse* partitionmetadataresponse_;
  ::pulsar::proto::CommandLookupTopic* lookuptopic_;
  ::pulsar::proto::CommandLookupTopicResponse* lookuptopicresponse_;
  ::pulsar::proto::CommandConsumerStats* consumerstats_;
  ::pulsar::proto::CommandConsumerStatsResponse* consumerstatsresponse_;
  int type_;
  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
  friend void  protobuf_AddDesc_PulsarApi_2eproto_impl();
  #else
  friend void  protobuf_AddDesc_PulsarApi_2eproto();
  #endif
  friend void protobuf_AssignDesc_PulsarApi_2eproto();
  friend void protobuf_ShutdownFile_PulsarApi_2eproto();

  void InitAsDefaultInstance();
  static BaseCommand* default_instance_;
};
// ===================================================================


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

// MessageIdData

// required uint64 ledgerId = 1;
inline bool MessageIdData::has_ledgerid() const {
  return (_has_bits_[0] & 0x00000001u) != 0;
}
inline void MessageIdData::set_has_ledgerid() {
  _has_bits_[0] |= 0x00000001u;
}
inline void MessageIdData::clear_has_ledgerid() {
  _has_bits_[0] &= ~0x00000001u;
}
inline void MessageIdData::clear_ledgerid() {
  ledgerid_ = GOOGLE_ULONGLONG(0);
  clear_has_ledgerid();
}
inline ::google::protobuf::uint64 MessageIdData::ledgerid() const {
  // @@protoc_insertion_point(field_get:pulsar.proto.MessageIdData.ledgerId)
  return ledgerid_;
}
inline void MessageIdData::set_ledgerid(::google::protobuf::uint64 value) {
  set_has_ledgerid();
  ledgerid_ = value;
  // @@protoc_insertion_point(field_set:pulsar.proto.MessageIdData.ledgerId)
}

// required uint64 entryId = 2;
inline bool MessageIdData::has_entryid() const {
  return (_has_bits_[0] & 0x00000002u) != 0;
}
inline void MessageIdData::set_has_entryid() {
  _has_bits_[0] |= 0x00000002u;
}
inline void MessageIdData::clear_has_entryid() {
  _has_bits_[0] &= ~0x00000002u;
}
inline void MessageIdData::clear_entryid() {
  entryid_ = GOOGLE_ULONGLONG(0);
  clear_has_entryid();
}
inline ::google::protobuf::uint64 MessageIdData::entryid() const {
  // @@protoc_insertion_point(field_get:pulsar.proto.MessageIdData.entryId)
  return entryid_;
}
inline void MessageIdData::set_entryid(::google::protobuf::uint64 value) {
  set_has_entryid();
  entryid_ = value;
  // @@protoc_insertion_point(field_set:pulsar.proto.MessageIdData.entryId)
}

// optional int32 partition = 3 [default = -1];
inline bool MessageIdData::has_partition() const {
  return (_has_bits_[0] & 0x00000004u) != 0;
}
inline void MessageIdData::set_has_partition() {
  _has_bits_[0] |= 0x00000004u;
}
inline void MessageIdData::clear_has_partition() {
  _has_bits_[0] &= ~0x00000004u;
}
inline void MessageIdData::clear_partition() {
  partition_ = -1;
  clear_has_partition();
}
inline ::google::protobuf::int32 MessageIdData::partition() const {
  // @@protoc_insertion_point(field_get:pulsar.proto.MessageIdData.partition)
  return partition_;
}
inline void MessageIdData::set_partition(::google::protobuf::int32 value) {
  set_has_partition();
  partition_ = value;
  // @@protoc_insertion_point(field_set:pulsar.proto.MessageIdData.partition)
}

// optional int32 batch_index = 4 [default = -1];
inline bool MessageIdData::has_batch_index() const {
  return (_has_bits_[0] & 0x00000008u) != 0;
}
inline void MessageIdData::set_has_batch_index() {
  _has_bits_[0] |= 0x00000008u;
}
inline void MessageIdData::clear_has_batch_index() {
  _has_bits_[0] &= ~0x00000008u;
}
inline void MessageIdData::clear_batch_index() {
  batch_index_ = -1;
  clear_has_batch_index();
}
inline ::google::protobuf::int32 MessageIdData::batch_index() const {
  // @@protoc_insertion_point(field_get:pulsar.proto.MessageIdData.batch_index)
  return batch_index_;
}
inline void MessageIdData::set_batch_index(::google::protobuf::int32 value) {
  set_has_batch_index();
  batch_index_ = value;
  // @@protoc_insertion_point(field_set:pulsar.proto.MessageIdData.batch_index)
}

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

// KeyValue

// required string key = 1;
inline bool KeyValue::has_key() const {
  return (_has_bits_[0] & 0x00000001u) != 0;
}
inline void KeyValue::set_has_key() {
  _has_bits_[0] |= 0x00000001u;
}
inline void KeyValue::clear_has_key() {
  _has_bits_[0] &= ~0x00000001u;
}
inline void KeyValue::clear_key() {
  if (key_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    key_->clear();
  }
  clear_has_key();
}
inline const ::std::string& KeyValue::key() const {
  // @@protoc_insertion_point(field_get:pulsar.proto.KeyValue.key)
  return *key_;
}
inline void KeyValue::set_key(const ::std::string& value) {
  set_has_key();
  if (key_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    key_ = new ::std::string;
  }
  key_->assign(value);
  // @@protoc_insertion_point(field_set:pulsar.proto.KeyValue.key)
}
inline void KeyValue::set_key(const char* value) {
  set_has_key();
  if (key_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    key_ = new ::std::string;
  }
  key_->assign(value);
  // @@protoc_insertion_point(field_set_char:pulsar.proto.KeyValue.key)
}
inline void KeyValue::set_key(const char* value, size_t size) {
  set_has_key();
  if (key_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    key_ = new ::std::string;
  }
  key_->assign(reinterpret_cast<const char*>(value), size);
  // @@protoc_insertion_point(field_set_pointer:pulsar.proto.KeyValue.key)
}
inline ::std::string* KeyValue::mutable_key() {
  set_has_key();
  if (key_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    key_ = new ::std::string;
  }
  // @@protoc_insertion_point(field_mutable:pulsar.proto.KeyValue.key)
  return key_;
}
inline ::std::string* KeyValue::release_key() {
  clear_has_key();
  if (key_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    return NULL;
  } else {
    ::std::string* temp = key_;
    key_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    return temp;
  }
}
inline void KeyValue::set_allocated_key(::std::string* key) {
  if (key_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    delete key_;
  }
  if (key) {
    set_has_key();
    key_ = key;
  } else {
    clear_has_key();
    key_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  }
  // @@protoc_insertion_point(field_set_allocated:pulsar.proto.KeyValue.key)
}

// required string value = 2;
inline bool KeyValue::has_value() const {
  return (_has_bits_[0] & 0x00000002u) != 0;
}
inline void KeyValue::set_has_value() {
  _has_bits_[0] |= 0x00000002u;
}
inline void KeyValue::clear_has_value() {
  _has_bits_[0] &= ~0x00000002u;
}
inline void KeyValue::clear_value() {
  if (value_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    value_->clear();
  }
  clear_has_value();
}
inline const ::std::string& KeyValue::value() const {
  // @@protoc_insertion_point(field_get:pulsar.proto.KeyValue.value)
  return *value_;
}
inline void KeyValue::set_value(const ::std::string& value) {
  set_has_value();
  if (value_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    value_ = new ::std::string;
  }
  value_->assign(value);
  // @@protoc_insertion_point(field_set:pulsar.proto.KeyValue.value)
}
inline void KeyValue::set_value(const char* value) {
  set_has_value();
  if (value_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    value_ = new ::std::string;
  }
  value_->assign(value);
  // @@protoc_insertion_point(field_set_char:pulsar.proto.KeyValue.value)
}
inline void KeyValue::set_value(const char* value, size_t size) {
  set_has_value();
  if (value_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    value_ = new ::std::string;
  }
  value_->assign(reinterpret_cast<const char*>(value), size);
  // @@protoc_insertion_point(field_set_pointer:pulsar.proto.KeyValue.value)
}
inline ::std::string* KeyValue::mutable_value() {
  set_has_value();
  if (value_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    value_ = new ::std::string;
  }
  // @@protoc_insertion_point(field_mutable:pulsar.proto.KeyValue.value)
  return value_;
}
inline ::std::string* KeyValue::release_value() {
  clear_has_value();
  if (value_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    return NULL;
  } else {
    ::std::string* temp = value_;
    value_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    return temp;
  }
}
inline void KeyValue::set_allocated_value(::std::string* value) {
  if (value_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    delete value_;
  }
  if (value) {
    set_has_value();
    value_ = value;
  } else {
    clear_has_value();
    value_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  }
  // @@protoc_insertion_point(field_set_allocated:pulsar.proto.KeyValue.value)
}

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

// MessageMetadata

// required string producer_name = 1;
inline bool MessageMetadata::has_producer_name() const {
  return (_has_bits_[0] & 0x00000001u) != 0;
}
inline void MessageMetadata::set_has_producer_name() {
  _has_bits_[0] |= 0x00000001u;
}
inline void MessageMetadata::clear_has_producer_name() {
  _has_bits_[0] &= ~0x00000001u;
}
inline void MessageMetadata::clear_producer_name() {
  if (producer_name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    producer_name_->clear();
  }
  clear_has_producer_name();
}
inline const ::std::string& MessageMetadata::producer_name() const {
  // @@protoc_insertion_point(field_get:pulsar.proto.MessageMetadata.producer_name)
  return *producer_name_;
}
inline void MessageMetadata::set_producer_name(const ::std::string& value) {
  set_has_producer_name();
  if (producer_name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    producer_name_ = new ::std::string;
  }
  producer_name_->assign(value);
  // @@protoc_insertion_point(field_set:pulsar.proto.MessageMetadata.producer_name)
}
inline void MessageMetadata::set_producer_name(const char* value) {
  set_has_producer_name();
  if (producer_name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    producer_name_ = new ::std::string;
  }
  producer_name_->assign(value);
  // @@protoc_insertion_point(field_set_char:pulsar.proto.MessageMetadata.producer_name)
}
inline void MessageMetadata::set_producer_name(const char* value, size_t size) {
  set_has_producer_name();
  if (producer_name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    producer_name_ = new ::std::string;
  }
  producer_name_->assign(reinterpret_cast<const char*>(value), size);
  // @@protoc_insertion_point(field_set_pointer:pulsar.proto.MessageMetadata.producer_name)
}
inline ::std::string* MessageMetadata::mutable_producer_name() {
  set_has_producer_name();
  if (producer_name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    producer_name_ = new ::std::string;
  }
  // @@protoc_insertion_point(field_mutable:pulsar.proto.MessageMetadata.producer_name)
  return producer_name_;
}
inline ::std::string* MessageMetadata::release_producer_name() {
  clear_has_producer_name();
  if (producer_name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    return NULL;
  } else {
    ::std::string* temp = producer_name_;
    producer_name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    return temp;
  }
}
inline void MessageMetadata::set_allocated_producer_name(::std::string* producer_name) {
  if (producer_name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    delete producer_name_;
  }
  if (producer_name) {
    set_has_producer_name();
    producer_name_ = producer_name;
  } else {
    clear_has_producer_name();
    producer_name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  }
  // @@protoc_insertion_point(field_set_allocated:pulsar.proto.MessageMetadata.producer_name)
}

// required uint64 sequence_id = 2;
inline bool MessageMetadata::has_sequence_id() const {
  return (_has_bits_[0] & 0x00000002u) != 0;
}
inline void MessageMetadata::set_has_sequence_id() {
  _has_bits_[0] |= 0x00000002u;
}
inline void MessageMetadata::clear_has_sequence_id() {
  _has_bits_[0] &= ~0x00000002u;
}
inline void MessageMetadata::clear_sequence_id() {
  sequence_id_ = GOOGLE_ULONGLONG(0);
  clear_has_sequence_id();
}
inline ::google::protobuf::uint64 MessageMetadata::sequence_id() const {
  // @@protoc_insertion_point(field_get:pulsar.proto.MessageMetadata.sequence_id)
  return sequence_id_;
}
inline void MessageMetadata::set_sequence_id(::google::protobuf::uint64 value) {
  set_has_sequence_id();
  sequence_id_ = value;
  // @@protoc_insertion_point(field_set:pulsar.proto.MessageMetadata.sequence_id)
}

// required uint64 publish_time = 3;
inline bool MessageMetadata::has_publish_time() const {
  return (_has_bits_[0] & 0x00000004u) != 0;
}
inline void MessageMetadata::set_has_publish_time() {
  _has_bits_[0] |= 0x00000004u;
}
inline void MessageMetadata::clear_has_publish_time() {
  _has_bits_[0] &= ~0x00000004u;
}
inline void MessageMetadata::clear_publish_time() {
  publish_time_ = GOOGLE_ULONGLONG(0);
  clear_has_publish_time();
}
inline ::google::protobuf::uint64 MessageMetadata::publish_time() const {
  // @@protoc_insertion_point(field_get:pulsar.proto.MessageMetadata.publish_time)
  return publish_time_;
}
inline void MessageMetadata::set_publish_time(::google::protobuf::uint64 value) {
  set_has_publish_time();
  publish_time_ = value;
  // @@protoc_insertion_point(field_set:pulsar.proto.MessageMetadata.publish_time)
}

// repeated .pulsar.proto.KeyValue properties = 4;
inline int MessageMetadata::properties_size() const {
  return properties_.size();
}
inline void MessageMetadata::clear_properties() {
  properties_.Clear();
}
inline const ::pulsar::proto::KeyValue& MessageMetadata::properties(int index) const {
  // @@protoc_insertion_point(field_get:pulsar.proto.MessageMetadata.properties)
  return properties_.Get(index);
}
inline ::pulsar::proto::KeyValue* MessageMetadata::mutable_properties(int index) {
  // @@protoc_insertion_point(field_mutable:pulsar.proto.MessageMetadata.properties)
  return properties_.Mutable(index);
}
inline ::pulsar::proto::KeyValue* MessageMetadata::add_properties() {
  // @@protoc_insertion_point(field_add:pulsar.proto.MessageMetadata.properties)
  return properties_.Add();
}
inline const ::google::protobuf::RepeatedPtrField< ::pulsar::proto::KeyValue >&
MessageMetadata::properties() const {
  // @@protoc_insertion_point(field_list:pulsar.proto.MessageMetadata.properties)
  return properties_;
}
inline ::google::protobuf::RepeatedPtrField< ::pulsar::proto::KeyValue >*
MessageMetadata::mutable_properties() {
  // @@protoc_insertion_point(field_mutable_list:pulsar.proto.MessageMetadata.properties)
  return &properties_;
}

// optional string replicated_from = 5;
inline bool MessageMetadata::has_replicated_from() const {
  return (_has_bits_[0] & 0x00000010u) != 0;
}
inline void MessageMetadata::set_has_replicated_from() {
  _has_bits_[0] |= 0x00000010u;
}
inline void MessageMetadata::clear_has_replicated_from() {
  _has_bits_[0] &= ~0x00000010u;
}
inline void MessageMetadata::clear_replicated_from() {
  if (replicated_from_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    replicated_from_->clear();
  }
  clear_has_replicated_from();
}
inline const ::std::string& MessageMetadata::replicated_from() const {
  // @@protoc_insertion_point(field_get:pulsar.proto.MessageMetadata.replicated_from)
  return *replicated_from_;
}
inline void MessageMetadata::set_replicated_from(const ::std::string& value) {
  set_has_replicated_from();
  if (replicated_from_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    replicated_from_ = new ::std::string;
  }
  replicated_from_->assign(value);
  // @@protoc_insertion_point(field_set:pulsar.proto.MessageMetadata.replicated_from)
}
inline void MessageMetadata::set_replicated_from(const char* value) {
  set_has_replicated_from();
  if (replicated_from_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    replicated_from_ = new ::std::string;
  }
  replicated_from_->assign(value);
  // @@protoc_insertion_point(field_set_char:pulsar.proto.MessageMetadata.replicated_from)
}
inline void MessageMetadata::set_replicated_from(const char* value, size_t size) {
  set_has_replicated_from();
  if (replicated_from_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    replicated_from_ = new ::std::string;
  }
  replicated_from_->assign(reinterpret_cast<const char*>(value), size);
  // @@protoc_insertion_point(field_set_pointer:pulsar.proto.MessageMetadata.replicated_from)
}
inline ::std::string* MessageMetadata::mutable_replicated_from() {
  set_has_replicated_from();
  if (replicated_from_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    replicated_from_ = new ::std::string;
  }
  // @@protoc_insertion_point(field_mutable:pulsar.proto.MessageMetadata.replicated_from)
  return replicated_from_;
}
inline ::std::string* MessageMetadata::release_replicated_from() {
  clear_has_replicated_from();
  if (replicated_from_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    return NULL;
  } else {
    ::std::string* temp = replicated_from_;
    replicated_from_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    return temp;
  }
}
inline void MessageMetadata::set_allocated_replicated_from(::std::string* replicated_from) {
  if (replicated_from_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    delete replicated_from_;
  }
  if (replicated_from) {
    set_has_replicated_from();
    replicated_from_ = replicated_from;
  } else {
    clear_has_replicated_from();
    replicated_from_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  }
  // @@protoc_insertion_point(field_set_allocated:pulsar.proto.MessageMetadata.replicated_from)
}

// optional string partition_key = 6;
inline bool MessageMetadata::has_partition_key() const {
  return (_has_bits_[0] & 0x00000020u) != 0;
}
inline void MessageMetadata::set_has_partition_key() {
  _has_bits_[0] |= 0x00000020u;
}
inline void MessageMetadata::clear_has_partition_key() {
  _has_bits_[0] &= ~0x00000020u;
}
inline void MessageMetadata::clear_partition_key() {
  if (partition_key_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    partition_key_->clear();
  }
  clear_has_partition_key();
}
inline const ::std::string& MessageMetadata::partition_key() const {
  // @@protoc_insertion_point(field_get:pulsar.proto.MessageMetadata.partition_key)
  return *partition_key_;
}
inline void MessageMetadata::set_partition_key(const ::std::string& value) {
  set_has_partition_key();
  if (partition_key_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    partition_key_ = new ::std::string;
  }
  partition_key_->assign(value);
  // @@protoc_insertion_point(field_set:pulsar.proto.MessageMetadata.partition_key)
}
inline void MessageMetadata::set_partition_key(const char* value) {
  set_has_partition_key();
  if (partition_key_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    partition_key_ = new ::std::string;
  }
  partition_key_->assign(value);
  // @@protoc_insertion_point(field_set_char:pulsar.proto.MessageMetadata.partition_key)
}
inline void MessageMetadata::set_partition_key(const char* value, size_t size) {
  set_has_partition_key();
  if (partition_key_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    partition_key_ = new ::std::string;
  }
  partition_key_->assign(reinterpret_cast<const char*>(value), size);
  // @@protoc_insertion_point(field_set_pointer:pulsar.proto.MessageMetadata.partition_key)
}
inline ::std::string* MessageMetadata::mutable_partition_key() {
  set_has_partition_key();
  if (partition_key_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    partition_key_ = new ::std::string;
  }
  // @@protoc_insertion_point(field_mutable:pulsar.proto.MessageMetadata.partition_key)
  return partition_key_;
}
inline ::std::string* MessageMetadata::release_partition_key() {
  clear_has_partition_key();
  if (partition_key_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    return NULL;
  } else {
    ::std::string* temp = partition_key_;
    partition_key_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    return temp;
  }
}
inline void MessageMetadata::set_allocated_partition_key(::std::string* partition_key) {
  if (partition_key_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    delete partition_key_;
  }
  if (partition_key) {
    set_has_partition_key();
    partition_key_ = partition_key;
  } else {
    clear_has_partition_key();
    partition_key_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  }
  // @@protoc_insertion_point(field_set_allocated:pulsar.proto.MessageMetadata.partition_key)
}

// repeated string replicate_to = 7;
inline int MessageMetadata::replicate_to_size() const {
  return replicate_to_.size();
}
inline void MessageMetadata::clear_replicate_to() {
  replicate_to_.Clear();
}
inline const ::std::string& MessageMetadata::replicate_to(int index) const {
  // @@protoc_insertion_point(field_get:pulsar.proto.MessageMetadata.replicate_to)
  return replicate_to_.Get(index);
}
inline ::std::string* MessageMetadata::mutable_replicate_to(int index) {
  // @@protoc_insertion_point(field_mutable:pulsar.proto.MessageMetadata.replicate_to)
  return replicate_to_.Mutable(index);
}
inline void MessageMetadata::set_replicate_to(int index, const ::std::string& value) {
  // @@protoc_insertion_point(field_set:pulsar.proto.MessageMetadata.replicate_to)
  replicate_to_.Mutable(index)->assign(value);
}
inline void MessageMetadata::set_replicate_to(int index, const char* value) {
  replicate_to_.Mutable(index)->assign(value);
  // @@protoc_insertion_point(field_set_char:pulsar.proto.MessageMetadata.replicate_to)
}
inline void MessageMetadata::set_replicate_to(int index, const char* value, size_t size) {
  replicate_to_.Mutable(index)->assign(
    reinterpret_cast<const char*>(value), size);
  // @@protoc_insertion_point(field_set_pointer:pulsar.proto.MessageMetadata.replicate_to)
}
inline ::std::string* MessageMetadata::add_replicate_to() {
  return replicate_to_.Add();
}
inline void MessageMetadata::add_replicate_to(const ::std::string& value) {
  replicate_to_.Add()->assign(value);
  // @@protoc_insertion_point(field_add:pulsar.proto.MessageMetadata.replicate_to)
}
inline void MessageMetadata::add_replicate_to(const char* value) {
  replicate_to_.Add()->assign(value);
  // @@protoc_insertion_point(field_add_char:pulsar.proto.MessageMetadata.replicate_to)
}
inline void MessageMetadata::add_replicate_to(const char* value, size_t size) {
  replicate_to_.Add()->assign(reinterpret_cast<const char*>(value), size);
  // @@protoc_insertion_point(field_add_pointer:pulsar.proto.MessageMetadata.replicate_to)
}
inline const ::google::protobuf::RepeatedPtrField< ::std::string>&
MessageMetadata::replicate_to() const {
  // @@protoc_insertion_point(field_list:pulsar.proto.MessageMetadata.replicate_to)
  return replicate_to_;
}
inline ::google::protobuf::RepeatedPtrField< ::std::string>*
MessageMetadata::mutable_replicate_to() {
  // @@protoc_insertion_point(field_mutable_list:pulsar.proto.MessageMetadata.replicate_to)
  return &replicate_to_;
}

// optional .pulsar.proto.CompressionType compression = 8 [default = NONE];
inline bool MessageMetadata::has_compression() const {
  return (_has_bits_[0] & 0x00000080u) != 0;
}
inline void MessageMetadata::set_has_compression() {
  _has_bits_[0] |= 0x00000080u;
}
inline void MessageMetadata::clear_has_compression() {
  _has_bits_[0] &= ~0x00000080u;
}
inline void MessageMetadata::clear_compression() {
  compression_ = 0;
  clear_has_compression();
}
inline ::pulsar::proto::CompressionType MessageMetadata::compression() const {
  // @@protoc_insertion_point(field_get:pulsar.proto.MessageMetadata.compression)
  return static_cast< ::pulsar::proto::CompressionType >(compression_);
}
inline void MessageMetadata::set_compression(::pulsar::proto::CompressionType value) {
  assert(::pulsar::proto::CompressionType_IsValid(value));
  set_has_compression();
  compression_ = value;
  // @@protoc_insertion_point(field_set:pulsar.proto.MessageMetadata.compression)
}

// optional uint32 uncompressed_size = 9 [default = 0];
inline bool MessageMetadata::has_uncompressed_size() const {
  return (_has_bits_[0] & 0x00000100u) != 0;
}
inline void MessageMetadata::set_has_uncompressed_size() {
  _has_bits_[0] |= 0x00000100u;
}
inline void MessageMetadata::clear_has_uncompressed_size() {
  _has_bits_[0] &= ~0x00000100u;
}
inline void MessageMetadata::clear_uncompressed_size() {
  uncompressed_size_ = 0u;
  clear_has_uncompressed_size();
}
inline ::google::protobuf::uint32 MessageMetadata::uncompressed_size() const {
  // @@protoc_insertion_point(field_get:pulsar.proto.MessageMetadata.uncompressed_size)
  return uncompressed_size_;
}
inline void MessageMetadata::set_uncompressed_size(::google::protobuf::uint32 value) {
  set_has_uncompressed_size();
  uncompressed_size_ = value;
  // @@protoc_insertion_point(field_set:pulsar.proto.MessageMetadata.uncompressed_size)
}

// optional int32 num_messages_in_batch = 11 [default = 1];
inline bool MessageMetadata::has_num_messages_in_batch() const {
  return (_has_bits_[0] & 0x00000200u) != 0;
}
inline void MessageMetadata::set_has_num_messages_in_batch() {
  _has_bits_[0] |= 0x00000200u;
}
inline void MessageMetadata::clear_has_num_messages_in_batch() {
  _has_bits_[0] &= ~0x00000200u;
}
inline void MessageMetadata::clear_num_messages_in_batch() {
  num_messages_in_batch_ = 1;
  clear_has_num_messages_in_batch();
}
inline ::google::protobuf::int32 MessageMetadata::num_messages_in_batch() const {
  // @@protoc_insertion_point(field_get:pulsar.proto.MessageMetadata.num_messages_in_batch)
  return num_messages_in_batch_;
}
inline void MessageMetadata::set_num_messages_in_batch(::google::protobuf::int32 value) {
  set_has_num_messages_in_batch();
  num_messages_in_batch_ = value;
  // @@protoc_insertion_point(field_set:pulsar.proto.MessageMetadata.num_messages_in_batch)
}

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

// SingleMessageMetadata

// repeated .pulsar.proto.KeyValue properties = 1;
inline int SingleMessageMetadata::properties_size() const {
  return properties_.size();
}
inline void SingleMessageMetadata::clear_properties() {
  properties_.Clear();
}
inline const ::pulsar::proto::KeyValue& SingleMessageMetadata::properties(int index) const {
  // @@protoc_insertion_point(field_get:pulsar.proto.SingleMessageMetadata.properties)
  return properties_.Get(index);
}
inline ::pulsar::proto::KeyValue* SingleMessageMetadata::mutable_properties(int index) {
  // @@protoc_insertion_point(field_mutable:pulsar.proto.SingleMessageMetadata.properties)
  return properties_.Mutable(index);
}
inline ::pulsar::proto::KeyValue* SingleMessageMetadata::add_properties() {
  // @@protoc_insertion_point(field_add:pulsar.proto.SingleMessageMetadata.properties)
  return properties_.Add();
}
inline const ::google::protobuf::RepeatedPtrField< ::pulsar::proto::KeyValue >&
SingleMessageMetadata::properties() const {
  // @@protoc_insertion_point(field_list:pulsar.proto.SingleMessageMetadata.properties)
  return properties_;
}
inline ::google::protobuf::RepeatedPtrField< ::pulsar::proto::KeyValue >*
SingleMessageMetadata::mutable_properties() {
  // @@protoc_insertion_point(field_mutable_list:pulsar.proto.SingleMessageMetadata.properties)
  return &properties_;
}

// optional string partition_key = 2;
inline bool SingleMessageMetadata::has_partition_key() const {
  return (_has_bits_[0] & 0x00000002u) != 0;
}
inline void SingleMessageMetadata::set_has_partition_key() {
  _has_bits_[0] |= 0x00000002u;
}
inline void SingleMessageMetadata::clear_has_partition_key() {
  _has_bits_[0] &= ~0x00000002u;
}
inline void SingleMessageMetadata::clear_partition_key() {
  if (partition_key_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    partition_key_->clear();
  }
  clear_has_partition_key();
}
inline const ::std::string& SingleMessageMetadata::partition_key() const {
  // @@protoc_insertion_point(field_get:pulsar.proto.SingleMessageMetadata.partition_key)
  return *partition_key_;
}
inline void SingleMessageMetadata::set_partition_key(const ::std::string& value) {
  set_has_partition_key();
  if (partition_key_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    partition_key_ = new ::std::string;
  }
  partition_key_->assign(value);
  // @@protoc_insertion_point(field_set:pulsar.proto.SingleMessageMetadata.partition_key)
}
inline void SingleMessageMetadata::set_partition_key(const char* value) {
  set_has_partition_key();
  if (partition_key_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    partition_key_ = new ::std::string;
  }
  partition_key_->assign(value);
  // @@protoc_insertion_point(field_set_char:pulsar.proto.SingleMessageMetadata.partition_key)
}
inline void SingleMessageMetadata::set_partition_key(const char* value, size_t size) {
  set_has_partition_key();
  if (partition_key_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    partition_key_ = new ::std::string;
  }
  partition_key_->assign(reinterpret_cast<const char*>(value), size);
  // @@protoc_insertion_point(field_set_pointer:pulsar.proto.SingleMessageMetadata.partition_key)
}
inline ::std::string* SingleMessageMetadata::mutable_partition_key() {
  set_has_partition_key();
  if (partition_key_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    partition_key_ = new ::std::string;
  }
  // @@protoc_insertion_point(field_mutable:pulsar.proto.SingleMessageMetadata.partition_key)
  return partition_key_;
}
inline ::std::string* SingleMessageMetadata::release_partition_key() {
  clear_has_partition_key();
  if (partition_key_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    return NULL;
  } else {
    ::std::string* temp = partition_key_;
    partition_key_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    return temp;
  }
}
inline void SingleMessageMetadata::set_allocated_partition_key(::std::string* partition_key) {
  if (partition_key_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    delete partition_key_;
  }
  if (partition_key) {
    set_has_partition_key();
    partition_key_ = partition_key;
  } else {
    clear_has_partition_key();
    partition_key_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  }
  // @@protoc_insertion_point(field_set_allocated:pulsar.proto.SingleMessageMetadata.partition_key)
}

// required int32 payload_size = 3;
inline bool SingleMessageMetadata::has_payload_size() const {
  return (_has_bits_[0] & 0x00000004u) != 0;
}
inline void SingleMessageMetadata::set_has_payload_size() {
  _has_bits_[0] |= 0x00000004u;
}
inline void SingleMessageMetadata::clear_has_payload_size() {
  _has_bits_[0] &= ~0x00000004u;
}
inline void SingleMessageMetadata::clear_payload_size() {
  payload_size_ = 0;
  clear_has_payload_size();
}
inline ::google::protobuf::int32 SingleMessageMetadata::payload_size() const {
  // @@protoc_insertion_point(field_get:pulsar.proto.SingleMessageMetadata.payload_size)
  return payload_size_;
}
inline void SingleMessageMetadata::set_payload_size(::google::protobuf::int32 value) {
  set_has_payload_size();
  payload_size_ = value;
  // @@protoc_insertion_point(field_set:pulsar.proto.SingleMessageMetadata.payload_size)
}

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

// CommandConnect

// required string client_version = 1;
inline bool CommandConnect::has_client_version() const {
  return (_has_bits_[0] & 0x00000001u) != 0;
}
inline void CommandConnect::set_has_client_version() {
  _has_bits_[0] |= 0x00000001u;
}
inline void CommandConnect::clear_has_client_version() {
  _has_bits_[0] &= ~0x00000001u;
}
inline void CommandConnect::clear_client_version() {
  if (client_version_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    client_version_->clear();
  }
  clear_has_client_version();
}
inline const ::std::string& CommandConnect::client_version() const {
  // @@protoc_insertion_point(field_get:pulsar.proto.CommandConnect.client_version)
  return *client_version_;
}
inline void CommandConnect::set_client_version(const ::std::string& value) {
  set_has_client_version();
  if (client_version_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    client_version_ = new ::std::string;
  }
  client_version_->assign(value);
  // @@protoc_insertion_point(field_set:pulsar.proto.CommandConnect.client_version)
}
inline void CommandConnect::set_client_version(const char* value) {
  set_has_client_version();
  if (client_version_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    client_version_ = new ::std::string;
  }
  client_version_->assign(value);
  // @@protoc_insertion_point(field_set_char:pulsar.proto.CommandConnect.client_version)
}
inline void CommandConnect::set_client_version(const char* value, size_t size) {
  set_has_client_version();
  if (client_version_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    client_version_ = new ::std::string;
  }
  client_version_->assign(reinterpret_cast<const char*>(value), size);
  // @@protoc_insertion_point(field_set_pointer:pulsar.proto.CommandConnect.client_version)
}
inline ::std::string* CommandConnect::mutable_client_version() {
  set_has_client_version();
  if (client_version_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    client_version_ = new ::std::string;
  }
  // @@protoc_insertion_point(field_mutable:pulsar.proto.CommandConnect.client_version)
  return client_version_;
}
inline ::std::string* CommandConnect::release_client_version() {
  clear_has_client_version();
  if (client_version_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    return NULL;
  } else {
    ::std::string* temp = client_version_;
    client_version_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    return temp;
  }
}
inline void CommandConnect::set_allocated_client_version(::std::string* client_version) {
  if (client_version_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    delete client_version_;
  }
  if (client_version) {
    set_has_client_version();
    client_version_ = client_version;
  } else {
    clear_has_client_version();
    client_version_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  }
  // @@protoc_insertion_point(field_set_allocated:pulsar.proto.CommandConnect.client_version)
}

// optional .pulsar.proto.AuthMethod auth_method = 2;
inline bool CommandConnect::has_auth_method() const {
  return (_has_bits_[0] & 0x00000002u) != 0;
}
inline void CommandConnect::set_has_auth_method() {
  _has_bits_[0] |= 0x00000002u;
}
inline void CommandConnect::clear_has_auth_method() {
  _has_bits_[0] &= ~0x00000002u;
}
inline void CommandConnect::clear_auth_method() {
  auth_method_ = 0;
  clear_has_auth_method();
}
inline ::pulsar::proto::AuthMethod CommandConnect::auth_method() const {
  // @@protoc_insertion_point(field_get:pulsar.proto.CommandConnect.auth_method)
  return static_cast< ::pulsar::proto::AuthMethod >(auth_method_);
}
inline void CommandConnect::set_auth_method(::pulsar::proto::AuthMethod value) {
  assert(::pulsar::proto::AuthMethod_IsValid(value));
  set_has_auth_method();
  auth_method_ = value;
  // @@protoc_insertion_point(field_set:pulsar.proto.CommandConnect.auth_method)
}

// optional string auth_method_name = 5;
inline bool CommandConnect::has_auth_method_name() const {
  return (_has_bits_[0] & 0x00000004u) != 0;
}
inline void CommandConnect::set_has_auth_method_name() {
  _has_bits_[0] |= 0x00000004u;
}
inline void CommandConnect::clear_has_auth_method_name() {
  _has_bits_[0] &= ~0x00000004u;
}
inline void CommandConnect::clear_auth_method_name() {
  if (auth_method_name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    auth_method_name_->clear();
  }
  clear_has_auth_method_name();
}
inline const ::std::string& CommandConnect::auth_method_name() const {
  // @@protoc_insertion_point(field_get:pulsar.proto.CommandConnect.auth_method_name)
  return *auth_method_name_;
}
inline void CommandConnect::set_auth_method_name(const ::std::string& value) {
  set_has_auth_method_name();
  if (auth_method_name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    auth_method_name_ = new ::std::string;
  }
  auth_method_name_->assign(value);
  // @@protoc_insertion_point(field_set:pulsar.proto.CommandConnect.auth_method_name)
}
inline void CommandConnect::set_auth_method_name(const char* value) {
  set_has_auth_method_name();
  if (auth_method_name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    auth_method_name_ = new ::std::string;
  }
  auth_method_name_->assign(value);
  // @@protoc_insertion_point(field_set_char:pulsar.proto.CommandConnect.auth_method_name)
}
inline void CommandConnect::set_auth_method_name(const char* value, size_t size) {
  set_has_auth_method_name();
  if (auth_method_name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    auth_method_name_ = new ::std::string;
  }
  auth_method_name_->assign(reinterpret_cast<const char*>(value), size);
  // @@protoc_insertion_point(field_set_pointer:pulsar.proto.CommandConnect.auth_method_name)
}
inline ::std::string* CommandConnect::mutable_auth_method_name() {
  set_has_auth_method_name();
  if (auth_method_name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    auth_method_name_ = new ::std::string;
  }
  // @@protoc_insertion_point(field_mutable:pulsar.proto.CommandConnect.auth_method_name)
  return auth_method_name_;
}
inline ::std::string* CommandConnect::release_auth_method_name() {
  clear_has_auth_method_name();
  if (auth_method_name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    return NULL;
  } else {
    ::std::string* temp = auth_method_name_;
    auth_method_name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    return temp;
  }
}
inline void CommandConnect::set_allocated_auth_method_name(::std::string* auth_method_name) {
  if (auth_method_name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    delete auth_method_name_;
  }
  if (auth_method_name) {
    set_has_auth_method_name();
    auth_method_name_ = auth_method_name;
  } else {
    clear_has_auth_method_name();
    auth_method_name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  }
  // @@protoc_insertion_point(field_set_allocated:pulsar.proto.CommandConnect.auth_method_name)
}

// optional bytes auth_data = 3;
inline bool CommandConnect::has_auth_data() const {
  return (_has_bits_[0] & 0x00000008u) != 0;
}
inline void CommandConnect::set_has_auth_data() {
  _has_bits_[0] |= 0x00000008u;
}
inline void CommandConnect::clear_has_auth_data() {
  _has_bits_[0] &= ~0x00000008u;
}
inline void CommandConnect::clear_auth_data() {
  if (auth_data_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    auth_data_->clear();
  }
  clear_has_auth_data();
}
inline const ::std::string& CommandConnect::auth_data() const {
  // @@protoc_insertion_point(field_get:pulsar.proto.CommandConnect.auth_data)
  return *auth_data_;
}
inline void CommandConnect::set_auth_data(const ::std::string& value) {
  set_has_auth_data();
  if (auth_data_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    auth_data_ = new ::std::string;
  }
  auth_data_->assign(value);
  // @@protoc_insertion_point(field_set:pulsar.proto.CommandConnect.auth_data)
}
inline void CommandConnect::set_auth_data(const char* value) {
  set_has_auth_data();
  if (auth_data_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    auth_data_ = new ::std::string;
  }
  auth_data_->assign(value);
  // @@protoc_insertion_point(field_set_char:pulsar.proto.CommandConnect.auth_data)
}
inline void CommandConnect::set_auth_data(const void* value, size_t size) {
  set_has_auth_data();
  if (auth_data_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    auth_data_ = new ::std::string;
  }
  auth_data_->assign(reinterpret_cast<const char*>(value), size);
  // @@protoc_insertion_point(field_set_pointer:pulsar.proto.CommandConnect.auth_data)
}
inline ::std::string* CommandConnect::mutable_auth_data() {
  set_has_auth_data();
  if (auth_data_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    auth_data_ = new ::std::string;
  }
  // @@protoc_insertion_point(field_mutable:pulsar.proto.CommandConnect.auth_data)
  return auth_data_;
}
inline ::std::string* CommandConnect::release_auth_data() {
  clear_has_auth_data();
  if (auth_data_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    return NULL;
  } else {
    ::std::string* temp = auth_data_;
    auth_data_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    return temp;
  }
}
inline void CommandConnect::set_allocated_auth_data(::std::string* auth_data) {
  if (auth_data_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    delete auth_data_;
  }
  if (auth_data) {
    set_has_auth_data();
    auth_data_ = auth_data;
  } else {
    clear_has_auth_data();
    auth_data_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  }
  // @@protoc_insertion_point(field_set_allocated:pulsar.proto.CommandConnect.auth_data)
}

// optional int32 protocol_version = 4 [default = 0];
inline bool CommandConnect::has_protocol_version() const {
  return (_has_bits_[0] & 0x00000010u) != 0;
}
inline void CommandConnect::set_has_protocol_version() {
  _has_bits_[0] |= 0x00000010u;
}
inline void CommandConnect::clear_has_protocol_version() {
  _has_bits_[0] &= ~0x00000010u;
}
inline void CommandConnect::clear_protocol_version() {
  protocol_version_ = 0;
  clear_has_protocol_version();
}
inline ::google::protobuf::int32 CommandConnect::protocol_version() const {
  // @@protoc_insertion_point(field_get:pulsar.proto.CommandConnect.protocol_version)
  return protocol_version_;
}
inline void CommandConnect::set_protocol_version(::google::protobuf::int32 value) {
  set_has_protocol_version();
  protocol_version_ = value;
  // @@protoc_insertion_point(field_set:pulsar.proto.CommandConnect.protocol_version)
}

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

// CommandConnected

// required string server_version = 1;
inline bool CommandConnected::has_server_version() const {
  return (_has_bits_[0] & 0x00000001u) != 0;
}
inline void CommandConnected::set_has_server_version() {
  _has_bits_[0] |= 0x00000001u;
}
inline void CommandConnected::clear_has_server_version() {
  _has_bits_[0] &= ~0x00000001u;
}
inline void CommandConnected::clear_server_version() {
  if (server_version_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    server_version_->clear();
  }
  clear_has_server_version();
}
inline const ::std::string& CommandConnected::server_version() const {
  // @@protoc_insertion_point(field_get:pulsar.proto.CommandConnected.server_version)
  return *server_version_;
}
inline void CommandConnected::set_server_version(const ::std::string& value) {
  set_has_server_version();
  if (server_version_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    server_version_ = new ::std::string;
  }
  server_version_->assign(value);
  // @@protoc_insertion_point(field_set:pulsar.proto.CommandConnected.server_version)
}
inline void CommandConnected::set_server_version(const char* value) {
  set_has_server_version();
  if (server_version_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    server_version_ = new ::std::string;
  }
  server_version_->assign(value);
  // @@protoc_insertion_point(field_set_char:pulsar.proto.CommandConnected.server_version)
}
inline void CommandConnected::set_server_version(const char* value, size_t size) {
  set_has_server_version();
  if (server_version_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    server_version_ = new ::std::string;
  }
  server_version_->assign(reinterpret_cast<const char*>(value), size);
  // @@protoc_insertion_point(field_set_pointer:pulsar.proto.CommandConnected.server_version)
}
inline ::std::string* CommandConnected::mutable_server_version() {
  set_has_server_version();
  if (server_version_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    server_version_ = new ::std::string;
  }
  // @@protoc_insertion_point(field_mutable:pulsar.proto.CommandConnected.server_version)
  return server_version_;
}
inline ::std::string* CommandConnected::release_server_version() {
  clear_has_server_version();
  if (server_version_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    return NULL;
  } else {
    ::std::string* temp = server_version_;
    server_version_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    return temp;
  }
}
inline void CommandConnected::set_allocated_server_version(::std::string* server_version) {
  if (server_version_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    delete server_version_;
  }
  if (server_version) {
    set_has_server_version();
    server_version_ = server_version;
  } else {
    clear_has_server_version();
    server_version_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  }
  // @@protoc_insertion_point(field_set_allocated:pulsar.proto.CommandConnected.server_version)
}

// optional int32 protocol_version = 2 [default = 0];
inline bool CommandConnected::has_protocol_version() const {
  return (_has_bits_[0] & 0x00000002u) != 0;
}
inline void CommandConnected::set_has_protocol_version() {
  _has_bits_[0] |= 0x00000002u;
}
inline void CommandConnected::clear_has_protocol_version() {
  _has_bits_[0] &= ~0x00000002u;
}
inline void CommandConnected::clear_protocol_version() {
  protocol_version_ = 0;
  clear_has_protocol_version();
}
inline ::google::protobuf::int32 CommandConnected::protocol_version() const {
  // @@protoc_insertion_point(field_get:pulsar.proto.CommandConnected.protocol_version)
  return protocol_version_;
}
inline void CommandConnected::set_protocol_version(::google::protobuf::int32 value) {
  set_has_protocol_version();
  protocol_version_ = value;
  // @@protoc_insertion_point(field_set:pulsar.proto.CommandConnected.protocol_version)
}

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

// CommandSubscribe

// required string topic = 1;
inline bool CommandSubscribe::has_topic() const {
  return (_has_bits_[0] & 0x00000001u) != 0;
}
inline void CommandSubscribe::set_has_topic() {
  _has_bits_[0] |= 0x00000001u;
}
inline void CommandSubscribe::clear_has_topic() {
  _has_bits_[0] &= ~0x00000001u;
}
inline void CommandSubscribe::clear_topic() {
  if (topic_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    topic_->clear();
  }
  clear_has_topic();
}
inline const ::std::string& CommandSubscribe::topic() const {
  // @@protoc_insertion_point(field_get:pulsar.proto.CommandSubscribe.topic)
  return *topic_;
}
inline void CommandSubscribe::set_topic(const ::std::string& value) {
  set_has_topic();
  if (topic_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    topic_ = new ::std::string;
  }
  topic_->assign(value);
  // @@protoc_insertion_point(field_set:pulsar.proto.CommandSubscribe.topic)
}
inline void CommandSubscribe::set_topic(const char* value) {
  set_has_topic();
  if (topic_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    topic_ = new ::std::string;
  }
  topic_->assign(value);
  // @@protoc_insertion_point(field_set_char:pulsar.proto.CommandSubscribe.topic)
}
inline void CommandSubscribe::set_topic(const char* value, size_t size) {
  set_has_topic();
  if (topic_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    topic_ = new ::std::string;
  }
  topic_->assign(reinterpret_cast<const char*>(value), size);
  // @@protoc_insertion_point(field_set_pointer:pulsar.proto.CommandSubscribe.topic)
}
inline ::std::string* CommandSubscribe::mutable_topic() {
  set_has_topic();
  if (topic_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    topic_ = new ::std::string;
  }
  // @@protoc_insertion_point(field_mutable:pulsar.proto.CommandSubscribe.topic)
  return topic_;
}
inline ::std::string* CommandSubscribe::release_topic() {
  clear_has_topic();
  if (topic_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    return NULL;
  } else {
    ::std::string* temp = topic_;
    topic_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    return temp;
  }
}
inline void CommandSubscribe::set_allocated_topic(::std::string* topic) {
  if (topic_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    delete topic_;
  }
  if (topic) {
    set_has_topic();
    topic_ = topic;
  } else {
    clear_has_topic();
    topic_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  }
  // @@protoc_insertion_point(field_set_allocated:pulsar.proto.CommandSubscribe.topic)
}

// required string subscription = 2;
inline bool CommandSubscribe::has_subscription() const {
  return (_has_bits_[0] & 0x00000002u) != 0;
}
inline void CommandSubscribe::set_has_subscription() {
  _has_bits_[0] |= 0x00000002u;
}
inline void CommandSubscribe::clear_has_subscription() {
  _has_bits_[0] &= ~0x00000002u;
}
inline void CommandSubscribe::clear_subscription() {
  if (subscription_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    subscription_->clear();
  }
  clear_has_subscription();
}
inline const ::std::string& CommandSubscribe::subscription() const {
  // @@protoc_insertion_point(field_get:pulsar.proto.CommandSubscribe.subscription)
  return *subscription_;
}
inline void CommandSubscribe::set_subscription(const ::std::string& value) {
  set_has_subscription();
  if (subscription_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    subscription_ = new ::std::string;
  }
  subscription_->assign(value);
  // @@protoc_insertion_point(field_set:pulsar.proto.CommandSubscribe.subscription)
}
inline void CommandSubscribe::set_subscription(const char* value) {
  set_has_subscription();
  if (subscription_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    subscription_ = new ::std::string;
  }
  subscription_->assign(value);
  // @@protoc_insertion_point(field_set_char:pulsar.proto.CommandSubscribe.subscription)
}
inline void CommandSubscribe::set_subscription(const char* value, size_t size) {
  set_has_subscription();
  if (subscription_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    subscription_ = new ::std::string;
  }
  subscription_->assign(reinterpret_cast<const char*>(value), size);
  // @@protoc_insertion_point(field_set_pointer:pulsar.proto.CommandSubscribe.subscription)
}
inline ::std::string* CommandSubscribe::mutable_subscription() {
  set_has_subscription();
  if (subscription_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    subscription_ = new ::std::string;
  }
  // @@protoc_insertion_point(field_mutable:pulsar.proto.CommandSubscribe.subscription)
  return subscription_;
}
inline ::std::string* CommandSubscribe::release_subscription() {
  clear_has_subscription();
  if (subscription_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    return NULL;
  } else {
    ::std::string* temp = subscription_;
    subscription_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    return temp;
  }
}
inline void CommandSubscribe::set_allocated_subscription(::std::string* subscription) {
  if (subscription_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    delete subscription_;
  }
  if (subscription) {
    set_has_subscription();
    subscription_ = subscription;
  } else {
    clear_has_subscription();
    subscription_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  }
  // @@protoc_insertion_point(field_set_allocated:pulsar.proto.CommandSubscribe.subscription)
}

// required .pulsar.proto.CommandSubscribe.SubType subType = 3;
inline bool CommandSubscribe::has_subtype() const {
  return (_has_bits_[0] & 0x00000004u) != 0;
}
inline void CommandSubscribe::set_has_subtype() {
  _has_bits_[0] |= 0x00000004u;
}
inline void CommandSubscribe::clear_has_subtype() {
  _has_bits_[0] &= ~0x00000004u;
}
inline void CommandSubscribe::clear_subtype() {
  subtype_ = 0;
  clear_has_subtype();
}
inline ::pulsar::proto::CommandSubscribe_SubType CommandSubscribe::subtype() const {
  // @@protoc_insertion_point(field_get:pulsar.proto.CommandSubscribe.subType)
  return static_cast< ::pulsar::proto::CommandSubscribe_SubType >(subtype_);
}
inline void CommandSubscribe::set_subtype(::pulsar::proto::CommandSubscribe_SubType value) {
  assert(::pulsar::proto::CommandSubscribe_SubType_IsValid(value));
  set_has_subtype();
  subtype_ = value;
  // @@protoc_insertion_point(field_set:pulsar.proto.CommandSubscribe.subType)
}

// required uint64 consumer_id = 4;
inline bool CommandSubscribe::has_consumer_id() const {
  return (_has_bits_[0] & 0x00000008u) != 0;
}
inline void CommandSubscribe::set_has_consumer_id() {
  _has_bits_[0] |= 0x00000008u;
}
inline void CommandSubscribe::clear_has_consumer_id() {
  _has_bits_[0] &= ~0x00000008u;
}
inline void CommandSubscribe::clear_consumer_id() {
  consumer_id_ = GOOGLE_ULONGLONG(0);
  clear_has_consumer_id();
}
inline ::google::protobuf::uint64 CommandSubscribe::consumer_id() const {
  // @@protoc_insertion_point(field_get:pulsar.proto.CommandSubscribe.consumer_id)
  return consumer_id_;
}
inline void CommandSubscribe::set_consumer_id(::google::protobuf::uint64 value) {
  set_has_consumer_id();
  consumer_id_ = value;
  // @@protoc_insertion_point(field_set:pulsar.proto.CommandSubscribe.consumer_id)
}

// required uint64 request_id = 5;
inline bool CommandSubscribe::has_request_id() const {
  return (_has_bits_[0] & 0x00000010u) != 0;
}
inline void CommandSubscribe::set_has_request_id() {
  _has_bits_[0] |= 0x00000010u;
}
inline void CommandSubscribe::clear_has_request_id() {
  _has_bits_[0] &= ~0x00000010u;
}
inline void CommandSubscribe::clear_request_id() {
  request_id_ = GOOGLE_ULONGLONG(0);
  clear_has_request_id();
}
inline ::google::protobuf::uint64 CommandSubscribe::request_id() const {
  // @@protoc_insertion_point(field_get:pulsar.proto.CommandSubscribe.request_id)
  return request_id_;
}
inline void CommandSubscribe::set_request_id(::google::protobuf::uint64 value) {
  set_has_request_id();
  request_id_ = value;
  // @@protoc_insertion_point(field_set:pulsar.proto.CommandSubscribe.request_id)
}

// optional string consumer_name = 6;
inline bool CommandSubscribe::has_consumer_name() const {
  return (_has_bits_[0] & 0x00000020u) != 0;
}
inline void CommandSubscribe::set_has_consumer_name() {
  _has_bits_[0] |= 0x00000020u;
}
inline void CommandSubscribe::clear_has_consumer_name() {
  _has_bits_[0] &= ~0x00000020u;
}
inline void CommandSubscribe::clear_consumer_name() {
  if (consumer_name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    consumer_name_->clear();
  }
  clear_has_consumer_name();
}
inline const ::std::string& CommandSubscribe::consumer_name() const {
  // @@protoc_insertion_point(field_get:pulsar.proto.CommandSubscribe.consumer_name)
  return *consumer_name_;
}
inline void CommandSubscribe::set_consumer_name(const ::std::string& value) {
  set_has_consumer_name();
  if (consumer_name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    consumer_name_ = new ::std::string;
  }
  consumer_name_->assign(value);
  // @@protoc_insertion_point(field_set:pulsar.proto.CommandSubscribe.consumer_name)
}
inline void CommandSubscribe::set_consumer_name(const char* value) {
  set_has_consumer_name();
  if (consumer_name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    consumer_name_ = new ::std::string;
  }
  consumer_name_->assign(value);
  // @@protoc_insertion_point(field_set_char:pulsar.proto.CommandSubscribe.consumer_name)
}
inline void CommandSubscribe::set_consumer_name(const char* value, size_t size) {
  set_has_consumer_name();
  if (consumer_name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    consumer_name_ = new ::std::string;
  }
  consumer_name_->assign(reinterpret_cast<const char*>(value), size);
  // @@protoc_insertion_point(field_set_pointer:pulsar.proto.CommandSubscribe.consumer_name)
}
inline ::std::string* CommandSubscribe::mutable_consumer_name() {
  set_has_consumer_name();
  if (consumer_name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    consumer_name_ = new ::std::string;
  }
  // @@protoc_insertion_point(field_mutable:pulsar.proto.CommandSubscribe.consumer_name)
  return consumer_name_;
}
inline ::std::string* CommandSubscribe::release_consumer_name() {
  clear_has_consumer_name();
  if (consumer_name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    return NULL;
  } else {
    ::std::string* temp = consumer_name_;
    consumer_name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    return temp;
  }
}
inline void CommandSubscribe::set_allocated_consumer_name(::std::string* consumer_name) {
  if (consumer_name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    delete consumer_name_;
  }
  if (consumer_name) {
    set_has_consumer_name();
    consumer_name_ = consumer_name;
  } else {
    clear_has_consumer_name();
    consumer_name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  }
  // @@protoc_insertion_point(field_set_allocated:pulsar.proto.CommandSubscribe.consumer_name)
}

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

// CommandPartitionedTopicMetadata

// required string topic = 1;
inline bool CommandPartitionedTopicMetadata::has_topic() const {
  return (_has_bits_[0] & 0x00000001u) != 0;
}
inline void CommandPartitionedTopicMetadata::set_has_topic() {
  _has_bits_[0] |= 0x00000001u;
}
inline void CommandPartitionedTopicMetadata::clear_has_topic() {
  _has_bits_[0] &= ~0x00000001u;
}
inline void CommandPartitionedTopicMetadata::clear_topic() {
  if (topic_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    topic_->clear();
  }
  clear_has_topic();
}
inline const ::std::string& CommandPartitionedTopicMetadata::topic() const {
  // @@protoc_insertion_point(field_get:pulsar.proto.CommandPartitionedTopicMetadata.topic)
  return *topic_;
}
inline void CommandPartitionedTopicMetadata::set_topic(const ::std::string& value) {
  set_has_topic();
  if (topic_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    topic_ = new ::std::string;
  }
  topic_->assign(value);
  // @@protoc_insertion_point(field_set:pulsar.proto.CommandPartitionedTopicMetadata.topic)
}
inline void CommandPartitionedTopicMetadata::set_topic(const char* value) {
  set_has_topic();
  if (topic_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    topic_ = new ::std::string;
  }
  topic_->assign(value);
  // @@protoc_insertion_point(field_set_char:pulsar.proto.CommandPartitionedTopicMetadata.topic)
}
inline void CommandPartitionedTopicMetadata::set_topic(const char* value, size_t size) {
  set_has_topic();
  if (topic_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    topic_ = new ::std::string;
  }
  topic_->assign(reinterpret_cast<const char*>(value), size);
  // @@protoc_insertion_point(field_set_pointer:pulsar.proto.CommandPartitionedTopicMetadata.topic)
}
inline ::std::string* CommandPartitionedTopicMetadata::mutable_topic() {
  set_has_topic();
  if (topic_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    topic_ = new ::std::string;
  }
  // @@protoc_insertion_point(field_mutable:pulsar.proto.CommandPartitionedTopicMetadata.topic)
  return topic_;
}
inline ::std::string* CommandPartitionedTopicMetadata::release_topic() {
  clear_has_topic();
  if (topic_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    return NULL;
  } else {
    ::std::string* temp = topic_;
    topic_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    return temp;
  }
}
inline void CommandPartitionedTopicMetadata::set_allocated_topic(::std::string* topic) {
  if (topic_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    delete topic_;
  }
  if (topic) {
    set_has_topic();
    topic_ = topic;
  } else {
    clear_has_topic();
    topic_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  }
  // @@protoc_insertion_point(field_set_allocated:pulsar.proto.CommandPartitionedTopicMetadata.topic)
}

// required uint64 request_id = 2;
inline bool CommandPartitionedTopicMetadata::has_request_id() const {
  return (_has_bits_[0] & 0x00000002u) != 0;
}
inline void CommandPartitionedTopicMetadata::set_has_request_id() {
  _has_bits_[0] |= 0x00000002u;
}
inline void CommandPartitionedTopicMetadata::clear_has_request_id() {
  _has_bits_[0] &= ~0x00000002u;
}
inline void CommandPartitionedTopicMetadata::clear_request_id() {
  request_id_ = GOOGLE_ULONGLONG(0);
  clear_has_request_id();
}
inline ::google::protobuf::uint64 CommandPartitionedTopicMetadata::request_id() const {
  // @@protoc_insertion_point(field_get:pulsar.proto.CommandPartitionedTopicMetadata.request_id)
  return request_id_;
}
inline void CommandPartitionedTopicMetadata::set_request_id(::google::protobuf::uint64 value) {
  set_has_request_id();
  request_id_ = value;
  // @@protoc_insertion_point(field_set:pulsar.proto.CommandPartitionedTopicMetadata.request_id)
}

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

// CommandPartitionedTopicMetadataResponse

// optional uint32 partitions = 1;
inline bool CommandPartitionedTopicMetadataResponse::has_partitions() const {
  return (_has_bits_[0] & 0x00000001u) != 0;
}
inline void CommandPartitionedTopicMetadataResponse::set_has_partitions() {
  _has_bits_[0] |= 0x00000001u;
}
inline void CommandPartitionedTopicMetadataResponse::clear_has_partitions() {
  _has_bits_[0] &= ~0x00000001u;
}
inline void CommandPartitionedTopicMetadataResponse::clear_partitions() {
  partitions_ = 0u;
  clear_has_partitions();
}
inline ::google::protobuf::uint32 CommandPartitionedTopicMetadataResponse::partitions() const {
  // @@protoc_insertion_point(field_get:pulsar.proto.CommandPartitionedTopicMetadataResponse.partitions)
  return partitions_;
}
inline void CommandPartitionedTopicMetadataResponse::set_partitions(::google::protobuf::uint32 value) {
  set_has_partitions();
  partitions_ = value;
  // @@protoc_insertion_point(field_set:pulsar.proto.CommandPartitionedTopicMetadataResponse.partitions)
}

// required uint64 request_id = 2;
inline bool CommandPartitionedTopicMetadataResponse::has_request_id() const {
  return (_has_bits_[0] & 0x00000002u) != 0;
}
inline void CommandPartitionedTopicMetadataResponse::set_has_request_id() {
  _has_bits_[0] |= 0x00000002u;
}
inline void CommandPartitionedTopicMetadataResponse::clear_has_request_id() {
  _has_bits_[0] &= ~0x00000002u;
}
inline void CommandPartitionedTopicMetadataResponse::clear_request_id() {
  request_id_ = GOOGLE_ULONGLONG(0);
  clear_has_request_id();
}
inline ::google::protobuf::uint64 CommandPartitionedTopicMetadataResponse::request_id() const {
  // @@protoc_insertion_point(field_get:pulsar.proto.CommandPartitionedTopicMetadataResponse.request_id)
  return request_id_;
}
inline void CommandPartitionedTopicMetadataResponse::set_request_id(::google::protobuf::uint64 value) {
  set_has_request_id();
  request_id_ = value;
  // @@protoc_insertion_point(field_set:pulsar.proto.CommandPartitionedTopicMetadataResponse.request_id)
}

// optional .pulsar.proto.CommandPartitionedTopicMetadataResponse.LookupType response = 3;
inline bool CommandPartitionedTopicMetadataResponse::has_response() const {
  return (_has_bits_[0] & 0x00000004u) != 0;
}
inline void CommandPartitionedTopicMetadataResponse::set_has_response() {
  _has_bits_[0] |= 0x00000004u;
}
inline void CommandPartitionedTopicMetadataResponse::clear_has_response() {
  _has_bits_[0] &= ~0x00000004u;
}
inline void CommandPartitionedTopicMetadataResponse::clear_response() {
  response_ = 0;
  clear_has_response();
}
inline ::pulsar::proto::CommandPartitionedTopicMetadataResponse_LookupType CommandPartitionedTopicMetadataResponse::response() const {
  // @@protoc_insertion_point(field_get:pulsar.proto.CommandPartitionedTopicMetadataResponse.response)
  return static_cast< ::pulsar::proto::CommandPartitionedTopicMetadataResponse_LookupType >(response_);
}
inline void CommandPartitionedTopicMetadataResponse::set_response(::pulsar::proto::CommandPartitionedTopicMetadataResponse_LookupType value) {
  assert(::pulsar::proto::CommandPartitionedTopicMetadataResponse_LookupType_IsValid(value));
  set_has_response();
  response_ = value;
  // @@protoc_insertion_point(field_set:pulsar.proto.CommandPartitionedTopicMetadataResponse.response)
}

// optional .pulsar.proto.ServerError error = 4;
inline bool CommandPartitionedTopicMetadataResponse::has_error() const {
  return (_has_bits_[0] & 0x00000008u) != 0;
}
inline void CommandPartitionedTopicMetadataResponse::set_has_error() {
  _has_bits_[0] |= 0x00000008u;
}
inline void CommandPartitionedTopicMetadataResponse::clear_has_error() {
  _has_bits_[0] &= ~0x00000008u;
}
inline void CommandPartitionedTopicMetadataResponse::clear_error() {
  error_ = 0;
  clear_has_error();
}
inline ::pulsar::proto::ServerError CommandPartitionedTopicMetadataResponse::error() const {
  // @@protoc_insertion_point(field_get:pulsar.proto.CommandPartitionedTopicMetadataResponse.error)
  return static_cast< ::pulsar::proto::ServerError >(error_);
}
inline void CommandPartitionedTopicMetadataResponse::set_error(::pulsar::proto::ServerError value) {
  assert(::pulsar::proto::ServerError_IsValid(value));
  set_has_error();
  error_ = value;
  // @@protoc_insertion_point(field_set:pulsar.proto.CommandPartitionedTopicMetadataResponse.error)
}

// optional string message = 5;
inline bool CommandPartitionedTopicMetadataResponse::has_message() const {
  return (_has_bits_[0] & 0x00000010u) != 0;
}
inline void CommandPartitionedTopicMetadataResponse::set_has_message() {
  _has_bits_[0] |= 0x00000010u;
}
inline void CommandPartitionedTopicMetadataResponse::clear_has_message() {
  _has_bits_[0] &= ~0x00000010u;
}
inline void CommandPartitionedTopicMetadataResponse::clear_message() {
  if (message_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    message_->clear();
  }
  clear_has_message();
}
inline const ::std::string& CommandPartitionedTopicMetadataResponse::message() const {
  // @@protoc_insertion_point(field_get:pulsar.proto.CommandPartitionedTopicMetadataResponse.message)
  return *message_;
}
inline void CommandPartitionedTopicMetadataResponse::set_message(const ::std::string& value) {
  set_has_message();
  if (message_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    message_ = new ::std::string;
  }
  message_->assign(value);
  // @@protoc_insertion_point(field_set:pulsar.proto.CommandPartitionedTopicMetadataResponse.message)
}
inline void CommandPartitionedTopicMetadataResponse::set_message(const char* value) {
  set_has_message();
  if (message_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    message_ = new ::std::string;
  }
  message_->assign(value);
  // @@protoc_insertion_point(field_set_char:pulsar.proto.CommandPartitionedTopicMetadataResponse.message)
}
inline void CommandPartitionedTopicMetadataResponse::set_message(const char* value, size_t size) {
  set_has_message();
  if (message_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    message_ = new ::std::string;
  }
  message_->assign(reinterpret_cast<const char*>(value), size);
  // @@protoc_insertion_point(field_set_pointer:pulsar.proto.CommandPartitionedTopicMetadataResponse.message)
}
inline ::std::string* CommandPartitionedTopicMetadataResponse::mutable_message() {
  set_has_message();
  if (message_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    message_ = new ::std::string;
  }
  // @@protoc_insertion_point(field_mutable:pulsar.proto.CommandPartitionedTopicMetadataResponse.message)
  return message_;
}
inline ::std::string* CommandPartitionedTopicMetadataResponse::release_message() {
  clear_has_message();
  if (message_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    return NULL;
  } else {
    ::std::string* temp = message_;
    message_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    return temp;
  }
}
inline void CommandPartitionedTopicMetadataResponse::set_allocated_message(::std::string* message) {
  if (message_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    delete message_;
  }
  if (message) {
    set_has_message();
    message_ = message;
  } else {
    clear_has_message();
    message_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  }
  // @@protoc_insertion_point(field_set_allocated:pulsar.proto.CommandPartitionedTopicMetadataResponse.message)
}

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

// CommandLookupTopic

// required string topic = 1;
inline bool CommandLookupTopic::has_topic() const {
  return (_has_bits_[0] & 0x00000001u) != 0;
}
inline void CommandLookupTopic::set_has_topic() {
  _has_bits_[0] |= 0x00000001u;
}
inline void CommandLookupTopic::clear_has_topic() {
  _has_bits_[0] &= ~0x00000001u;
}
inline void CommandLookupTopic::clear_topic() {
  if (topic_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    topic_->clear();
  }
  clear_has_topic();
}
inline const ::std::string& CommandLookupTopic::topic() const {
  // @@protoc_insertion_point(field_get:pulsar.proto.CommandLookupTopic.topic)
  return *topic_;
}
inline void CommandLookupTopic::set_topic(const ::std::string& value) {
  set_has_topic();
  if (topic_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    topic_ = new ::std::string;
  }
  topic_->assign(value);
  // @@protoc_insertion_point(field_set:pulsar.proto.CommandLookupTopic.topic)
}
inline void CommandLookupTopic::set_topic(const char* value) {
  set_has_topic();
  if (topic_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    topic_ = new ::std::string;
  }
  topic_->assign(value);
  // @@protoc_insertion_point(field_set_char:pulsar.proto.CommandLookupTopic.topic)
}
inline void CommandLookupTopic::set_topic(const char* value, size_t size) {
  set_has_topic();
  if (topic_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    topic_ = new ::std::string;
  }
  topic_->assign(reinterpret_cast<const char*>(value), size);
  // @@protoc_insertion_point(field_set_pointer:pulsar.proto.CommandLookupTopic.topic)
}
inline ::std::string* CommandLookupTopic::mutable_topic() {
  set_has_topic();
  if (topic_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    topic_ = new ::std::string;
  }
  // @@protoc_insertion_point(field_mutable:pulsar.proto.CommandLookupTopic.topic)
  return topic_;
}
inline ::std::string* CommandLookupTopic::release_topic() {
  clear_has_topic();
  if (topic_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    return NULL;
  } else {
    ::std::string* temp = topic_;
    topic_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    return temp;
  }
}
inline void CommandLookupTopic::set_allocated_topic(::std::string* topic) {
  if (topic_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    delete topic_;
  }
  if (topic) {
    set_has_topic();
    topic_ = topic;
  } else {
    clear_has_topic();
    topic_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  }
  // @@protoc_insertion_point(field_set_allocated:pulsar.proto.CommandLookupTopic.topic)
}

// required uint64 request_id = 2;
inline bool CommandLookupTopic::has_request_id() const {
  return (_has_bits_[0] & 0x00000002u) != 0;
}
inline void CommandLookupTopic::set_has_request_id() {
  _has_bits_[0] |= 0x00000002u;
}
inline void CommandLookupTopic::clear_has_request_id() {
  _has_bits_[0] &= ~0x00000002u;
}
inline void CommandLookupTopic::clear_request_id() {
  request_id_ = GOOGLE_ULONGLONG(0);
  clear_has_request_id();
}
inline ::google::protobuf::uint64 CommandLookupTopic::request_id() const {
  // @@protoc_insertion_point(field_get:pulsar.proto.CommandLookupTopic.request_id)
  return request_id_;
}
inline void CommandLookupTopic::set_request_id(::google::protobuf::uint64 value) {
  set_has_request_id();
  request_id_ = value;
  // @@protoc_insertion_point(field_set:pulsar.proto.CommandLookupTopic.request_id)
}

// optional bool authoritative = 3 [default = false];
inline bool CommandLookupTopic::has_authoritative() const {
  return (_has_bits_[0] & 0x00000004u) != 0;
}
inline void CommandLookupTopic::set_has_authoritative() {
  _has_bits_[0] |= 0x00000004u;
}
inline void CommandLookupTopic::clear_has_authoritative() {
  _has_bits_[0] &= ~0x00000004u;
}
inline void CommandLookupTopic::clear_authoritative() {
  authoritative_ = false;
  clear_has_authoritative();
}
inline bool CommandLookupTopic::authoritative() const {
  // @@protoc_insertion_point(field_get:pulsar.proto.CommandLookupTopic.authoritative)
  return authoritative_;
}
inline void CommandLookupTopic::set_authoritative(bool value) {
  set_has_authoritative();
  authoritative_ = value;
  // @@protoc_insertion_point(field_set:pulsar.proto.CommandLookupTopic.authoritative)
}

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

// CommandLookupTopicResponse

// optional string brokerServiceUrl = 1;
inline bool CommandLookupTopicResponse::has_brokerserviceurl() const {
  return (_has_bits_[0] & 0x00000001u) != 0;
}
inline void CommandLookupTopicResponse::set_has_brokerserviceurl() {
  _has_bits_[0] |= 0x00000001u;
}
inline void CommandLookupTopicResponse::clear_has_brokerserviceurl() {
  _has_bits_[0] &= ~0x00000001u;
}
inline void CommandLookupTopicResponse::clear_brokerserviceurl() {
  if (brokerserviceurl_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    brokerserviceurl_->clear();
  }
  clear_has_brokerserviceurl();
}
inline const ::std::string& CommandLookupTopicResponse::brokerserviceurl() const {
  // @@protoc_insertion_point(field_get:pulsar.proto.CommandLookupTopicResponse.brokerServiceUrl)
  return *brokerserviceurl_;
}
inline void CommandLookupTopicResponse::set_brokerserviceurl(const ::std::string& value) {
  set_has_brokerserviceurl();
  if (brokerserviceurl_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    brokerserviceurl_ = new ::std::string;
  }
  brokerserviceurl_->assign(value);
  // @@protoc_insertion_point(field_set:pulsar.proto.CommandLookupTopicResponse.brokerServiceUrl)
}
inline void CommandLookupTopicResponse::set_brokerserviceurl(const char* value) {
  set_has_brokerserviceurl();
  if (brokerserviceurl_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    brokerserviceurl_ = new ::std::string;
  }
  brokerserviceurl_->assign(value);
  // @@protoc_insertion_point(field_set_char:pulsar.proto.CommandLookupTopicResponse.brokerServiceUrl)
}
inline void CommandLookupTopicResponse::set_brokerserviceurl(const char* value, size_t size) {
  set_has_brokerserviceurl();
  if (brokerserviceurl_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    brokerserviceurl_ = new ::std::string;
  }
  brokerserviceurl_->assign(reinterpret_cast<const char*>(value), size);
  // @@protoc_insertion_point(field_set_pointer:pulsar.proto.CommandLookupTopicResponse.brokerServiceUrl)
}
inline ::std::string* CommandLookupTopicResponse::mutable_brokerserviceurl() {
  set_has_brokerserviceurl();
  if (brokerserviceurl_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    brokerserviceurl_ = new ::std::string;
  }
  // @@protoc_insertion_point(field_mutable:pulsar.proto.CommandLookupTopicResponse.brokerServiceUrl)
  return brokerserviceurl_;
}
inline ::std::string* CommandLookupTopicResponse::release_brokerserviceurl() {
  clear_has_brokerserviceurl();
  if (brokerserviceurl_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    return NULL;
  } else {
    ::std::string* temp = brokerserviceurl_;
    brokerserviceurl_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    return temp;
  }
}
inline void CommandLookupTopicResponse::set_allocated_brokerserviceurl(::std::string* brokerserviceurl) {
  if (brokerserviceurl_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    delete brokerserviceurl_;
  }
  if (brokerserviceurl) {
    set_has_brokerserviceurl();
    brokerserviceurl_ = brokerserviceurl;
  } else {
    clear_has_brokerserviceurl();
    brokerserviceurl_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  }
  // @@protoc_insertion_point(field_set_allocated:pulsar.proto.CommandLookupTopicResponse.brokerServiceUrl)
}

// optional string brokerServiceUrlTls = 2;
inline bool CommandLookupTopicResponse::has_brokerserviceurltls() const {
  return (_has_bits_[0] & 0x00000002u) != 0;
}
inline void CommandLookupTopicResponse::set_has_brokerserviceurltls() {
  _has_bits_[0] |= 0x00000002u;
}
inline void CommandLookupTopicResponse::clear_has_brokerserviceurltls() {
  _has_bits_[0] &= ~0x00000002u;
}
inline void CommandLookupTopicResponse::clear_brokerserviceurltls() {
  if (brokerserviceurltls_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    brokerserviceurltls_->clear();
  }
  clear_has_brokerserviceurltls();
}
inline const ::std::string& CommandLookupTopicResponse::brokerserviceurltls() const {
  // @@protoc_insertion_point(field_get:pulsar.proto.CommandLookupTopicResponse.brokerServiceUrlTls)
  return *brokerserviceurltls_;
}
inline void CommandLookupTopicResponse::set_brokerserviceurltls(const ::std::string& value) {
  set_has_brokerserviceurltls();
  if (brokerserviceurltls_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    brokerserviceurltls_ = new ::std::string;
  }
  brokerserviceurltls_->assign(value);
  // @@protoc_insertion_point(field_set:pulsar.proto.CommandLookupTopicResponse.brokerServiceUrlTls)
}
inline void CommandLookupTopicResponse::set_brokerserviceurltls(const char* value) {
  set_has_brokerserviceurltls();
  if (brokerserviceurltls_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    brokerserviceurltls_ = new ::std::string;
  }
  brokerserviceurltls_->assign(value);
  // @@protoc_insertion_point(field_set_char:pulsar.proto.CommandLookupTopicResponse.brokerServiceUrlTls)
}
inline void CommandLookupTopicResponse::set_brokerserviceurltls(const char* value, size_t size) {
  set_has_brokerserviceurltls();
  if (brokerserviceurltls_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    brokerserviceurltls_ = new ::std::string;
  }
  brokerserviceurltls_->assign(reinterpret_cast<const char*>(value), size);
  // @@protoc_insertion_point(field_set_pointer:pulsar.proto.CommandLookupTopicResponse.brokerServiceUrlTls)
}
inline ::std::string* CommandLookupTopicResponse::mutable_brokerserviceurltls() {
  set_has_brokerserviceurltls();
  if (brokerserviceurltls_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    brokerserviceurltls_ = new ::std::string;
  }
  // @@protoc_insertion_point(field_mutable:pulsar.proto.CommandLookupTopicResponse.brokerServiceUrlTls)
  return brokerserviceurltls_;
}
inline ::std::string* CommandLookupTopicResponse::release_brokerserviceurltls() {
  clear_has_brokerserviceurltls();
  if (brokerserviceurltls_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    return NULL;
  } else {
    ::std::string* temp = brokerserviceurltls_;
    brokerserviceurltls_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    return temp;
  }
}
inline void CommandLookupTopicResponse::set_allocated_brokerserviceurltls(::std::string* brokerserviceurltls) {
  if (brokerserviceurltls_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    delete brokerserviceurltls_;
  }
  if (brokerserviceurltls) {
    set_has_brokerserviceurltls();
    brokerserviceurltls_ = brokerserviceurltls;
  } else {
    clear_has_brokerserviceurltls();
    brokerserviceurltls_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  }
  // @@protoc_insertion_point(field_set_allocated:pulsar.proto.CommandLookupTopicResponse.brokerServiceUrlTls)
}

// optional .pulsar.proto.CommandLookupTopicResponse.LookupType response = 3;
inline bool CommandLookupTopicResponse::has_response() const {
  return (_has_bits_[0] & 0x00000004u) != 0;
}
inline void CommandLookupTopicResponse::set_has_response() {
  _has_bits_[0] |= 0x00000004u;
}
inline void CommandLookupTopicResponse::clear_has_response() {
  _has_bits_[0] &= ~0x00000004u;
}
inline void CommandLookupTopicResponse::clear_response() {
  response_ = 0;
  clear_has_response();
}
inline ::pulsar::proto::CommandLookupTopicResponse_LookupType CommandLookupTopicResponse::response() const {
  // @@protoc_insertion_point(field_get:pulsar.proto.CommandLookupTopicResponse.response)
  return static_cast< ::pulsar::proto::CommandLookupTopicResponse_LookupType >(response_);
}
inline void CommandLookupTopicResponse::set_response(::pulsar::proto::CommandLookupTopicResponse_LookupType value) {
  assert(::pulsar::proto::CommandLookupTopicResponse_LookupType_IsValid(value));
  set_has_response();
  response_ = value;
  // @@protoc_insertion_point(field_set:pulsar.proto.CommandLookupTopicResponse.response)
}

// required uint64 request_id = 4;
inline bool CommandLookupTopicResponse::has_request_id() const {
  return (_has_bits_[0] & 0x00000008u) != 0;
}
inline void CommandLookupTopicResponse::set_has_request_id() {
  _has_bits_[0] |= 0x00000008u;
}
inline void CommandLookupTopicResponse::clear_has_request_id() {
  _has_bits_[0] &= ~0x00000008u;
}
inline void CommandLookupTopicResponse::clear_request_id() {
  request_id_ = GOOGLE_ULONGLONG(0);
  clear_has_request_id();
}
inline ::google::protobuf::uint64 CommandLookupTopicResponse::request_id() const {
  // @@protoc_insertion_point(field_get:pulsar.proto.CommandLookupTopicResponse.request_id)
  return request_id_;
}
inline void CommandLookupTopicResponse::set_request_id(::google::protobuf::uint64 value) {
  set_has_request_id();
  request_id_ = value;
  // @@protoc_insertion_point(field_set:pulsar.proto.CommandLookupTopicResponse.request_id)
}

// optional bool authoritative = 5 [default = false];
inline bool CommandLookupTopicResponse::has_authoritative() const {
  return (_has_bits_[0] & 0x00000010u) != 0;
}
inline void CommandLookupTopicResponse::set_has_authoritative() {
  _has_bits_[0] |= 0x00000010u;
}
inline void CommandLookupTopicResponse::clear_has_authoritative() {
  _has_bits_[0] &= ~0x00000010u;
}
inline void CommandLookupTopicResponse::clear_authoritative() {
  authoritative_ = false;
  clear_has_authoritative();
}
inline bool CommandLookupTopicResponse::authoritative() const {
  // @@protoc_insertion_point(field_get:pulsar.proto.CommandLookupTopicResponse.authoritative)
  return authoritative_;
}
inline void CommandLookupTopicResponse::set_authoritative(bool value) {
  set_has_authoritative();
  authoritative_ = value;
  // @@protoc_insertion_point(field_set:pulsar.proto.CommandLookupTopicResponse.authoritative)
}

// optional .pulsar.proto.ServerError error = 6;
inline bool CommandLookupTopicResponse::has_error() const {
  return (_has_bits_[0] & 0x00000020u) != 0;
}
inline void CommandLookupTopicResponse::set_has_error() {
  _has_bits_[0] |= 0x00000020u;
}
inline void CommandLookupTopicResponse::clear_has_error() {
  _has_bits_[0] &= ~0x00000020u;
}
inline void CommandLookupTopicResponse::clear_error() {
  error_ = 0;
  clear_has_error();
}
inline ::pulsar::proto::ServerError CommandLookupTopicResponse::error() const {
  // @@protoc_insertion_point(field_get:pulsar.proto.CommandLookupTopicResponse.error)
  return static_cast< ::pulsar::proto::ServerError >(error_);
}
inline void CommandLookupTopicResponse::set_error(::pulsar::proto::ServerError value) {
  assert(::pulsar::proto::ServerError_IsValid(value));
  set_has_error();
  error_ = value;
  // @@protoc_insertion_point(field_set:pulsar.proto.CommandLookupTopicResponse.error)
}

// optional string message = 7;
inline bool CommandLookupTopicResponse::has_message() const {
  return (_has_bits_[0] & 0x00000040u) != 0;
}
inline void CommandLookupTopicResponse::set_has_message() {
  _has_bits_[0] |= 0x00000040u;
}
inline void CommandLookupTopicResponse::clear_has_message() {
  _has_bits_[0] &= ~0x00000040u;
}
inline void CommandLookupTopicResponse::clear_message() {
  if (message_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    message_->clear();
  }
  clear_has_message();
}
inline const ::std::string& CommandLookupTopicResponse::message() const {
  // @@protoc_insertion_point(field_get:pulsar.proto.CommandLookupTopicResponse.message)
  return *message_;
}
inline void CommandLookupTopicResponse::set_message(const ::std::string& value) {
  set_has_message();
  if (message_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    message_ = new ::std::string;
  }
  message_->assign(value);
  // @@protoc_insertion_point(field_set:pulsar.proto.CommandLookupTopicResponse.message)
}
inline void CommandLookupTopicResponse::set_message(const char* value) {
  set_has_message();
  if (message_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    message_ = new ::std::string;
  }
  message_->assign(value);
  // @@protoc_insertion_point(field_set_char:pulsar.proto.CommandLookupTopicResponse.message)
}
inline void CommandLookupTopicResponse::set_message(const char* value, size_t size) {
  set_has_message();
  if (message_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    message_ = new ::std::string;
  }
  message_->assign(reinterpret_cast<const char*>(value), size);
  // @@protoc_insertion_point(field_set_pointer:pulsar.proto.CommandLookupTopicResponse.message)
}
inline ::std::string* CommandLookupTopicResponse::mutable_message() {
  set_has_message();
  if (message_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    message_ = new ::std::string;
  }
  // @@protoc_insertion_point(field_mutable:pulsar.proto.CommandLookupTopicResponse.message)
  return message_;
}
inline ::std::string* CommandLookupTopicResponse::release_message() {
  clear_has_message();
  if (message_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    return NULL;
  } else {
    ::std::string* temp = message_;
    message_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    return temp;
  }
}
inline void CommandLookupTopicResponse::set_allocated_message(::std::string* message) {
  if (message_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    delete message_;
  }
  if (message) {
    set_has_message();
    message_ = message;
  } else {
    clear_has_message();
    message_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  }
  // @@protoc_insertion_point(field_set_allocated:pulsar.proto.CommandLookupTopicResponse.message)
}

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

// CommandProducer

// required string topic = 1;
inline bool CommandProducer::has_topic() const {
  return (_has_bits_[0] & 0x00000001u) != 0;
}
inline void CommandProducer::set_has_topic() {
  _has_bits_[0] |= 0x00000001u;
}
inline void CommandProducer::clear_has_topic() {
  _has_bits_[0] &= ~0x00000001u;
}
inline void CommandProducer::clear_topic() {
  if (topic_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    topic_->clear();
  }
  clear_has_topic();
}
inline const ::std::string& CommandProducer::topic() const {
  // @@protoc_insertion_point(field_get:pulsar.proto.CommandProducer.topic)
  return *topic_;
}
inline void CommandProducer::set_topic(const ::std::string& value) {
  set_has_topic();
  if (topic_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    topic_ = new ::std::string;
  }
  topic_->assign(value);
  // @@protoc_insertion_point(field_set:pulsar.proto.CommandProducer.topic)
}
inline void CommandProducer::set_topic(const char* value) {
  set_has_topic();
  if (topic_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    topic_ = new ::std::string;
  }
  topic_->assign(value);
  // @@protoc_insertion_point(field_set_char:pulsar.proto.CommandProducer.topic)
}
inline void CommandProducer::set_topic(const char* value, size_t size) {
  set_has_topic();
  if (topic_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    topic_ = new ::std::string;
  }
  topic_->assign(reinterpret_cast<const char*>(value), size);
  // @@protoc_insertion_point(field_set_pointer:pulsar.proto.CommandProducer.topic)
}
inline ::std::string* CommandProducer::mutable_topic() {
  set_has_topic();
  if (topic_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    topic_ = new ::std::string;
  }
  // @@protoc_insertion_point(field_mutable:pulsar.proto.CommandProducer.topic)
  return topic_;
}
inline ::std::string* CommandProducer::release_topic() {
  clear_has_topic();
  if (topic_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    return NULL;
  } else {
    ::std::string* temp = topic_;
    topic_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    return temp;
  }
}
inline void CommandProducer::set_allocated_topic(::std::string* topic) {
  if (topic_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    delete topic_;
  }
  if (topic) {
    set_has_topic();
    topic_ = topic;
  } else {
    clear_has_topic();
    topic_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  }
  // @@protoc_insertion_point(field_set_allocated:pulsar.proto.CommandProducer.topic)
}

// required uint64 producer_id = 2;
inline bool CommandProducer::has_producer_id() const {
  return (_has_bits_[0] & 0x00000002u) != 0;
}
inline void CommandProducer::set_has_producer_id() {
  _has_bits_[0] |= 0x00000002u;
}
inline void CommandProducer::clear_has_producer_id() {
  _has_bits_[0] &= ~0x00000002u;
}
inline void CommandProducer::clear_producer_id() {
  producer_id_ = GOOGLE_ULONGLONG(0);
  clear_has_producer_id();
}
inline ::google::protobuf::uint64 CommandProducer::producer_id() const {
  // @@protoc_insertion_point(field_get:pulsar.proto.CommandProducer.producer_id)
  return producer_id_;
}
inline void CommandProducer::set_producer_id(::google::protobuf::uint64 value) {
  set_has_producer_id();
  producer_id_ = value;
  // @@protoc_insertion_point(field_set:pulsar.proto.CommandProducer.producer_id)
}

// required uint64 request_id = 3;
inline bool CommandProducer::has_request_id() const {
  return (_has_bits_[0] & 0x00000004u) != 0;
}
inline void CommandProducer::set_has_request_id() {
  _has_bits_[0] |= 0x00000004u;
}
inline void CommandProducer::clear_has_request_id() {
  _has_bits_[0] &= ~0x00000004u;
}
inline void CommandProducer::clear_request_id() {
  request_id_ = GOOGLE_ULONGLONG(0);
  clear_has_request_id();
}
inline ::google::protobuf::uint64 CommandProducer::request_id() const {
  // @@protoc_insertion_point(field_get:pulsar.proto.CommandProducer.request_id)
  return request_id_;
}
inline void CommandProducer::set_request_id(::google::protobuf::uint64 value) {
  set_has_request_id();
  request_id_ = value;
  // @@protoc_insertion_point(field_set:pulsar.proto.CommandProducer.request_id)
}

// optional string producer_name = 4;
inline bool CommandProducer::has_producer_name() const {
  return (_has_bits_[0] & 0x00000008u) != 0;
}
inline void CommandProducer::set_has_producer_name() {
  _has_bits_[0] |= 0x00000008u;
}
inline void CommandProducer::clear_has_producer_name() {
  _has_bits_[0] &= ~0x00000008u;
}
inline void CommandProducer::clear_producer_name() {
  if (producer_name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    producer_name_->clear();
  }
  clear_has_producer_name();
}
inline const ::std::string& CommandProducer::producer_name() const {
  // @@protoc_insertion_point(field_get:pulsar.proto.CommandProducer.producer_name)
  return *producer_name_;
}
inline void CommandProducer::set_producer_name(const ::std::string& value) {
  set_has_producer_name();
  if (producer_name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    producer_name_ = new ::std::string;
  }
  producer_name_->assign(value);
  // @@protoc_insertion_point(field_set:pulsar.proto.CommandProducer.producer_name)
}
inline void CommandProducer::set_producer_name(const char* value) {
  set_has_producer_name();
  if (producer_name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    producer_name_ = new ::std::string;
  }
  producer_name_->assign(value);
  // @@protoc_insertion_point(field_set_char:pulsar.proto.CommandProducer.producer_name)
}
inline void CommandProducer::set_producer_name(const char* value, size_t size) {
  set_has_producer_name();
  if (producer_name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    producer_name_ = new ::std::string;
  }
  producer_name_->assign(reinterpret_cast<const char*>(value), size);
  // @@protoc_insertion_point(field_set_pointer:pulsar.proto.CommandProducer.producer_name)
}
inline ::std::string* CommandProducer::mutable_producer_name() {
  set_has_producer_name();
  if (producer_name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    producer_name_ = new ::std::string;
  }
  // @@protoc_insertion_point(field_mutable:pulsar.proto.CommandProducer.producer_name)
  return producer_name_;
}
inline ::std::string* CommandProducer::release_producer_name() {
  clear_has_producer_name();
  if (producer_name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    return NULL;
  } else {
    ::std::string* temp = producer_name_;
    producer_name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    return temp;
  }
}
inline void CommandProducer::set_allocated_producer_name(::std::string* producer_name) {
  if (producer_name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    delete producer_name_;
  }
  if (producer_name) {
    set_has_producer_name();
    producer_name_ = producer_name;
  } else {
    clear_has_producer_name();
    producer_name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  }
  // @@protoc_insertion_point(field_set_allocated:pulsar.proto.CommandProducer.producer_name)
}

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

// CommandSend

// required uint64 producer_id = 1;
inline bool CommandSend::has_producer_id() const {
  return (_has_bits_[0] & 0x00000001u) != 0;
}
inline void CommandSend::set_has_producer_id() {
  _has_bits_[0] |= 0x00000001u;
}
inline void CommandSend::clear_has_producer_id() {
  _has_bits_[0] &= ~0x00000001u;
}
inline void CommandSend::clear_producer_id() {
  producer_id_ = GOOGLE_ULONGLONG(0);
  clear_has_producer_id();
}
inline ::google::protobuf::uint64 CommandSend::producer_id() const {
  // @@protoc_insertion_point(field_get:pulsar.proto.CommandSend.producer_id)
  return producer_id_;
}
inline void CommandSend::set_producer_id(::google::protobuf::uint64 value) {
  set_has_producer_id();
  producer_id_ = value;
  // @@protoc_insertion_point(field_set:pulsar.proto.CommandSend.producer_id)
}

// required uint64 sequence_id = 2;
inline bool CommandSend::has_sequence_id() const {
  return (_has_bits_[0] & 0x00000002u) != 0;
}
inline void CommandSend::set_has_sequence_id() {
  _has_bits_[0] |= 0x00000002u;
}
inline void CommandSend::clear_has_sequence_id() {
  _has_bits_[0] &= ~0x00000002u;
}
inline void CommandSend::clear_sequence_id() {
  sequence_id_ = GOOGLE_ULONGLONG(0);
  clear_has_sequence_id();
}
inline ::google::protobuf::uint64 CommandSend::sequence_id() const {
  // @@protoc_insertion_point(field_get:pulsar.proto.CommandSend.sequence_id)
  return sequence_id_;
}
inline void CommandSend::set_sequence_id(::google::protobuf::uint64 value) {
  set_has_sequence_id();
  sequence_id_ = value;
  // @@protoc_insertion_point(field_set:pulsar.proto.CommandSend.sequence_id)
}

// optional int32 num_messages = 3 [default = 1];
inline bool CommandSend::has_num_messages() const {
  return (_has_bits_[0] & 0x00000004u) != 0;
}
inline void CommandSend::set_has_num_messages() {
  _has_bits_[0] |= 0x00000004u;
}
inline void CommandSend::clear_has_num_messages() {
  _has_bits_[0] &= ~0x00000004u;
}
inline void CommandSend::clear_num_messages() {
  num_messages_ = 1;
  clear_has_num_messages();
}
inline ::google::protobuf::int32 CommandSend::num_messages() const {
  // @@protoc_insertion_point(field_get:pulsar.proto.CommandSend.num_messages)
  return num_messages_;
}
inline void CommandSend::set_num_messages(::google::protobuf::int32 value) {
  set_has_num_messages();
  num_messages_ = value;
  // @@protoc_insertion_point(field_set:pulsar.proto.CommandSend.num_messages)
}

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

// CommandSendReceipt

// required uint64 producer_id = 1;
inline bool CommandSendReceipt::has_producer_id() const {
  return (_has_bits_[0] & 0x00000001u) != 0;
}
inline void CommandSendReceipt::set_has_producer_id() {
  _has_bits_[0] |= 0x00000001u;
}
inline void CommandSendReceipt::clear_has_producer_id() {
  _has_bits_[0] &= ~0x00000001u;
}
inline void CommandSendReceipt::clear_producer_id() {
  producer_id_ = GOOGLE_ULONGLONG(0);
  clear_has_producer_id();
}
inline ::google::protobuf::uint64 CommandSendReceipt::producer_id() const {
  // @@protoc_insertion_point(field_get:pulsar.proto.CommandSendReceipt.producer_id)
  return producer_id_;
}
inline void CommandSendReceipt::set_producer_id(::google::protobuf::uint64 value) {
  set_has_producer_id();
  producer_id_ = value;
  // @@protoc_insertion_point(field_set:pulsar.proto.CommandSendReceipt.producer_id)
}

// required uint64 sequence_id = 2;
inline bool CommandSendReceipt::has_sequence_id() const {
  return (_has_bits_[0] & 0x00000002u) != 0;
}
inline void CommandSendReceipt::set_has_sequence_id() {
  _has_bits_[0] |= 0x00000002u;
}
inline void CommandSendReceipt::clear_has_sequence_id() {
  _has_bits_[0] &= ~0x00000002u;
}
inline void CommandSendReceipt::clear_sequence_id() {
  sequence_id_ = GOOGLE_ULONGLONG(0);
  clear_has_sequence_id();
}
inline ::google::protobuf::uint64 CommandSendReceipt::sequence_id() const {
  // @@protoc_insertion_point(field_get:pulsar.proto.CommandSendReceipt.sequence_id)
  return sequence_id_;
}
inline void CommandSendReceipt::set_sequence_id(::google::protobuf::uint64 value) {
  set_has_sequence_id();
  sequence_id_ = value;
  // @@protoc_insertion_point(field_set:pulsar.proto.CommandSendReceipt.sequence_id)
}

// optional .pulsar.proto.MessageIdData message_id = 3;
inline bool CommandSendReceipt::has_message_id() const {
  return (_has_bits_[0] & 0x00000004u) != 0;
}
inline void CommandSendReceipt::set_has_message_id() {
  _has_bits_[0] |= 0x00000004u;
}
inline void CommandSendReceipt::clear_has_message_id() {
  _has_bits_[0] &= ~0x00000004u;
}
inline void CommandSendReceipt::clear_message_id() {
  if (message_id_ != NULL) message_id_->::pulsar::proto::MessageIdData::Clear();
  clear_has_message_id();
}
inline const ::pulsar::proto::MessageIdData& CommandSendReceipt::message_id() const {
  // @@protoc_insertion_point(field_get:pulsar.proto.CommandSendReceipt.message_id)
#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
  return message_id_ != NULL ? *message_id_ : *default_instance().message_id_;
#else
  return message_id_ != NULL ? *message_id_ : *default_instance_->message_id_;
#endif
}
inline ::pulsar::proto::MessageIdData* CommandSendReceipt::mutable_message_id() {
  set_has_message_id();
  if (message_id_ == NULL) message_id_ = new ::pulsar::proto::MessageIdData;
  // @@protoc_insertion_point(field_mutable:pulsar.proto.CommandSendReceipt.message_id)
  return message_id_;
}
inline ::pulsar::proto::MessageIdData* CommandSendReceipt::release_message_id() {
  clear_has_message_id();
  ::pulsar::proto::MessageIdData* temp = message_id_;
  message_id_ = NULL;
  return temp;
}
inline void CommandSendReceipt::set_allocated_message_id(::pulsar::proto::MessageIdData* message_id) {
  delete message_id_;
  message_id_ = message_id;
  if (message_id) {
    set_has_message_id();
  } else {
    clear_has_message_id();
  }
  // @@protoc_insertion_point(field_set_allocated:pulsar.proto.CommandSendReceipt.message_id)
}

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

// CommandSendError

// required uint64 producer_id = 1;
inline bool CommandSendError::has_producer_id() const {
  return (_has_bits_[0] & 0x00000001u) != 0;
}
inline void CommandSendError::set_has_producer_id() {
  _has_bits_[0] |= 0x00000001u;
}
inline void CommandSendError::clear_has_producer_id() {
  _has_bits_[0] &= ~0x00000001u;
}
inline void CommandSendError::clear_producer_id() {
  producer_id_ = GOOGLE_ULONGLONG(0);
  clear_has_producer_id();
}
inline ::google::protobuf::uint64 CommandSendError::producer_id() const {
  // @@protoc_insertion_point(field_get:pulsar.proto.CommandSendError.producer_id)
  return producer_id_;
}
inline void CommandSendError::set_producer_id(::google::protobuf::uint64 value) {
  set_has_producer_id();
  producer_id_ = value;
  // @@protoc_insertion_point(field_set:pulsar.proto.CommandSendError.producer_id)
}

// required uint64 sequence_id = 2;
inline bool CommandSendError::has_sequence_id() const {
  return (_has_bits_[0] & 0x00000002u) != 0;
}
inline void CommandSendError::set_has_sequence_id() {
  _has_bits_[0] |= 0x00000002u;
}
inline void CommandSendError::clear_has_sequence_id() {
  _has_bits_[0] &= ~0x00000002u;
}
inline void CommandSendError::clear_sequence_id() {
  sequence_id_ = GOOGLE_ULONGLONG(0);
  clear_has_sequence_id();
}
inline ::google::protobuf::uint64 CommandSendError::sequence_id() const {
  // @@protoc_insertion_point(field_get:pulsar.proto.CommandSendError.sequence_id)
  return sequence_id_;
}
inline void CommandSendError::set_sequence_id(::google::protobuf::uint64 value) {
  set_has_sequence_id();
  sequence_id_ = value;
  // @@protoc_insertion_point(field_set:pulsar.proto.CommandSendError.sequence_id)
}

// required .pulsar.proto.ServerError error = 3;
inline bool CommandSendError::has_error() const {
  return (_has_bits_[0] & 0x00000004u) != 0;
}
inline void CommandSendError::set_has_error() {
  _has_bits_[0] |= 0x00000004u;
}
inline void CommandSendError::clear_has_error() {
  _has_bits_[0] &= ~0x00000004u;
}
inline void CommandSendError::clear_error() {
  error_ = 0;
  clear_has_error();
}
inline ::pulsar::proto::ServerError CommandSendError::error() const {
  // @@protoc_insertion_point(field_get:pulsar.proto.CommandSendError.error)
  return static_cast< ::pulsar::proto::ServerError >(error_);
}
inline void CommandSendError::set_error(::pulsar::proto::ServerError value) {
  assert(::pulsar::proto::ServerError_IsValid(value));
  set_has_error();
  error_ = value;
  // @@protoc_insertion_point(field_set:pulsar.proto.CommandSendError.error)
}

// required string message = 4;
inline bool CommandSendError::has_message() const {
  return (_has_bits_[0] & 0x00000008u) != 0;
}
inline void CommandSendError::set_has_message() {
  _has_bits_[0] |= 0x00000008u;
}
inline void CommandSendError::clear_has_message() {
  _has_bits_[0] &= ~0x00000008u;
}
inline void CommandSendError::clear_message() {
  if (message_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    message_->clear();
  }
  clear_has_message();
}
inline const ::std::string& CommandSendError::message() const {
  // @@protoc_insertion_point(field_get:pulsar.proto.CommandSendError.message)
  return *message_;
}
inline void CommandSendError::set_message(const ::std::string& value) {
  set_has_message();
  if (message_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    message_ = new ::std::string;
  }
  message_->assign(value);
  // @@protoc_insertion_point(field_set:pulsar.proto.CommandSendError.message)
}
inline void CommandSendError::set_message(const char* value) {
  set_has_message();
  if (message_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    message_ = new ::std::string;
  }
  message_->assign(value);
  // @@protoc_insertion_point(field_set_char:pulsar.proto.CommandSendError.message)
}
inline void CommandSendError::set_message(const char* value, size_t size) {
  set_has_message();
  if (message_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    message_ = new ::std::string;
  }
  message_->assign(reinterpret_cast<const char*>(value), size);
  // @@protoc_insertion_point(field_set_pointer:pulsar.proto.CommandSendError.message)
}
inline ::std::string* CommandSendError::mutable_message() {
  set_has_message();
  if (message_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    message_ = new ::std::string;
  }
  // @@protoc_insertion_point(field_mutable:pulsar.proto.CommandSendError.message)
  return message_;
}
inline ::std::string* CommandSendError::release_message() {
  clear_has_message();
  if (message_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    return NULL;
  } else {
    ::std::string* temp = message_;
    message_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    return temp;
  }
}
inline void CommandSendError::set_allocated_message(::std::string* message) {
  if (message_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    delete message_;
  }
  if (message) {
    set_has_message();
    message_ = message;
  } else {
    clear_has_message();
    message_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  }
  // @@protoc_insertion_point(field_set_allocated:pulsar.proto.CommandSendError.message)
}

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

// CommandMessage

// required uint64 consumer_id = 1;
inline bool CommandMessage::has_consumer_id() const {
  return (_has_bits_[0] & 0x00000001u) != 0;
}
inline void CommandMessage::set_has_consumer_id() {
  _has_bits_[0] |= 0x00000001u;
}
inline void CommandMessage::clear_has_consumer_id() {
  _has_bits_[0] &= ~0x00000001u;
}
inline void CommandMessage::clear_consumer_id() {
  consumer_id_ = GOOGLE_ULONGLONG(0);
  clear_has_consumer_id();
}
inline ::google::protobuf::uint64 CommandMessage::consumer_id() const {
  // @@protoc_insertion_point(field_get:pulsar.proto.CommandMessage.consumer_id)
  return consumer_id_;
}
inline void CommandMessage::set_consumer_id(::google::protobuf::uint64 value) {
  set_has_consumer_id();
  consumer_id_ = value;
  // @@protoc_insertion_point(field_set:pulsar.proto.CommandMessage.consumer_id)
}

// required .pulsar.proto.MessageIdData message_id = 2;
inline bool CommandMessage::has_message_id() const {
  return (_has_bits_[0] & 0x00000002u) != 0;
}
inline void CommandMessage::set_has_message_id() {
  _has_bits_[0] |= 0x00000002u;
}
inline void CommandMessage::clear_has_message_id() {
  _has_bits_[0] &= ~0x00000002u;
}
inline void CommandMessage::clear_message_id() {
  if (message_id_ != NULL) message_id_->::pulsar::proto::MessageIdData::Clear();
  clear_has_message_id();
}
inline const ::pulsar::proto::MessageIdData& CommandMessage::message_id() const {
  // @@protoc_insertion_point(field_get:pulsar.proto.CommandMessage.message_id)
#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
  return message_id_ != NULL ? *message_id_ : *default_instance().message_id_;
#else
  return message_id_ != NULL ? *message_id_ : *default_instance_->message_id_;
#endif
}
inline ::pulsar::proto::MessageIdData* CommandMessage::mutable_message_id() {
  set_has_message_id();
  if (message_id_ == NULL) message_id_ = new ::pulsar::proto::MessageIdData;
  // @@protoc_insertion_point(field_mutable:pulsar.proto.CommandMessage.message_id)
  return message_id_;
}
inline ::pulsar::proto::MessageIdData* CommandMessage::release_message_id() {
  clear_has_message_id();
  ::pulsar::proto::MessageIdData* temp = message_id_;
  message_id_ = NULL;
  return temp;
}
inline void CommandMessage::set_allocated_message_id(::pulsar::proto::MessageIdData* message_id) {
  delete message_id_;
  message_id_ = message_id;
  if (message_id) {
    set_has_message_id();
  } else {
    clear_has_message_id();
  }
  // @@protoc_insertion_point(field_set_allocated:pulsar.proto.CommandMessage.message_id)
}

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

// CommandAck

// required uint64 consumer_id = 1;
inline bool CommandAck::has_consumer_id() const {
  return (_has_bits_[0] & 0x00000001u) != 0;
}
inline void CommandAck::set_has_consumer_id() {
  _has_bits_[0] |= 0x00000001u;
}
inline void CommandAck::clear_has_consumer_id() {
  _has_bits_[0] &= ~0x00000001u;
}
inline void CommandAck::clear_consumer_id() {
  consumer_id_ = GOOGLE_ULONGLONG(0);
  clear_has_consumer_id();
}
inline ::google::protobuf::uint64 CommandAck::consumer_id() const {
  // @@protoc_insertion_point(field_get:pulsar.proto.CommandAck.consumer_id)
  return consumer_id_;
}
inline void CommandAck::set_consumer_id(::google::protobuf::uint64 value) {
  set_has_consumer_id();
  consumer_id_ = value;
  // @@protoc_insertion_point(field_set:pulsar.proto.CommandAck.consumer_id)
}

// required .pulsar.proto.CommandAck.AckType ack_type = 2;
inline bool CommandAck::has_ack_type() const {
  return (_has_bits_[0] & 0x00000002u) != 0;
}
inline void CommandAck::set_has_ack_type() {
  _has_bits_[0] |= 0x00000002u;
}
inline void CommandAck::clear_has_ack_type() {
  _has_bits_[0] &= ~0x00000002u;
}
inline void CommandAck::clear_ack_type() {
  ack_type_ = 0;
  clear_has_ack_type();
}
inline ::pulsar::proto::CommandAck_AckType CommandAck::ack_type() const {
  // @@protoc_insertion_point(field_get:pulsar.proto.CommandAck.ack_type)
  return static_cast< ::pulsar::proto::CommandAck_AckType >(ack_type_);
}
inline void CommandAck::set_ack_type(::pulsar::proto::CommandAck_AckType value) {
  assert(::pulsar::proto::CommandAck_AckType_IsValid(value));
  set_has_ack_type();
  ack_type_ = value;
  // @@protoc_insertion_point(field_set:pulsar.proto.CommandAck.ack_type)
}

// required .pulsar.proto.MessageIdData message_id = 3;
inline bool CommandAck::has_message_id() const {
  return (_has_bits_[0] & 0x00000004u) != 0;
}
inline void CommandAck::set_has_message_id() {
  _has_bits_[0] |= 0x00000004u;
}
inline void CommandAck::clear_has_message_id() {
  _has_bits_[0] &= ~0x00000004u;
}
inline void CommandAck::clear_message_id() {
  if (message_id_ != NULL) message_id_->::pulsar::proto::MessageIdData::Clear();
  clear_has_message_id();
}
inline const ::pulsar::proto::MessageIdData& CommandAck::message_id() const {
  // @@protoc_insertion_point(field_get:pulsar.proto.CommandAck.message_id)
#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
  return message_id_ != NULL ? *message_id_ : *default_instance().message_id_;
#else
  return message_id_ != NULL ? *message_id_ : *default_instance_->message_id_;
#endif
}
inline ::pulsar::proto::MessageIdData* CommandAck::mutable_message_id() {
  set_has_message_id();
  if (message_id_ == NULL) message_id_ = new ::pulsar::proto::MessageIdData;
  // @@protoc_insertion_point(field_mutable:pulsar.proto.CommandAck.message_id)
  return message_id_;
}
inline ::pulsar::proto::MessageIdData* CommandAck::release_message_id() {
  clear_has_message_id();
  ::pulsar::proto::MessageIdData* temp = message_id_;
  message_id_ = NULL;
  return temp;
}
inline void CommandAck::set_allocated_message_id(::pulsar::proto::MessageIdData* message_id) {
  delete message_id_;
  message_id_ = message_id;
  if (message_id) {
    set_has_message_id();
  } else {
    clear_has_message_id();
  }
  // @@protoc_insertion_point(field_set_allocated:pulsar.proto.CommandAck.message_id)
}

// optional .pulsar.proto.CommandAck.ValidationError validation_error = 4;
inline bool CommandAck::has_validation_error() const {
  return (_has_bits_[0] & 0x00000008u) != 0;
}
inline void CommandAck::set_has_validation_error() {
  _has_bits_[0] |= 0x00000008u;
}
inline void CommandAck::clear_has_validation_error() {
  _has_bits_[0] &= ~0x00000008u;
}
inline void CommandAck::clear_validation_error() {
  validation_error_ = 0;
  clear_has_validation_error();
}
inline ::pulsar::proto::CommandAck_ValidationError CommandAck::validation_error() const {
  // @@protoc_insertion_point(field_get:pulsar.proto.CommandAck.validation_error)
  return static_cast< ::pulsar::proto::CommandAck_ValidationError >(validation_error_);
}
inline void CommandAck::set_validation_error(::pulsar::proto::CommandAck_ValidationError value) {
  assert(::pulsar::proto::CommandAck_ValidationError_IsValid(value));
  set_has_validation_error();
  validation_error_ = value;
  // @@protoc_insertion_point(field_set:pulsar.proto.CommandAck.validation_error)
}

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

// CommandFlow

// required uint64 consumer_id = 1;
inline bool CommandFlow::has_consumer_id() const {
  return (_has_bits_[0] & 0x00000001u) != 0;
}
inline void CommandFlow::set_has_consumer_id() {
  _has_bits_[0] |= 0x00000001u;
}
inline void CommandFlow::clear_has_consumer_id() {
  _has_bits_[0] &= ~0x00000001u;
}
inline void CommandFlow::clear_consumer_id() {
  consumer_id_ = GOOGLE_ULONGLONG(0);
  clear_has_consumer_id();
}
inline ::google::protobuf::uint64 CommandFlow::consumer_id() const {
  // @@protoc_insertion_point(field_get:pulsar.proto.CommandFlow.consumer_id)
  return consumer_id_;
}
inline void CommandFlow::set_consumer_id(::google::protobuf::uint64 value) {
  set_has_consumer_id();
  consumer_id_ = value;
  // @@protoc_insertion_point(field_set:pulsar.proto.CommandFlow.consumer_id)
}

// required uint32 messagePermits = 2;
inline bool CommandFlow::has_messagepermits() const {
  return (_has_bits_[0] & 0x00000002u) != 0;
}
inline void CommandFlow::set_has_messagepermits() {
  _has_bits_[0] |= 0x00000002u;
}
inline void CommandFlow::clear_has_messagepermits() {
  _has_bits_[0] &= ~0x00000002u;
}
inline void CommandFlow::clear_messagepermits() {
  messagepermits_ = 0u;
  clear_has_messagepermits();
}
inline ::google::protobuf::uint32 CommandFlow::messagepermits() const {
  // @@protoc_insertion_point(field_get:pulsar.proto.CommandFlow.messagePermits)
  return messagepermits_;
}
inline void CommandFlow::set_messagepermits(::google::protobuf::uint32 value) {
  set_has_messagepermits();
  messagepermits_ = value;
  // @@protoc_insertion_point(field_set:pulsar.proto.CommandFlow.messagePermits)
}

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

// CommandUnsubscribe

// required uint64 consumer_id = 1;
inline bool CommandUnsubscribe::has_consumer_id() const {
  return (_has_bits_[0] & 0x00000001u) != 0;
}
inline void CommandUnsubscribe::set_has_consumer_id() {
  _has_bits_[0] |= 0x00000001u;
}
inline void CommandUnsubscribe::clear_has_consumer_id() {
  _has_bits_[0] &= ~0x00000001u;
}
inline void CommandUnsubscribe::clear_consumer_id() {
  consumer_id_ = GOOGLE_ULONGLONG(0);
  clear_has_consumer_id();
}
inline ::google::protobuf::uint64 CommandUnsubscribe::consumer_id() const {
  // @@protoc_insertion_point(field_get:pulsar.proto.CommandUnsubscribe.consumer_id)
  return consumer_id_;
}
inline void CommandUnsubscribe::set_consumer_id(::google::protobuf::uint64 value) {
  set_has_consumer_id();
  consumer_id_ = value;
  // @@protoc_insertion_point(field_set:pulsar.proto.CommandUnsubscribe.consumer_id)
}

// required uint64 request_id = 2;
inline bool CommandUnsubscribe::has_request_id() const {
  return (_has_bits_[0] & 0x00000002u) != 0;
}
inline void CommandUnsubscribe::set_has_request_id() {
  _has_bits_[0] |= 0x00000002u;
}
inline void CommandUnsubscribe::clear_has_request_id() {
  _has_bits_[0] &= ~0x00000002u;
}
inline void CommandUnsubscribe::clear_request_id() {
  request_id_ = GOOGLE_ULONGLONG(0);
  clear_has_request_id();
}
inline ::google::protobuf::uint64 CommandUnsubscribe::request_id() const {
  // @@protoc_insertion_point(field_get:pulsar.proto.CommandUnsubscribe.request_id)
  return request_id_;
}
inline void CommandUnsubscribe::set_request_id(::google::protobuf::uint64 value) {
  set_has_request_id();
  request_id_ = value;
  // @@protoc_insertion_point(field_set:pulsar.proto.CommandUnsubscribe.request_id)
}

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

// CommandCloseProducer

// required uint64 producer_id = 1;
inline bool CommandCloseProducer::has_producer_id() const {
  return (_has_bits_[0] & 0x00000001u) != 0;
}
inline void CommandCloseProducer::set_has_producer_id() {
  _has_bits_[0] |= 0x00000001u;
}
inline void CommandCloseProducer::clear_has_producer_id() {
  _has_bits_[0] &= ~0x00000001u;
}
inline void CommandCloseProducer::clear_producer_id() {
  producer_id_ = GOOGLE_ULONGLONG(0);
  clear_has_producer_id();
}
inline ::google::protobuf::uint64 CommandCloseProducer::producer_id() const {
  // @@protoc_insertion_point(field_get:pulsar.proto.CommandCloseProducer.producer_id)
  return producer_id_;
}
inline void CommandCloseProducer::set_producer_id(::google::protobuf::uint64 value) {
  set_has_producer_id();
  producer_id_ = value;
  // @@protoc_insertion_point(field_set:pulsar.proto.CommandCloseProducer.producer_id)
}

// required uint64 request_id = 2;
inline bool CommandCloseProducer::has_request_id() const {
  return (_has_bits_[0] & 0x00000002u) != 0;
}
inline void CommandCloseProducer::set_has_request_id() {
  _has_bits_[0] |= 0x00000002u;
}
inline void CommandCloseProducer::clear_has_request_id() {
  _has_bits_[0] &= ~0x00000002u;
}
inline void CommandCloseProducer::clear_request_id() {
  request_id_ = GOOGLE_ULONGLONG(0);
  clear_has_request_id();
}
inline ::google::protobuf::uint64 CommandCloseProducer::request_id() const {
  // @@protoc_insertion_point(field_get:pulsar.proto.CommandCloseProducer.request_id)
  return request_id_;
}
inline void CommandCloseProducer::set_request_id(::google::protobuf::uint64 value) {
  set_has_request_id();
  request_id_ = value;
  // @@protoc_insertion_point(field_set:pulsar.proto.CommandCloseProducer.request_id)
}

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

// CommandCloseConsumer

// required uint64 consumer_id = 1;
inline bool CommandCloseConsumer::has_consumer_id() const {
  return (_has_bits_[0] & 0x00000001u) != 0;
}
inline void CommandCloseConsumer::set_has_consumer_id() {
  _has_bits_[0] |= 0x00000001u;
}
inline void CommandCloseConsumer::clear_has_consumer_id() {
  _has_bits_[0] &= ~0x00000001u;
}
inline void CommandCloseConsumer::clear_consumer_id() {
  consumer_id_ = GOOGLE_ULONGLONG(0);
  clear_has_consumer_id();
}
inline ::google::protobuf::uint64 CommandCloseConsumer::consumer_id() const {
  // @@protoc_insertion_point(field_get:pulsar.proto.CommandCloseConsumer.consumer_id)
  return consumer_id_;
}
inline void CommandCloseConsumer::set_consumer_id(::google::protobuf::uint64 value) {
  set_has_consumer_id();
  consumer_id_ = value;
  // @@protoc_insertion_point(field_set:pulsar.proto.CommandCloseConsumer.consumer_id)
}

// required uint64 request_id = 2;
inline bool CommandCloseConsumer::has_request_id() const {
  return (_has_bits_[0] & 0x00000002u) != 0;
}
inline void CommandCloseConsumer::set_has_request_id() {
  _has_bits_[0] |= 0x00000002u;
}
inline void CommandCloseConsumer::clear_has_request_id() {
  _has_bits_[0] &= ~0x00000002u;
}
inline void CommandCloseConsumer::clear_request_id() {
  request_id_ = GOOGLE_ULONGLONG(0);
  clear_has_request_id();
}
inline ::google::protobuf::uint64 CommandCloseConsumer::request_id() const {
  // @@protoc_insertion_point(field_get:pulsar.proto.CommandCloseConsumer.request_id)
  return request_id_;
}
inline void CommandCloseConsumer::set_request_id(::google::protobuf::uint64 value) {
  set_has_request_id();
  request_id_ = value;
  // @@protoc_insertion_point(field_set:pulsar.proto.CommandCloseConsumer.request_id)
}

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

// CommandRedeliverUnacknowledgedMessages

// required uint64 consumer_id = 1;
inline bool CommandRedeliverUnacknowledgedMessages::has_consumer_id() const {
  return (_has_bits_[0] & 0x00000001u) != 0;
}
inline void CommandRedeliverUnacknowledgedMessages::set_has_consumer_id() {
  _has_bits_[0] |= 0x00000001u;
}
inline void CommandRedeliverUnacknowledgedMessages::clear_has_consumer_id() {
  _has_bits_[0] &= ~0x00000001u;
}
inline void CommandRedeliverUnacknowledgedMessages::clear_consumer_id() {
  consumer_id_ = GOOGLE_ULONGLONG(0);
  clear_has_consumer_id();
}
inline ::google::protobuf::uint64 CommandRedeliverUnacknowledgedMessages::consumer_id() const {
  // @@protoc_insertion_point(field_get:pulsar.proto.CommandRedeliverUnacknowledgedMessages.consumer_id)
  return consumer_id_;
}
inline void CommandRedeliverUnacknowledgedMessages::set_consumer_id(::google::protobuf::uint64 value) {
  set_has_consumer_id();
  consumer_id_ = value;
  // @@protoc_insertion_point(field_set:pulsar.proto.CommandRedeliverUnacknowledgedMessages.consumer_id)
}

// repeated .pulsar.proto.MessageIdData message_ids = 2;
inline int CommandRedeliverUnacknowledgedMessages::message_ids_size() const {
  return message_ids_.size();
}
inline void CommandRedeliverUnacknowledgedMessages::clear_message_ids() {
  message_ids_.Clear();
}
inline const ::pulsar::proto::MessageIdData& CommandRedeliverUnacknowledgedMessages::message_ids(int index) const {
  // @@protoc_insertion_point(field_get:pulsar.proto.CommandRedeliverUnacknowledgedMessages.message_ids)
  return message_ids_.Get(index);
}
inline ::pulsar::proto::MessageIdData* CommandRedeliverUnacknowledgedMessages::mutable_message_ids(int index) {
  // @@protoc_insertion_point(field_mutable:pulsar.proto.CommandRedeliverUnacknowledgedMessages.message_ids)
  return message_ids_.Mutable(index);
}
inline ::pulsar::proto::MessageIdData* CommandRedeliverUnacknowledgedMessages::add_message_ids() {
  // @@protoc_insertion_point(field_add:pulsar.proto.CommandRedeliverUnacknowledgedMessages.message_ids)
  return message_ids_.Add();
}
inline const ::google::protobuf::RepeatedPtrField< ::pulsar::proto::MessageIdData >&
CommandRedeliverUnacknowledgedMessages::message_ids() const {
  // @@protoc_insertion_point(field_list:pulsar.proto.CommandRedeliverUnacknowledgedMessages.message_ids)
  return message_ids_;
}
inline ::google::protobuf::RepeatedPtrField< ::pulsar::proto::MessageIdData >*
CommandRedeliverUnacknowledgedMessages::mutable_message_ids() {
  // @@protoc_insertion_point(field_mutable_list:pulsar.proto.CommandRedeliverUnacknowledgedMessages.message_ids)
  return &message_ids_;
}

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

// CommandSuccess

// required uint64 request_id = 1;
inline bool CommandSuccess::has_request_id() const {
  return (_has_bits_[0] & 0x00000001u) != 0;
}
inline void CommandSuccess::set_has_request_id() {
  _has_bits_[0] |= 0x00000001u;
}
inline void CommandSuccess::clear_has_request_id() {
  _has_bits_[0] &= ~0x00000001u;
}
inline void CommandSuccess::clear_request_id() {
  request_id_ = GOOGLE_ULONGLONG(0);
  clear_has_request_id();
}
inline ::google::protobuf::uint64 CommandSuccess::request_id() const {
  // @@protoc_insertion_point(field_get:pulsar.proto.CommandSuccess.request_id)
  return request_id_;
}
inline void CommandSuccess::set_request_id(::google::protobuf::uint64 value) {
  set_has_request_id();
  request_id_ = value;
  // @@protoc_insertion_point(field_set:pulsar.proto.CommandSuccess.request_id)
}

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

// CommandProducerSuccess

// required uint64 request_id = 1;
inline bool CommandProducerSuccess::has_request_id() const {
  return (_has_bits_[0] & 0x00000001u) != 0;
}
inline void CommandProducerSuccess::set_has_request_id() {
  _has_bits_[0] |= 0x00000001u;
}
inline void CommandProducerSuccess::clear_has_request_id() {
  _has_bits_[0] &= ~0x00000001u;
}
inline void CommandProducerSuccess::clear_request_id() {
  request_id_ = GOOGLE_ULONGLONG(0);
  clear_has_request_id();
}
inline ::google::protobuf::uint64 CommandProducerSuccess::request_id() const {
  // @@protoc_insertion_point(field_get:pulsar.proto.CommandProducerSuccess.request_id)
  return request_id_;
}
inline void CommandProducerSuccess::set_request_id(::google::protobuf::uint64 value) {
  set_has_request_id();
  request_id_ = value;
  // @@protoc_insertion_point(field_set:pulsar.proto.CommandProducerSuccess.request_id)
}

// required string producer_name = 2;
inline bool CommandProducerSuccess::has_producer_name() const {
  return (_has_bits_[0] & 0x00000002u) != 0;
}
inline void CommandProducerSuccess::set_has_producer_name() {
  _has_bits_[0] |= 0x00000002u;
}
inline void CommandProducerSuccess::clear_has_producer_name() {
  _has_bits_[0] &= ~0x00000002u;
}
inline void CommandProducerSuccess::clear_producer_name() {
  if (producer_name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    producer_name_->clear();
  }
  clear_has_producer_name();
}
inline const ::std::string& CommandProducerSuccess::producer_name() const {
  // @@protoc_insertion_point(field_get:pulsar.proto.CommandProducerSuccess.producer_name)
  return *producer_name_;
}
inline void CommandProducerSuccess::set_producer_name(const ::std::string& value) {
  set_has_producer_name();
  if (producer_name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    producer_name_ = new ::std::string;
  }
  producer_name_->assign(value);
  // @@protoc_insertion_point(field_set:pulsar.proto.CommandProducerSuccess.producer_name)
}
inline void CommandProducerSuccess::set_producer_name(const char* value) {
  set_has_producer_name();
  if (producer_name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    producer_name_ = new ::std::string;
  }
  producer_name_->assign(value);
  // @@protoc_insertion_point(field_set_char:pulsar.proto.CommandProducerSuccess.producer_name)
}
inline void CommandProducerSuccess::set_producer_name(const char* value, size_t size) {
  set_has_producer_name();
  if (producer_name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    producer_name_ = new ::std::string;
  }
  producer_name_->assign(reinterpret_cast<const char*>(value), size);
  // @@protoc_insertion_point(field_set_pointer:pulsar.proto.CommandProducerSuccess.producer_name)
}
inline ::std::string* CommandProducerSuccess::mutable_producer_name() {
  set_has_producer_name();
  if (producer_name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    producer_name_ = new ::std::string;
  }
  // @@protoc_insertion_point(field_mutable:pulsar.proto.CommandProducerSuccess.producer_name)
  return producer_name_;
}
inline ::std::string* CommandProducerSuccess::release_producer_name() {
  clear_has_producer_name();
  if (producer_name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    return NULL;
  } else {
    ::std::string* temp = producer_name_;
    producer_name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    return temp;
  }
}
inline void CommandProducerSuccess::set_allocated_producer_name(::std::string* producer_name) {
  if (producer_name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    delete producer_name_;
  }
  if (producer_name) {
    set_has_producer_name();
    producer_name_ = producer_name;
  } else {
    clear_has_producer_name();
    producer_name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  }
  // @@protoc_insertion_point(field_set_allocated:pulsar.proto.CommandProducerSuccess.producer_name)
}

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

// CommandError

// required uint64 request_id = 1;
inline bool CommandError::has_request_id() const {
  return (_has_bits_[0] & 0x00000001u) != 0;
}
inline void CommandError::set_has_request_id() {
  _has_bits_[0] |= 0x00000001u;
}
inline void CommandError::clear_has_request_id() {
  _has_bits_[0] &= ~0x00000001u;
}
inline void CommandError::clear_request_id() {
  request_id_ = GOOGLE_ULONGLONG(0);
  clear_has_request_id();
}
inline ::google::protobuf::uint64 CommandError::request_id() const {
  // @@protoc_insertion_point(field_get:pulsar.proto.CommandError.request_id)
  return request_id_;
}
inline void CommandError::set_request_id(::google::protobuf::uint64 value) {
  set_has_request_id();
  request_id_ = value;
  // @@protoc_insertion_point(field_set:pulsar.proto.CommandError.request_id)
}

// required .pulsar.proto.ServerError error = 2;
inline bool CommandError::has_error() const {
  return (_has_bits_[0] & 0x00000002u) != 0;
}
inline void CommandError::set_has_error() {
  _has_bits_[0] |= 0x00000002u;
}
inline void CommandError::clear_has_error() {
  _has_bits_[0] &= ~0x00000002u;
}
inline void CommandError::clear_error() {
  error_ = 0;
  clear_has_error();
}
inline ::pulsar::proto::ServerError CommandError::error() const {
  // @@protoc_insertion_point(field_get:pulsar.proto.CommandError.error)
  return static_cast< ::pulsar::proto::ServerError >(error_);
}
inline void CommandError::set_error(::pulsar::proto::ServerError value) {
  assert(::pulsar::proto::ServerError_IsValid(value));
  set_has_error();
  error_ = value;
  // @@protoc_insertion_point(field_set:pulsar.proto.CommandError.error)
}

// required string message = 3;
inline bool CommandError::has_message() const {
  return (_has_bits_[0] & 0x00000004u) != 0;
}
inline void CommandError::set_has_message() {
  _has_bits_[0] |= 0x00000004u;
}
inline void CommandError::clear_has_message() {
  _has_bits_[0] &= ~0x00000004u;
}
inline void CommandError::clear_message() {
  if (message_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    message_->clear();
  }
  clear_has_message();
}
inline const ::std::string& CommandError::message() const {
  // @@protoc_insertion_point(field_get:pulsar.proto.CommandError.message)
  return *message_;
}
inline void CommandError::set_message(const ::std::string& value) {
  set_has_message();
  if (message_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    message_ = new ::std::string;
  }
  message_->assign(value);
  // @@protoc_insertion_point(field_set:pulsar.proto.CommandError.message)
}
inline void CommandError::set_message(const char* value) {
  set_has_message();
  if (message_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    message_ = new ::std::string;
  }
  message_->assign(value);
  // @@protoc_insertion_point(field_set_char:pulsar.proto.CommandError.message)
}
inline void CommandError::set_message(const char* value, size_t size) {
  set_has_message();
  if (message_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    message_ = new ::std::string;
  }
  message_->assign(reinterpret_cast<const char*>(value), size);
  // @@protoc_insertion_point(field_set_pointer:pulsar.proto.CommandError.message)
}
inline ::std::string* CommandError::mutable_message() {
  set_has_message();
  if (message_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    message_ = new ::std::string;
  }
  // @@protoc_insertion_point(field_mutable:pulsar.proto.CommandError.message)
  return message_;
}
inline ::std::string* CommandError::release_message() {
  clear_has_message();
  if (message_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    return NULL;
  } else {
    ::std::string* temp = message_;
    message_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    return temp;
  }
}
inline void CommandError::set_allocated_message(::std::string* message) {
  if (message_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    delete message_;
  }
  if (message) {
    set_has_message();
    message_ = message;
  } else {
    clear_has_message();
    message_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  }
  // @@protoc_insertion_point(field_set_allocated:pulsar.proto.CommandError.message)
}

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

// CommandPing

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

// CommandPong

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

// CommandConsumerStats

// required uint64 request_id = 1;
inline bool CommandConsumerStats::has_request_id() const {
  return (_has_bits_[0] & 0x00000001u) != 0;
}
inline void CommandConsumerStats::set_has_request_id() {
  _has_bits_[0] |= 0x00000001u;
}
inline void CommandConsumerStats::clear_has_request_id() {
  _has_bits_[0] &= ~0x00000001u;
}
inline void CommandConsumerStats::clear_request_id() {
  request_id_ = GOOGLE_ULONGLONG(0);
  clear_has_request_id();
}
inline ::google::protobuf::uint64 CommandConsumerStats::request_id() const {
  // @@protoc_insertion_point(field_get:pulsar.proto.CommandConsumerStats.request_id)
  return request_id_;
}
inline void CommandConsumerStats::set_request_id(::google::protobuf::uint64 value) {
  set_has_request_id();
  request_id_ = value;
  // @@protoc_insertion_point(field_set:pulsar.proto.CommandConsumerStats.request_id)
}

// required string topic_name = 2;
inline bool CommandConsumerStats::has_topic_name() const {
  return (_has_bits_[0] & 0x00000002u) != 0;
}
inline void CommandConsumerStats::set_has_topic_name() {
  _has_bits_[0] |= 0x00000002u;
}
inline void CommandConsumerStats::clear_has_topic_name() {
  _has_bits_[0] &= ~0x00000002u;
}
inline void CommandConsumerStats::clear_topic_name() {
  if (topic_name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    topic_name_->clear();
  }
  clear_has_topic_name();
}
inline const ::std::string& CommandConsumerStats::topic_name() const {
  // @@protoc_insertion_point(field_get:pulsar.proto.CommandConsumerStats.topic_name)
  return *topic_name_;
}
inline void CommandConsumerStats::set_topic_name(const ::std::string& value) {
  set_has_topic_name();
  if (topic_name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    topic_name_ = new ::std::string;
  }
  topic_name_->assign(value);
  // @@protoc_insertion_point(field_set:pulsar.proto.CommandConsumerStats.topic_name)
}
inline void CommandConsumerStats::set_topic_name(const char* value) {
  set_has_topic_name();
  if (topic_name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    topic_name_ = new ::std::string;
  }
  topic_name_->assign(value);
  // @@protoc_insertion_point(field_set_char:pulsar.proto.CommandConsumerStats.topic_name)
}
inline void CommandConsumerStats::set_topic_name(const char* value, size_t size) {
  set_has_topic_name();
  if (topic_name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    topic_name_ = new ::std::string;
  }
  topic_name_->assign(reinterpret_cast<const char*>(value), size);
  // @@protoc_insertion_point(field_set_pointer:pulsar.proto.CommandConsumerStats.topic_name)
}
inline ::std::string* CommandConsumerStats::mutable_topic_name() {
  set_has_topic_name();
  if (topic_name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    topic_name_ = new ::std::string;
  }
  // @@protoc_insertion_point(field_mutable:pulsar.proto.CommandConsumerStats.topic_name)
  return topic_name_;
}
inline ::std::string* CommandConsumerStats::release_topic_name() {
  clear_has_topic_name();
  if (topic_name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    return NULL;
  } else {
    ::std::string* temp = topic_name_;
    topic_name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    return temp;
  }
}
inline void CommandConsumerStats::set_allocated_topic_name(::std::string* topic_name) {
  if (topic_name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    delete topic_name_;
  }
  if (topic_name) {
    set_has_topic_name();
    topic_name_ = topic_name;
  } else {
    clear_has_topic_name();
    topic_name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  }
  // @@protoc_insertion_point(field_set_allocated:pulsar.proto.CommandConsumerStats.topic_name)
}

// required string subscription_name = 3;
inline bool CommandConsumerStats::has_subscription_name() const {
  return (_has_bits_[0] & 0x00000004u) != 0;
}
inline void CommandConsumerStats::set_has_subscription_name() {
  _has_bits_[0] |= 0x00000004u;
}
inline void CommandConsumerStats::clear_has_subscription_name() {
  _has_bits_[0] &= ~0x00000004u;
}
inline void CommandConsumerStats::clear_subscription_name() {
  if (subscription_name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    subscription_name_->clear();
  }
  clear_has_subscription_name();
}
inline const ::std::string& CommandConsumerStats::subscription_name() const {
  // @@protoc_insertion_point(field_get:pulsar.proto.CommandConsumerStats.subscription_name)
  return *subscription_name_;
}
inline void CommandConsumerStats::set_subscription_name(const ::std::string& value) {
  set_has_subscription_name();
  if (subscription_name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    subscription_name_ = new ::std::string;
  }
  subscription_name_->assign(value);
  // @@protoc_insertion_point(field_set:pulsar.proto.CommandConsumerStats.subscription_name)
}
inline void CommandConsumerStats::set_subscription_name(const char* value) {
  set_has_subscription_name();
  if (subscription_name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    subscription_name_ = new ::std::string;
  }
  subscription_name_->assign(value);
  // @@protoc_insertion_point(field_set_char:pulsar.proto.CommandConsumerStats.subscription_name)
}
inline void CommandConsumerStats::set_subscription_name(const char* value, size_t size) {
  set_has_subscription_name();
  if (subscription_name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    subscription_name_ = new ::std::string;
  }
  subscription_name_->assign(reinterpret_cast<const char*>(value), size);
  // @@protoc_insertion_point(field_set_pointer:pulsar.proto.CommandConsumerStats.subscription_name)
}
inline ::std::string* CommandConsumerStats::mutable_subscription_name() {
  set_has_subscription_name();
  if (subscription_name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    subscription_name_ = new ::std::string;
  }
  // @@protoc_insertion_point(field_mutable:pulsar.proto.CommandConsumerStats.subscription_name)
  return subscription_name_;
}
inline ::std::string* CommandConsumerStats::release_subscription_name() {
  clear_has_subscription_name();
  if (subscription_name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    return NULL;
  } else {
    ::std::string* temp = subscription_name_;
    subscription_name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    return temp;
  }
}
inline void CommandConsumerStats::set_allocated_subscription_name(::std::string* subscription_name) {
  if (subscription_name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    delete subscription_name_;
  }
  if (subscription_name) {
    set_has_subscription_name();
    subscription_name_ = subscription_name;
  } else {
    clear_has_subscription_name();
    subscription_name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  }
  // @@protoc_insertion_point(field_set_allocated:pulsar.proto.CommandConsumerStats.subscription_name)
}

// required uint64 consumer_id = 4;
inline bool CommandConsumerStats::has_consumer_id() const {
  return (_has_bits_[0] & 0x00000008u) != 0;
}
inline void CommandConsumerStats::set_has_consumer_id() {
  _has_bits_[0] |= 0x00000008u;
}
inline void CommandConsumerStats::clear_has_consumer_id() {
  _has_bits_[0] &= ~0x00000008u;
}
inline void CommandConsumerStats::clear_consumer_id() {
  consumer_id_ = GOOGLE_ULONGLONG(0);
  clear_has_consumer_id();
}
inline ::google::protobuf::uint64 CommandConsumerStats::consumer_id() const {
  // @@protoc_insertion_point(field_get:pulsar.proto.CommandConsumerStats.consumer_id)
  return consumer_id_;
}
inline void CommandConsumerStats::set_consumer_id(::google::protobuf::uint64 value) {
  set_has_consumer_id();
  consumer_id_ = value;
  // @@protoc_insertion_point(field_set:pulsar.proto.CommandConsumerStats.consumer_id)
}

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

// CommandConsumerStatsResponse

// required uint64 request_id = 1;
inline bool CommandConsumerStatsResponse::has_request_id() const {
  return (_has_bits_[0] & 0x00000001u) != 0;
}
inline void CommandConsumerStatsResponse::set_has_request_id() {
  _has_bits_[0] |= 0x00000001u;
}
inline void CommandConsumerStatsResponse::clear_has_request_id() {
  _has_bits_[0] &= ~0x00000001u;
}
inline void CommandConsumerStatsResponse::clear_request_id() {
  request_id_ = GOOGLE_ULONGLONG(0);
  clear_has_request_id();
}
inline ::google::protobuf::uint64 CommandConsumerStatsResponse::request_id() const {
  // @@protoc_insertion_point(field_get:pulsar.proto.CommandConsumerStatsResponse.request_id)
  return request_id_;
}
inline void CommandConsumerStatsResponse::set_request_id(::google::protobuf::uint64 value) {
  set_has_request_id();
  request_id_ = value;
  // @@protoc_insertion_point(field_set:pulsar.proto.CommandConsumerStatsResponse.request_id)
}

// optional .pulsar.proto.ServerError error_code = 2;
inline bool CommandConsumerStatsResponse::has_error_code() const {
  return (_has_bits_[0] & 0x00000002u) != 0;
}
inline void CommandConsumerStatsResponse::set_has_error_code() {
  _has_bits_[0] |= 0x00000002u;
}
inline void CommandConsumerStatsResponse::clear_has_error_code() {
  _has_bits_[0] &= ~0x00000002u;
}
inline void CommandConsumerStatsResponse::clear_error_code() {
  error_code_ = 0;
  clear_has_error_code();
}
inline ::pulsar::proto::ServerError CommandConsumerStatsResponse::error_code() const {
  // @@protoc_insertion_point(field_get:pulsar.proto.CommandConsumerStatsResponse.error_code)
  return static_cast< ::pulsar::proto::ServerError >(error_code_);
}
inline void CommandConsumerStatsResponse::set_error_code(::pulsar::proto::ServerError value) {
  assert(::pulsar::proto::ServerError_IsValid(value));
  set_has_error_code();
  error_code_ = value;
  // @@protoc_insertion_point(field_set:pulsar.proto.CommandConsumerStatsResponse.error_code)
}

// optional string error_message = 3;
inline bool CommandConsumerStatsResponse::has_error_message() const {
  return (_has_bits_[0] & 0x00000004u) != 0;
}
inline void CommandConsumerStatsResponse::set_has_error_message() {
  _has_bits_[0] |= 0x00000004u;
}
inline void CommandConsumerStatsResponse::clear_has_error_message() {
  _has_bits_[0] &= ~0x00000004u;
}
inline void CommandConsumerStatsResponse::clear_error_message() {
  if (error_message_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    error_message_->clear();
  }
  clear_has_error_message();
}
inline const ::std::string& CommandConsumerStatsResponse::error_message() const {
  // @@protoc_insertion_point(field_get:pulsar.proto.CommandConsumerStatsResponse.error_message)
  return *error_message_;
}
inline void CommandConsumerStatsResponse::set_error_message(const ::std::string& value) {
  set_has_error_message();
  if (error_message_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    error_message_ = new ::std::string;
  }
  error_message_->assign(value);
  // @@protoc_insertion_point(field_set:pulsar.proto.CommandConsumerStatsResponse.error_message)
}
inline void CommandConsumerStatsResponse::set_error_message(const char* value) {
  set_has_error_message();
  if (error_message_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    error_message_ = new ::std::string;
  }
  error_message_->assign(value);
  // @@protoc_insertion_point(field_set_char:pulsar.proto.CommandConsumerStatsResponse.error_message)
}
inline void CommandConsumerStatsResponse::set_error_message(const char* value, size_t size) {
  set_has_error_message();
  if (error_message_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    error_message_ = new ::std::string;
  }
  error_message_->assign(reinterpret_cast<const char*>(value), size);
  // @@protoc_insertion_point(field_set_pointer:pulsar.proto.CommandConsumerStatsResponse.error_message)
}
inline ::std::string* CommandConsumerStatsResponse::mutable_error_message() {
  set_has_error_message();
  if (error_message_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    error_message_ = new ::std::string;
  }
  // @@protoc_insertion_point(field_mutable:pulsar.proto.CommandConsumerStatsResponse.error_message)
  return error_message_;
}
inline ::std::string* CommandConsumerStatsResponse::release_error_message() {
  clear_has_error_message();
  if (error_message_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    return NULL;
  } else {
    ::std::string* temp = error_message_;
    error_message_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    return temp;
  }
}
inline void CommandConsumerStatsResponse::set_allocated_error_message(::std::string* error_message) {
  if (error_message_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    delete error_message_;
  }
  if (error_message) {
    set_has_error_message();
    error_message_ = error_message;
  } else {
    clear_has_error_message();
    error_message_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  }
  // @@protoc_insertion_point(field_set_allocated:pulsar.proto.CommandConsumerStatsResponse.error_message)
}

// optional double msgRateOut = 4;
inline bool CommandConsumerStatsResponse::has_msgrateout() const {
  return (_has_bits_[0] & 0x00000008u) != 0;
}
inline void CommandConsumerStatsResponse::set_has_msgrateout() {
  _has_bits_[0] |= 0x00000008u;
}
inline void CommandConsumerStatsResponse::clear_has_msgrateout() {
  _has_bits_[0] &= ~0x00000008u;
}
inline void CommandConsumerStatsResponse::clear_msgrateout() {
  msgrateout_ = 0;
  clear_has_msgrateout();
}
inline double CommandConsumerStatsResponse::msgrateout() const {
  // @@protoc_insertion_point(field_get:pulsar.proto.CommandConsumerStatsResponse.msgRateOut)
  return msgrateout_;
}
inline void CommandConsumerStatsResponse::set_msgrateout(double value) {
  set_has_msgrateout();
  msgrateout_ = value;
  // @@protoc_insertion_point(field_set:pulsar.proto.CommandConsumerStatsResponse.msgRateOut)
}

// optional double msgThroughputOut = 5;
inline bool CommandConsumerStatsResponse::has_msgthroughputout() const {
  return (_has_bits_[0] & 0x00000010u) != 0;
}
inline void CommandConsumerStatsResponse::set_has_msgthroughputout() {
  _has_bits_[0] |= 0x00000010u;
}
inline void CommandConsumerStatsResponse::clear_has_msgthroughputout() {
  _has_bits_[0] &= ~0x00000010u;
}
inline void CommandConsumerStatsResponse::clear_msgthroughputout() {
  msgthroughputout_ = 0;
  clear_has_msgthroughputout();
}
inline double CommandConsumerStatsResponse::msgthroughputout() const {
  // @@protoc_insertion_point(field_get:pulsar.proto.CommandConsumerStatsResponse.msgThroughputOut)
  return msgthroughputout_;
}
inline void CommandConsumerStatsResponse::set_msgthroughputout(double value) {
  set_has_msgthroughputout();
  msgthroughputout_ = value;
  // @@protoc_insertion_point(field_set:pulsar.proto.CommandConsumerStatsResponse.msgThroughputOut)
}

// optional double msgRateRedeliver = 6;
inline bool CommandConsumerStatsResponse::has_msgrateredeliver() const {
  return (_has_bits_[0] & 0x00000020u) != 0;
}
inline void CommandConsumerStatsResponse::set_has_msgrateredeliver() {
  _has_bits_[0] |= 0x00000020u;
}
inline void CommandConsumerStatsResponse::clear_has_msgrateredeliver() {
  _has_bits_[0] &= ~0x00000020u;
}
inline void CommandConsumerStatsResponse::clear_msgrateredeliver() {
  msgrateredeliver_ = 0;
  clear_has_msgrateredeliver();
}
inline double CommandConsumerStatsResponse::msgrateredeliver() const {
  // @@protoc_insertion_point(field_get:pulsar.proto.CommandConsumerStatsResponse.msgRateRedeliver)
  return msgrateredeliver_;
}
inline void CommandConsumerStatsResponse::set_msgrateredeliver(double value) {
  set_has_msgrateredeliver();
  msgrateredeliver_ = value;
  // @@protoc_insertion_point(field_set:pulsar.proto.CommandConsumerStatsResponse.msgRateRedeliver)
}

// optional string consumerName = 7;
inline bool CommandConsumerStatsResponse::has_consumername() const {
  return (_has_bits_[0] & 0x00000040u) != 0;
}
inline void CommandConsumerStatsResponse::set_has_consumername() {
  _has_bits_[0] |= 0x00000040u;
}
inline void CommandConsumerStatsResponse::clear_has_consumername() {
  _has_bits_[0] &= ~0x00000040u;
}
inline void CommandConsumerStatsResponse::clear_consumername() {
  if (consumername_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    consumername_->clear();
  }
  clear_has_consumername();
}
inline const ::std::string& CommandConsumerStatsResponse::consumername() const {
  // @@protoc_insertion_point(field_get:pulsar.proto.CommandConsumerStatsResponse.consumerName)
  return *consumername_;
}
inline void CommandConsumerStatsResponse::set_consumername(const ::std::string& value) {
  set_has_consumername();
  if (consumername_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    consumername_ = new ::std::string;
  }
  consumername_->assign(value);
  // @@protoc_insertion_point(field_set:pulsar.proto.CommandConsumerStatsResponse.consumerName)
}
inline void CommandConsumerStatsResponse::set_consumername(const char* value) {
  set_has_consumername();
  if (consumername_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    consumername_ = new ::std::string;
  }
  consumername_->assign(value);
  // @@protoc_insertion_point(field_set_char:pulsar.proto.CommandConsumerStatsResponse.consumerName)
}
inline void CommandConsumerStatsResponse::set_consumername(const char* value, size_t size) {
  set_has_consumername();
  if (consumername_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    consumername_ = new ::std::string;
  }
  consumername_->assign(reinterpret_cast<const char*>(value), size);
  // @@protoc_insertion_point(field_set_pointer:pulsar.proto.CommandConsumerStatsResponse.consumerName)
}
inline ::std::string* CommandConsumerStatsResponse::mutable_consumername() {
  set_has_consumername();
  if (consumername_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    consumername_ = new ::std::string;
  }
  // @@protoc_insertion_point(field_mutable:pulsar.proto.CommandConsumerStatsResponse.consumerName)
  return consumername_;
}
inline ::std::string* CommandConsumerStatsResponse::release_consumername() {
  clear_has_consumername();
  if (consumername_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    return NULL;
  } else {
    ::std::string* temp = consumername_;
    consumername_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    return temp;
  }
}
inline void CommandConsumerStatsResponse::set_allocated_consumername(::std::string* consumername) {
  if (consumername_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    delete consumername_;
  }
  if (consumername) {
    set_has_consumername();
    consumername_ = consumername;
  } else {
    clear_has_consumername();
    consumername_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  }
  // @@protoc_insertion_point(field_set_allocated:pulsar.proto.CommandConsumerStatsResponse.consumerName)
}

// optional uint64 availablePermits = 8;
inline bool CommandConsumerStatsResponse::has_availablepermits() const {
  return (_has_bits_[0] & 0x00000080u) != 0;
}
inline void CommandConsumerStatsResponse::set_has_availablepermits() {
  _has_bits_[0] |= 0x00000080u;
}
inline void CommandConsumerStatsResponse::clear_has_availablepermits() {
  _has_bits_[0] &= ~0x00000080u;
}
inline void CommandConsumerStatsResponse::clear_availablepermits() {
  availablepermits_ = GOOGLE_ULONGLONG(0);
  clear_has_availablepermits();
}
inline ::google::protobuf::uint64 CommandConsumerStatsResponse::availablepermits() const {
  // @@protoc_insertion_point(field_get:pulsar.proto.CommandConsumerStatsResponse.availablePermits)
  return availablepermits_;
}
inline void CommandConsumerStatsResponse::set_availablepermits(::google::protobuf::uint64 value) {
  set_has_availablepermits();
  availablepermits_ = value;
  // @@protoc_insertion_point(field_set:pulsar.proto.CommandConsumerStatsResponse.availablePermits)
}

// optional uint64 unackedMessages = 9;
inline bool CommandConsumerStatsResponse::has_unackedmessages() const {
  return (_has_bits_[0] & 0x00000100u) != 0;
}
inline void CommandConsumerStatsResponse::set_has_unackedmessages() {
  _has_bits_[0] |= 0x00000100u;
}
inline void CommandConsumerStatsResponse::clear_has_unackedmessages() {
  _has_bits_[0] &= ~0x00000100u;
}
inline void CommandConsumerStatsResponse::clear_unackedmessages() {
  unackedmessages_ = GOOGLE_ULONGLONG(0);
  clear_has_unackedmessages();
}
inline ::google::protobuf::uint64 CommandConsumerStatsResponse::unackedmessages() const {
  // @@protoc_insertion_point(field_get:pulsar.proto.CommandConsumerStatsResponse.unackedMessages)
  return unackedmessages_;
}
inline void CommandConsumerStatsResponse::set_unackedmessages(::google::protobuf::uint64 value) {
  set_has_unackedmessages();
  unackedmessages_ = value;
  // @@protoc_insertion_point(field_set:pulsar.proto.CommandConsumerStatsResponse.unackedMessages)
}

// optional bool blockedConsumerOnUnackedMsgs = 10;
inline bool CommandConsumerStatsResponse::has_blockedconsumeronunackedmsgs() const {
  return (_has_bits_[0] & 0x00000200u) != 0;
}
inline void CommandConsumerStatsResponse::set_has_blockedconsumeronunackedmsgs() {
  _has_bits_[0] |= 0x00000200u;
}
inline void CommandConsumerStatsResponse::clear_has_blockedconsumeronunackedmsgs() {
  _has_bits_[0] &= ~0x00000200u;
}
inline void CommandConsumerStatsResponse::clear_blockedconsumeronunackedmsgs() {
  blockedconsumeronunackedmsgs_ = false;
  clear_has_blockedconsumeronunackedmsgs();
}
inline bool CommandConsumerStatsResponse::blockedconsumeronunackedmsgs() const {
  // @@protoc_insertion_point(field_get:pulsar.proto.CommandConsumerStatsResponse.blockedConsumerOnUnackedMsgs)
  return blockedconsumeronunackedmsgs_;
}
inline void CommandConsumerStatsResponse::set_blockedconsumeronunackedmsgs(bool value) {
  set_has_blockedconsumeronunackedmsgs();
  blockedconsumeronunackedmsgs_ = value;
  // @@protoc_insertion_point(field_set:pulsar.proto.CommandConsumerStatsResponse.blockedConsumerOnUnackedMsgs)
}

// optional string address = 11;
inline bool CommandConsumerStatsResponse::has_address() const {
  return (_has_bits_[0] & 0x00000400u) != 0;
}
inline void CommandConsumerStatsResponse::set_has_address() {
  _has_bits_[0] |= 0x00000400u;
}
inline void CommandConsumerStatsResponse::clear_has_address() {
  _has_bits_[0] &= ~0x00000400u;
}
inline void CommandConsumerStatsResponse::clear_address() {
  if (address_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    address_->clear();
  }
  clear_has_address();
}
inline const ::std::string& CommandConsumerStatsResponse::address() const {
  // @@protoc_insertion_point(field_get:pulsar.proto.CommandConsumerStatsResponse.address)
  return *address_;
}
inline void CommandConsumerStatsResponse::set_address(const ::std::string& value) {
  set_has_address();
  if (address_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    address_ = new ::std::string;
  }
  address_->assign(value);
  // @@protoc_insertion_point(field_set:pulsar.proto.CommandConsumerStatsResponse.address)
}
inline void CommandConsumerStatsResponse::set_address(const char* value) {
  set_has_address();
  if (address_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    address_ = new ::std::string;
  }
  address_->assign(value);
  // @@protoc_insertion_point(field_set_char:pulsar.proto.CommandConsumerStatsResponse.address)
}
inline void CommandConsumerStatsResponse::set_address(const char* value, size_t size) {
  set_has_address();
  if (address_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    address_ = new ::std::string;
  }
  address_->assign(reinterpret_cast<const char*>(value), size);
  // @@protoc_insertion_point(field_set_pointer:pulsar.proto.CommandConsumerStatsResponse.address)
}
inline ::std::string* CommandConsumerStatsResponse::mutable_address() {
  set_has_address();
  if (address_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    address_ = new ::std::string;
  }
  // @@protoc_insertion_point(field_mutable:pulsar.proto.CommandConsumerStatsResponse.address)
  return address_;
}
inline ::std::string* CommandConsumerStatsResponse::release_address() {
  clear_has_address();
  if (address_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    return NULL;
  } else {
    ::std::string* temp = address_;
    address_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    return temp;
  }
}
inline void CommandConsumerStatsResponse::set_allocated_address(::std::string* address) {
  if (address_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    delete address_;
  }
  if (address) {
    set_has_address();
    address_ = address;
  } else {
    clear_has_address();
    address_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  }
  // @@protoc_insertion_point(field_set_allocated:pulsar.proto.CommandConsumerStatsResponse.address)
}

// optional string connectedSince = 12;
inline bool CommandConsumerStatsResponse::has_connectedsince() const {
  return (_has_bits_[0] & 0x00000800u) != 0;
}
inline void CommandConsumerStatsResponse::set_has_connectedsince() {
  _has_bits_[0] |= 0x00000800u;
}
inline void CommandConsumerStatsResponse::clear_has_connectedsince() {
  _has_bits_[0] &= ~0x00000800u;
}
inline void CommandConsumerStatsResponse::clear_connectedsince() {
  if (connectedsince_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    connectedsince_->clear();
  }
  clear_has_connectedsince();
}
inline const ::std::string& CommandConsumerStatsResponse::connectedsince() const {
  // @@protoc_insertion_point(field_get:pulsar.proto.CommandConsumerStatsResponse.connectedSince)
  return *connectedsince_;
}
inline void CommandConsumerStatsResponse::set_connectedsince(const ::std::string& value) {
  set_has_connectedsince();
  if (connectedsince_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    connectedsince_ = new ::std::string;
  }
  connectedsince_->assign(value);
  // @@protoc_insertion_point(field_set:pulsar.proto.CommandConsumerStatsResponse.connectedSince)
}
inline void CommandConsumerStatsResponse::set_connectedsince(const char* value) {
  set_has_connectedsince();
  if (connectedsince_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    connectedsince_ = new ::std::string;
  }
  connectedsince_->assign(value);
  // @@protoc_insertion_point(field_set_char:pulsar.proto.CommandConsumerStatsResponse.connectedSince)
}
inline void CommandConsumerStatsResponse::set_connectedsince(const char* value, size_t size) {
  set_has_connectedsince();
  if (connectedsince_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    connectedsince_ = new ::std::string;
  }
  connectedsince_->assign(reinterpret_cast<const char*>(value), size);
  // @@protoc_insertion_point(field_set_pointer:pulsar.proto.CommandConsumerStatsResponse.connectedSince)
}
inline ::std::string* CommandConsumerStatsResponse::mutable_connectedsince() {
  set_has_connectedsince();
  if (connectedsince_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    connectedsince_ = new ::std::string;
  }
  // @@protoc_insertion_point(field_mutable:pulsar.proto.CommandConsumerStatsResponse.connectedSince)
  return connectedsince_;
}
inline ::std::string* CommandConsumerStatsResponse::release_connectedsince() {
  clear_has_connectedsince();
  if (connectedsince_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    return NULL;
  } else {
    ::std::string* temp = connectedsince_;
    connectedsince_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    return temp;
  }
}
inline void CommandConsumerStatsResponse::set_allocated_connectedsince(::std::string* connectedsince) {
  if (connectedsince_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    delete connectedsince_;
  }
  if (connectedsince) {
    set_has_connectedsince();
    connectedsince_ = connectedsince;
  } else {
    clear_has_connectedsince();
    connectedsince_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  }
  // @@protoc_insertion_point(field_set_allocated:pulsar.proto.CommandConsumerStatsResponse.connectedSince)
}

// optional string type = 13;
inline bool CommandConsumerStatsResponse::has_type() const {
  return (_has_bits_[0] & 0x00001000u) != 0;
}
inline void CommandConsumerStatsResponse::set_has_type() {
  _has_bits_[0] |= 0x00001000u;
}
inline void CommandConsumerStatsResponse::clear_has_type() {
  _has_bits_[0] &= ~0x00001000u;
}
inline void CommandConsumerStatsResponse::clear_type() {
  if (type_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    type_->clear();
  }
  clear_has_type();
}
inline const ::std::string& CommandConsumerStatsResponse::type() const {
  // @@protoc_insertion_point(field_get:pulsar.proto.CommandConsumerStatsResponse.type)
  return *type_;
}
inline void CommandConsumerStatsResponse::set_type(const ::std::string& value) {
  set_has_type();
  if (type_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    type_ = new ::std::string;
  }
  type_->assign(value);
  // @@protoc_insertion_point(field_set:pulsar.proto.CommandConsumerStatsResponse.type)
}
inline void CommandConsumerStatsResponse::set_type(const char* value) {
  set_has_type();
  if (type_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    type_ = new ::std::string;
  }
  type_->assign(value);
  // @@protoc_insertion_point(field_set_char:pulsar.proto.CommandConsumerStatsResponse.type)
}
inline void CommandConsumerStatsResponse::set_type(const char* value, size_t size) {
  set_has_type();
  if (type_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    type_ = new ::std::string;
  }
  type_->assign(reinterpret_cast<const char*>(value), size);
  // @@protoc_insertion_point(field_set_pointer:pulsar.proto.CommandConsumerStatsResponse.type)
}
inline ::std::string* CommandConsumerStatsResponse::mutable_type() {
  set_has_type();
  if (type_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    type_ = new ::std::string;
  }
  // @@protoc_insertion_point(field_mutable:pulsar.proto.CommandConsumerStatsResponse.type)
  return type_;
}
inline ::std::string* CommandConsumerStatsResponse::release_type() {
  clear_has_type();
  if (type_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    return NULL;
  } else {
    ::std::string* temp = type_;
    type_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    return temp;
  }
}
inline void CommandConsumerStatsResponse::set_allocated_type(::std::string* type) {
  if (type_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    delete type_;
  }
  if (type) {
    set_has_type();
    type_ = type;
  } else {
    clear_has_type();
    type_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  }
  // @@protoc_insertion_point(field_set_allocated:pulsar.proto.CommandConsumerStatsResponse.type)
}

// optional double msgRateExpired = 14;
inline bool CommandConsumerStatsResponse::has_msgrateexpired() const {
  return (_has_bits_[0] & 0x00002000u) != 0;
}
inline void CommandConsumerStatsResponse::set_has_msgrateexpired() {
  _has_bits_[0] |= 0x00002000u;
}
inline void CommandConsumerStatsResponse::clear_has_msgrateexpired() {
  _has_bits_[0] &= ~0x00002000u;
}
inline void CommandConsumerStatsResponse::clear_msgrateexpired() {
  msgrateexpired_ = 0;
  clear_has_msgrateexpired();
}
inline double CommandConsumerStatsResponse::msgrateexpired() const {
  // @@protoc_insertion_point(field_get:pulsar.proto.CommandConsumerStatsResponse.msgRateExpired)
  return msgrateexpired_;
}
inline void CommandConsumerStatsResponse::set_msgrateexpired(double value) {
  set_has_msgrateexpired();
  msgrateexpired_ = value;
  // @@protoc_insertion_point(field_set:pulsar.proto.CommandConsumerStatsResponse.msgRateExpired)
}

// optional uint64 msgBacklog = 15;
inline bool CommandConsumerStatsResponse::has_msgbacklog() const {
  return (_has_bits_[0] & 0x00004000u) != 0;
}
inline void CommandConsumerStatsResponse::set_has_msgbacklog() {
  _has_bits_[0] |= 0x00004000u;
}
inline void CommandConsumerStatsResponse::clear_has_msgbacklog() {
  _has_bits_[0] &= ~0x00004000u;
}
inline void CommandConsumerStatsResponse::clear_msgbacklog() {
  msgbacklog_ = GOOGLE_ULONGLONG(0);
  clear_has_msgbacklog();
}
inline ::google::protobuf::uint64 CommandConsumerStatsResponse::msgbacklog() const {
  // @@protoc_insertion_point(field_get:pulsar.proto.CommandConsumerStatsResponse.msgBacklog)
  return msgbacklog_;
}
inline void CommandConsumerStatsResponse::set_msgbacklog(::google::protobuf::uint64 value) {
  set_has_msgbacklog();
  msgbacklog_ = value;
  // @@protoc_insertion_point(field_set:pulsar.proto.CommandConsumerStatsResponse.msgBacklog)
}

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

// BaseCommand

// required .pulsar.proto.BaseCommand.Type type = 1;
inline bool BaseCommand::has_type() const {
  return (_has_bits_[0] & 0x00000001u) != 0;
}
inline void BaseCommand::set_has_type() {
  _has_bits_[0] |= 0x00000001u;
}
inline void BaseCommand::clear_has_type() {
  _has_bits_[0] &= ~0x00000001u;
}
inline void BaseCommand::clear_type() {
  type_ = 2;
  clear_has_type();
}
inline ::pulsar::proto::BaseCommand_Type BaseCommand::type() const {
  // @@protoc_insertion_point(field_get:pulsar.proto.BaseCommand.type)
  return static_cast< ::pulsar::proto::BaseCommand_Type >(type_);
}
inline void BaseCommand::set_type(::pulsar::proto::BaseCommand_Type value) {
  assert(::pulsar::proto::BaseCommand_Type_IsValid(value));
  set_has_type();
  type_ = value;
  // @@protoc_insertion_point(field_set:pulsar.proto.BaseCommand.type)
}

// optional .pulsar.proto.CommandConnect connect = 2;
inline bool BaseCommand::has_connect() const {
  return (_has_bits_[0] & 0x00000002u) != 0;
}
inline void BaseCommand::set_has_connect() {
  _has_bits_[0] |= 0x00000002u;
}
inline void BaseCommand::clear_has_connect() {
  _has_bits_[0] &= ~0x00000002u;
}
inline void BaseCommand::clear_connect() {
  if (connect_ != NULL) connect_->::pulsar::proto::CommandConnect::Clear();
  clear_has_connect();
}
inline const ::pulsar::proto::CommandConnect& BaseCommand::connect() const {
  // @@protoc_insertion_point(field_get:pulsar.proto.BaseCommand.connect)
#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
  return connect_ != NULL ? *connect_ : *default_instance().connect_;
#else
  return connect_ != NULL ? *connect_ : *default_instance_->connect_;
#endif
}
inline ::pulsar::proto::CommandConnect* BaseCommand::mutable_connect() {
  set_has_connect();
  if (connect_ == NULL) connect_ = new ::pulsar::proto::CommandConnect;
  // @@protoc_insertion_point(field_mutable:pulsar.proto.BaseCommand.connect)
  return connect_;
}
inline ::pulsar::proto::CommandConnect* BaseCommand::release_connect() {
  clear_has_connect();
  ::pulsar::proto::CommandConnect* temp = connect_;
  connect_ = NULL;
  return temp;
}
inline void BaseCommand::set_allocated_connect(::pulsar::proto::CommandConnect* connect) {
  delete connect_;
  connect_ = connect;
  if (connect) {
    set_has_connect();
  } else {
    clear_has_connect();
  }
  // @@protoc_insertion_point(field_set_allocated:pulsar.proto.BaseCommand.connect)
}

// optional .pulsar.proto.CommandConnected connected = 3;
inline bool BaseCommand::has_connected() const {
  return (_has_bits_[0] & 0x00000004u) != 0;
}
inline void BaseCommand::set_has_connected() {
  _has_bits_[0] |= 0x00000004u;
}
inline void BaseCommand::clear_has_connected() {
  _has_bits_[0] &= ~0x00000004u;
}
inline void BaseCommand::clear_connected() {
  if (connected_ != NULL) connected_->::pulsar::proto::CommandConnected::Clear();
  clear_has_connected();
}
inline const ::pulsar::proto::CommandConnected& BaseCommand::connected() const {
  // @@protoc_insertion_point(field_get:pulsar.proto.BaseCommand.connected)
#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
  return connected_ != NULL ? *connected_ : *default_instance().connected_;
#else
  return connected_ != NULL ? *connected_ : *default_instance_->connected_;
#endif
}
inline ::pulsar::proto::CommandConnected* BaseCommand::mutable_connected() {
  set_has_connected();
  if (connected_ == NULL) connected_ = new ::pulsar::proto::CommandConnected;
  // @@protoc_insertion_point(field_mutable:pulsar.proto.BaseCommand.connected)
  return connected_;
}
inline ::pulsar::proto::CommandConnected* BaseCommand::release_connected() {
  clear_has_connected();
  ::pulsar::proto::CommandConnected* temp = connected_;
  connected_ = NULL;
  return temp;
}
inline void BaseCommand::set_allocated_connected(::pulsar::proto::CommandConnected* connected) {
  delete connected_;
  connected_ = connected;
  if (connected) {
    set_has_connected();
  } else {
    clear_has_connected();
  }
  // @@protoc_insertion_point(field_set_allocated:pulsar.proto.BaseCommand.connected)
}

// optional .pulsar.proto.CommandSubscribe subscribe = 4;
inline bool BaseCommand::has_subscribe() const {
  return (_has_bits_[0] & 0x00000008u) != 0;
}
inline void BaseCommand::set_has_subscribe() {
  _has_bits_[0] |= 0x00000008u;
}
inline void BaseCommand::clear_has_subscribe() {
  _has_bits_[0] &= ~0x00000008u;
}
inline void BaseCommand::clear_subscribe() {
  if (subscribe_ != NULL) subscribe_->::pulsar::proto::CommandSubscribe::Clear();
  clear_has_subscribe();
}
inline const ::pulsar::proto::CommandSubscribe& BaseCommand::subscribe() const {
  // @@protoc_insertion_point(field_get:pulsar.proto.BaseCommand.subscribe)
#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
  return subscribe_ != NULL ? *subscribe_ : *default_instance().subscribe_;
#else
  return subscribe_ != NULL ? *subscribe_ : *default_instance_->subscribe_;
#endif
}
inline ::pulsar::proto::CommandSubscribe* BaseCommand::mutable_subscribe() {
  set_has_subscribe();
  if (subscribe_ == NULL) subscribe_ = new ::pulsar::proto::CommandSubscribe;
  // @@protoc_insertion_point(field_mutable:pulsar.proto.BaseCommand.subscribe)
  return subscribe_;
}
inline ::pulsar::proto::CommandSubscribe* BaseCommand::release_subscribe() {
  clear_has_subscribe();
  ::pulsar::proto::CommandSubscribe* temp = subscribe_;
  subscribe_ = NULL;
  return temp;
}
inline void BaseCommand::set_allocated_subscribe(::pulsar::proto::CommandSubscribe* subscribe) {
  delete subscribe_;
  subscribe_ = subscribe;
  if (subscribe) {
    set_has_subscribe();
  } else {
    clear_has_subscribe();
  }
  // @@protoc_insertion_point(field_set_allocated:pulsar.proto.BaseCommand.subscribe)
}

// optional .pulsar.proto.CommandProducer producer = 5;
inline bool BaseCommand::has_producer() const {
  return (_has_bits_[0] & 0x00000010u) != 0;
}
inline void BaseCommand::set_has_producer() {
  _has_bits_[0] |= 0x00000010u;
}
inline void BaseCommand::clear_has_producer() {
  _has_bits_[0] &= ~0x00000010u;
}
inline void BaseCommand::clear_producer() {
  if (producer_ != NULL) producer_->::pulsar::proto::CommandProducer::Clear();
  clear_has_producer();
}
inline const ::pulsar::proto::CommandProducer& BaseCommand::producer() const {
  // @@protoc_insertion_point(field_get:pulsar.proto.BaseCommand.producer)
#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
  return producer_ != NULL ? *producer_ : *default_instance().producer_;
#else
  return producer_ != NULL ? *producer_ : *default_instance_->producer_;
#endif
}
inline ::pulsar::proto::CommandProducer* BaseCommand::mutable_producer() {
  set_has_producer();
  if (producer_ == NULL) producer_ = new ::pulsar::proto::CommandProducer;
  // @@protoc_insertion_point(field_mutable:pulsar.proto.BaseCommand.producer)
  return producer_;
}
inline ::pulsar::proto::CommandProducer* BaseCommand::release_producer() {
  clear_has_producer();
  ::pulsar::proto::CommandProducer* temp = producer_;
  producer_ = NULL;
  return temp;
}
inline void BaseCommand::set_allocated_producer(::pulsar::proto::CommandProducer* producer) {
  delete producer_;
  producer_ = producer;
  if (producer) {
    set_has_producer();
  } else {
    clear_has_producer();
  }
  // @@protoc_insertion_point(field_set_allocated:pulsar.proto.BaseCommand.producer)
}

// optional .pulsar.proto.CommandSend send = 6;
inline bool BaseCommand::has_send() const {
  return (_has_bits_[0] & 0x00000020u) != 0;
}
inline void BaseCommand::set_has_send() {
  _has_bits_[0] |= 0x00000020u;
}
inline void BaseCommand::clear_has_send() {
  _has_bits_[0] &= ~0x00000020u;
}
inline void BaseCommand::clear_send() {
  if (send_ != NULL) send_->::pulsar::proto::CommandSend::Clear();
  clear_has_send();
}
inline const ::pulsar::proto::CommandSend& BaseCommand::send() const {
  // @@protoc_insertion_point(field_get:pulsar.proto.BaseCommand.send)
#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
  return send_ != NULL ? *send_ : *default_instance().send_;
#else
  return send_ != NULL ? *send_ : *default_instance_->send_;
#endif
}
inline ::pulsar::proto::CommandSend* BaseCommand::mutable_send() {
  set_has_send();
  if (send_ == NULL) send_ = new ::pulsar::proto::CommandSend;
  // @@protoc_insertion_point(field_mutable:pulsar.proto.BaseCommand.send)
  return send_;
}
inline ::pulsar::proto::CommandSend* BaseCommand::release_send() {
  clear_has_send();
  ::pulsar::proto::CommandSend* temp = send_;
  send_ = NULL;
  return temp;
}
inline void BaseCommand::set_allocated_send(::pulsar::proto::CommandSend* send) {
  delete send_;
  send_ = send;
  if (send) {
    set_has_send();
  } else {
    clear_has_send();
  }
  // @@protoc_insertion_point(field_set_allocated:pulsar.proto.BaseCommand.send)
}

// optional .pulsar.proto.CommandSendReceipt send_receipt = 7;
inline bool BaseCommand::has_send_receipt() const {
  return (_has_bits_[0] & 0x00000040u) != 0;
}
inline void BaseCommand::set_has_send_receipt() {
  _has_bits_[0] |= 0x00000040u;
}
inline void BaseCommand::clear_has_send_receipt() {
  _has_bits_[0] &= ~0x00000040u;
}
inline void BaseCommand::clear_send_receipt() {
  if (send_receipt_ != NULL) send_receipt_->::pulsar::proto::CommandSendReceipt::Clear();
  clear_has_send_receipt();
}
inline const ::pulsar::proto::CommandSendReceipt& BaseCommand::send_receipt() const {
  // @@protoc_insertion_point(field_get:pulsar.proto.BaseCommand.send_receipt)
#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
  return send_receipt_ != NULL ? *send_receipt_ : *default_instance().send_receipt_;
#else
  return send_receipt_ != NULL ? *send_receipt_ : *default_instance_->send_receipt_;
#endif
}
inline ::pulsar::proto::CommandSendReceipt* BaseCommand::mutable_send_receipt() {
  set_has_send_receipt();
  if (send_receipt_ == NULL) send_receipt_ = new ::pulsar::proto::CommandSendReceipt;
  // @@protoc_insertion_point(field_mutable:pulsar.proto.BaseCommand.send_receipt)
  return send_receipt_;
}
inline ::pulsar::proto::CommandSendReceipt* BaseCommand::release_send_receipt() {
  clear_has_send_receipt();
  ::pulsar::proto::CommandSendReceipt* temp = send_receipt_;
  send_receipt_ = NULL;
  return temp;
}
inline void BaseCommand::set_allocated_send_receipt(::pulsar::proto::CommandSendReceipt* send_receipt) {
  delete send_receipt_;
  send_receipt_ = send_receipt;
  if (send_receipt) {
    set_has_send_receipt();
  } else {
    clear_has_send_receipt();
  }
  // @@protoc_insertion_point(field_set_allocated:pulsar.proto.BaseCommand.send_receipt)
}

// optional .pulsar.proto.CommandSendError send_error = 8;
inline bool BaseCommand::has_send_error() const {
  return (_has_bits_[0] & 0x00000080u) != 0;
}
inline void BaseCommand::set_has_send_error() {
  _has_bits_[0] |= 0x00000080u;
}
inline void BaseCommand::clear_has_send_error() {
  _has_bits_[0] &= ~0x00000080u;
}
inline void BaseCommand::clear_send_error() {
  if (send_error_ != NULL) send_error_->::pulsar::proto::CommandSendError::Clear();
  clear_has_send_error();
}
inline const ::pulsar::proto::CommandSendError& BaseCommand::send_error() const {
  // @@protoc_insertion_point(field_get:pulsar.proto.BaseCommand.send_error)
#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
  return send_error_ != NULL ? *send_error_ : *default_instance().send_error_;
#else
  return send_error_ != NULL ? *send_error_ : *default_instance_->send_error_;
#endif
}
inline ::pulsar::proto::CommandSendError* BaseCommand::mutable_send_error() {
  set_has_send_error();
  if (send_error_ == NULL) send_error_ = new ::pulsar::proto::CommandSendError;
  // @@protoc_insertion_point(field_mutable:pulsar.proto.BaseCommand.send_error)
  return send_error_;
}
inline ::pulsar::proto::CommandSendError* BaseCommand::release_send_error() {
  clear_has_send_error();
  ::pulsar::proto::CommandSendError* temp = send_error_;
  send_error_ = NULL;
  return temp;
}
inline void BaseCommand::set_allocated_send_error(::pulsar::proto::CommandSendError* send_error) {
  delete send_error_;
  send_error_ = send_error;
  if (send_error) {
    set_has_send_error();
  } else {
    clear_has_send_error();
  }
  // @@protoc_insertion_point(field_set_allocated:pulsar.proto.BaseCommand.send_error)
}

// optional .pulsar.proto.CommandMessage message = 9;
inline bool BaseCommand::has_message() const {
  return (_has_bits_[0] & 0x00000100u) != 0;
}
inline void BaseCommand::set_has_message() {
  _has_bits_[0] |= 0x00000100u;
}
inline void BaseCommand::clear_has_message() {
  _has_bits_[0] &= ~0x00000100u;
}
inline void BaseCommand::clear_message() {
  if (message_ != NULL) message_->::pulsar::proto::CommandMessage::Clear();
  clear_has_message();
}
inline const ::pulsar::proto::CommandMessage& BaseCommand::message() const {
  // @@protoc_insertion_point(field_get:pulsar.proto.BaseCommand.message)
#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
  return message_ != NULL ? *message_ : *default_instance().message_;
#else
  return message_ != NULL ? *message_ : *default_instance_->message_;
#endif
}
inline ::pulsar::proto::CommandMessage* BaseCommand::mutable_message() {
  set_has_message();
  if (message_ == NULL) message_ = new ::pulsar::proto::CommandMessage;
  // @@protoc_insertion_point(field_mutable:pulsar.proto.BaseCommand.message)
  return message_;
}
inline ::pulsar::proto::CommandMessage* BaseCommand::release_message() {
  clear_has_message();
  ::pulsar::proto::CommandMessage* temp = message_;
  message_ = NULL;
  return temp;
}
inline void BaseCommand::set_allocated_message(::pulsar::proto::CommandMessage* message) {
  delete message_;
  message_ = message;
  if (message) {
    set_has_message();
  } else {
    clear_has_message();
  }
  // @@protoc_insertion_point(field_set_allocated:pulsar.proto.BaseCommand.message)
}

// optional .pulsar.proto.CommandAck ack = 10;
inline bool BaseCommand::has_ack() const {
  return (_has_bits_[0] & 0x00000200u) != 0;
}
inline void BaseCommand::set_has_ack() {
  _has_bits_[0] |= 0x00000200u;
}
inline void BaseCommand::clear_has_ack() {
  _has_bits_[0] &= ~0x00000200u;
}
inline void BaseCommand::clear_ack() {
  if (ack_ != NULL) ack_->::pulsar::proto::CommandAck::Clear();
  clear_has_ack();
}
inline const ::pulsar::proto::CommandAck& BaseCommand::ack() const {
  // @@protoc_insertion_point(field_get:pulsar.proto.BaseCommand.ack)
#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
  return ack_ != NULL ? *ack_ : *default_instance().ack_;
#else
  return ack_ != NULL ? *ack_ : *default_instance_->ack_;
#endif
}
inline ::pulsar::proto::CommandAck* BaseCommand::mutable_ack() {
  set_has_ack();
  if (ack_ == NULL) ack_ = new ::pulsar::proto::CommandAck;
  // @@protoc_insertion_point(field_mutable:pulsar.proto.BaseCommand.ack)
  return ack_;
}
inline ::pulsar::proto::CommandAck* BaseCommand::release_ack() {
  clear_has_ack();
  ::pulsar::proto::CommandAck* temp = ack_;
  ack_ = NULL;
  return temp;
}
inline void BaseCommand::set_allocated_ack(::pulsar::proto::CommandAck* ack) {
  delete ack_;
  ack_ = ack;
  if (ack) {
    set_has_ack();
  } else {
    clear_has_ack();
  }
  // @@protoc_insertion_point(field_set_allocated:pulsar.proto.BaseCommand.ack)
}

// optional .pulsar.proto.CommandFlow flow = 11;
inline bool BaseCommand::has_flow() const {
  return (_has_bits_[0] & 0x00000400u) != 0;
}
inline void BaseCommand::set_has_flow() {
  _has_bits_[0] |= 0x00000400u;
}
inline void BaseCommand::clear_has_flow() {
  _has_bits_[0] &= ~0x00000400u;
}
inline void BaseCommand::clear_flow() {
  if (flow_ != NULL) flow_->::pulsar::proto::CommandFlow::Clear();
  clear_has_flow();
}
inline const ::pulsar::proto::CommandFlow& BaseCommand::flow() const {
  // @@protoc_insertion_point(field_get:pulsar.proto.BaseCommand.flow)
#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
  return flow_ != NULL ? *flow_ : *default_instance().flow_;
#else
  return flow_ != NULL ? *flow_ : *default_instance_->flow_;
#endif
}
inline ::pulsar::proto::CommandFlow* BaseCommand::mutable_flow() {
  set_has_flow();
  if (flow_ == NULL) flow_ = new ::pulsar::proto::CommandFlow;
  // @@protoc_insertion_point(field_mutable:pulsar.proto.BaseCommand.flow)
  return flow_;
}
inline ::pulsar::proto::CommandFlow* BaseCommand::release_flow() {
  clear_has_flow();
  ::pulsar::proto::CommandFlow* temp = flow_;
  flow_ = NULL;
  return temp;
}
inline void BaseCommand::set_allocated_flow(::pulsar::proto::CommandFlow* flow) {
  delete flow_;
  flow_ = flow;
  if (flow) {
    set_has_flow();
  } else {
    clear_has_flow();
  }
  // @@protoc_insertion_point(field_set_allocated:pulsar.proto.BaseCommand.flow)
}

// optional .pulsar.proto.CommandUnsubscribe unsubscribe = 12;
inline bool BaseCommand::has_unsubscribe() const {
  return (_has_bits_[0] & 0x00000800u) != 0;
}
inline void BaseCommand::set_has_unsubscribe() {
  _has_bits_[0] |= 0x00000800u;
}
inline void BaseCommand::clear_has_unsubscribe() {
  _has_bits_[0] &= ~0x00000800u;
}
inline void BaseCommand::clear_unsubscribe() {
  if (unsubscribe_ != NULL) unsubscribe_->::pulsar::proto::CommandUnsubscribe::Clear();
  clear_has_unsubscribe();
}
inline const ::pulsar::proto::CommandUnsubscribe& BaseCommand::unsubscribe() const {
  // @@protoc_insertion_point(field_get:pulsar.proto.BaseCommand.unsubscribe)
#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
  return unsubscribe_ != NULL ? *unsubscribe_ : *default_instance().unsubscribe_;
#else
  return unsubscribe_ != NULL ? *unsubscribe_ : *default_instance_->unsubscribe_;
#endif
}
inline ::pulsar::proto::CommandUnsubscribe* BaseCommand::mutable_unsubscribe() {
  set_has_unsubscribe();
  if (unsubscribe_ == NULL) unsubscribe_ = new ::pulsar::proto::CommandUnsubscribe;
  // @@protoc_insertion_point(field_mutable:pulsar.proto.BaseCommand.unsubscribe)
  return unsubscribe_;
}
inline ::pulsar::proto::CommandUnsubscribe* BaseCommand::release_unsubscribe() {
  clear_has_unsubscribe();
  ::pulsar::proto::CommandUnsubscribe* temp = unsubscribe_;
  unsubscribe_ = NULL;
  return temp;
}
inline void BaseCommand::set_allocated_unsubscribe(::pulsar::proto::CommandUnsubscribe* unsubscribe) {
  delete unsubscribe_;
  unsubscribe_ = unsubscribe;
  if (unsubscribe) {
    set_has_unsubscribe();
  } else {
    clear_has_unsubscribe();
  }
  // @@protoc_insertion_point(field_set_allocated:pulsar.proto.BaseCommand.unsubscribe)
}

// optional .pulsar.proto.CommandSuccess success = 13;
inline bool BaseCommand::has_success() const {
  return (_has_bits_[0] & 0x00001000u) != 0;
}
inline void BaseCommand::set_has_success() {
  _has_bits_[0] |= 0x00001000u;
}
inline void BaseCommand::clear_has_success() {
  _has_bits_[0] &= ~0x00001000u;
}
inline void BaseCommand::clear_success() {
  if (success_ != NULL) success_->::pulsar::proto::CommandSuccess::Clear();
  clear_has_success();
}
inline const ::pulsar::proto::CommandSuccess& BaseCommand::success() const {
  // @@protoc_insertion_point(field_get:pulsar.proto.BaseCommand.success)
#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
  return success_ != NULL ? *success_ : *default_instance().success_;
#else
  return success_ != NULL ? *success_ : *default_instance_->success_;
#endif
}
inline ::pulsar::proto::CommandSuccess* BaseCommand::mutable_success() {
  set_has_success();
  if (success_ == NULL) success_ = new ::pulsar::proto::CommandSuccess;
  // @@protoc_insertion_point(field_mutable:pulsar.proto.BaseCommand.success)
  return success_;
}
inline ::pulsar::proto::CommandSuccess* BaseCommand::release_success() {
  clear_has_success();
  ::pulsar::proto::CommandSuccess* temp = success_;
  success_ = NULL;
  return temp;
}
inline void BaseCommand::set_allocated_success(::pulsar::proto::CommandSuccess* success) {
  delete success_;
  success_ = success;
  if (success) {
    set_has_success();
  } else {
    clear_has_success();
  }
  // @@protoc_insertion_point(field_set_allocated:pulsar.proto.BaseCommand.success)
}

// optional .pulsar.proto.CommandError error = 14;
inline bool BaseCommand::has_error() const {
  return (_has_bits_[0] & 0x00002000u) != 0;
}
inline void BaseCommand::set_has_error() {
  _has_bits_[0] |= 0x00002000u;
}
inline void BaseCommand::clear_has_error() {
  _has_bits_[0] &= ~0x00002000u;
}
inline void BaseCommand::clear_error() {
  if (error_ != NULL) error_->::pulsar::proto::CommandError::Clear();
  clear_has_error();
}
inline const ::pulsar::proto::CommandError& BaseCommand::error() const {
  // @@protoc_insertion_point(field_get:pulsar.proto.BaseCommand.error)
#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
  return error_ != NULL ? *error_ : *default_instance().error_;
#else
  return error_ != NULL ? *error_ : *default_instance_->error_;
#endif
}
inline ::pulsar::proto::CommandError* BaseCommand::mutable_error() {
  set_has_error();
  if (error_ == NULL) error_ = new ::pulsar::proto::CommandError;
  // @@protoc_insertion_point(field_mutable:pulsar.proto.BaseCommand.error)
  return error_;
}
inline ::pulsar::proto::CommandError* BaseCommand::release_error() {
  clear_has_error();
  ::pulsar::proto::CommandError* temp = error_;
  error_ = NULL;
  return temp;
}
inline void BaseCommand::set_allocated_error(::pulsar::proto::CommandError* error) {
  delete error_;
  error_ = error;
  if (error) {
    set_has_error();
  } else {
    clear_has_error();
  }
  // @@protoc_insertion_point(field_set_allocated:pulsar.proto.BaseCommand.error)
}

// optional .pulsar.proto.CommandCloseProducer close_producer = 15;
inline bool BaseCommand::has_close_producer() const {
  return (_has_bits_[0] & 0x00004000u) != 0;
}
inline void BaseCommand::set_has_close_producer() {
  _has_bits_[0] |= 0x00004000u;
}
inline void BaseCommand::clear_has_close_producer() {
  _has_bits_[0] &= ~0x00004000u;
}
inline void BaseCommand::clear_close_producer() {
  if (close_producer_ != NULL) close_producer_->::pulsar::proto::CommandCloseProducer::Clear();
  clear_has_close_producer();
}
inline const ::pulsar::proto::CommandCloseProducer& BaseCommand::close_producer() const {
  // @@protoc_insertion_point(field_get:pulsar.proto.BaseCommand.close_producer)
#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
  return close_producer_ != NULL ? *close_producer_ : *default_instance().close_producer_;
#else
  return close_producer_ != NULL ? *close_producer_ : *default_instance_->close_producer_;
#endif
}
inline ::pulsar::proto::CommandCloseProducer* BaseCommand::mutable_close_producer() {
  set_has_close_producer();
  if (close_producer_ == NULL) close_producer_ = new ::pulsar::proto::CommandCloseProducer;
  // @@protoc_insertion_point(field_mutable:pulsar.proto.BaseCommand.close_producer)
  return close_producer_;
}
inline ::pulsar::proto::CommandCloseProducer* BaseCommand::release_close_producer() {
  clear_has_close_producer();
  ::pulsar::proto::CommandCloseProducer* temp = close_producer_;
  close_producer_ = NULL;
  return temp;
}
inline void BaseCommand::set_allocated_close_producer(::pulsar::proto::CommandCloseProducer* close_producer) {
  delete close_producer_;
  close_producer_ = close_producer;
  if (close_producer) {
    set_has_close_producer();
  } else {
    clear_has_close_producer();
  }
  // @@protoc_insertion_point(field_set_allocated:pulsar.proto.BaseCommand.close_producer)
}

// optional .pulsar.proto.CommandCloseConsumer close_consumer = 16;
inline bool BaseCommand::has_close_consumer() const {
  return (_has_bits_[0] & 0x00008000u) != 0;
}
inline void BaseCommand::set_has_close_consumer() {
  _has_bits_[0] |= 0x00008000u;
}
inline void BaseCommand::clear_has_close_consumer() {
  _has_bits_[0] &= ~0x00008000u;
}
inline void BaseCommand::clear_close_consumer() {
  if (close_consumer_ != NULL) close_consumer_->::pulsar::proto::CommandCloseConsumer::Clear();
  clear_has_close_consumer();
}
inline const ::pulsar::proto::CommandCloseConsumer& BaseCommand::close_consumer() const {
  // @@protoc_insertion_point(field_get:pulsar.proto.BaseCommand.close_consumer)
#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
  return close_consumer_ != NULL ? *close_consumer_ : *default_instance().close_consumer_;
#else
  return close_consumer_ != NULL ? *close_consumer_ : *default_instance_->close_consumer_;
#endif
}
inline ::pulsar::proto::CommandCloseConsumer* BaseCommand::mutable_close_consumer() {
  set_has_close_consumer();
  if (close_consumer_ == NULL) close_consumer_ = new ::pulsar::proto::CommandCloseConsumer;
  // @@protoc_insertion_point(field_mutable:pulsar.proto.BaseCommand.close_consumer)
  return close_consumer_;
}
inline ::pulsar::proto::CommandCloseConsumer* BaseCommand::release_close_consumer() {
  clear_has_close_consumer();
  ::pulsar::proto::CommandCloseConsumer* temp = close_consumer_;
  close_consumer_ = NULL;
  return temp;
}
inline void BaseCommand::set_allocated_close_consumer(::pulsar::proto::CommandCloseConsumer* close_consumer) {
  delete close_consumer_;
  close_consumer_ = close_consumer;
  if (close_consumer) {
    set_has_close_consumer();
  } else {
    clear_has_close_consumer();
  }
  // @@protoc_insertion_point(field_set_allocated:pulsar.proto.BaseCommand.close_consumer)
}

// optional .pulsar.proto.CommandProducerSuccess producer_success = 17;
inline bool BaseCommand::has_producer_success() const {
  return (_has_bits_[0] & 0x00010000u) != 0;
}
inline void BaseCommand::set_has_producer_success() {
  _has_bits_[0] |= 0x00010000u;
}
inline void BaseCommand::clear_has_producer_success() {
  _has_bits_[0] &= ~0x00010000u;
}
inline void BaseCommand::clear_producer_success() {
  if (producer_success_ != NULL) producer_success_->::pulsar::proto::CommandProducerSuccess::Clear();
  clear_has_producer_success();
}
inline const ::pulsar::proto::CommandProducerSuccess& BaseCommand::producer_success() const {
  // @@protoc_insertion_point(field_get:pulsar.proto.BaseCommand.producer_success)
#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
  return producer_success_ != NULL ? *producer_success_ : *default_instance().producer_success_;
#else
  return producer_success_ != NULL ? *producer_success_ : *default_instance_->producer_success_;
#endif
}
inline ::pulsar::proto::CommandProducerSuccess* BaseCommand::mutable_producer_success() {
  set_has_producer_success();
  if (producer_success_ == NULL) producer_success_ = new ::pulsar::proto::CommandProducerSuccess;
  // @@protoc_insertion_point(field_mutable:pulsar.proto.BaseCommand.producer_success)
  return producer_success_;
}
inline ::pulsar::proto::CommandProducerSuccess* BaseCommand::release_producer_success() {
  clear_has_producer_success();
  ::pulsar::proto::CommandProducerSuccess* temp = producer_success_;
  producer_success_ = NULL;
  return temp;
}
inline void BaseCommand::set_allocated_producer_success(::pulsar::proto::CommandProducerSuccess* producer_success) {
  delete producer_success_;
  producer_success_ = producer_success;
  if (producer_success) {
    set_has_producer_success();
  } else {
    clear_has_producer_success();
  }
  // @@protoc_insertion_point(field_set_allocated:pulsar.proto.BaseCommand.producer_success)
}

// optional .pulsar.proto.CommandPing ping = 18;
inline bool BaseCommand::has_ping() const {
  return (_has_bits_[0] & 0x00020000u) != 0;
}
inline void BaseCommand::set_has_ping() {
  _has_bits_[0] |= 0x00020000u;
}
inline void BaseCommand::clear_has_ping() {
  _has_bits_[0] &= ~0x00020000u;
}
inline void BaseCommand::clear_ping() {
  if (ping_ != NULL) ping_->::pulsar::proto::CommandPing::Clear();
  clear_has_ping();
}
inline const ::pulsar::proto::CommandPing& BaseCommand::ping() const {
  // @@protoc_insertion_point(field_get:pulsar.proto.BaseCommand.ping)
#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
  return ping_ != NULL ? *ping_ : *default_instance().ping_;
#else
  return ping_ != NULL ? *ping_ : *default_instance_->ping_;
#endif
}
inline ::pulsar::proto::CommandPing* BaseCommand::mutable_ping() {
  set_has_ping();
  if (ping_ == NULL) ping_ = new ::pulsar::proto::CommandPing;
  // @@protoc_insertion_point(field_mutable:pulsar.proto.BaseCommand.ping)
  return ping_;
}
inline ::pulsar::proto::CommandPing* BaseCommand::release_ping() {
  clear_has_ping();
  ::pulsar::proto::CommandPing* temp = ping_;
  ping_ = NULL;
  return temp;
}
inline void BaseCommand::set_allocated_ping(::pulsar::proto::CommandPing* ping) {
  delete ping_;
  ping_ = ping;
  if (ping) {
    set_has_ping();
  } else {
    clear_has_ping();
  }
  // @@protoc_insertion_point(field_set_allocated:pulsar.proto.BaseCommand.ping)
}

// optional .pulsar.proto.CommandPong pong = 19;
inline bool BaseCommand::has_pong() const {
  return (_has_bits_[0] & 0x00040000u) != 0;
}
inline void BaseCommand::set_has_pong() {
  _has_bits_[0] |= 0x00040000u;
}
inline void BaseCommand::clear_has_pong() {
  _has_bits_[0] &= ~0x00040000u;
}
inline void BaseCommand::clear_pong() {
  if (pong_ != NULL) pong_->::pulsar::proto::CommandPong::Clear();
  clear_has_pong();
}
inline const ::pulsar::proto::CommandPong& BaseCommand::pong() const {
  // @@protoc_insertion_point(field_get:pulsar.proto.BaseCommand.pong)
#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
  return pong_ != NULL ? *pong_ : *default_instance().pong_;
#else
  return pong_ != NULL ? *pong_ : *default_instance_->pong_;
#endif
}
inline ::pulsar::proto::CommandPong* BaseCommand::mutable_pong() {
  set_has_pong();
  if (pong_ == NULL) pong_ = new ::pulsar::proto::CommandPong;
  // @@protoc_insertion_point(field_mutable:pulsar.proto.BaseCommand.pong)
  return pong_;
}
inline ::pulsar::proto::CommandPong* BaseCommand::release_pong() {
  clear_has_pong();
  ::pulsar::proto::CommandPong* temp = pong_;
  pong_ = NULL;
  return temp;
}
inline void BaseCommand::set_allocated_pong(::pulsar::proto::CommandPong* pong) {
  delete pong_;
  pong_ = pong;
  if (pong) {
    set_has_pong();
  } else {
    clear_has_pong();
  }
  // @@protoc_insertion_point(field_set_allocated:pulsar.proto.BaseCommand.pong)
}

// optional .pulsar.proto.CommandRedeliverUnacknowledgedMessages redeliverUnacknowledgedMessages = 20;
inline bool BaseCommand::has_redeliverunacknowledgedmessages() const {
  return (_has_bits_[0] & 0x00080000u) != 0;
}
inline void BaseCommand::set_has_redeliverunacknowledgedmessages() {
  _has_bits_[0] |= 0x00080000u;
}
inline void BaseCommand::clear_has_redeliverunacknowledgedmessages() {
  _has_bits_[0] &= ~0x00080000u;
}
inline void BaseCommand::clear_redeliverunacknowledgedmessages() {
  if (redeliverunacknowledgedmessages_ != NULL) redeliverunacknowledgedmessages_->::pulsar::proto::CommandRedeliverUnacknowledgedMessages::Clear();
  clear_has_redeliverunacknowledgedmessages();
}
inline const ::pulsar::proto::CommandRedeliverUnacknowledgedMessages& BaseCommand::redeliverunacknowledgedmessages() const {
  // @@protoc_insertion_point(field_get:pulsar.proto.BaseCommand.redeliverUnacknowledgedMessages)
#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
  return redeliverunacknowledgedmessages_ != NULL ? *redeliverunacknowledgedmessages_ : *default_instance().redeliverunacknowledgedmessages_;
#else
  return redeliverunacknowledgedmessages_ != NULL ? *redeliverunacknowledgedmessages_ : *default_instance_->redeliverunacknowledgedmessages_;
#endif
}
inline ::pulsar::proto::CommandRedeliverUnacknowledgedMessages* BaseCommand::mutable_redeliverunacknowledgedmessages() {
  set_has_redeliverunacknowledgedmessages();
  if (redeliverunacknowledgedmessages_ == NULL) redeliverunacknowledgedmessages_ = new ::pulsar::proto::CommandRedeliverUnacknowledgedMessages;
  // @@protoc_insertion_point(field_mutable:pulsar.proto.BaseCommand.redeliverUnacknowledgedMessages)
  return redeliverunacknowledgedmessages_;
}
inline ::pulsar::proto::CommandRedeliverUnacknowledgedMessages* BaseCommand::release_redeliverunacknowledgedmessages() {
  clear_has_redeliverunacknowledgedmessages();
  ::pulsar::proto::CommandRedeliverUnacknowledgedMessages* temp = redeliverunacknowledgedmessages_;
  redeliverunacknowledgedmessages_ = NULL;
  return temp;
}
inline void BaseCommand::set_allocated_redeliverunacknowledgedmessages(::pulsar::proto::CommandRedeliverUnacknowledgedMessages* redeliverunacknowledgedmessages) {
  delete redeliverunacknowledgedmessages_;
  redeliverunacknowledgedmessages_ = redeliverunacknowledgedmessages;
  if (redeliverunacknowledgedmessages) {
    set_has_redeliverunacknowledgedmessages();
  } else {
    clear_has_redeliverunacknowledgedmessages();
  }
  // @@protoc_insertion_point(field_set_allocated:pulsar.proto.BaseCommand.redeliverUnacknowledgedMessages)
}

// optional .pulsar.proto.CommandPartitionedTopicMetadata partitionMetadata = 21;
inline bool BaseCommand::has_partitionmetadata() const {
  return (_has_bits_[0] & 0x00100000u) != 0;
}
inline void BaseCommand::set_has_partitionmetadata() {
  _has_bits_[0] |= 0x00100000u;
}
inline void BaseCommand::clear_has_partitionmetadata() {
  _has_bits_[0] &= ~0x00100000u;
}
inline void BaseCommand::clear_partitionmetadata() {
  if (partitionmetadata_ != NULL) partitionmetadata_->::pulsar::proto::CommandPartitionedTopicMetadata::Clear();
  clear_has_partitionmetadata();
}
inline const ::pulsar::proto::CommandPartitionedTopicMetadata& BaseCommand::partitionmetadata() const {
  // @@protoc_insertion_point(field_get:pulsar.proto.BaseCommand.partitionMetadata)
#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
  return partitionmetadata_ != NULL ? *partitionmetadata_ : *default_instance().partitionmetadata_;
#else
  return partitionmetadata_ != NULL ? *partitionmetadata_ : *default_instance_->partitionmetadata_;
#endif
}
inline ::pulsar::proto::CommandPartitionedTopicMetadata* BaseCommand::mutable_partitionmetadata() {
  set_has_partitionmetadata();
  if (partitionmetadata_ == NULL) partitionmetadata_ = new ::pulsar::proto::CommandPartitionedTopicMetadata;
  // @@protoc_insertion_point(field_mutable:pulsar.proto.BaseCommand.partitionMetadata)
  return partitionmetadata_;
}
inline ::pulsar::proto::CommandPartitionedTopicMetadata* BaseCommand::release_partitionmetadata() {
  clear_has_partitionmetadata();
  ::pulsar::proto::CommandPartitionedTopicMetadata* temp = partitionmetadata_;
  partitionmetadata_ = NULL;
  return temp;
}
inline void BaseCommand::set_allocated_partitionmetadata(::pulsar::proto::CommandPartitionedTopicMetadata* partitionmetadata) {
  delete partitionmetadata_;
  partitionmetadata_ = partitionmetadata;
  if (partitionmetadata) {
    set_has_partitionmetadata();
  } else {
    clear_has_partitionmetadata();
  }
  // @@protoc_insertion_point(field_set_allocated:pulsar.proto.BaseCommand.partitionMetadata)
}

// optional .pulsar.proto.CommandPartitionedTopicMetadataResponse partitionMetadataResponse = 22;
inline bool BaseCommand::has_partitionmetadataresponse() const {
  return (_has_bits_[0] & 0x00200000u) != 0;
}
inline void BaseCommand::set_has_partitionmetadataresponse() {
  _has_bits_[0] |= 0x00200000u;
}
inline void BaseCommand::clear_has_partitionmetadataresponse() {
  _has_bits_[0] &= ~0x00200000u;
}
inline void BaseCommand::clear_partitionmetadataresponse() {
  if (partitionmetadataresponse_ != NULL) partitionmetadataresponse_->::pulsar::proto::CommandPartitionedTopicMetadataResponse::Clear();
  clear_has_partitionmetadataresponse();
}
inline const ::pulsar::proto::CommandPartitionedTopicMetadataResponse& BaseCommand::partitionmetadataresponse() const {
  // @@protoc_insertion_point(field_get:pulsar.proto.BaseCommand.partitionMetadataResponse)
#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
  return partitionmetadataresponse_ != NULL ? *partitionmetadataresponse_ : *default_instance().partitionmetadataresponse_;
#else
  return partitionmetadataresponse_ != NULL ? *partitionmetadataresponse_ : *default_instance_->partitionmetadataresponse_;
#endif
}
inline ::pulsar::proto::CommandPartitionedTopicMetadataResponse* BaseCommand::mutable_partitionmetadataresponse() {
  set_has_partitionmetadataresponse();
  if (partitionmetadataresponse_ == NULL) partitionmetadataresponse_ = new ::pulsar::proto::CommandPartitionedTopicMetadataResponse;
  // @@protoc_insertion_point(field_mutable:pulsar.proto.BaseCommand.partitionMetadataResponse)
  return partitionmetadataresponse_;
}
inline ::pulsar::proto::CommandPartitionedTopicMetadataResponse* BaseCommand::release_partitionmetadataresponse() {
  clear_has_partitionmetadataresponse();
  ::pulsar::proto::CommandPartitionedTopicMetadataResponse* temp = partitionmetadataresponse_;
  partitionmetadataresponse_ = NULL;
  return temp;
}
inline void BaseCommand::set_allocated_partitionmetadataresponse(::pulsar::proto::CommandPartitionedTopicMetadataResponse* partitionmetadataresponse) {
  delete partitionmetadataresponse_;
  partitionmetadataresponse_ = partitionmetadataresponse;
  if (partitionmetadataresponse) {
    set_has_partitionmetadataresponse();
  } else {
    clear_has_partitionmetadataresponse();
  }
  // @@protoc_insertion_point(field_set_allocated:pulsar.proto.BaseCommand.partitionMetadataResponse)
}

// optional .pulsar.proto.CommandLookupTopic lookupTopic = 23;
inline bool BaseCommand::has_lookuptopic() const {
  return (_has_bits_[0] & 0x00400000u) != 0;
}
inline void BaseCommand::set_has_lookuptopic() {
  _has_bits_[0] |= 0x00400000u;
}
inline void BaseCommand::clear_has_lookuptopic() {
  _has_bits_[0] &= ~0x00400000u;
}
inline void BaseCommand::clear_lookuptopic() {
  if (lookuptopic_ != NULL) lookuptopic_->::pulsar::proto::CommandLookupTopic::Clear();
  clear_has_lookuptopic();
}
inline const ::pulsar::proto::CommandLookupTopic& BaseCommand::lookuptopic() const {
  // @@protoc_insertion_point(field_get:pulsar.proto.BaseCommand.lookupTopic)
#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
  return lookuptopic_ != NULL ? *lookuptopic_ : *default_instance().lookuptopic_;
#else
  return lookuptopic_ != NULL ? *lookuptopic_ : *default_instance_->lookuptopic_;
#endif
}
inline ::pulsar::proto::CommandLookupTopic* BaseCommand::mutable_lookuptopic() {
  set_has_lookuptopic();
  if (lookuptopic_ == NULL) lookuptopic_ = new ::pulsar::proto::CommandLookupTopic;
  // @@protoc_insertion_point(field_mutable:pulsar.proto.BaseCommand.lookupTopic)
  return lookuptopic_;
}
inline ::pulsar::proto::CommandLookupTopic* BaseCommand::release_lookuptopic() {
  clear_has_lookuptopic();
  ::pulsar::proto::CommandLookupTopic* temp = lookuptopic_;
  lookuptopic_ = NULL;
  return temp;
}
inline void BaseCommand::set_allocated_lookuptopic(::pulsar::proto::CommandLookupTopic* lookuptopic) {
  delete lookuptopic_;
  lookuptopic_ = lookuptopic;
  if (lookuptopic) {
    set_has_lookuptopic();
  } else {
    clear_has_lookuptopic();
  }
  // @@protoc_insertion_point(field_set_allocated:pulsar.proto.BaseCommand.lookupTopic)
}

// optional .pulsar.proto.CommandLookupTopicResponse lookupTopicResponse = 24;
inline bool BaseCommand::has_lookuptopicresponse() const {
  return (_has_bits_[0] & 0x00800000u) != 0;
}
inline void BaseCommand::set_has_lookuptopicresponse() {
  _has_bits_[0] |= 0x00800000u;
}
inline void BaseCommand::clear_has_lookuptopicresponse() {
  _has_bits_[0] &= ~0x00800000u;
}
inline void BaseCommand::clear_lookuptopicresponse() {
  if (lookuptopicresponse_ != NULL) lookuptopicresponse_->::pulsar::proto::CommandLookupTopicResponse::Clear();
  clear_has_lookuptopicresponse();
}
inline const ::pulsar::proto::CommandLookupTopicResponse& BaseCommand::lookuptopicresponse() const {
  // @@protoc_insertion_point(field_get:pulsar.proto.BaseCommand.lookupTopicResponse)
#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
  return lookuptopicresponse_ != NULL ? *lookuptopicresponse_ : *default_instance().lookuptopicresponse_;
#else
  return lookuptopicresponse_ != NULL ? *lookuptopicresponse_ : *default_instance_->lookuptopicresponse_;
#endif
}
inline ::pulsar::proto::CommandLookupTopicResponse* BaseCommand::mutable_lookuptopicresponse() {
  set_has_lookuptopicresponse();
  if (lookuptopicresponse_ == NULL) lookuptopicresponse_ = new ::pulsar::proto::CommandLookupTopicResponse;
  // @@protoc_insertion_point(field_mutable:pulsar.proto.BaseCommand.lookupTopicResponse)
  return lookuptopicresponse_;
}
inline ::pulsar::proto::CommandLookupTopicResponse* BaseCommand::release_lookuptopicresponse() {
  clear_has_lookuptopicresponse();
  ::pulsar::proto::CommandLookupTopicResponse* temp = lookuptopicresponse_;
  lookuptopicresponse_ = NULL;
  return temp;
}
inline void BaseCommand::set_allocated_lookuptopicresponse(::pulsar::proto::CommandLookupTopicResponse* lookuptopicresponse) {
  delete lookuptopicresponse_;
  lookuptopicresponse_ = lookuptopicresponse;
  if (lookuptopicresponse) {
    set_has_lookuptopicresponse();
  } else {
    clear_has_lookuptopicresponse();
  }
  // @@protoc_insertion_point(field_set_allocated:pulsar.proto.BaseCommand.lookupTopicResponse)
}

// optional .pulsar.proto.CommandConsumerStats consumerStats = 25;
inline bool BaseCommand::has_consumerstats() const {
  return (_has_bits_[0] & 0x01000000u) != 0;
}
inline void BaseCommand::set_has_consumerstats() {
  _has_bits_[0] |= 0x01000000u;
}
inline void BaseCommand::clear_has_consumerstats() {
  _has_bits_[0] &= ~0x01000000u;
}
inline void BaseCommand::clear_consumerstats() {
  if (consumerstats_ != NULL) consumerstats_->::pulsar::proto::CommandConsumerStats::Clear();
  clear_has_consumerstats();
}
inline const ::pulsar::proto::CommandConsumerStats& BaseCommand::consumerstats() const {
  // @@protoc_insertion_point(field_get:pulsar.proto.BaseCommand.consumerStats)
#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
  return consumerstats_ != NULL ? *consumerstats_ : *default_instance().consumerstats_;
#else
  return consumerstats_ != NULL ? *consumerstats_ : *default_instance_->consumerstats_;
#endif
}
inline ::pulsar::proto::CommandConsumerStats* BaseCommand::mutable_consumerstats() {
  set_has_consumerstats();
  if (consumerstats_ == NULL) consumerstats_ = new ::pulsar::proto::CommandConsumerStats;
  // @@protoc_insertion_point(field_mutable:pulsar.proto.BaseCommand.consumerStats)
  return consumerstats_;
}
inline ::pulsar::proto::CommandConsumerStats* BaseCommand::release_consumerstats() {
  clear_has_consumerstats();
  ::pulsar::proto::CommandConsumerStats* temp = consumerstats_;
  consumerstats_ = NULL;
  return temp;
}
inline void BaseCommand::set_allocated_consumerstats(::pulsar::proto::CommandConsumerStats* consumerstats) {
  delete consumerstats_;
  consumerstats_ = consumerstats;
  if (consumerstats) {
    set_has_consumerstats();
  } else {
    clear_has_consumerstats();
  }
  // @@protoc_insertion_point(field_set_allocated:pulsar.proto.BaseCommand.consumerStats)
}

// optional .pulsar.proto.CommandConsumerStatsResponse consumerStatsResponse = 26;
inline bool BaseCommand::has_consumerstatsresponse() const {
  return (_has_bits_[0] & 0x02000000u) != 0;
}
inline void BaseCommand::set_has_consumerstatsresponse() {
  _has_bits_[0] |= 0x02000000u;
}
inline void BaseCommand::clear_has_consumerstatsresponse() {
  _has_bits_[0] &= ~0x02000000u;
}
inline void BaseCommand::clear_consumerstatsresponse() {
  if (consumerstatsresponse_ != NULL) consumerstatsresponse_->::pulsar::proto::CommandConsumerStatsResponse::Clear();
  clear_has_consumerstatsresponse();
}
inline const ::pulsar::proto::CommandConsumerStatsResponse& BaseCommand::consumerstatsresponse() const {
  // @@protoc_insertion_point(field_get:pulsar.proto.BaseCommand.consumerStatsResponse)
#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
  return consumerstatsresponse_ != NULL ? *consumerstatsresponse_ : *default_instance().consumerstatsresponse_;
#else
  return consumerstatsresponse_ != NULL ? *consumerstatsresponse_ : *default_instance_->consumerstatsresponse_;
#endif
}
inline ::pulsar::proto::CommandConsumerStatsResponse* BaseCommand::mutable_consumerstatsresponse() {
  set_has_consumerstatsresponse();
  if (consumerstatsresponse_ == NULL) consumerstatsresponse_ = new ::pulsar::proto::CommandConsumerStatsResponse;
  // @@protoc_insertion_point(field_mutable:pulsar.proto.BaseCommand.consumerStatsResponse)
  return consumerstatsresponse_;
}
inline ::pulsar::proto::CommandConsumerStatsResponse* BaseCommand::release_consumerstatsresponse() {
  clear_has_consumerstatsresponse();
  ::pulsar::proto::CommandConsumerStatsResponse* temp = consumerstatsresponse_;
  consumerstatsresponse_ = NULL;
  return temp;
}
inline void BaseCommand::set_allocated_consumerstatsresponse(::pulsar::proto::CommandConsumerStatsResponse* consumerstatsresponse) {
  delete consumerstatsresponse_;
  consumerstatsresponse_ = consumerstatsresponse;
  if (consumerstatsresponse) {
    set_has_consumerstatsresponse();
  } else {
    clear_has_consumerstatsresponse();
  }
  // @@protoc_insertion_point(field_set_allocated:pulsar.proto.BaseCommand.consumerStatsResponse)
}


// @@protoc_insertion_point(namespace_scope)

}  // namespace proto
}  // namespace pulsar

// @@protoc_insertion_point(global_scope)

#endif  // PROTOBUF_PulsarApi_2eproto__INCLUDED
