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

#ifndef PROTOBUF_Messages_2eproto__INCLUDED
#define PROTOBUF_Messages_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.h>
#include <google/protobuf/repeated_field.h>
#include <google/protobuf/extension_set.h>
#include <google/protobuf/unknown_field_set.h>
// @@protoc_insertion_point(includes)

namespace Messages {

// Internal implementation detail -- do not call these.
void  protobuf_AddDesc_Messages_2eproto();
void protobuf_AssignDesc_Messages_2eproto();
void protobuf_ShutdownFile_Messages_2eproto();

class InitialMessage;
class MessageMsg0;
class MessageMSG1;
class MessageMSG2;
class MessageMSG3;
class AttestationMessage;
class MessagePsiSalt;
class MessagePsiHashData;
class MessagePsiHashDataFinished;
class MessagePsiResult;
class MessagePsiIntersect;

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

class InitialMessage : public ::google::protobuf::Message {
 public:
  InitialMessage();
  virtual ~InitialMessage();

  InitialMessage(const InitialMessage& from);

  inline InitialMessage& operator=(const InitialMessage& 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 InitialMessage& default_instance();

  void Swap(InitialMessage* other);

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

  InitialMessage* New() const;
  void CopyFrom(const ::google::protobuf::Message& from);
  void MergeFrom(const ::google::protobuf::Message& from);
  void CopyFrom(const InitialMessage& from);
  void MergeFrom(const InitialMessage& 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 type = 1;
  inline bool has_type() const;
  inline void clear_type();
  static const int kTypeFieldNumber = 1;
  inline ::google::protobuf::uint32 type() const;
  inline void set_type(::google::protobuf::uint32 value);

  // optional uint32 size = 2;
  inline bool has_size() const;
  inline void clear_size();
  static const int kSizeFieldNumber = 2;
  inline ::google::protobuf::uint32 size() const;
  inline void set_size(::google::protobuf::uint32 value);

  // @@protoc_insertion_point(class_scope:Messages.InitialMessage)
 private:
  inline void set_has_type();
  inline void clear_has_type();
  inline void set_has_size();
  inline void clear_has_size();

  ::google::protobuf::UnknownFieldSet _unknown_fields_;

  ::google::protobuf::uint32 _has_bits_[1];
  mutable int _cached_size_;
  ::google::protobuf::uint32 type_;
  ::google::protobuf::uint32 size_;
  friend void  protobuf_AddDesc_Messages_2eproto();
  friend void protobuf_AssignDesc_Messages_2eproto();
  friend void protobuf_ShutdownFile_Messages_2eproto();

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

class MessageMsg0 : public ::google::protobuf::Message {
 public:
  MessageMsg0();
  virtual ~MessageMsg0();

  MessageMsg0(const MessageMsg0& from);

  inline MessageMsg0& operator=(const MessageMsg0& 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 MessageMsg0& default_instance();

  void Swap(MessageMsg0* other);

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

  MessageMsg0* New() const;
  void CopyFrom(const ::google::protobuf::Message& from);
  void MergeFrom(const ::google::protobuf::Message& from);
  void CopyFrom(const MessageMsg0& from);
  void MergeFrom(const MessageMsg0& 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 type = 1;
  inline bool has_type() const;
  inline void clear_type();
  static const int kTypeFieldNumber = 1;
  inline ::google::protobuf::uint32 type() const;
  inline void set_type(::google::protobuf::uint32 value);

  // required uint32 epid = 2;
  inline bool has_epid() const;
  inline void clear_epid();
  static const int kEpidFieldNumber = 2;
  inline ::google::protobuf::uint32 epid() const;
  inline void set_epid(::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);

  // @@protoc_insertion_point(class_scope:Messages.MessageMsg0)
 private:
  inline void set_has_type();
  inline void clear_has_type();
  inline void set_has_epid();
  inline void clear_has_epid();
  inline void set_has_status();
  inline void clear_has_status();

  ::google::protobuf::UnknownFieldSet _unknown_fields_;

  ::google::protobuf::uint32 _has_bits_[1];
  mutable int _cached_size_;
  ::google::protobuf::uint32 type_;
  ::google::protobuf::uint32 epid_;
  ::google::protobuf::uint32 status_;
  friend void  protobuf_AddDesc_Messages_2eproto();
  friend void protobuf_AssignDesc_Messages_2eproto();
  friend void protobuf_ShutdownFile_Messages_2eproto();

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

class MessageMSG1 : public ::google::protobuf::Message {
 public:
  MessageMSG1();
  virtual ~MessageMSG1();

  MessageMSG1(const MessageMSG1& from);

  inline MessageMSG1& operator=(const MessageMSG1& 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 MessageMSG1& default_instance();

  void Swap(MessageMSG1* other);

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

  MessageMSG1* New() const;
  void CopyFrom(const ::google::protobuf::Message& from);
  void MergeFrom(const ::google::protobuf::Message& from);
  void CopyFrom(const MessageMSG1& from);
  void MergeFrom(const MessageMSG1& 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 type = 1;
  inline bool has_type() const;
  inline void clear_type();
  static const int kTypeFieldNumber = 1;
  inline ::google::protobuf::uint32 type() const;
  inline void set_type(::google::protobuf::uint32 value);

  // required uint32 context = 2;
  inline bool has_context() const;
  inline void clear_context();
  static const int kContextFieldNumber = 2;
  inline ::google::protobuf::uint32 context() const;
  inline void set_context(::google::protobuf::uint32 value);

  // repeated uint32 GaX = 3 [packed = true];
  inline int gax_size() const;
  inline void clear_gax();
  static const int kGaXFieldNumber = 3;
  inline ::google::protobuf::uint32 gax(int index) const;
  inline void set_gax(int index, ::google::protobuf::uint32 value);
  inline void add_gax(::google::protobuf::uint32 value);
  inline const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
      gax() const;
  inline ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
      mutable_gax();

  // repeated uint32 GaY = 4 [packed = true];
  inline int gay_size() const;
  inline void clear_gay();
  static const int kGaYFieldNumber = 4;
  inline ::google::protobuf::uint32 gay(int index) const;
  inline void set_gay(int index, ::google::protobuf::uint32 value);
  inline void add_gay(::google::protobuf::uint32 value);
  inline const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
      gay() const;
  inline ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
      mutable_gay();

  // repeated uint32 GID = 5 [packed = true];
  inline int gid_size() const;
  inline void clear_gid();
  static const int kGIDFieldNumber = 5;
  inline ::google::protobuf::uint32 gid(int index) const;
  inline void set_gid(int index, ::google::protobuf::uint32 value);
  inline void add_gid(::google::protobuf::uint32 value);
  inline const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
      gid() const;
  inline ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
      mutable_gid();

  // @@protoc_insertion_point(class_scope:Messages.MessageMSG1)
 private:
  inline void set_has_type();
  inline void clear_has_type();
  inline void set_has_context();
  inline void clear_has_context();

  ::google::protobuf::UnknownFieldSet _unknown_fields_;

  ::google::protobuf::uint32 _has_bits_[1];
  mutable int _cached_size_;
  ::google::protobuf::uint32 type_;
  ::google::protobuf::uint32 context_;
  ::google::protobuf::RepeatedField< ::google::protobuf::uint32 > gax_;
  mutable int _gax_cached_byte_size_;
  ::google::protobuf::RepeatedField< ::google::protobuf::uint32 > gay_;
  mutable int _gay_cached_byte_size_;
  ::google::protobuf::RepeatedField< ::google::protobuf::uint32 > gid_;
  mutable int _gid_cached_byte_size_;
  friend void  protobuf_AddDesc_Messages_2eproto();
  friend void protobuf_AssignDesc_Messages_2eproto();
  friend void protobuf_ShutdownFile_Messages_2eproto();

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

class MessageMSG2 : public ::google::protobuf::Message {
 public:
  MessageMSG2();
  virtual ~MessageMSG2();

  MessageMSG2(const MessageMSG2& from);

  inline MessageMSG2& operator=(const MessageMSG2& 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 MessageMSG2& default_instance();

  void Swap(MessageMSG2* other);

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

  MessageMSG2* New() const;
  void CopyFrom(const ::google::protobuf::Message& from);
  void MergeFrom(const ::google::protobuf::Message& from);
  void CopyFrom(const MessageMSG2& from);
  void MergeFrom(const MessageMSG2& 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 type = 1;
  inline bool has_type() const;
  inline void clear_type();
  static const int kTypeFieldNumber = 1;
  inline ::google::protobuf::uint32 type() const;
  inline void set_type(::google::protobuf::uint32 value);

  // optional uint32 size = 2;
  inline bool has_size() const;
  inline void clear_size();
  static const int kSizeFieldNumber = 2;
  inline ::google::protobuf::uint32 size() const;
  inline void set_size(::google::protobuf::uint32 value);

  // required uint32 context = 3;
  inline bool has_context() const;
  inline void clear_context();
  static const int kContextFieldNumber = 3;
  inline ::google::protobuf::uint32 context() const;
  inline void set_context(::google::protobuf::uint32 value);

  // repeated uint32 public_key_gx = 4 [packed = true];
  inline int public_key_gx_size() const;
  inline void clear_public_key_gx();
  static const int kPublicKeyGxFieldNumber = 4;
  inline ::google::protobuf::uint32 public_key_gx(int index) const;
  inline void set_public_key_gx(int index, ::google::protobuf::uint32 value);
  inline void add_public_key_gx(::google::protobuf::uint32 value);
  inline const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
      public_key_gx() const;
  inline ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
      mutable_public_key_gx();

  // repeated uint32 public_key_gy = 5 [packed = true];
  inline int public_key_gy_size() const;
  inline void clear_public_key_gy();
  static const int kPublicKeyGyFieldNumber = 5;
  inline ::google::protobuf::uint32 public_key_gy(int index) const;
  inline void set_public_key_gy(int index, ::google::protobuf::uint32 value);
  inline void add_public_key_gy(::google::protobuf::uint32 value);
  inline const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
      public_key_gy() const;
  inline ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
      mutable_public_key_gy();

  // optional uint32 quote_type = 6;
  inline bool has_quote_type() const;
  inline void clear_quote_type();
  static const int kQuoteTypeFieldNumber = 6;
  inline ::google::protobuf::uint32 quote_type() const;
  inline void set_quote_type(::google::protobuf::uint32 value);

  // repeated uint32 spid = 7 [packed = true];
  inline int spid_size() const;
  inline void clear_spid();
  static const int kSpidFieldNumber = 7;
  inline ::google::protobuf::uint32 spid(int index) const;
  inline void set_spid(int index, ::google::protobuf::uint32 value);
  inline void add_spid(::google::protobuf::uint32 value);
  inline const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
      spid() const;
  inline ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
      mutable_spid();

  // optional uint32 cmac_kdf_id = 8;
  inline bool has_cmac_kdf_id() const;
  inline void clear_cmac_kdf_id();
  static const int kCmacKdfIdFieldNumber = 8;
  inline ::google::protobuf::uint32 cmac_kdf_id() const;
  inline void set_cmac_kdf_id(::google::protobuf::uint32 value);

  // repeated uint32 signature_x = 9 [packed = true];
  inline int signature_x_size() const;
  inline void clear_signature_x();
  static const int kSignatureXFieldNumber = 9;
  inline ::google::protobuf::uint32 signature_x(int index) const;
  inline void set_signature_x(int index, ::google::protobuf::uint32 value);
  inline void add_signature_x(::google::protobuf::uint32 value);
  inline const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
      signature_x() const;
  inline ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
      mutable_signature_x();

  // repeated uint32 signature_y = 10 [packed = true];
  inline int signature_y_size() const;
  inline void clear_signature_y();
  static const int kSignatureYFieldNumber = 10;
  inline ::google::protobuf::uint32 signature_y(int index) const;
  inline void set_signature_y(int index, ::google::protobuf::uint32 value);
  inline void add_signature_y(::google::protobuf::uint32 value);
  inline const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
      signature_y() const;
  inline ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
      mutable_signature_y();

  // repeated uint32 smac = 11 [packed = true];
  inline int smac_size() const;
  inline void clear_smac();
  static const int kSmacFieldNumber = 11;
  inline ::google::protobuf::uint32 smac(int index) const;
  inline void set_smac(int index, ::google::protobuf::uint32 value);
  inline void add_smac(::google::protobuf::uint32 value);
  inline const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
      smac() const;
  inline ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
      mutable_smac();

  // optional uint32 size_sigrl = 12;
  inline bool has_size_sigrl() const;
  inline void clear_size_sigrl();
  static const int kSizeSigrlFieldNumber = 12;
  inline ::google::protobuf::uint32 size_sigrl() const;
  inline void set_size_sigrl(::google::protobuf::uint32 value);

  // repeated uint32 sigrl = 13 [packed = true];
  inline int sigrl_size() const;
  inline void clear_sigrl();
  static const int kSigrlFieldNumber = 13;
  inline ::google::protobuf::uint32 sigrl(int index) const;
  inline void set_sigrl(int index, ::google::protobuf::uint32 value);
  inline void add_sigrl(::google::protobuf::uint32 value);
  inline const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
      sigrl() const;
  inline ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
      mutable_sigrl();

  // @@protoc_insertion_point(class_scope:Messages.MessageMSG2)
 private:
  inline void set_has_type();
  inline void clear_has_type();
  inline void set_has_size();
  inline void clear_has_size();
  inline void set_has_context();
  inline void clear_has_context();
  inline void set_has_quote_type();
  inline void clear_has_quote_type();
  inline void set_has_cmac_kdf_id();
  inline void clear_has_cmac_kdf_id();
  inline void set_has_size_sigrl();
  inline void clear_has_size_sigrl();

  ::google::protobuf::UnknownFieldSet _unknown_fields_;

  ::google::protobuf::uint32 _has_bits_[1];
  mutable int _cached_size_;
  ::google::protobuf::uint32 type_;
  ::google::protobuf::uint32 size_;
  ::google::protobuf::RepeatedField< ::google::protobuf::uint32 > public_key_gx_;
  mutable int _public_key_gx_cached_byte_size_;
  ::google::protobuf::uint32 context_;
  ::google::protobuf::uint32 quote_type_;
  ::google::protobuf::RepeatedField< ::google::protobuf::uint32 > public_key_gy_;
  mutable int _public_key_gy_cached_byte_size_;
  ::google::protobuf::RepeatedField< ::google::protobuf::uint32 > spid_;
  mutable int _spid_cached_byte_size_;
  ::google::protobuf::RepeatedField< ::google::protobuf::uint32 > signature_x_;
  mutable int _signature_x_cached_byte_size_;
  ::google::protobuf::RepeatedField< ::google::protobuf::uint32 > signature_y_;
  mutable int _signature_y_cached_byte_size_;
  ::google::protobuf::uint32 cmac_kdf_id_;
  ::google::protobuf::uint32 size_sigrl_;
  ::google::protobuf::RepeatedField< ::google::protobuf::uint32 > smac_;
  mutable int _smac_cached_byte_size_;
  ::google::protobuf::RepeatedField< ::google::protobuf::uint32 > sigrl_;
  mutable int _sigrl_cached_byte_size_;
  friend void  protobuf_AddDesc_Messages_2eproto();
  friend void protobuf_AssignDesc_Messages_2eproto();
  friend void protobuf_ShutdownFile_Messages_2eproto();

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

class MessageMSG3 : public ::google::protobuf::Message {
 public:
  MessageMSG3();
  virtual ~MessageMSG3();

  MessageMSG3(const MessageMSG3& from);

  inline MessageMSG3& operator=(const MessageMSG3& 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 MessageMSG3& default_instance();

  void Swap(MessageMSG3* other);

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

  MessageMSG3* New() const;
  void CopyFrom(const ::google::protobuf::Message& from);
  void MergeFrom(const ::google::protobuf::Message& from);
  void CopyFrom(const MessageMSG3& from);
  void MergeFrom(const MessageMSG3& 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 type = 1;
  inline bool has_type() const;
  inline void clear_type();
  static const int kTypeFieldNumber = 1;
  inline ::google::protobuf::uint32 type() const;
  inline void set_type(::google::protobuf::uint32 value);

  // optional uint32 size = 2;
  inline bool has_size() const;
  inline void clear_size();
  static const int kSizeFieldNumber = 2;
  inline ::google::protobuf::uint32 size() const;
  inline void set_size(::google::protobuf::uint32 value);

  // required uint32 context = 3;
  inline bool has_context() const;
  inline void clear_context();
  static const int kContextFieldNumber = 3;
  inline ::google::protobuf::uint32 context() const;
  inline void set_context(::google::protobuf::uint32 value);

  // repeated uint32 sgx_mac = 4 [packed = true];
  inline int sgx_mac_size() const;
  inline void clear_sgx_mac();
  static const int kSgxMacFieldNumber = 4;
  inline ::google::protobuf::uint32 sgx_mac(int index) const;
  inline void set_sgx_mac(int index, ::google::protobuf::uint32 value);
  inline void add_sgx_mac(::google::protobuf::uint32 value);
  inline const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
      sgx_mac() const;
  inline ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
      mutable_sgx_mac();

  // repeated uint32 gax_msg3 = 5 [packed = true];
  inline int gax_msg3_size() const;
  inline void clear_gax_msg3();
  static const int kGaxMsg3FieldNumber = 5;
  inline ::google::protobuf::uint32 gax_msg3(int index) const;
  inline void set_gax_msg3(int index, ::google::protobuf::uint32 value);
  inline void add_gax_msg3(::google::protobuf::uint32 value);
  inline const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
      gax_msg3() const;
  inline ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
      mutable_gax_msg3();

  // repeated uint32 gay_msg3 = 6 [packed = true];
  inline int gay_msg3_size() const;
  inline void clear_gay_msg3();
  static const int kGayMsg3FieldNumber = 6;
  inline ::google::protobuf::uint32 gay_msg3(int index) const;
  inline void set_gay_msg3(int index, ::google::protobuf::uint32 value);
  inline void add_gay_msg3(::google::protobuf::uint32 value);
  inline const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
      gay_msg3() const;
  inline ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
      mutable_gay_msg3();

  // repeated uint32 sec_property = 7 [packed = true];
  inline int sec_property_size() const;
  inline void clear_sec_property();
  static const int kSecPropertyFieldNumber = 7;
  inline ::google::protobuf::uint32 sec_property(int index) const;
  inline void set_sec_property(int index, ::google::protobuf::uint32 value);
  inline void add_sec_property(::google::protobuf::uint32 value);
  inline const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
      sec_property() const;
  inline ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
      mutable_sec_property();

  // repeated uint32 quote = 8 [packed = true];
  inline int quote_size() const;
  inline void clear_quote();
  static const int kQuoteFieldNumber = 8;
  inline ::google::protobuf::uint32 quote(int index) const;
  inline void set_quote(int index, ::google::protobuf::uint32 value);
  inline void add_quote(::google::protobuf::uint32 value);
  inline const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
      quote() const;
  inline ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
      mutable_quote();

  // @@protoc_insertion_point(class_scope:Messages.MessageMSG3)
 private:
  inline void set_has_type();
  inline void clear_has_type();
  inline void set_has_size();
  inline void clear_has_size();
  inline void set_has_context();
  inline void clear_has_context();

  ::google::protobuf::UnknownFieldSet _unknown_fields_;

  ::google::protobuf::uint32 _has_bits_[1];
  mutable int _cached_size_;
  ::google::protobuf::uint32 type_;
  ::google::protobuf::uint32 size_;
  ::google::protobuf::RepeatedField< ::google::protobuf::uint32 > sgx_mac_;
  mutable int _sgx_mac_cached_byte_size_;
  ::google::protobuf::RepeatedField< ::google::protobuf::uint32 > gax_msg3_;
  mutable int _gax_msg3_cached_byte_size_;
  ::google::protobuf::RepeatedField< ::google::protobuf::uint32 > gay_msg3_;
  mutable int _gay_msg3_cached_byte_size_;
  ::google::protobuf::RepeatedField< ::google::protobuf::uint32 > sec_property_;
  mutable int _sec_property_cached_byte_size_;
  ::google::protobuf::RepeatedField< ::google::protobuf::uint32 > quote_;
  mutable int _quote_cached_byte_size_;
  ::google::protobuf::uint32 context_;
  friend void  protobuf_AddDesc_Messages_2eproto();
  friend void protobuf_AssignDesc_Messages_2eproto();
  friend void protobuf_ShutdownFile_Messages_2eproto();

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

class AttestationMessage : public ::google::protobuf::Message {
 public:
  AttestationMessage();
  virtual ~AttestationMessage();

  AttestationMessage(const AttestationMessage& from);

  inline AttestationMessage& operator=(const AttestationMessage& 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 AttestationMessage& default_instance();

  void Swap(AttestationMessage* other);

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

  AttestationMessage* New() const;
  void CopyFrom(const ::google::protobuf::Message& from);
  void MergeFrom(const ::google::protobuf::Message& from);
  void CopyFrom(const AttestationMessage& from);
  void MergeFrom(const AttestationMessage& 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 type = 1;
  inline bool has_type() const;
  inline void clear_type();
  static const int kTypeFieldNumber = 1;
  inline ::google::protobuf::uint32 type() const;
  inline void set_type(::google::protobuf::uint32 value);

  // required uint32 size = 2;
  inline bool has_size() const;
  inline void clear_size();
  static const int kSizeFieldNumber = 2;
  inline ::google::protobuf::uint32 size() const;
  inline void set_size(::google::protobuf::uint32 value);

  // required uint32 context = 3;
  inline bool has_context() const;
  inline void clear_context();
  static const int kContextFieldNumber = 3;
  inline ::google::protobuf::uint32 context() const;
  inline void set_context(::google::protobuf::uint32 value);

  // optional uint32 epid_group_status = 4;
  inline bool has_epid_group_status() const;
  inline void clear_epid_group_status();
  static const int kEpidGroupStatusFieldNumber = 4;
  inline ::google::protobuf::uint32 epid_group_status() const;
  inline void set_epid_group_status(::google::protobuf::uint32 value);

  // optional uint32 tcb_evaluation_status = 5;
  inline bool has_tcb_evaluation_status() const;
  inline void clear_tcb_evaluation_status();
  static const int kTcbEvaluationStatusFieldNumber = 5;
  inline ::google::protobuf::uint32 tcb_evaluation_status() const;
  inline void set_tcb_evaluation_status(::google::protobuf::uint32 value);

  // optional uint32 pse_evaluation_status = 6;
  inline bool has_pse_evaluation_status() const;
  inline void clear_pse_evaluation_status();
  static const int kPseEvaluationStatusFieldNumber = 6;
  inline ::google::protobuf::uint32 pse_evaluation_status() const;
  inline void set_pse_evaluation_status(::google::protobuf::uint32 value);

  // repeated uint32 latest_equivalent_tcb_psvn = 7 [packed = true];
  inline int latest_equivalent_tcb_psvn_size() const;
  inline void clear_latest_equivalent_tcb_psvn();
  static const int kLatestEquivalentTcbPsvnFieldNumber = 7;
  inline ::google::protobuf::uint32 latest_equivalent_tcb_psvn(int index) const;
  inline void set_latest_equivalent_tcb_psvn(int index, ::google::protobuf::uint32 value);
  inline void add_latest_equivalent_tcb_psvn(::google::protobuf::uint32 value);
  inline const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
      latest_equivalent_tcb_psvn() const;
  inline ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
      mutable_latest_equivalent_tcb_psvn();

  // repeated uint32 latest_pse_isvsvn = 8 [packed = true];
  inline int latest_pse_isvsvn_size() const;
  inline void clear_latest_pse_isvsvn();
  static const int kLatestPseIsvsvnFieldNumber = 8;
  inline ::google::protobuf::uint32 latest_pse_isvsvn(int index) const;
  inline void set_latest_pse_isvsvn(int index, ::google::protobuf::uint32 value);
  inline void add_latest_pse_isvsvn(::google::protobuf::uint32 value);
  inline const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
      latest_pse_isvsvn() const;
  inline ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
      mutable_latest_pse_isvsvn();

  // repeated uint32 latest_psda_svn = 9 [packed = true];
  inline int latest_psda_svn_size() const;
  inline void clear_latest_psda_svn();
  static const int kLatestPsdaSvnFieldNumber = 9;
  inline ::google::protobuf::uint32 latest_psda_svn(int index) const;
  inline void set_latest_psda_svn(int index, ::google::protobuf::uint32 value);
  inline void add_latest_psda_svn(::google::protobuf::uint32 value);
  inline const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
      latest_psda_svn() const;
  inline ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
      mutable_latest_psda_svn();

  // repeated uint32 performance_rekey_gid = 10 [packed = true];
  inline int performance_rekey_gid_size() const;
  inline void clear_performance_rekey_gid();
  static const int kPerformanceRekeyGidFieldNumber = 10;
  inline ::google::protobuf::uint32 performance_rekey_gid(int index) const;
  inline void set_performance_rekey_gid(int index, ::google::protobuf::uint32 value);
  inline void add_performance_rekey_gid(::google::protobuf::uint32 value);
  inline const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
      performance_rekey_gid() const;
  inline ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
      mutable_performance_rekey_gid();

  // repeated uint32 ec_sign256_x = 11 [packed = true];
  inline int ec_sign256_x_size() const;
  inline void clear_ec_sign256_x();
  static const int kEcSign256XFieldNumber = 11;
  inline ::google::protobuf::uint32 ec_sign256_x(int index) const;
  inline void set_ec_sign256_x(int index, ::google::protobuf::uint32 value);
  inline void add_ec_sign256_x(::google::protobuf::uint32 value);
  inline const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
      ec_sign256_x() const;
  inline ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
      mutable_ec_sign256_x();

  // repeated uint32 ec_sign256_y = 12 [packed = true];
  inline int ec_sign256_y_size() const;
  inline void clear_ec_sign256_y();
  static const int kEcSign256YFieldNumber = 12;
  inline ::google::protobuf::uint32 ec_sign256_y(int index) const;
  inline void set_ec_sign256_y(int index, ::google::protobuf::uint32 value);
  inline void add_ec_sign256_y(::google::protobuf::uint32 value);
  inline const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
      ec_sign256_y() const;
  inline ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
      mutable_ec_sign256_y();

  // repeated uint32 mac_smk = 13 [packed = true];
  inline int mac_smk_size() const;
  inline void clear_mac_smk();
  static const int kMacSmkFieldNumber = 13;
  inline ::google::protobuf::uint32 mac_smk(int index) const;
  inline void set_mac_smk(int index, ::google::protobuf::uint32 value);
  inline void add_mac_smk(::google::protobuf::uint32 value);
  inline const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
      mac_smk() const;
  inline ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
      mutable_mac_smk();

  // optional uint32 result_size = 14;
  inline bool has_result_size() const;
  inline void clear_result_size();
  static const int kResultSizeFieldNumber = 14;
  inline ::google::protobuf::uint32 result_size() const;
  inline void set_result_size(::google::protobuf::uint32 value);

  // repeated uint32 reserved = 15 [packed = true];
  inline int reserved_size() const;
  inline void clear_reserved();
  static const int kReservedFieldNumber = 15;
  inline ::google::protobuf::uint32 reserved(int index) const;
  inline void set_reserved(int index, ::google::protobuf::uint32 value);
  inline void add_reserved(::google::protobuf::uint32 value);
  inline const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
      reserved() const;
  inline ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
      mutable_reserved();

  // repeated uint32 payload_tag = 16 [packed = true];
  inline int payload_tag_size() const;
  inline void clear_payload_tag();
  static const int kPayloadTagFieldNumber = 16;
  inline ::google::protobuf::uint32 payload_tag(int index) const;
  inline void set_payload_tag(int index, ::google::protobuf::uint32 value);
  inline void add_payload_tag(::google::protobuf::uint32 value);
  inline const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
      payload_tag() const;
  inline ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
      mutable_payload_tag();

  // repeated uint32 payload = 17 [packed = true];
  inline int payload_size() const;
  inline void clear_payload();
  static const int kPayloadFieldNumber = 17;
  inline ::google::protobuf::uint32 payload(int index) const;
  inline void set_payload(int index, ::google::protobuf::uint32 value);
  inline void add_payload(::google::protobuf::uint32 value);
  inline const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
      payload() const;
  inline ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
      mutable_payload();

  // @@protoc_insertion_point(class_scope:Messages.AttestationMessage)
 private:
  inline void set_has_type();
  inline void clear_has_type();
  inline void set_has_size();
  inline void clear_has_size();
  inline void set_has_context();
  inline void clear_has_context();
  inline void set_has_epid_group_status();
  inline void clear_has_epid_group_status();
  inline void set_has_tcb_evaluation_status();
  inline void clear_has_tcb_evaluation_status();
  inline void set_has_pse_evaluation_status();
  inline void clear_has_pse_evaluation_status();
  inline void set_has_result_size();
  inline void clear_has_result_size();

  ::google::protobuf::UnknownFieldSet _unknown_fields_;

  ::google::protobuf::uint32 _has_bits_[1];
  mutable int _cached_size_;
  ::google::protobuf::uint32 type_;
  ::google::protobuf::uint32 size_;
  ::google::protobuf::uint32 context_;
  ::google::protobuf::uint32 epid_group_status_;
  ::google::protobuf::uint32 tcb_evaluation_status_;
  ::google::protobuf::uint32 pse_evaluation_status_;
  ::google::protobuf::RepeatedField< ::google::protobuf::uint32 > latest_equivalent_tcb_psvn_;
  mutable int _latest_equivalent_tcb_psvn_cached_byte_size_;
  ::google::protobuf::RepeatedField< ::google::protobuf::uint32 > latest_pse_isvsvn_;
  mutable int _latest_pse_isvsvn_cached_byte_size_;
  ::google::protobuf::RepeatedField< ::google::protobuf::uint32 > latest_psda_svn_;
  mutable int _latest_psda_svn_cached_byte_size_;
  ::google::protobuf::RepeatedField< ::google::protobuf::uint32 > performance_rekey_gid_;
  mutable int _performance_rekey_gid_cached_byte_size_;
  ::google::protobuf::RepeatedField< ::google::protobuf::uint32 > ec_sign256_x_;
  mutable int _ec_sign256_x_cached_byte_size_;
  ::google::protobuf::RepeatedField< ::google::protobuf::uint32 > ec_sign256_y_;
  mutable int _ec_sign256_y_cached_byte_size_;
  ::google::protobuf::RepeatedField< ::google::protobuf::uint32 > mac_smk_;
  mutable int _mac_smk_cached_byte_size_;
  ::google::protobuf::RepeatedField< ::google::protobuf::uint32 > reserved_;
  mutable int _reserved_cached_byte_size_;
  ::google::protobuf::RepeatedField< ::google::protobuf::uint32 > payload_tag_;
  mutable int _payload_tag_cached_byte_size_;
  ::google::protobuf::RepeatedField< ::google::protobuf::uint32 > payload_;
  mutable int _payload_cached_byte_size_;
  ::google::protobuf::uint32 result_size_;
  friend void  protobuf_AddDesc_Messages_2eproto();
  friend void protobuf_AssignDesc_Messages_2eproto();
  friend void protobuf_ShutdownFile_Messages_2eproto();

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

class MessagePsiSalt : public ::google::protobuf::Message {
 public:
  MessagePsiSalt();
  virtual ~MessagePsiSalt();

  MessagePsiSalt(const MessagePsiSalt& from);

  inline MessagePsiSalt& operator=(const MessagePsiSalt& 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 MessagePsiSalt& default_instance();

  void Swap(MessagePsiSalt* other);

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

  MessagePsiSalt* New() const;
  void CopyFrom(const ::google::protobuf::Message& from);
  void MergeFrom(const ::google::protobuf::Message& from);
  void CopyFrom(const MessagePsiSalt& from);
  void MergeFrom(const MessagePsiSalt& 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 type = 1;
  inline bool has_type() const;
  inline void clear_type();
  static const int kTypeFieldNumber = 1;
  inline ::google::protobuf::uint32 type() const;
  inline void set_type(::google::protobuf::uint32 value);

  // required uint32 size = 2;
  inline bool has_size() const;
  inline void clear_size();
  static const int kSizeFieldNumber = 2;
  inline ::google::protobuf::uint32 size() const;
  inline void set_size(::google::protobuf::uint32 value);

  // required uint32 context = 3;
  inline bool has_context() const;
  inline void clear_context();
  static const int kContextFieldNumber = 3;
  inline ::google::protobuf::uint32 context() const;
  inline void set_context(::google::protobuf::uint32 value);

  // required uint32 id = 4;
  inline bool has_id() const;
  inline void clear_id();
  static const int kIdFieldNumber = 4;
  inline ::google::protobuf::uint32 id() const;
  inline void set_id(::google::protobuf::uint32 value);

  // required uint32 state = 5;
  inline bool has_state() const;
  inline void clear_state();
  static const int kStateFieldNumber = 5;
  inline ::google::protobuf::uint32 state() const;
  inline void set_state(::google::protobuf::uint32 value);

  // repeated uint32 mac = 6 [packed = true];
  inline int mac_size() const;
  inline void clear_mac();
  static const int kMacFieldNumber = 6;
  inline ::google::protobuf::uint32 mac(int index) const;
  inline void set_mac(int index, ::google::protobuf::uint32 value);
  inline void add_mac(::google::protobuf::uint32 value);
  inline const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
      mac() const;
  inline ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
      mutable_mac();

  // repeated uint32 salt = 7 [packed = true];
  inline int salt_size() const;
  inline void clear_salt();
  static const int kSaltFieldNumber = 7;
  inline ::google::protobuf::uint32 salt(int index) const;
  inline void set_salt(int index, ::google::protobuf::uint32 value);
  inline void add_salt(::google::protobuf::uint32 value);
  inline const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
      salt() const;
  inline ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
      mutable_salt();

  // @@protoc_insertion_point(class_scope:Messages.MessagePsiSalt)
 private:
  inline void set_has_type();
  inline void clear_has_type();
  inline void set_has_size();
  inline void clear_has_size();
  inline void set_has_context();
  inline void clear_has_context();
  inline void set_has_id();
  inline void clear_has_id();
  inline void set_has_state();
  inline void clear_has_state();

  ::google::protobuf::UnknownFieldSet _unknown_fields_;

  ::google::protobuf::uint32 _has_bits_[1];
  mutable int _cached_size_;
  ::google::protobuf::uint32 type_;
  ::google::protobuf::uint32 size_;
  ::google::protobuf::uint32 context_;
  ::google::protobuf::uint32 id_;
  ::google::protobuf::RepeatedField< ::google::protobuf::uint32 > mac_;
  mutable int _mac_cached_byte_size_;
  ::google::protobuf::RepeatedField< ::google::protobuf::uint32 > salt_;
  mutable int _salt_cached_byte_size_;
  ::google::protobuf::uint32 state_;
  friend void  protobuf_AddDesc_Messages_2eproto();
  friend void protobuf_AssignDesc_Messages_2eproto();
  friend void protobuf_ShutdownFile_Messages_2eproto();

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

class MessagePsiHashData : public ::google::protobuf::Message {
 public:
  MessagePsiHashData();
  virtual ~MessagePsiHashData();

  MessagePsiHashData(const MessagePsiHashData& from);

  inline MessagePsiHashData& operator=(const MessagePsiHashData& 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 MessagePsiHashData& default_instance();

  void Swap(MessagePsiHashData* other);

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

  MessagePsiHashData* New() const;
  void CopyFrom(const ::google::protobuf::Message& from);
  void MergeFrom(const ::google::protobuf::Message& from);
  void CopyFrom(const MessagePsiHashData& from);
  void MergeFrom(const MessagePsiHashData& 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 type = 1;
  inline bool has_type() const;
  inline void clear_type();
  static const int kTypeFieldNumber = 1;
  inline ::google::protobuf::uint32 type() const;
  inline void set_type(::google::protobuf::uint32 value);

  // required uint32 size = 2;
  inline bool has_size() const;
  inline void clear_size();
  static const int kSizeFieldNumber = 2;
  inline ::google::protobuf::uint32 size() const;
  inline void set_size(::google::protobuf::uint32 value);

  // required uint32 context = 3;
  inline bool has_context() const;
  inline void clear_context();
  static const int kContextFieldNumber = 3;
  inline ::google::protobuf::uint32 context() const;
  inline void set_context(::google::protobuf::uint32 value);

  // required uint32 id = 4;
  inline bool has_id() const;
  inline void clear_id();
  static const int kIdFieldNumber = 4;
  inline ::google::protobuf::uint32 id() const;
  inline void set_id(::google::protobuf::uint32 value);

  // repeated uint32 mac = 5 [packed = true];
  inline int mac_size() const;
  inline void clear_mac();
  static const int kMacFieldNumber = 5;
  inline ::google::protobuf::uint32 mac(int index) const;
  inline void set_mac(int index, ::google::protobuf::uint32 value);
  inline void add_mac(::google::protobuf::uint32 value);
  inline const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
      mac() const;
  inline ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
      mutable_mac();

  // repeated uint32 data = 6 [packed = true];
  inline int data_size() const;
  inline void clear_data();
  static const int kDataFieldNumber = 6;
  inline ::google::protobuf::uint32 data(int index) const;
  inline void set_data(int index, ::google::protobuf::uint32 value);
  inline void add_data(::google::protobuf::uint32 value);
  inline const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
      data() const;
  inline ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
      mutable_data();

  // @@protoc_insertion_point(class_scope:Messages.MessagePsiHashData)
 private:
  inline void set_has_type();
  inline void clear_has_type();
  inline void set_has_size();
  inline void clear_has_size();
  inline void set_has_context();
  inline void clear_has_context();
  inline void set_has_id();
  inline void clear_has_id();

  ::google::protobuf::UnknownFieldSet _unknown_fields_;

  ::google::protobuf::uint32 _has_bits_[1];
  mutable int _cached_size_;
  ::google::protobuf::uint32 type_;
  ::google::protobuf::uint32 size_;
  ::google::protobuf::uint32 context_;
  ::google::protobuf::uint32 id_;
  ::google::protobuf::RepeatedField< ::google::protobuf::uint32 > mac_;
  mutable int _mac_cached_byte_size_;
  ::google::protobuf::RepeatedField< ::google::protobuf::uint32 > data_;
  mutable int _data_cached_byte_size_;
  friend void  protobuf_AddDesc_Messages_2eproto();
  friend void protobuf_AssignDesc_Messages_2eproto();
  friend void protobuf_ShutdownFile_Messages_2eproto();

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

class MessagePsiHashDataFinished : public ::google::protobuf::Message {
 public:
  MessagePsiHashDataFinished();
  virtual ~MessagePsiHashDataFinished();

  MessagePsiHashDataFinished(const MessagePsiHashDataFinished& from);

  inline MessagePsiHashDataFinished& operator=(const MessagePsiHashDataFinished& 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 MessagePsiHashDataFinished& default_instance();

  void Swap(MessagePsiHashDataFinished* other);

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

  MessagePsiHashDataFinished* New() const;
  void CopyFrom(const ::google::protobuf::Message& from);
  void MergeFrom(const ::google::protobuf::Message& from);
  void CopyFrom(const MessagePsiHashDataFinished& from);
  void MergeFrom(const MessagePsiHashDataFinished& 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 type = 1;
  inline bool has_type() const;
  inline void clear_type();
  static const int kTypeFieldNumber = 1;
  inline ::google::protobuf::uint32 type() const;
  inline void set_type(::google::protobuf::uint32 value);

  // required uint32 size = 2;
  inline bool has_size() const;
  inline void clear_size();
  static const int kSizeFieldNumber = 2;
  inline ::google::protobuf::uint32 size() const;
  inline void set_size(::google::protobuf::uint32 value);

  // required uint32 context = 3;
  inline bool has_context() const;
  inline void clear_context();
  static const int kContextFieldNumber = 3;
  inline ::google::protobuf::uint32 context() const;
  inline void set_context(::google::protobuf::uint32 value);

  // required uint32 id = 4;
  inline bool has_id() const;
  inline void clear_id();
  static const int kIdFieldNumber = 4;
  inline ::google::protobuf::uint32 id() const;
  inline void set_id(::google::protobuf::uint32 value);

  // @@protoc_insertion_point(class_scope:Messages.MessagePsiHashDataFinished)
 private:
  inline void set_has_type();
  inline void clear_has_type();
  inline void set_has_size();
  inline void clear_has_size();
  inline void set_has_context();
  inline void clear_has_context();
  inline void set_has_id();
  inline void clear_has_id();

  ::google::protobuf::UnknownFieldSet _unknown_fields_;

  ::google::protobuf::uint32 _has_bits_[1];
  mutable int _cached_size_;
  ::google::protobuf::uint32 type_;
  ::google::protobuf::uint32 size_;
  ::google::protobuf::uint32 context_;
  ::google::protobuf::uint32 id_;
  friend void  protobuf_AddDesc_Messages_2eproto();
  friend void protobuf_AssignDesc_Messages_2eproto();
  friend void protobuf_ShutdownFile_Messages_2eproto();

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

class MessagePsiResult : public ::google::protobuf::Message {
 public:
  MessagePsiResult();
  virtual ~MessagePsiResult();

  MessagePsiResult(const MessagePsiResult& from);

  inline MessagePsiResult& operator=(const MessagePsiResult& 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 MessagePsiResult& default_instance();

  void Swap(MessagePsiResult* other);

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

  MessagePsiResult* New() const;
  void CopyFrom(const ::google::protobuf::Message& from);
  void MergeFrom(const ::google::protobuf::Message& from);
  void CopyFrom(const MessagePsiResult& from);
  void MergeFrom(const MessagePsiResult& 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 type = 1;
  inline bool has_type() const;
  inline void clear_type();
  static const int kTypeFieldNumber = 1;
  inline ::google::protobuf::uint32 type() const;
  inline void set_type(::google::protobuf::uint32 value);

  // required uint32 size = 2;
  inline bool has_size() const;
  inline void clear_size();
  static const int kSizeFieldNumber = 2;
  inline ::google::protobuf::uint32 size() const;
  inline void set_size(::google::protobuf::uint32 value);

  // required uint32 context = 3;
  inline bool has_context() const;
  inline void clear_context();
  static const int kContextFieldNumber = 3;
  inline ::google::protobuf::uint32 context() const;
  inline void set_context(::google::protobuf::uint32 value);

  // required uint32 id = 4;
  inline bool has_id() const;
  inline void clear_id();
  static const int kIdFieldNumber = 4;
  inline ::google::protobuf::uint32 id() const;
  inline void set_id(::google::protobuf::uint32 value);

  // required uint32 state = 5;
  inline bool has_state() const;
  inline void clear_state();
  static const int kStateFieldNumber = 5;
  inline ::google::protobuf::uint32 state() const;
  inline void set_state(::google::protobuf::uint32 value);

  // @@protoc_insertion_point(class_scope:Messages.MessagePsiResult)
 private:
  inline void set_has_type();
  inline void clear_has_type();
  inline void set_has_size();
  inline void clear_has_size();
  inline void set_has_context();
  inline void clear_has_context();
  inline void set_has_id();
  inline void clear_has_id();
  inline void set_has_state();
  inline void clear_has_state();

  ::google::protobuf::UnknownFieldSet _unknown_fields_;

  ::google::protobuf::uint32 _has_bits_[1];
  mutable int _cached_size_;
  ::google::protobuf::uint32 type_;
  ::google::protobuf::uint32 size_;
  ::google::protobuf::uint32 context_;
  ::google::protobuf::uint32 id_;
  ::google::protobuf::uint32 state_;
  friend void  protobuf_AddDesc_Messages_2eproto();
  friend void protobuf_AssignDesc_Messages_2eproto();
  friend void protobuf_ShutdownFile_Messages_2eproto();

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

class MessagePsiIntersect : public ::google::protobuf::Message {
 public:
  MessagePsiIntersect();
  virtual ~MessagePsiIntersect();

  MessagePsiIntersect(const MessagePsiIntersect& from);

  inline MessagePsiIntersect& operator=(const MessagePsiIntersect& 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 MessagePsiIntersect& default_instance();

  void Swap(MessagePsiIntersect* other);

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

  MessagePsiIntersect* New() const;
  void CopyFrom(const ::google::protobuf::Message& from);
  void MergeFrom(const ::google::protobuf::Message& from);
  void CopyFrom(const MessagePsiIntersect& from);
  void MergeFrom(const MessagePsiIntersect& 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 type = 1;
  inline bool has_type() const;
  inline void clear_type();
  static const int kTypeFieldNumber = 1;
  inline ::google::protobuf::uint32 type() const;
  inline void set_type(::google::protobuf::uint32 value);

  // required uint32 size = 2;
  inline bool has_size() const;
  inline void clear_size();
  static const int kSizeFieldNumber = 2;
  inline ::google::protobuf::uint32 size() const;
  inline void set_size(::google::protobuf::uint32 value);

  // required uint32 context = 3;
  inline bool has_context() const;
  inline void clear_context();
  static const int kContextFieldNumber = 3;
  inline ::google::protobuf::uint32 context() const;
  inline void set_context(::google::protobuf::uint32 value);

  // required uint32 id = 4;
  inline bool has_id() const;
  inline void clear_id();
  static const int kIdFieldNumber = 4;
  inline ::google::protobuf::uint32 id() const;
  inline void set_id(::google::protobuf::uint32 value);

  // repeated uint32 mac = 5 [packed = true];
  inline int mac_size() const;
  inline void clear_mac();
  static const int kMacFieldNumber = 5;
  inline ::google::protobuf::uint32 mac(int index) const;
  inline void set_mac(int index, ::google::protobuf::uint32 value);
  inline void add_mac(::google::protobuf::uint32 value);
  inline const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
      mac() const;
  inline ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
      mutable_mac();

  // repeated uint32 data = 6 [packed = true];
  inline int data_size() const;
  inline void clear_data();
  static const int kDataFieldNumber = 6;
  inline ::google::protobuf::uint32 data(int index) const;
  inline void set_data(int index, ::google::protobuf::uint32 value);
  inline void add_data(::google::protobuf::uint32 value);
  inline const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
      data() const;
  inline ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
      mutable_data();

  // @@protoc_insertion_point(class_scope:Messages.MessagePsiIntersect)
 private:
  inline void set_has_type();
  inline void clear_has_type();
  inline void set_has_size();
  inline void clear_has_size();
  inline void set_has_context();
  inline void clear_has_context();
  inline void set_has_id();
  inline void clear_has_id();

  ::google::protobuf::UnknownFieldSet _unknown_fields_;

  ::google::protobuf::uint32 _has_bits_[1];
  mutable int _cached_size_;
  ::google::protobuf::uint32 type_;
  ::google::protobuf::uint32 size_;
  ::google::protobuf::uint32 context_;
  ::google::protobuf::uint32 id_;
  ::google::protobuf::RepeatedField< ::google::protobuf::uint32 > mac_;
  mutable int _mac_cached_byte_size_;
  ::google::protobuf::RepeatedField< ::google::protobuf::uint32 > data_;
  mutable int _data_cached_byte_size_;
  friend void  protobuf_AddDesc_Messages_2eproto();
  friend void protobuf_AssignDesc_Messages_2eproto();
  friend void protobuf_ShutdownFile_Messages_2eproto();

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


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

// InitialMessage

// required uint32 type = 1;
inline bool InitialMessage::has_type() const {
  return (_has_bits_[0] & 0x00000001u) != 0;
}
inline void InitialMessage::set_has_type() {
  _has_bits_[0] |= 0x00000001u;
}
inline void InitialMessage::clear_has_type() {
  _has_bits_[0] &= ~0x00000001u;
}
inline void InitialMessage::clear_type() {
  type_ = 0u;
  clear_has_type();
}
inline ::google::protobuf::uint32 InitialMessage::type() const {
  // @@protoc_insertion_point(field_get:Messages.InitialMessage.type)
  return type_;
}
inline void InitialMessage::set_type(::google::protobuf::uint32 value) {
  set_has_type();
  type_ = value;
  // @@protoc_insertion_point(field_set:Messages.InitialMessage.type)
}

// optional uint32 size = 2;
inline bool InitialMessage::has_size() const {
  return (_has_bits_[0] & 0x00000002u) != 0;
}
inline void InitialMessage::set_has_size() {
  _has_bits_[0] |= 0x00000002u;
}
inline void InitialMessage::clear_has_size() {
  _has_bits_[0] &= ~0x00000002u;
}
inline void InitialMessage::clear_size() {
  size_ = 0u;
  clear_has_size();
}
inline ::google::protobuf::uint32 InitialMessage::size() const {
  // @@protoc_insertion_point(field_get:Messages.InitialMessage.size)
  return size_;
}
inline void InitialMessage::set_size(::google::protobuf::uint32 value) {
  set_has_size();
  size_ = value;
  // @@protoc_insertion_point(field_set:Messages.InitialMessage.size)
}

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

// MessageMsg0

// required uint32 type = 1;
inline bool MessageMsg0::has_type() const {
  return (_has_bits_[0] & 0x00000001u) != 0;
}
inline void MessageMsg0::set_has_type() {
  _has_bits_[0] |= 0x00000001u;
}
inline void MessageMsg0::clear_has_type() {
  _has_bits_[0] &= ~0x00000001u;
}
inline void MessageMsg0::clear_type() {
  type_ = 0u;
  clear_has_type();
}
inline ::google::protobuf::uint32 MessageMsg0::type() const {
  // @@protoc_insertion_point(field_get:Messages.MessageMsg0.type)
  return type_;
}
inline void MessageMsg0::set_type(::google::protobuf::uint32 value) {
  set_has_type();
  type_ = value;
  // @@protoc_insertion_point(field_set:Messages.MessageMsg0.type)
}

// required uint32 epid = 2;
inline bool MessageMsg0::has_epid() const {
  return (_has_bits_[0] & 0x00000002u) != 0;
}
inline void MessageMsg0::set_has_epid() {
  _has_bits_[0] |= 0x00000002u;
}
inline void MessageMsg0::clear_has_epid() {
  _has_bits_[0] &= ~0x00000002u;
}
inline void MessageMsg0::clear_epid() {
  epid_ = 0u;
  clear_has_epid();
}
inline ::google::protobuf::uint32 MessageMsg0::epid() const {
  // @@protoc_insertion_point(field_get:Messages.MessageMsg0.epid)
  return epid_;
}
inline void MessageMsg0::set_epid(::google::protobuf::uint32 value) {
  set_has_epid();
  epid_ = value;
  // @@protoc_insertion_point(field_set:Messages.MessageMsg0.epid)
}

// optional uint32 status = 3;
inline bool MessageMsg0::has_status() const {
  return (_has_bits_[0] & 0x00000004u) != 0;
}
inline void MessageMsg0::set_has_status() {
  _has_bits_[0] |= 0x00000004u;
}
inline void MessageMsg0::clear_has_status() {
  _has_bits_[0] &= ~0x00000004u;
}
inline void MessageMsg0::clear_status() {
  status_ = 0u;
  clear_has_status();
}
inline ::google::protobuf::uint32 MessageMsg0::status() const {
  // @@protoc_insertion_point(field_get:Messages.MessageMsg0.status)
  return status_;
}
inline void MessageMsg0::set_status(::google::protobuf::uint32 value) {
  set_has_status();
  status_ = value;
  // @@protoc_insertion_point(field_set:Messages.MessageMsg0.status)
}

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

// MessageMSG1

// required uint32 type = 1;
inline bool MessageMSG1::has_type() const {
  return (_has_bits_[0] & 0x00000001u) != 0;
}
inline void MessageMSG1::set_has_type() {
  _has_bits_[0] |= 0x00000001u;
}
inline void MessageMSG1::clear_has_type() {
  _has_bits_[0] &= ~0x00000001u;
}
inline void MessageMSG1::clear_type() {
  type_ = 0u;
  clear_has_type();
}
inline ::google::protobuf::uint32 MessageMSG1::type() const {
  // @@protoc_insertion_point(field_get:Messages.MessageMSG1.type)
  return type_;
}
inline void MessageMSG1::set_type(::google::protobuf::uint32 value) {
  set_has_type();
  type_ = value;
  // @@protoc_insertion_point(field_set:Messages.MessageMSG1.type)
}

// required uint32 context = 2;
inline bool MessageMSG1::has_context() const {
  return (_has_bits_[0] & 0x00000002u) != 0;
}
inline void MessageMSG1::set_has_context() {
  _has_bits_[0] |= 0x00000002u;
}
inline void MessageMSG1::clear_has_context() {
  _has_bits_[0] &= ~0x00000002u;
}
inline void MessageMSG1::clear_context() {
  context_ = 0u;
  clear_has_context();
}
inline ::google::protobuf::uint32 MessageMSG1::context() const {
  // @@protoc_insertion_point(field_get:Messages.MessageMSG1.context)
  return context_;
}
inline void MessageMSG1::set_context(::google::protobuf::uint32 value) {
  set_has_context();
  context_ = value;
  // @@protoc_insertion_point(field_set:Messages.MessageMSG1.context)
}

// repeated uint32 GaX = 3 [packed = true];
inline int MessageMSG1::gax_size() const {
  return gax_.size();
}
inline void MessageMSG1::clear_gax() {
  gax_.Clear();
}
inline ::google::protobuf::uint32 MessageMSG1::gax(int index) const {
  // @@protoc_insertion_point(field_get:Messages.MessageMSG1.GaX)
  return gax_.Get(index);
}
inline void MessageMSG1::set_gax(int index, ::google::protobuf::uint32 value) {
  gax_.Set(index, value);
  // @@protoc_insertion_point(field_set:Messages.MessageMSG1.GaX)
}
inline void MessageMSG1::add_gax(::google::protobuf::uint32 value) {
  gax_.Add(value);
  // @@protoc_insertion_point(field_add:Messages.MessageMSG1.GaX)
}
inline const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
MessageMSG1::gax() const {
  // @@protoc_insertion_point(field_list:Messages.MessageMSG1.GaX)
  return gax_;
}
inline ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
MessageMSG1::mutable_gax() {
  // @@protoc_insertion_point(field_mutable_list:Messages.MessageMSG1.GaX)
  return &gax_;
}

// repeated uint32 GaY = 4 [packed = true];
inline int MessageMSG1::gay_size() const {
  return gay_.size();
}
inline void MessageMSG1::clear_gay() {
  gay_.Clear();
}
inline ::google::protobuf::uint32 MessageMSG1::gay(int index) const {
  // @@protoc_insertion_point(field_get:Messages.MessageMSG1.GaY)
  return gay_.Get(index);
}
inline void MessageMSG1::set_gay(int index, ::google::protobuf::uint32 value) {
  gay_.Set(index, value);
  // @@protoc_insertion_point(field_set:Messages.MessageMSG1.GaY)
}
inline void MessageMSG1::add_gay(::google::protobuf::uint32 value) {
  gay_.Add(value);
  // @@protoc_insertion_point(field_add:Messages.MessageMSG1.GaY)
}
inline const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
MessageMSG1::gay() const {
  // @@protoc_insertion_point(field_list:Messages.MessageMSG1.GaY)
  return gay_;
}
inline ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
MessageMSG1::mutable_gay() {
  // @@protoc_insertion_point(field_mutable_list:Messages.MessageMSG1.GaY)
  return &gay_;
}

// repeated uint32 GID = 5 [packed = true];
inline int MessageMSG1::gid_size() const {
  return gid_.size();
}
inline void MessageMSG1::clear_gid() {
  gid_.Clear();
}
inline ::google::protobuf::uint32 MessageMSG1::gid(int index) const {
  // @@protoc_insertion_point(field_get:Messages.MessageMSG1.GID)
  return gid_.Get(index);
}
inline void MessageMSG1::set_gid(int index, ::google::protobuf::uint32 value) {
  gid_.Set(index, value);
  // @@protoc_insertion_point(field_set:Messages.MessageMSG1.GID)
}
inline void MessageMSG1::add_gid(::google::protobuf::uint32 value) {
  gid_.Add(value);
  // @@protoc_insertion_point(field_add:Messages.MessageMSG1.GID)
}
inline const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
MessageMSG1::gid() const {
  // @@protoc_insertion_point(field_list:Messages.MessageMSG1.GID)
  return gid_;
}
inline ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
MessageMSG1::mutable_gid() {
  // @@protoc_insertion_point(field_mutable_list:Messages.MessageMSG1.GID)
  return &gid_;
}

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

// MessageMSG2

// required uint32 type = 1;
inline bool MessageMSG2::has_type() const {
  return (_has_bits_[0] & 0x00000001u) != 0;
}
inline void MessageMSG2::set_has_type() {
  _has_bits_[0] |= 0x00000001u;
}
inline void MessageMSG2::clear_has_type() {
  _has_bits_[0] &= ~0x00000001u;
}
inline void MessageMSG2::clear_type() {
  type_ = 0u;
  clear_has_type();
}
inline ::google::protobuf::uint32 MessageMSG2::type() const {
  // @@protoc_insertion_point(field_get:Messages.MessageMSG2.type)
  return type_;
}
inline void MessageMSG2::set_type(::google::protobuf::uint32 value) {
  set_has_type();
  type_ = value;
  // @@protoc_insertion_point(field_set:Messages.MessageMSG2.type)
}

// optional uint32 size = 2;
inline bool MessageMSG2::has_size() const {
  return (_has_bits_[0] & 0x00000002u) != 0;
}
inline void MessageMSG2::set_has_size() {
  _has_bits_[0] |= 0x00000002u;
}
inline void MessageMSG2::clear_has_size() {
  _has_bits_[0] &= ~0x00000002u;
}
inline void MessageMSG2::clear_size() {
  size_ = 0u;
  clear_has_size();
}
inline ::google::protobuf::uint32 MessageMSG2::size() const {
  // @@protoc_insertion_point(field_get:Messages.MessageMSG2.size)
  return size_;
}
inline void MessageMSG2::set_size(::google::protobuf::uint32 value) {
  set_has_size();
  size_ = value;
  // @@protoc_insertion_point(field_set:Messages.MessageMSG2.size)
}

// required uint32 context = 3;
inline bool MessageMSG2::has_context() const {
  return (_has_bits_[0] & 0x00000004u) != 0;
}
inline void MessageMSG2::set_has_context() {
  _has_bits_[0] |= 0x00000004u;
}
inline void MessageMSG2::clear_has_context() {
  _has_bits_[0] &= ~0x00000004u;
}
inline void MessageMSG2::clear_context() {
  context_ = 0u;
  clear_has_context();
}
inline ::google::protobuf::uint32 MessageMSG2::context() const {
  // @@protoc_insertion_point(field_get:Messages.MessageMSG2.context)
  return context_;
}
inline void MessageMSG2::set_context(::google::protobuf::uint32 value) {
  set_has_context();
  context_ = value;
  // @@protoc_insertion_point(field_set:Messages.MessageMSG2.context)
}

// repeated uint32 public_key_gx = 4 [packed = true];
inline int MessageMSG2::public_key_gx_size() const {
  return public_key_gx_.size();
}
inline void MessageMSG2::clear_public_key_gx() {
  public_key_gx_.Clear();
}
inline ::google::protobuf::uint32 MessageMSG2::public_key_gx(int index) const {
  // @@protoc_insertion_point(field_get:Messages.MessageMSG2.public_key_gx)
  return public_key_gx_.Get(index);
}
inline void MessageMSG2::set_public_key_gx(int index, ::google::protobuf::uint32 value) {
  public_key_gx_.Set(index, value);
  // @@protoc_insertion_point(field_set:Messages.MessageMSG2.public_key_gx)
}
inline void MessageMSG2::add_public_key_gx(::google::protobuf::uint32 value) {
  public_key_gx_.Add(value);
  // @@protoc_insertion_point(field_add:Messages.MessageMSG2.public_key_gx)
}
inline const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
MessageMSG2::public_key_gx() const {
  // @@protoc_insertion_point(field_list:Messages.MessageMSG2.public_key_gx)
  return public_key_gx_;
}
inline ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
MessageMSG2::mutable_public_key_gx() {
  // @@protoc_insertion_point(field_mutable_list:Messages.MessageMSG2.public_key_gx)
  return &public_key_gx_;
}

// repeated uint32 public_key_gy = 5 [packed = true];
inline int MessageMSG2::public_key_gy_size() const {
  return public_key_gy_.size();
}
inline void MessageMSG2::clear_public_key_gy() {
  public_key_gy_.Clear();
}
inline ::google::protobuf::uint32 MessageMSG2::public_key_gy(int index) const {
  // @@protoc_insertion_point(field_get:Messages.MessageMSG2.public_key_gy)
  return public_key_gy_.Get(index);
}
inline void MessageMSG2::set_public_key_gy(int index, ::google::protobuf::uint32 value) {
  public_key_gy_.Set(index, value);
  // @@protoc_insertion_point(field_set:Messages.MessageMSG2.public_key_gy)
}
inline void MessageMSG2::add_public_key_gy(::google::protobuf::uint32 value) {
  public_key_gy_.Add(value);
  // @@protoc_insertion_point(field_add:Messages.MessageMSG2.public_key_gy)
}
inline const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
MessageMSG2::public_key_gy() const {
  // @@protoc_insertion_point(field_list:Messages.MessageMSG2.public_key_gy)
  return public_key_gy_;
}
inline ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
MessageMSG2::mutable_public_key_gy() {
  // @@protoc_insertion_point(field_mutable_list:Messages.MessageMSG2.public_key_gy)
  return &public_key_gy_;
}

// optional uint32 quote_type = 6;
inline bool MessageMSG2::has_quote_type() const {
  return (_has_bits_[0] & 0x00000020u) != 0;
}
inline void MessageMSG2::set_has_quote_type() {
  _has_bits_[0] |= 0x00000020u;
}
inline void MessageMSG2::clear_has_quote_type() {
  _has_bits_[0] &= ~0x00000020u;
}
inline void MessageMSG2::clear_quote_type() {
  quote_type_ = 0u;
  clear_has_quote_type();
}
inline ::google::protobuf::uint32 MessageMSG2::quote_type() const {
  // @@protoc_insertion_point(field_get:Messages.MessageMSG2.quote_type)
  return quote_type_;
}
inline void MessageMSG2::set_quote_type(::google::protobuf::uint32 value) {
  set_has_quote_type();
  quote_type_ = value;
  // @@protoc_insertion_point(field_set:Messages.MessageMSG2.quote_type)
}

// repeated uint32 spid = 7 [packed = true];
inline int MessageMSG2::spid_size() const {
  return spid_.size();
}
inline void MessageMSG2::clear_spid() {
  spid_.Clear();
}
inline ::google::protobuf::uint32 MessageMSG2::spid(int index) const {
  // @@protoc_insertion_point(field_get:Messages.MessageMSG2.spid)
  return spid_.Get(index);
}
inline void MessageMSG2::set_spid(int index, ::google::protobuf::uint32 value) {
  spid_.Set(index, value);
  // @@protoc_insertion_point(field_set:Messages.MessageMSG2.spid)
}
inline void MessageMSG2::add_spid(::google::protobuf::uint32 value) {
  spid_.Add(value);
  // @@protoc_insertion_point(field_add:Messages.MessageMSG2.spid)
}
inline const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
MessageMSG2::spid() const {
  // @@protoc_insertion_point(field_list:Messages.MessageMSG2.spid)
  return spid_;
}
inline ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
MessageMSG2::mutable_spid() {
  // @@protoc_insertion_point(field_mutable_list:Messages.MessageMSG2.spid)
  return &spid_;
}

// optional uint32 cmac_kdf_id = 8;
inline bool MessageMSG2::has_cmac_kdf_id() const {
  return (_has_bits_[0] & 0x00000080u) != 0;
}
inline void MessageMSG2::set_has_cmac_kdf_id() {
  _has_bits_[0] |= 0x00000080u;
}
inline void MessageMSG2::clear_has_cmac_kdf_id() {
  _has_bits_[0] &= ~0x00000080u;
}
inline void MessageMSG2::clear_cmac_kdf_id() {
  cmac_kdf_id_ = 0u;
  clear_has_cmac_kdf_id();
}
inline ::google::protobuf::uint32 MessageMSG2::cmac_kdf_id() const {
  // @@protoc_insertion_point(field_get:Messages.MessageMSG2.cmac_kdf_id)
  return cmac_kdf_id_;
}
inline void MessageMSG2::set_cmac_kdf_id(::google::protobuf::uint32 value) {
  set_has_cmac_kdf_id();
  cmac_kdf_id_ = value;
  // @@protoc_insertion_point(field_set:Messages.MessageMSG2.cmac_kdf_id)
}

// repeated uint32 signature_x = 9 [packed = true];
inline int MessageMSG2::signature_x_size() const {
  return signature_x_.size();
}
inline void MessageMSG2::clear_signature_x() {
  signature_x_.Clear();
}
inline ::google::protobuf::uint32 MessageMSG2::signature_x(int index) const {
  // @@protoc_insertion_point(field_get:Messages.MessageMSG2.signature_x)
  return signature_x_.Get(index);
}
inline void MessageMSG2::set_signature_x(int index, ::google::protobuf::uint32 value) {
  signature_x_.Set(index, value);
  // @@protoc_insertion_point(field_set:Messages.MessageMSG2.signature_x)
}
inline void MessageMSG2::add_signature_x(::google::protobuf::uint32 value) {
  signature_x_.Add(value);
  // @@protoc_insertion_point(field_add:Messages.MessageMSG2.signature_x)
}
inline const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
MessageMSG2::signature_x() const {
  // @@protoc_insertion_point(field_list:Messages.MessageMSG2.signature_x)
  return signature_x_;
}
inline ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
MessageMSG2::mutable_signature_x() {
  // @@protoc_insertion_point(field_mutable_list:Messages.MessageMSG2.signature_x)
  return &signature_x_;
}

// repeated uint32 signature_y = 10 [packed = true];
inline int MessageMSG2::signature_y_size() const {
  return signature_y_.size();
}
inline void MessageMSG2::clear_signature_y() {
  signature_y_.Clear();
}
inline ::google::protobuf::uint32 MessageMSG2::signature_y(int index) const {
  // @@protoc_insertion_point(field_get:Messages.MessageMSG2.signature_y)
  return signature_y_.Get(index);
}
inline void MessageMSG2::set_signature_y(int index, ::google::protobuf::uint32 value) {
  signature_y_.Set(index, value);
  // @@protoc_insertion_point(field_set:Messages.MessageMSG2.signature_y)
}
inline void MessageMSG2::add_signature_y(::google::protobuf::uint32 value) {
  signature_y_.Add(value);
  // @@protoc_insertion_point(field_add:Messages.MessageMSG2.signature_y)
}
inline const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
MessageMSG2::signature_y() const {
  // @@protoc_insertion_point(field_list:Messages.MessageMSG2.signature_y)
  return signature_y_;
}
inline ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
MessageMSG2::mutable_signature_y() {
  // @@protoc_insertion_point(field_mutable_list:Messages.MessageMSG2.signature_y)
  return &signature_y_;
}

// repeated uint32 smac = 11 [packed = true];
inline int MessageMSG2::smac_size() const {
  return smac_.size();
}
inline void MessageMSG2::clear_smac() {
  smac_.Clear();
}
inline ::google::protobuf::uint32 MessageMSG2::smac(int index) const {
  // @@protoc_insertion_point(field_get:Messages.MessageMSG2.smac)
  return smac_.Get(index);
}
inline void MessageMSG2::set_smac(int index, ::google::protobuf::uint32 value) {
  smac_.Set(index, value);
  // @@protoc_insertion_point(field_set:Messages.MessageMSG2.smac)
}
inline void MessageMSG2::add_smac(::google::protobuf::uint32 value) {
  smac_.Add(value);
  // @@protoc_insertion_point(field_add:Messages.MessageMSG2.smac)
}
inline const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
MessageMSG2::smac() const {
  // @@protoc_insertion_point(field_list:Messages.MessageMSG2.smac)
  return smac_;
}
inline ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
MessageMSG2::mutable_smac() {
  // @@protoc_insertion_point(field_mutable_list:Messages.MessageMSG2.smac)
  return &smac_;
}

// optional uint32 size_sigrl = 12;
inline bool MessageMSG2::has_size_sigrl() const {
  return (_has_bits_[0] & 0x00000800u) != 0;
}
inline void MessageMSG2::set_has_size_sigrl() {
  _has_bits_[0] |= 0x00000800u;
}
inline void MessageMSG2::clear_has_size_sigrl() {
  _has_bits_[0] &= ~0x00000800u;
}
inline void MessageMSG2::clear_size_sigrl() {
  size_sigrl_ = 0u;
  clear_has_size_sigrl();
}
inline ::google::protobuf::uint32 MessageMSG2::size_sigrl() const {
  // @@protoc_insertion_point(field_get:Messages.MessageMSG2.size_sigrl)
  return size_sigrl_;
}
inline void MessageMSG2::set_size_sigrl(::google::protobuf::uint32 value) {
  set_has_size_sigrl();
  size_sigrl_ = value;
  // @@protoc_insertion_point(field_set:Messages.MessageMSG2.size_sigrl)
}

// repeated uint32 sigrl = 13 [packed = true];
inline int MessageMSG2::sigrl_size() const {
  return sigrl_.size();
}
inline void MessageMSG2::clear_sigrl() {
  sigrl_.Clear();
}
inline ::google::protobuf::uint32 MessageMSG2::sigrl(int index) const {
  // @@protoc_insertion_point(field_get:Messages.MessageMSG2.sigrl)
  return sigrl_.Get(index);
}
inline void MessageMSG2::set_sigrl(int index, ::google::protobuf::uint32 value) {
  sigrl_.Set(index, value);
  // @@protoc_insertion_point(field_set:Messages.MessageMSG2.sigrl)
}
inline void MessageMSG2::add_sigrl(::google::protobuf::uint32 value) {
  sigrl_.Add(value);
  // @@protoc_insertion_point(field_add:Messages.MessageMSG2.sigrl)
}
inline const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
MessageMSG2::sigrl() const {
  // @@protoc_insertion_point(field_list:Messages.MessageMSG2.sigrl)
  return sigrl_;
}
inline ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
MessageMSG2::mutable_sigrl() {
  // @@protoc_insertion_point(field_mutable_list:Messages.MessageMSG2.sigrl)
  return &sigrl_;
}

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

// MessageMSG3

// required uint32 type = 1;
inline bool MessageMSG3::has_type() const {
  return (_has_bits_[0] & 0x00000001u) != 0;
}
inline void MessageMSG3::set_has_type() {
  _has_bits_[0] |= 0x00000001u;
}
inline void MessageMSG3::clear_has_type() {
  _has_bits_[0] &= ~0x00000001u;
}
inline void MessageMSG3::clear_type() {
  type_ = 0u;
  clear_has_type();
}
inline ::google::protobuf::uint32 MessageMSG3::type() const {
  // @@protoc_insertion_point(field_get:Messages.MessageMSG3.type)
  return type_;
}
inline void MessageMSG3::set_type(::google::protobuf::uint32 value) {
  set_has_type();
  type_ = value;
  // @@protoc_insertion_point(field_set:Messages.MessageMSG3.type)
}

// optional uint32 size = 2;
inline bool MessageMSG3::has_size() const {
  return (_has_bits_[0] & 0x00000002u) != 0;
}
inline void MessageMSG3::set_has_size() {
  _has_bits_[0] |= 0x00000002u;
}
inline void MessageMSG3::clear_has_size() {
  _has_bits_[0] &= ~0x00000002u;
}
inline void MessageMSG3::clear_size() {
  size_ = 0u;
  clear_has_size();
}
inline ::google::protobuf::uint32 MessageMSG3::size() const {
  // @@protoc_insertion_point(field_get:Messages.MessageMSG3.size)
  return size_;
}
inline void MessageMSG3::set_size(::google::protobuf::uint32 value) {
  set_has_size();
  size_ = value;
  // @@protoc_insertion_point(field_set:Messages.MessageMSG3.size)
}

// required uint32 context = 3;
inline bool MessageMSG3::has_context() const {
  return (_has_bits_[0] & 0x00000004u) != 0;
}
inline void MessageMSG3::set_has_context() {
  _has_bits_[0] |= 0x00000004u;
}
inline void MessageMSG3::clear_has_context() {
  _has_bits_[0] &= ~0x00000004u;
}
inline void MessageMSG3::clear_context() {
  context_ = 0u;
  clear_has_context();
}
inline ::google::protobuf::uint32 MessageMSG3::context() const {
  // @@protoc_insertion_point(field_get:Messages.MessageMSG3.context)
  return context_;
}
inline void MessageMSG3::set_context(::google::protobuf::uint32 value) {
  set_has_context();
  context_ = value;
  // @@protoc_insertion_point(field_set:Messages.MessageMSG3.context)
}

// repeated uint32 sgx_mac = 4 [packed = true];
inline int MessageMSG3::sgx_mac_size() const {
  return sgx_mac_.size();
}
inline void MessageMSG3::clear_sgx_mac() {
  sgx_mac_.Clear();
}
inline ::google::protobuf::uint32 MessageMSG3::sgx_mac(int index) const {
  // @@protoc_insertion_point(field_get:Messages.MessageMSG3.sgx_mac)
  return sgx_mac_.Get(index);
}
inline void MessageMSG3::set_sgx_mac(int index, ::google::protobuf::uint32 value) {
  sgx_mac_.Set(index, value);
  // @@protoc_insertion_point(field_set:Messages.MessageMSG3.sgx_mac)
}
inline void MessageMSG3::add_sgx_mac(::google::protobuf::uint32 value) {
  sgx_mac_.Add(value);
  // @@protoc_insertion_point(field_add:Messages.MessageMSG3.sgx_mac)
}
inline const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
MessageMSG3::sgx_mac() const {
  // @@protoc_insertion_point(field_list:Messages.MessageMSG3.sgx_mac)
  return sgx_mac_;
}
inline ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
MessageMSG3::mutable_sgx_mac() {
  // @@protoc_insertion_point(field_mutable_list:Messages.MessageMSG3.sgx_mac)
  return &sgx_mac_;
}

// repeated uint32 gax_msg3 = 5 [packed = true];
inline int MessageMSG3::gax_msg3_size() const {
  return gax_msg3_.size();
}
inline void MessageMSG3::clear_gax_msg3() {
  gax_msg3_.Clear();
}
inline ::google::protobuf::uint32 MessageMSG3::gax_msg3(int index) const {
  // @@protoc_insertion_point(field_get:Messages.MessageMSG3.gax_msg3)
  return gax_msg3_.Get(index);
}
inline void MessageMSG3::set_gax_msg3(int index, ::google::protobuf::uint32 value) {
  gax_msg3_.Set(index, value);
  // @@protoc_insertion_point(field_set:Messages.MessageMSG3.gax_msg3)
}
inline void MessageMSG3::add_gax_msg3(::google::protobuf::uint32 value) {
  gax_msg3_.Add(value);
  // @@protoc_insertion_point(field_add:Messages.MessageMSG3.gax_msg3)
}
inline const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
MessageMSG3::gax_msg3() const {
  // @@protoc_insertion_point(field_list:Messages.MessageMSG3.gax_msg3)
  return gax_msg3_;
}
inline ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
MessageMSG3::mutable_gax_msg3() {
  // @@protoc_insertion_point(field_mutable_list:Messages.MessageMSG3.gax_msg3)
  return &gax_msg3_;
}

// repeated uint32 gay_msg3 = 6 [packed = true];
inline int MessageMSG3::gay_msg3_size() const {
  return gay_msg3_.size();
}
inline void MessageMSG3::clear_gay_msg3() {
  gay_msg3_.Clear();
}
inline ::google::protobuf::uint32 MessageMSG3::gay_msg3(int index) const {
  // @@protoc_insertion_point(field_get:Messages.MessageMSG3.gay_msg3)
  return gay_msg3_.Get(index);
}
inline void MessageMSG3::set_gay_msg3(int index, ::google::protobuf::uint32 value) {
  gay_msg3_.Set(index, value);
  // @@protoc_insertion_point(field_set:Messages.MessageMSG3.gay_msg3)
}
inline void MessageMSG3::add_gay_msg3(::google::protobuf::uint32 value) {
  gay_msg3_.Add(value);
  // @@protoc_insertion_point(field_add:Messages.MessageMSG3.gay_msg3)
}
inline const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
MessageMSG3::gay_msg3() const {
  // @@protoc_insertion_point(field_list:Messages.MessageMSG3.gay_msg3)
  return gay_msg3_;
}
inline ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
MessageMSG3::mutable_gay_msg3() {
  // @@protoc_insertion_point(field_mutable_list:Messages.MessageMSG3.gay_msg3)
  return &gay_msg3_;
}

// repeated uint32 sec_property = 7 [packed = true];
inline int MessageMSG3::sec_property_size() const {
  return sec_property_.size();
}
inline void MessageMSG3::clear_sec_property() {
  sec_property_.Clear();
}
inline ::google::protobuf::uint32 MessageMSG3::sec_property(int index) const {
  // @@protoc_insertion_point(field_get:Messages.MessageMSG3.sec_property)
  return sec_property_.Get(index);
}
inline void MessageMSG3::set_sec_property(int index, ::google::protobuf::uint32 value) {
  sec_property_.Set(index, value);
  // @@protoc_insertion_point(field_set:Messages.MessageMSG3.sec_property)
}
inline void MessageMSG3::add_sec_property(::google::protobuf::uint32 value) {
  sec_property_.Add(value);
  // @@protoc_insertion_point(field_add:Messages.MessageMSG3.sec_property)
}
inline const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
MessageMSG3::sec_property() const {
  // @@protoc_insertion_point(field_list:Messages.MessageMSG3.sec_property)
  return sec_property_;
}
inline ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
MessageMSG3::mutable_sec_property() {
  // @@protoc_insertion_point(field_mutable_list:Messages.MessageMSG3.sec_property)
  return &sec_property_;
}

// repeated uint32 quote = 8 [packed = true];
inline int MessageMSG3::quote_size() const {
  return quote_.size();
}
inline void MessageMSG3::clear_quote() {
  quote_.Clear();
}
inline ::google::protobuf::uint32 MessageMSG3::quote(int index) const {
  // @@protoc_insertion_point(field_get:Messages.MessageMSG3.quote)
  return quote_.Get(index);
}
inline void MessageMSG3::set_quote(int index, ::google::protobuf::uint32 value) {
  quote_.Set(index, value);
  // @@protoc_insertion_point(field_set:Messages.MessageMSG3.quote)
}
inline void MessageMSG3::add_quote(::google::protobuf::uint32 value) {
  quote_.Add(value);
  // @@protoc_insertion_point(field_add:Messages.MessageMSG3.quote)
}
inline const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
MessageMSG3::quote() const {
  // @@protoc_insertion_point(field_list:Messages.MessageMSG3.quote)
  return quote_;
}
inline ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
MessageMSG3::mutable_quote() {
  // @@protoc_insertion_point(field_mutable_list:Messages.MessageMSG3.quote)
  return &quote_;
}

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

// AttestationMessage

// required uint32 type = 1;
inline bool AttestationMessage::has_type() const {
  return (_has_bits_[0] & 0x00000001u) != 0;
}
inline void AttestationMessage::set_has_type() {
  _has_bits_[0] |= 0x00000001u;
}
inline void AttestationMessage::clear_has_type() {
  _has_bits_[0] &= ~0x00000001u;
}
inline void AttestationMessage::clear_type() {
  type_ = 0u;
  clear_has_type();
}
inline ::google::protobuf::uint32 AttestationMessage::type() const {
  // @@protoc_insertion_point(field_get:Messages.AttestationMessage.type)
  return type_;
}
inline void AttestationMessage::set_type(::google::protobuf::uint32 value) {
  set_has_type();
  type_ = value;
  // @@protoc_insertion_point(field_set:Messages.AttestationMessage.type)
}

// required uint32 size = 2;
inline bool AttestationMessage::has_size() const {
  return (_has_bits_[0] & 0x00000002u) != 0;
}
inline void AttestationMessage::set_has_size() {
  _has_bits_[0] |= 0x00000002u;
}
inline void AttestationMessage::clear_has_size() {
  _has_bits_[0] &= ~0x00000002u;
}
inline void AttestationMessage::clear_size() {
  size_ = 0u;
  clear_has_size();
}
inline ::google::protobuf::uint32 AttestationMessage::size() const {
  // @@protoc_insertion_point(field_get:Messages.AttestationMessage.size)
  return size_;
}
inline void AttestationMessage::set_size(::google::protobuf::uint32 value) {
  set_has_size();
  size_ = value;
  // @@protoc_insertion_point(field_set:Messages.AttestationMessage.size)
}

// required uint32 context = 3;
inline bool AttestationMessage::has_context() const {
  return (_has_bits_[0] & 0x00000004u) != 0;
}
inline void AttestationMessage::set_has_context() {
  _has_bits_[0] |= 0x00000004u;
}
inline void AttestationMessage::clear_has_context() {
  _has_bits_[0] &= ~0x00000004u;
}
inline void AttestationMessage::clear_context() {
  context_ = 0u;
  clear_has_context();
}
inline ::google::protobuf::uint32 AttestationMessage::context() const {
  // @@protoc_insertion_point(field_get:Messages.AttestationMessage.context)
  return context_;
}
inline void AttestationMessage::set_context(::google::protobuf::uint32 value) {
  set_has_context();
  context_ = value;
  // @@protoc_insertion_point(field_set:Messages.AttestationMessage.context)
}

// optional uint32 epid_group_status = 4;
inline bool AttestationMessage::has_epid_group_status() const {
  return (_has_bits_[0] & 0x00000008u) != 0;
}
inline void AttestationMessage::set_has_epid_group_status() {
  _has_bits_[0] |= 0x00000008u;
}
inline void AttestationMessage::clear_has_epid_group_status() {
  _has_bits_[0] &= ~0x00000008u;
}
inline void AttestationMessage::clear_epid_group_status() {
  epid_group_status_ = 0u;
  clear_has_epid_group_status();
}
inline ::google::protobuf::uint32 AttestationMessage::epid_group_status() const {
  // @@protoc_insertion_point(field_get:Messages.AttestationMessage.epid_group_status)
  return epid_group_status_;
}
inline void AttestationMessage::set_epid_group_status(::google::protobuf::uint32 value) {
  set_has_epid_group_status();
  epid_group_status_ = value;
  // @@protoc_insertion_point(field_set:Messages.AttestationMessage.epid_group_status)
}

// optional uint32 tcb_evaluation_status = 5;
inline bool AttestationMessage::has_tcb_evaluation_status() const {
  return (_has_bits_[0] & 0x00000010u) != 0;
}
inline void AttestationMessage::set_has_tcb_evaluation_status() {
  _has_bits_[0] |= 0x00000010u;
}
inline void AttestationMessage::clear_has_tcb_evaluation_status() {
  _has_bits_[0] &= ~0x00000010u;
}
inline void AttestationMessage::clear_tcb_evaluation_status() {
  tcb_evaluation_status_ = 0u;
  clear_has_tcb_evaluation_status();
}
inline ::google::protobuf::uint32 AttestationMessage::tcb_evaluation_status() const {
  // @@protoc_insertion_point(field_get:Messages.AttestationMessage.tcb_evaluation_status)
  return tcb_evaluation_status_;
}
inline void AttestationMessage::set_tcb_evaluation_status(::google::protobuf::uint32 value) {
  set_has_tcb_evaluation_status();
  tcb_evaluation_status_ = value;
  // @@protoc_insertion_point(field_set:Messages.AttestationMessage.tcb_evaluation_status)
}

// optional uint32 pse_evaluation_status = 6;
inline bool AttestationMessage::has_pse_evaluation_status() const {
  return (_has_bits_[0] & 0x00000020u) != 0;
}
inline void AttestationMessage::set_has_pse_evaluation_status() {
  _has_bits_[0] |= 0x00000020u;
}
inline void AttestationMessage::clear_has_pse_evaluation_status() {
  _has_bits_[0] &= ~0x00000020u;
}
inline void AttestationMessage::clear_pse_evaluation_status() {
  pse_evaluation_status_ = 0u;
  clear_has_pse_evaluation_status();
}
inline ::google::protobuf::uint32 AttestationMessage::pse_evaluation_status() const {
  // @@protoc_insertion_point(field_get:Messages.AttestationMessage.pse_evaluation_status)
  return pse_evaluation_status_;
}
inline void AttestationMessage::set_pse_evaluation_status(::google::protobuf::uint32 value) {
  set_has_pse_evaluation_status();
  pse_evaluation_status_ = value;
  // @@protoc_insertion_point(field_set:Messages.AttestationMessage.pse_evaluation_status)
}

// repeated uint32 latest_equivalent_tcb_psvn = 7 [packed = true];
inline int AttestationMessage::latest_equivalent_tcb_psvn_size() const {
  return latest_equivalent_tcb_psvn_.size();
}
inline void AttestationMessage::clear_latest_equivalent_tcb_psvn() {
  latest_equivalent_tcb_psvn_.Clear();
}
inline ::google::protobuf::uint32 AttestationMessage::latest_equivalent_tcb_psvn(int index) const {
  // @@protoc_insertion_point(field_get:Messages.AttestationMessage.latest_equivalent_tcb_psvn)
  return latest_equivalent_tcb_psvn_.Get(index);
}
inline void AttestationMessage::set_latest_equivalent_tcb_psvn(int index, ::google::protobuf::uint32 value) {
  latest_equivalent_tcb_psvn_.Set(index, value);
  // @@protoc_insertion_point(field_set:Messages.AttestationMessage.latest_equivalent_tcb_psvn)
}
inline void AttestationMessage::add_latest_equivalent_tcb_psvn(::google::protobuf::uint32 value) {
  latest_equivalent_tcb_psvn_.Add(value);
  // @@protoc_insertion_point(field_add:Messages.AttestationMessage.latest_equivalent_tcb_psvn)
}
inline const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
AttestationMessage::latest_equivalent_tcb_psvn() const {
  // @@protoc_insertion_point(field_list:Messages.AttestationMessage.latest_equivalent_tcb_psvn)
  return latest_equivalent_tcb_psvn_;
}
inline ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
AttestationMessage::mutable_latest_equivalent_tcb_psvn() {
  // @@protoc_insertion_point(field_mutable_list:Messages.AttestationMessage.latest_equivalent_tcb_psvn)
  return &latest_equivalent_tcb_psvn_;
}

// repeated uint32 latest_pse_isvsvn = 8 [packed = true];
inline int AttestationMessage::latest_pse_isvsvn_size() const {
  return latest_pse_isvsvn_.size();
}
inline void AttestationMessage::clear_latest_pse_isvsvn() {
  latest_pse_isvsvn_.Clear();
}
inline ::google::protobuf::uint32 AttestationMessage::latest_pse_isvsvn(int index) const {
  // @@protoc_insertion_point(field_get:Messages.AttestationMessage.latest_pse_isvsvn)
  return latest_pse_isvsvn_.Get(index);
}
inline void AttestationMessage::set_latest_pse_isvsvn(int index, ::google::protobuf::uint32 value) {
  latest_pse_isvsvn_.Set(index, value);
  // @@protoc_insertion_point(field_set:Messages.AttestationMessage.latest_pse_isvsvn)
}
inline void AttestationMessage::add_latest_pse_isvsvn(::google::protobuf::uint32 value) {
  latest_pse_isvsvn_.Add(value);
  // @@protoc_insertion_point(field_add:Messages.AttestationMessage.latest_pse_isvsvn)
}
inline const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
AttestationMessage::latest_pse_isvsvn() const {
  // @@protoc_insertion_point(field_list:Messages.AttestationMessage.latest_pse_isvsvn)
  return latest_pse_isvsvn_;
}
inline ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
AttestationMessage::mutable_latest_pse_isvsvn() {
  // @@protoc_insertion_point(field_mutable_list:Messages.AttestationMessage.latest_pse_isvsvn)
  return &latest_pse_isvsvn_;
}

// repeated uint32 latest_psda_svn = 9 [packed = true];
inline int AttestationMessage::latest_psda_svn_size() const {
  return latest_psda_svn_.size();
}
inline void AttestationMessage::clear_latest_psda_svn() {
  latest_psda_svn_.Clear();
}
inline ::google::protobuf::uint32 AttestationMessage::latest_psda_svn(int index) const {
  // @@protoc_insertion_point(field_get:Messages.AttestationMessage.latest_psda_svn)
  return latest_psda_svn_.Get(index);
}
inline void AttestationMessage::set_latest_psda_svn(int index, ::google::protobuf::uint32 value) {
  latest_psda_svn_.Set(index, value);
  // @@protoc_insertion_point(field_set:Messages.AttestationMessage.latest_psda_svn)
}
inline void AttestationMessage::add_latest_psda_svn(::google::protobuf::uint32 value) {
  latest_psda_svn_.Add(value);
  // @@protoc_insertion_point(field_add:Messages.AttestationMessage.latest_psda_svn)
}
inline const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
AttestationMessage::latest_psda_svn() const {
  // @@protoc_insertion_point(field_list:Messages.AttestationMessage.latest_psda_svn)
  return latest_psda_svn_;
}
inline ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
AttestationMessage::mutable_latest_psda_svn() {
  // @@protoc_insertion_point(field_mutable_list:Messages.AttestationMessage.latest_psda_svn)
  return &latest_psda_svn_;
}

// repeated uint32 performance_rekey_gid = 10 [packed = true];
inline int AttestationMessage::performance_rekey_gid_size() const {
  return performance_rekey_gid_.size();
}
inline void AttestationMessage::clear_performance_rekey_gid() {
  performance_rekey_gid_.Clear();
}
inline ::google::protobuf::uint32 AttestationMessage::performance_rekey_gid(int index) const {
  // @@protoc_insertion_point(field_get:Messages.AttestationMessage.performance_rekey_gid)
  return performance_rekey_gid_.Get(index);
}
inline void AttestationMessage::set_performance_rekey_gid(int index, ::google::protobuf::uint32 value) {
  performance_rekey_gid_.Set(index, value);
  // @@protoc_insertion_point(field_set:Messages.AttestationMessage.performance_rekey_gid)
}
inline void AttestationMessage::add_performance_rekey_gid(::google::protobuf::uint32 value) {
  performance_rekey_gid_.Add(value);
  // @@protoc_insertion_point(field_add:Messages.AttestationMessage.performance_rekey_gid)
}
inline const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
AttestationMessage::performance_rekey_gid() const {
  // @@protoc_insertion_point(field_list:Messages.AttestationMessage.performance_rekey_gid)
  return performance_rekey_gid_;
}
inline ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
AttestationMessage::mutable_performance_rekey_gid() {
  // @@protoc_insertion_point(field_mutable_list:Messages.AttestationMessage.performance_rekey_gid)
  return &performance_rekey_gid_;
}

// repeated uint32 ec_sign256_x = 11 [packed = true];
inline int AttestationMessage::ec_sign256_x_size() const {
  return ec_sign256_x_.size();
}
inline void AttestationMessage::clear_ec_sign256_x() {
  ec_sign256_x_.Clear();
}
inline ::google::protobuf::uint32 AttestationMessage::ec_sign256_x(int index) const {
  // @@protoc_insertion_point(field_get:Messages.AttestationMessage.ec_sign256_x)
  return ec_sign256_x_.Get(index);
}
inline void AttestationMessage::set_ec_sign256_x(int index, ::google::protobuf::uint32 value) {
  ec_sign256_x_.Set(index, value);
  // @@protoc_insertion_point(field_set:Messages.AttestationMessage.ec_sign256_x)
}
inline void AttestationMessage::add_ec_sign256_x(::google::protobuf::uint32 value) {
  ec_sign256_x_.Add(value);
  // @@protoc_insertion_point(field_add:Messages.AttestationMessage.ec_sign256_x)
}
inline const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
AttestationMessage::ec_sign256_x() const {
  // @@protoc_insertion_point(field_list:Messages.AttestationMessage.ec_sign256_x)
  return ec_sign256_x_;
}
inline ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
AttestationMessage::mutable_ec_sign256_x() {
  // @@protoc_insertion_point(field_mutable_list:Messages.AttestationMessage.ec_sign256_x)
  return &ec_sign256_x_;
}

// repeated uint32 ec_sign256_y = 12 [packed = true];
inline int AttestationMessage::ec_sign256_y_size() const {
  return ec_sign256_y_.size();
}
inline void AttestationMessage::clear_ec_sign256_y() {
  ec_sign256_y_.Clear();
}
inline ::google::protobuf::uint32 AttestationMessage::ec_sign256_y(int index) const {
  // @@protoc_insertion_point(field_get:Messages.AttestationMessage.ec_sign256_y)
  return ec_sign256_y_.Get(index);
}
inline void AttestationMessage::set_ec_sign256_y(int index, ::google::protobuf::uint32 value) {
  ec_sign256_y_.Set(index, value);
  // @@protoc_insertion_point(field_set:Messages.AttestationMessage.ec_sign256_y)
}
inline void AttestationMessage::add_ec_sign256_y(::google::protobuf::uint32 value) {
  ec_sign256_y_.Add(value);
  // @@protoc_insertion_point(field_add:Messages.AttestationMessage.ec_sign256_y)
}
inline const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
AttestationMessage::ec_sign256_y() const {
  // @@protoc_insertion_point(field_list:Messages.AttestationMessage.ec_sign256_y)
  return ec_sign256_y_;
}
inline ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
AttestationMessage::mutable_ec_sign256_y() {
  // @@protoc_insertion_point(field_mutable_list:Messages.AttestationMessage.ec_sign256_y)
  return &ec_sign256_y_;
}

// repeated uint32 mac_smk = 13 [packed = true];
inline int AttestationMessage::mac_smk_size() const {
  return mac_smk_.size();
}
inline void AttestationMessage::clear_mac_smk() {
  mac_smk_.Clear();
}
inline ::google::protobuf::uint32 AttestationMessage::mac_smk(int index) const {
  // @@protoc_insertion_point(field_get:Messages.AttestationMessage.mac_smk)
  return mac_smk_.Get(index);
}
inline void AttestationMessage::set_mac_smk(int index, ::google::protobuf::uint32 value) {
  mac_smk_.Set(index, value);
  // @@protoc_insertion_point(field_set:Messages.AttestationMessage.mac_smk)
}
inline void AttestationMessage::add_mac_smk(::google::protobuf::uint32 value) {
  mac_smk_.Add(value);
  // @@protoc_insertion_point(field_add:Messages.AttestationMessage.mac_smk)
}
inline const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
AttestationMessage::mac_smk() const {
  // @@protoc_insertion_point(field_list:Messages.AttestationMessage.mac_smk)
  return mac_smk_;
}
inline ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
AttestationMessage::mutable_mac_smk() {
  // @@protoc_insertion_point(field_mutable_list:Messages.AttestationMessage.mac_smk)
  return &mac_smk_;
}

// optional uint32 result_size = 14;
inline bool AttestationMessage::has_result_size() const {
  return (_has_bits_[0] & 0x00002000u) != 0;
}
inline void AttestationMessage::set_has_result_size() {
  _has_bits_[0] |= 0x00002000u;
}
inline void AttestationMessage::clear_has_result_size() {
  _has_bits_[0] &= ~0x00002000u;
}
inline void AttestationMessage::clear_result_size() {
  result_size_ = 0u;
  clear_has_result_size();
}
inline ::google::protobuf::uint32 AttestationMessage::result_size() const {
  // @@protoc_insertion_point(field_get:Messages.AttestationMessage.result_size)
  return result_size_;
}
inline void AttestationMessage::set_result_size(::google::protobuf::uint32 value) {
  set_has_result_size();
  result_size_ = value;
  // @@protoc_insertion_point(field_set:Messages.AttestationMessage.result_size)
}

// repeated uint32 reserved = 15 [packed = true];
inline int AttestationMessage::reserved_size() const {
  return reserved_.size();
}
inline void AttestationMessage::clear_reserved() {
  reserved_.Clear();
}
inline ::google::protobuf::uint32 AttestationMessage::reserved(int index) const {
  // @@protoc_insertion_point(field_get:Messages.AttestationMessage.reserved)
  return reserved_.Get(index);
}
inline void AttestationMessage::set_reserved(int index, ::google::protobuf::uint32 value) {
  reserved_.Set(index, value);
  // @@protoc_insertion_point(field_set:Messages.AttestationMessage.reserved)
}
inline void AttestationMessage::add_reserved(::google::protobuf::uint32 value) {
  reserved_.Add(value);
  // @@protoc_insertion_point(field_add:Messages.AttestationMessage.reserved)
}
inline const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
AttestationMessage::reserved() const {
  // @@protoc_insertion_point(field_list:Messages.AttestationMessage.reserved)
  return reserved_;
}
inline ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
AttestationMessage::mutable_reserved() {
  // @@protoc_insertion_point(field_mutable_list:Messages.AttestationMessage.reserved)
  return &reserved_;
}

// repeated uint32 payload_tag = 16 [packed = true];
inline int AttestationMessage::payload_tag_size() const {
  return payload_tag_.size();
}
inline void AttestationMessage::clear_payload_tag() {
  payload_tag_.Clear();
}
inline ::google::protobuf::uint32 AttestationMessage::payload_tag(int index) const {
  // @@protoc_insertion_point(field_get:Messages.AttestationMessage.payload_tag)
  return payload_tag_.Get(index);
}
inline void AttestationMessage::set_payload_tag(int index, ::google::protobuf::uint32 value) {
  payload_tag_.Set(index, value);
  // @@protoc_insertion_point(field_set:Messages.AttestationMessage.payload_tag)
}
inline void AttestationMessage::add_payload_tag(::google::protobuf::uint32 value) {
  payload_tag_.Add(value);
  // @@protoc_insertion_point(field_add:Messages.AttestationMessage.payload_tag)
}
inline const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
AttestationMessage::payload_tag() const {
  // @@protoc_insertion_point(field_list:Messages.AttestationMessage.payload_tag)
  return payload_tag_;
}
inline ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
AttestationMessage::mutable_payload_tag() {
  // @@protoc_insertion_point(field_mutable_list:Messages.AttestationMessage.payload_tag)
  return &payload_tag_;
}

// repeated uint32 payload = 17 [packed = true];
inline int AttestationMessage::payload_size() const {
  return payload_.size();
}
inline void AttestationMessage::clear_payload() {
  payload_.Clear();
}
inline ::google::protobuf::uint32 AttestationMessage::payload(int index) const {
  // @@protoc_insertion_point(field_get:Messages.AttestationMessage.payload)
  return payload_.Get(index);
}
inline void AttestationMessage::set_payload(int index, ::google::protobuf::uint32 value) {
  payload_.Set(index, value);
  // @@protoc_insertion_point(field_set:Messages.AttestationMessage.payload)
}
inline void AttestationMessage::add_payload(::google::protobuf::uint32 value) {
  payload_.Add(value);
  // @@protoc_insertion_point(field_add:Messages.AttestationMessage.payload)
}
inline const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
AttestationMessage::payload() const {
  // @@protoc_insertion_point(field_list:Messages.AttestationMessage.payload)
  return payload_;
}
inline ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
AttestationMessage::mutable_payload() {
  // @@protoc_insertion_point(field_mutable_list:Messages.AttestationMessage.payload)
  return &payload_;
}

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

// MessagePsiSalt

// required uint32 type = 1;
inline bool MessagePsiSalt::has_type() const {
  return (_has_bits_[0] & 0x00000001u) != 0;
}
inline void MessagePsiSalt::set_has_type() {
  _has_bits_[0] |= 0x00000001u;
}
inline void MessagePsiSalt::clear_has_type() {
  _has_bits_[0] &= ~0x00000001u;
}
inline void MessagePsiSalt::clear_type() {
  type_ = 0u;
  clear_has_type();
}
inline ::google::protobuf::uint32 MessagePsiSalt::type() const {
  // @@protoc_insertion_point(field_get:Messages.MessagePsiSalt.type)
  return type_;
}
inline void MessagePsiSalt::set_type(::google::protobuf::uint32 value) {
  set_has_type();
  type_ = value;
  // @@protoc_insertion_point(field_set:Messages.MessagePsiSalt.type)
}

// required uint32 size = 2;
inline bool MessagePsiSalt::has_size() const {
  return (_has_bits_[0] & 0x00000002u) != 0;
}
inline void MessagePsiSalt::set_has_size() {
  _has_bits_[0] |= 0x00000002u;
}
inline void MessagePsiSalt::clear_has_size() {
  _has_bits_[0] &= ~0x00000002u;
}
inline void MessagePsiSalt::clear_size() {
  size_ = 0u;
  clear_has_size();
}
inline ::google::protobuf::uint32 MessagePsiSalt::size() const {
  // @@protoc_insertion_point(field_get:Messages.MessagePsiSalt.size)
  return size_;
}
inline void MessagePsiSalt::set_size(::google::protobuf::uint32 value) {
  set_has_size();
  size_ = value;
  // @@protoc_insertion_point(field_set:Messages.MessagePsiSalt.size)
}

// required uint32 context = 3;
inline bool MessagePsiSalt::has_context() const {
  return (_has_bits_[0] & 0x00000004u) != 0;
}
inline void MessagePsiSalt::set_has_context() {
  _has_bits_[0] |= 0x00000004u;
}
inline void MessagePsiSalt::clear_has_context() {
  _has_bits_[0] &= ~0x00000004u;
}
inline void MessagePsiSalt::clear_context() {
  context_ = 0u;
  clear_has_context();
}
inline ::google::protobuf::uint32 MessagePsiSalt::context() const {
  // @@protoc_insertion_point(field_get:Messages.MessagePsiSalt.context)
  return context_;
}
inline void MessagePsiSalt::set_context(::google::protobuf::uint32 value) {
  set_has_context();
  context_ = value;
  // @@protoc_insertion_point(field_set:Messages.MessagePsiSalt.context)
}

// required uint32 id = 4;
inline bool MessagePsiSalt::has_id() const {
  return (_has_bits_[0] & 0x00000008u) != 0;
}
inline void MessagePsiSalt::set_has_id() {
  _has_bits_[0] |= 0x00000008u;
}
inline void MessagePsiSalt::clear_has_id() {
  _has_bits_[0] &= ~0x00000008u;
}
inline void MessagePsiSalt::clear_id() {
  id_ = 0u;
  clear_has_id();
}
inline ::google::protobuf::uint32 MessagePsiSalt::id() const {
  // @@protoc_insertion_point(field_get:Messages.MessagePsiSalt.id)
  return id_;
}
inline void MessagePsiSalt::set_id(::google::protobuf::uint32 value) {
  set_has_id();
  id_ = value;
  // @@protoc_insertion_point(field_set:Messages.MessagePsiSalt.id)
}

// required uint32 state = 5;
inline bool MessagePsiSalt::has_state() const {
  return (_has_bits_[0] & 0x00000010u) != 0;
}
inline void MessagePsiSalt::set_has_state() {
  _has_bits_[0] |= 0x00000010u;
}
inline void MessagePsiSalt::clear_has_state() {
  _has_bits_[0] &= ~0x00000010u;
}
inline void MessagePsiSalt::clear_state() {
  state_ = 0u;
  clear_has_state();
}
inline ::google::protobuf::uint32 MessagePsiSalt::state() const {
  // @@protoc_insertion_point(field_get:Messages.MessagePsiSalt.state)
  return state_;
}
inline void MessagePsiSalt::set_state(::google::protobuf::uint32 value) {
  set_has_state();
  state_ = value;
  // @@protoc_insertion_point(field_set:Messages.MessagePsiSalt.state)
}

// repeated uint32 mac = 6 [packed = true];
inline int MessagePsiSalt::mac_size() const {
  return mac_.size();
}
inline void MessagePsiSalt::clear_mac() {
  mac_.Clear();
}
inline ::google::protobuf::uint32 MessagePsiSalt::mac(int index) const {
  // @@protoc_insertion_point(field_get:Messages.MessagePsiSalt.mac)
  return mac_.Get(index);
}
inline void MessagePsiSalt::set_mac(int index, ::google::protobuf::uint32 value) {
  mac_.Set(index, value);
  // @@protoc_insertion_point(field_set:Messages.MessagePsiSalt.mac)
}
inline void MessagePsiSalt::add_mac(::google::protobuf::uint32 value) {
  mac_.Add(value);
  // @@protoc_insertion_point(field_add:Messages.MessagePsiSalt.mac)
}
inline const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
MessagePsiSalt::mac() const {
  // @@protoc_insertion_point(field_list:Messages.MessagePsiSalt.mac)
  return mac_;
}
inline ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
MessagePsiSalt::mutable_mac() {
  // @@protoc_insertion_point(field_mutable_list:Messages.MessagePsiSalt.mac)
  return &mac_;
}

// repeated uint32 salt = 7 [packed = true];
inline int MessagePsiSalt::salt_size() const {
  return salt_.size();
}
inline void MessagePsiSalt::clear_salt() {
  salt_.Clear();
}
inline ::google::protobuf::uint32 MessagePsiSalt::salt(int index) const {
  // @@protoc_insertion_point(field_get:Messages.MessagePsiSalt.salt)
  return salt_.Get(index);
}
inline void MessagePsiSalt::set_salt(int index, ::google::protobuf::uint32 value) {
  salt_.Set(index, value);
  // @@protoc_insertion_point(field_set:Messages.MessagePsiSalt.salt)
}
inline void MessagePsiSalt::add_salt(::google::protobuf::uint32 value) {
  salt_.Add(value);
  // @@protoc_insertion_point(field_add:Messages.MessagePsiSalt.salt)
}
inline const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
MessagePsiSalt::salt() const {
  // @@protoc_insertion_point(field_list:Messages.MessagePsiSalt.salt)
  return salt_;
}
inline ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
MessagePsiSalt::mutable_salt() {
  // @@protoc_insertion_point(field_mutable_list:Messages.MessagePsiSalt.salt)
  return &salt_;
}

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

// MessagePsiHashData

// required uint32 type = 1;
inline bool MessagePsiHashData::has_type() const {
  return (_has_bits_[0] & 0x00000001u) != 0;
}
inline void MessagePsiHashData::set_has_type() {
  _has_bits_[0] |= 0x00000001u;
}
inline void MessagePsiHashData::clear_has_type() {
  _has_bits_[0] &= ~0x00000001u;
}
inline void MessagePsiHashData::clear_type() {
  type_ = 0u;
  clear_has_type();
}
inline ::google::protobuf::uint32 MessagePsiHashData::type() const {
  // @@protoc_insertion_point(field_get:Messages.MessagePsiHashData.type)
  return type_;
}
inline void MessagePsiHashData::set_type(::google::protobuf::uint32 value) {
  set_has_type();
  type_ = value;
  // @@protoc_insertion_point(field_set:Messages.MessagePsiHashData.type)
}

// required uint32 size = 2;
inline bool MessagePsiHashData::has_size() const {
  return (_has_bits_[0] & 0x00000002u) != 0;
}
inline void MessagePsiHashData::set_has_size() {
  _has_bits_[0] |= 0x00000002u;
}
inline void MessagePsiHashData::clear_has_size() {
  _has_bits_[0] &= ~0x00000002u;
}
inline void MessagePsiHashData::clear_size() {
  size_ = 0u;
  clear_has_size();
}
inline ::google::protobuf::uint32 MessagePsiHashData::size() const {
  // @@protoc_insertion_point(field_get:Messages.MessagePsiHashData.size)
  return size_;
}
inline void MessagePsiHashData::set_size(::google::protobuf::uint32 value) {
  set_has_size();
  size_ = value;
  // @@protoc_insertion_point(field_set:Messages.MessagePsiHashData.size)
}

// required uint32 context = 3;
inline bool MessagePsiHashData::has_context() const {
  return (_has_bits_[0] & 0x00000004u) != 0;
}
inline void MessagePsiHashData::set_has_context() {
  _has_bits_[0] |= 0x00000004u;
}
inline void MessagePsiHashData::clear_has_context() {
  _has_bits_[0] &= ~0x00000004u;
}
inline void MessagePsiHashData::clear_context() {
  context_ = 0u;
  clear_has_context();
}
inline ::google::protobuf::uint32 MessagePsiHashData::context() const {
  // @@protoc_insertion_point(field_get:Messages.MessagePsiHashData.context)
  return context_;
}
inline void MessagePsiHashData::set_context(::google::protobuf::uint32 value) {
  set_has_context();
  context_ = value;
  // @@protoc_insertion_point(field_set:Messages.MessagePsiHashData.context)
}

// required uint32 id = 4;
inline bool MessagePsiHashData::has_id() const {
  return (_has_bits_[0] & 0x00000008u) != 0;
}
inline void MessagePsiHashData::set_has_id() {
  _has_bits_[0] |= 0x00000008u;
}
inline void MessagePsiHashData::clear_has_id() {
  _has_bits_[0] &= ~0x00000008u;
}
inline void MessagePsiHashData::clear_id() {
  id_ = 0u;
  clear_has_id();
}
inline ::google::protobuf::uint32 MessagePsiHashData::id() const {
  // @@protoc_insertion_point(field_get:Messages.MessagePsiHashData.id)
  return id_;
}
inline void MessagePsiHashData::set_id(::google::protobuf::uint32 value) {
  set_has_id();
  id_ = value;
  // @@protoc_insertion_point(field_set:Messages.MessagePsiHashData.id)
}

// repeated uint32 mac = 5 [packed = true];
inline int MessagePsiHashData::mac_size() const {
  return mac_.size();
}
inline void MessagePsiHashData::clear_mac() {
  mac_.Clear();
}
inline ::google::protobuf::uint32 MessagePsiHashData::mac(int index) const {
  // @@protoc_insertion_point(field_get:Messages.MessagePsiHashData.mac)
  return mac_.Get(index);
}
inline void MessagePsiHashData::set_mac(int index, ::google::protobuf::uint32 value) {
  mac_.Set(index, value);
  // @@protoc_insertion_point(field_set:Messages.MessagePsiHashData.mac)
}
inline void MessagePsiHashData::add_mac(::google::protobuf::uint32 value) {
  mac_.Add(value);
  // @@protoc_insertion_point(field_add:Messages.MessagePsiHashData.mac)
}
inline const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
MessagePsiHashData::mac() const {
  // @@protoc_insertion_point(field_list:Messages.MessagePsiHashData.mac)
  return mac_;
}
inline ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
MessagePsiHashData::mutable_mac() {
  // @@protoc_insertion_point(field_mutable_list:Messages.MessagePsiHashData.mac)
  return &mac_;
}

// repeated uint32 data = 6 [packed = true];
inline int MessagePsiHashData::data_size() const {
  return data_.size();
}
inline void MessagePsiHashData::clear_data() {
  data_.Clear();
}
inline ::google::protobuf::uint32 MessagePsiHashData::data(int index) const {
  // @@protoc_insertion_point(field_get:Messages.MessagePsiHashData.data)
  return data_.Get(index);
}
inline void MessagePsiHashData::set_data(int index, ::google::protobuf::uint32 value) {
  data_.Set(index, value);
  // @@protoc_insertion_point(field_set:Messages.MessagePsiHashData.data)
}
inline void MessagePsiHashData::add_data(::google::protobuf::uint32 value) {
  data_.Add(value);
  // @@protoc_insertion_point(field_add:Messages.MessagePsiHashData.data)
}
inline const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
MessagePsiHashData::data() const {
  // @@protoc_insertion_point(field_list:Messages.MessagePsiHashData.data)
  return data_;
}
inline ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
MessagePsiHashData::mutable_data() {
  // @@protoc_insertion_point(field_mutable_list:Messages.MessagePsiHashData.data)
  return &data_;
}

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

// MessagePsiHashDataFinished

// required uint32 type = 1;
inline bool MessagePsiHashDataFinished::has_type() const {
  return (_has_bits_[0] & 0x00000001u) != 0;
}
inline void MessagePsiHashDataFinished::set_has_type() {
  _has_bits_[0] |= 0x00000001u;
}
inline void MessagePsiHashDataFinished::clear_has_type() {
  _has_bits_[0] &= ~0x00000001u;
}
inline void MessagePsiHashDataFinished::clear_type() {
  type_ = 0u;
  clear_has_type();
}
inline ::google::protobuf::uint32 MessagePsiHashDataFinished::type() const {
  // @@protoc_insertion_point(field_get:Messages.MessagePsiHashDataFinished.type)
  return type_;
}
inline void MessagePsiHashDataFinished::set_type(::google::protobuf::uint32 value) {
  set_has_type();
  type_ = value;
  // @@protoc_insertion_point(field_set:Messages.MessagePsiHashDataFinished.type)
}

// required uint32 size = 2;
inline bool MessagePsiHashDataFinished::has_size() const {
  return (_has_bits_[0] & 0x00000002u) != 0;
}
inline void MessagePsiHashDataFinished::set_has_size() {
  _has_bits_[0] |= 0x00000002u;
}
inline void MessagePsiHashDataFinished::clear_has_size() {
  _has_bits_[0] &= ~0x00000002u;
}
inline void MessagePsiHashDataFinished::clear_size() {
  size_ = 0u;
  clear_has_size();
}
inline ::google::protobuf::uint32 MessagePsiHashDataFinished::size() const {
  // @@protoc_insertion_point(field_get:Messages.MessagePsiHashDataFinished.size)
  return size_;
}
inline void MessagePsiHashDataFinished::set_size(::google::protobuf::uint32 value) {
  set_has_size();
  size_ = value;
  // @@protoc_insertion_point(field_set:Messages.MessagePsiHashDataFinished.size)
}

// required uint32 context = 3;
inline bool MessagePsiHashDataFinished::has_context() const {
  return (_has_bits_[0] & 0x00000004u) != 0;
}
inline void MessagePsiHashDataFinished::set_has_context() {
  _has_bits_[0] |= 0x00000004u;
}
inline void MessagePsiHashDataFinished::clear_has_context() {
  _has_bits_[0] &= ~0x00000004u;
}
inline void MessagePsiHashDataFinished::clear_context() {
  context_ = 0u;
  clear_has_context();
}
inline ::google::protobuf::uint32 MessagePsiHashDataFinished::context() const {
  // @@protoc_insertion_point(field_get:Messages.MessagePsiHashDataFinished.context)
  return context_;
}
inline void MessagePsiHashDataFinished::set_context(::google::protobuf::uint32 value) {
  set_has_context();
  context_ = value;
  // @@protoc_insertion_point(field_set:Messages.MessagePsiHashDataFinished.context)
}

// required uint32 id = 4;
inline bool MessagePsiHashDataFinished::has_id() const {
  return (_has_bits_[0] & 0x00000008u) != 0;
}
inline void MessagePsiHashDataFinished::set_has_id() {
  _has_bits_[0] |= 0x00000008u;
}
inline void MessagePsiHashDataFinished::clear_has_id() {
  _has_bits_[0] &= ~0x00000008u;
}
inline void MessagePsiHashDataFinished::clear_id() {
  id_ = 0u;
  clear_has_id();
}
inline ::google::protobuf::uint32 MessagePsiHashDataFinished::id() const {
  // @@protoc_insertion_point(field_get:Messages.MessagePsiHashDataFinished.id)
  return id_;
}
inline void MessagePsiHashDataFinished::set_id(::google::protobuf::uint32 value) {
  set_has_id();
  id_ = value;
  // @@protoc_insertion_point(field_set:Messages.MessagePsiHashDataFinished.id)
}

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

// MessagePsiResult

// required uint32 type = 1;
inline bool MessagePsiResult::has_type() const {
  return (_has_bits_[0] & 0x00000001u) != 0;
}
inline void MessagePsiResult::set_has_type() {
  _has_bits_[0] |= 0x00000001u;
}
inline void MessagePsiResult::clear_has_type() {
  _has_bits_[0] &= ~0x00000001u;
}
inline void MessagePsiResult::clear_type() {
  type_ = 0u;
  clear_has_type();
}
inline ::google::protobuf::uint32 MessagePsiResult::type() const {
  // @@protoc_insertion_point(field_get:Messages.MessagePsiResult.type)
  return type_;
}
inline void MessagePsiResult::set_type(::google::protobuf::uint32 value) {
  set_has_type();
  type_ = value;
  // @@protoc_insertion_point(field_set:Messages.MessagePsiResult.type)
}

// required uint32 size = 2;
inline bool MessagePsiResult::has_size() const {
  return (_has_bits_[0] & 0x00000002u) != 0;
}
inline void MessagePsiResult::set_has_size() {
  _has_bits_[0] |= 0x00000002u;
}
inline void MessagePsiResult::clear_has_size() {
  _has_bits_[0] &= ~0x00000002u;
}
inline void MessagePsiResult::clear_size() {
  size_ = 0u;
  clear_has_size();
}
inline ::google::protobuf::uint32 MessagePsiResult::size() const {
  // @@protoc_insertion_point(field_get:Messages.MessagePsiResult.size)
  return size_;
}
inline void MessagePsiResult::set_size(::google::protobuf::uint32 value) {
  set_has_size();
  size_ = value;
  // @@protoc_insertion_point(field_set:Messages.MessagePsiResult.size)
}

// required uint32 context = 3;
inline bool MessagePsiResult::has_context() const {
  return (_has_bits_[0] & 0x00000004u) != 0;
}
inline void MessagePsiResult::set_has_context() {
  _has_bits_[0] |= 0x00000004u;
}
inline void MessagePsiResult::clear_has_context() {
  _has_bits_[0] &= ~0x00000004u;
}
inline void MessagePsiResult::clear_context() {
  context_ = 0u;
  clear_has_context();
}
inline ::google::protobuf::uint32 MessagePsiResult::context() const {
  // @@protoc_insertion_point(field_get:Messages.MessagePsiResult.context)
  return context_;
}
inline void MessagePsiResult::set_context(::google::protobuf::uint32 value) {
  set_has_context();
  context_ = value;
  // @@protoc_insertion_point(field_set:Messages.MessagePsiResult.context)
}

// required uint32 id = 4;
inline bool MessagePsiResult::has_id() const {
  return (_has_bits_[0] & 0x00000008u) != 0;
}
inline void MessagePsiResult::set_has_id() {
  _has_bits_[0] |= 0x00000008u;
}
inline void MessagePsiResult::clear_has_id() {
  _has_bits_[0] &= ~0x00000008u;
}
inline void MessagePsiResult::clear_id() {
  id_ = 0u;
  clear_has_id();
}
inline ::google::protobuf::uint32 MessagePsiResult::id() const {
  // @@protoc_insertion_point(field_get:Messages.MessagePsiResult.id)
  return id_;
}
inline void MessagePsiResult::set_id(::google::protobuf::uint32 value) {
  set_has_id();
  id_ = value;
  // @@protoc_insertion_point(field_set:Messages.MessagePsiResult.id)
}

// required uint32 state = 5;
inline bool MessagePsiResult::has_state() const {
  return (_has_bits_[0] & 0x00000010u) != 0;
}
inline void MessagePsiResult::set_has_state() {
  _has_bits_[0] |= 0x00000010u;
}
inline void MessagePsiResult::clear_has_state() {
  _has_bits_[0] &= ~0x00000010u;
}
inline void MessagePsiResult::clear_state() {
  state_ = 0u;
  clear_has_state();
}
inline ::google::protobuf::uint32 MessagePsiResult::state() const {
  // @@protoc_insertion_point(field_get:Messages.MessagePsiResult.state)
  return state_;
}
inline void MessagePsiResult::set_state(::google::protobuf::uint32 value) {
  set_has_state();
  state_ = value;
  // @@protoc_insertion_point(field_set:Messages.MessagePsiResult.state)
}

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

// MessagePsiIntersect

// required uint32 type = 1;
inline bool MessagePsiIntersect::has_type() const {
  return (_has_bits_[0] & 0x00000001u) != 0;
}
inline void MessagePsiIntersect::set_has_type() {
  _has_bits_[0] |= 0x00000001u;
}
inline void MessagePsiIntersect::clear_has_type() {
  _has_bits_[0] &= ~0x00000001u;
}
inline void MessagePsiIntersect::clear_type() {
  type_ = 0u;
  clear_has_type();
}
inline ::google::protobuf::uint32 MessagePsiIntersect::type() const {
  // @@protoc_insertion_point(field_get:Messages.MessagePsiIntersect.type)
  return type_;
}
inline void MessagePsiIntersect::set_type(::google::protobuf::uint32 value) {
  set_has_type();
  type_ = value;
  // @@protoc_insertion_point(field_set:Messages.MessagePsiIntersect.type)
}

// required uint32 size = 2;
inline bool MessagePsiIntersect::has_size() const {
  return (_has_bits_[0] & 0x00000002u) != 0;
}
inline void MessagePsiIntersect::set_has_size() {
  _has_bits_[0] |= 0x00000002u;
}
inline void MessagePsiIntersect::clear_has_size() {
  _has_bits_[0] &= ~0x00000002u;
}
inline void MessagePsiIntersect::clear_size() {
  size_ = 0u;
  clear_has_size();
}
inline ::google::protobuf::uint32 MessagePsiIntersect::size() const {
  // @@protoc_insertion_point(field_get:Messages.MessagePsiIntersect.size)
  return size_;
}
inline void MessagePsiIntersect::set_size(::google::protobuf::uint32 value) {
  set_has_size();
  size_ = value;
  // @@protoc_insertion_point(field_set:Messages.MessagePsiIntersect.size)
}

// required uint32 context = 3;
inline bool MessagePsiIntersect::has_context() const {
  return (_has_bits_[0] & 0x00000004u) != 0;
}
inline void MessagePsiIntersect::set_has_context() {
  _has_bits_[0] |= 0x00000004u;
}
inline void MessagePsiIntersect::clear_has_context() {
  _has_bits_[0] &= ~0x00000004u;
}
inline void MessagePsiIntersect::clear_context() {
  context_ = 0u;
  clear_has_context();
}
inline ::google::protobuf::uint32 MessagePsiIntersect::context() const {
  // @@protoc_insertion_point(field_get:Messages.MessagePsiIntersect.context)
  return context_;
}
inline void MessagePsiIntersect::set_context(::google::protobuf::uint32 value) {
  set_has_context();
  context_ = value;
  // @@protoc_insertion_point(field_set:Messages.MessagePsiIntersect.context)
}

// required uint32 id = 4;
inline bool MessagePsiIntersect::has_id() const {
  return (_has_bits_[0] & 0x00000008u) != 0;
}
inline void MessagePsiIntersect::set_has_id() {
  _has_bits_[0] |= 0x00000008u;
}
inline void MessagePsiIntersect::clear_has_id() {
  _has_bits_[0] &= ~0x00000008u;
}
inline void MessagePsiIntersect::clear_id() {
  id_ = 0u;
  clear_has_id();
}
inline ::google::protobuf::uint32 MessagePsiIntersect::id() const {
  // @@protoc_insertion_point(field_get:Messages.MessagePsiIntersect.id)
  return id_;
}
inline void MessagePsiIntersect::set_id(::google::protobuf::uint32 value) {
  set_has_id();
  id_ = value;
  // @@protoc_insertion_point(field_set:Messages.MessagePsiIntersect.id)
}

// repeated uint32 mac = 5 [packed = true];
inline int MessagePsiIntersect::mac_size() const {
  return mac_.size();
}
inline void MessagePsiIntersect::clear_mac() {
  mac_.Clear();
}
inline ::google::protobuf::uint32 MessagePsiIntersect::mac(int index) const {
  // @@protoc_insertion_point(field_get:Messages.MessagePsiIntersect.mac)
  return mac_.Get(index);
}
inline void MessagePsiIntersect::set_mac(int index, ::google::protobuf::uint32 value) {
  mac_.Set(index, value);
  // @@protoc_insertion_point(field_set:Messages.MessagePsiIntersect.mac)
}
inline void MessagePsiIntersect::add_mac(::google::protobuf::uint32 value) {
  mac_.Add(value);
  // @@protoc_insertion_point(field_add:Messages.MessagePsiIntersect.mac)
}
inline const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
MessagePsiIntersect::mac() const {
  // @@protoc_insertion_point(field_list:Messages.MessagePsiIntersect.mac)
  return mac_;
}
inline ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
MessagePsiIntersect::mutable_mac() {
  // @@protoc_insertion_point(field_mutable_list:Messages.MessagePsiIntersect.mac)
  return &mac_;
}

// repeated uint32 data = 6 [packed = true];
inline int MessagePsiIntersect::data_size() const {
  return data_.size();
}
inline void MessagePsiIntersect::clear_data() {
  data_.Clear();
}
inline ::google::protobuf::uint32 MessagePsiIntersect::data(int index) const {
  // @@protoc_insertion_point(field_get:Messages.MessagePsiIntersect.data)
  return data_.Get(index);
}
inline void MessagePsiIntersect::set_data(int index, ::google::protobuf::uint32 value) {
  data_.Set(index, value);
  // @@protoc_insertion_point(field_set:Messages.MessagePsiIntersect.data)
}
inline void MessagePsiIntersect::add_data(::google::protobuf::uint32 value) {
  data_.Add(value);
  // @@protoc_insertion_point(field_add:Messages.MessagePsiIntersect.data)
}
inline const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
MessagePsiIntersect::data() const {
  // @@protoc_insertion_point(field_list:Messages.MessagePsiIntersect.data)
  return data_;
}
inline ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
MessagePsiIntersect::mutable_data() {
  // @@protoc_insertion_point(field_mutable_list:Messages.MessagePsiIntersect.data)
  return &data_;
}


// @@protoc_insertion_point(namespace_scope)

}  // namespace Messages

#ifndef SWIG
namespace google {
namespace protobuf {


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

// @@protoc_insertion_point(global_scope)

#endif  // PROTOBUF_Messages_2eproto__INCLUDED
