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

#ifndef PROTOBUF_msgheader_2eproto__INCLUDED
#define PROTOBUF_msgheader_2eproto__INCLUDED

#include <string>

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

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

namespace communication {

// Internal implementation detail -- do not call these.
void  protobuf_AddDesc_msgheader_2eproto();
void protobuf_AssignDesc_msgheader_2eproto();
void protobuf_ShutdownFile_msgheader_2eproto();

class MsgHeader;

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

class MsgHeader : public ::google::protobuf::Message {
 public:
  MsgHeader();
  virtual ~MsgHeader();
  
  MsgHeader(const MsgHeader& from);
  
  inline MsgHeader& operator=(const MsgHeader& from) {
    CopyFrom(from);
    return *this;
  }
  
  inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
    return _unknown_fields_;
  }
  
  inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
    return &_unknown_fields_;
  }
  
  static const ::google::protobuf::Descriptor* descriptor();
  static const MsgHeader& default_instance();
  
  void Swap(MsgHeader* other);
  
  // implements Message ----------------------------------------------
  
  MsgHeader* New() const;
  void CopyFrom(const ::google::protobuf::Message& from);
  void MergeFrom(const ::google::protobuf::Message& from);
  void CopyFrom(const MsgHeader& from);
  void MergeFrom(const MsgHeader& from);
  void Clear();
  bool IsInitialized() const;
  
  int ByteSize() const;
  bool MergePartialFromCodedStream(
      ::google::protobuf::io::CodedInputStream* input);
  void SerializeWithCachedSizes(
      ::google::protobuf::io::CodedOutputStream* output) const;
  ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
  int GetCachedSize() const { return _cached_size_; }
  private:
  void SharedCtor();
  void SharedDtor();
  void SetCachedSize(int size) const;
  public:
  
  ::google::protobuf::Metadata GetMetadata() const;
  
  // nested types ----------------------------------------------------
  
  // accessors -------------------------------------------------------
  
  // required uint32 cmd = 1;
  inline bool has_cmd() const;
  inline void clear_cmd();
  static const int kCmdFieldNumber = 1;
  inline ::google::protobuf::uint32 cmd() const;
  inline void set_cmd(::google::protobuf::uint32 value);
  
  // required uint32 length_data = 2;
  inline bool has_length_data() const;
  inline void clear_length_data();
  static const int kLengthDataFieldNumber = 2;
  inline ::google::protobuf::uint32 length_data() const;
  inline void set_length_data(::google::protobuf::uint32 value);
  
  // optional uint32 status = 3;
  inline bool has_status() const;
  inline void clear_status();
  static const int kStatusFieldNumber = 3;
  inline ::google::protobuf::uint32 status() const;
  inline void set_status(::google::protobuf::uint32 value);
  
  // optional uint64 token = 4;
  inline bool has_token() const;
  inline void clear_token();
  static const int kTokenFieldNumber = 4;
  inline ::google::protobuf::uint64 token() const;
  inline void set_token(::google::protobuf::uint64 value);
  
  // @@protoc_insertion_point(class_scope:communication.MsgHeader)
 private:
  ::google::protobuf::UnknownFieldSet _unknown_fields_;
  mutable int _cached_size_;
  
  ::google::protobuf::uint32 cmd_;
  ::google::protobuf::uint32 length_data_;
  ::google::protobuf::uint32 status_;
  ::google::protobuf::uint64 token_;
  friend void  protobuf_AddDesc_msgheader_2eproto();
  friend void protobuf_AssignDesc_msgheader_2eproto();
  friend void protobuf_ShutdownFile_msgheader_2eproto();
  
  ::google::protobuf::uint32 _has_bits_[(4 + 31) / 32];
  
  // WHY DOES & HAVE LOWER PRECEDENCE THAN != !?
  inline bool _has_bit(int index) const {
    return (_has_bits_[index / 32] & (1u << (index % 32))) != 0;
  }
  inline void _set_bit(int index) {
    _has_bits_[index / 32] |= (1u << (index % 32));
  }
  inline void _clear_bit(int index) {
    _has_bits_[index / 32] &= ~(1u << (index % 32));
  }
  
  void InitAsDefaultInstance();
  static MsgHeader* default_instance_;
};
// ===================================================================


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

// MsgHeader

// required uint32 cmd = 1;
inline bool MsgHeader::has_cmd() const {
  return _has_bit(0);
}
inline void MsgHeader::clear_cmd() {
  cmd_ = 0u;
  _clear_bit(0);
}
inline ::google::protobuf::uint32 MsgHeader::cmd() const {
  return cmd_;
}
inline void MsgHeader::set_cmd(::google::protobuf::uint32 value) {
  _set_bit(0);
  cmd_ = value;
}

// required uint32 length_data = 2;
inline bool MsgHeader::has_length_data() const {
  return _has_bit(1);
}
inline void MsgHeader::clear_length_data() {
  length_data_ = 0u;
  _clear_bit(1);
}
inline ::google::protobuf::uint32 MsgHeader::length_data() const {
  return length_data_;
}
inline void MsgHeader::set_length_data(::google::protobuf::uint32 value) {
  _set_bit(1);
  length_data_ = value;
}

// optional uint32 status = 3;
inline bool MsgHeader::has_status() const {
  return _has_bit(2);
}
inline void MsgHeader::clear_status() {
  status_ = 0u;
  _clear_bit(2);
}
inline ::google::protobuf::uint32 MsgHeader::status() const {
  return status_;
}
inline void MsgHeader::set_status(::google::protobuf::uint32 value) {
  _set_bit(2);
  status_ = value;
}

// optional uint64 token = 4;
inline bool MsgHeader::has_token() const {
  return _has_bit(3);
}
inline void MsgHeader::clear_token() {
  token_ = GOOGLE_ULONGLONG(0);
  _clear_bit(3);
}
inline ::google::protobuf::uint64 MsgHeader::token() const {
  return token_;
}
inline void MsgHeader::set_token(::google::protobuf::uint64 value) {
  _set_bit(3);
  token_ = value;
}


// @@protoc_insertion_point(namespace_scope)

}  // namespace communication

#ifndef SWIG
namespace google {
namespace protobuf {


}  // namespace google
}  // namespace protobuf
#endif  // SWIG

// @@protoc_insertion_point(global_scope)

#endif  // PROTOBUF_msgheader_2eproto__INCLUDED
