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

#define INTERNAL_SUPPRESS_PROTOBUF_FIELD_DEPRECATION
#include "Messages.pb.h"

#include <algorithm>

#include <google/protobuf/stubs/common.h>
#include <google/protobuf/stubs/once.h>
#include <google/protobuf/io/coded_stream.h>
#include <google/protobuf/wire_format_lite_inl.h>
#include <google/protobuf/descriptor.h>
#include <google/protobuf/generated_message_reflection.h>
#include <google/protobuf/reflection_ops.h>
#include <google/protobuf/wire_format.h>
// @@protoc_insertion_point(includes)

namespace Messages {

namespace {

const ::google::protobuf::Descriptor* InitialMessage_descriptor_ = NULL;
const ::google::protobuf::internal::GeneratedMessageReflection*
  InitialMessage_reflection_ = NULL;
const ::google::protobuf::Descriptor* MessageMsg0_descriptor_ = NULL;
const ::google::protobuf::internal::GeneratedMessageReflection*
  MessageMsg0_reflection_ = NULL;
const ::google::protobuf::Descriptor* MessageMSG1_descriptor_ = NULL;
const ::google::protobuf::internal::GeneratedMessageReflection*
  MessageMSG1_reflection_ = NULL;
const ::google::protobuf::Descriptor* MessageMSG2_descriptor_ = NULL;
const ::google::protobuf::internal::GeneratedMessageReflection*
  MessageMSG2_reflection_ = NULL;
const ::google::protobuf::Descriptor* MessageMSG3_descriptor_ = NULL;
const ::google::protobuf::internal::GeneratedMessageReflection*
  MessageMSG3_reflection_ = NULL;
const ::google::protobuf::Descriptor* AttestationMessage_descriptor_ = NULL;
const ::google::protobuf::internal::GeneratedMessageReflection*
  AttestationMessage_reflection_ = NULL;
const ::google::protobuf::Descriptor* MessagePsiSalt_descriptor_ = NULL;
const ::google::protobuf::internal::GeneratedMessageReflection*
  MessagePsiSalt_reflection_ = NULL;
const ::google::protobuf::Descriptor* MessagePsiHashData_descriptor_ = NULL;
const ::google::protobuf::internal::GeneratedMessageReflection*
  MessagePsiHashData_reflection_ = NULL;
const ::google::protobuf::Descriptor* MessagePsiHashDataFinished_descriptor_ = NULL;
const ::google::protobuf::internal::GeneratedMessageReflection*
  MessagePsiHashDataFinished_reflection_ = NULL;
const ::google::protobuf::Descriptor* MessagePsiResult_descriptor_ = NULL;
const ::google::protobuf::internal::GeneratedMessageReflection*
  MessagePsiResult_reflection_ = NULL;
const ::google::protobuf::Descriptor* MessagePsiIntersect_descriptor_ = NULL;
const ::google::protobuf::internal::GeneratedMessageReflection*
  MessagePsiIntersect_reflection_ = NULL;

}  // namespace


void protobuf_AssignDesc_Messages_2eproto() {
  protobuf_AddDesc_Messages_2eproto();
  const ::google::protobuf::FileDescriptor* file =
    ::google::protobuf::DescriptorPool::generated_pool()->FindFileByName(
      "Messages.proto");
  GOOGLE_CHECK(file != NULL);
  InitialMessage_descriptor_ = file->message_type(0);
  static const int InitialMessage_offsets_[2] = {
    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(InitialMessage, type_),
    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(InitialMessage, size_),
  };
  InitialMessage_reflection_ =
    new ::google::protobuf::internal::GeneratedMessageReflection(
      InitialMessage_descriptor_,
      InitialMessage::default_instance_,
      InitialMessage_offsets_,
      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(InitialMessage, _has_bits_[0]),
      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(InitialMessage, _unknown_fields_),
      -1,
      ::google::protobuf::DescriptorPool::generated_pool(),
      ::google::protobuf::MessageFactory::generated_factory(),
      sizeof(InitialMessage));
  MessageMsg0_descriptor_ = file->message_type(1);
  static const int MessageMsg0_offsets_[3] = {
    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessageMsg0, type_),
    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessageMsg0, epid_),
    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessageMsg0, status_),
  };
  MessageMsg0_reflection_ =
    new ::google::protobuf::internal::GeneratedMessageReflection(
      MessageMsg0_descriptor_,
      MessageMsg0::default_instance_,
      MessageMsg0_offsets_,
      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessageMsg0, _has_bits_[0]),
      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessageMsg0, _unknown_fields_),
      -1,
      ::google::protobuf::DescriptorPool::generated_pool(),
      ::google::protobuf::MessageFactory::generated_factory(),
      sizeof(MessageMsg0));
  MessageMSG1_descriptor_ = file->message_type(2);
  static const int MessageMSG1_offsets_[5] = {
    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessageMSG1, type_),
    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessageMSG1, context_),
    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessageMSG1, gax_),
    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessageMSG1, gay_),
    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessageMSG1, gid_),
  };
  MessageMSG1_reflection_ =
    new ::google::protobuf::internal::GeneratedMessageReflection(
      MessageMSG1_descriptor_,
      MessageMSG1::default_instance_,
      MessageMSG1_offsets_,
      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessageMSG1, _has_bits_[0]),
      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessageMSG1, _unknown_fields_),
      -1,
      ::google::protobuf::DescriptorPool::generated_pool(),
      ::google::protobuf::MessageFactory::generated_factory(),
      sizeof(MessageMSG1));
  MessageMSG2_descriptor_ = file->message_type(3);
  static const int MessageMSG2_offsets_[13] = {
    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessageMSG2, type_),
    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessageMSG2, size_),
    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessageMSG2, context_),
    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessageMSG2, public_key_gx_),
    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessageMSG2, public_key_gy_),
    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessageMSG2, quote_type_),
    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessageMSG2, spid_),
    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessageMSG2, cmac_kdf_id_),
    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessageMSG2, signature_x_),
    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessageMSG2, signature_y_),
    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessageMSG2, smac_),
    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessageMSG2, size_sigrl_),
    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessageMSG2, sigrl_),
  };
  MessageMSG2_reflection_ =
    new ::google::protobuf::internal::GeneratedMessageReflection(
      MessageMSG2_descriptor_,
      MessageMSG2::default_instance_,
      MessageMSG2_offsets_,
      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessageMSG2, _has_bits_[0]),
      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessageMSG2, _unknown_fields_),
      -1,
      ::google::protobuf::DescriptorPool::generated_pool(),
      ::google::protobuf::MessageFactory::generated_factory(),
      sizeof(MessageMSG2));
  MessageMSG3_descriptor_ = file->message_type(4);
  static const int MessageMSG3_offsets_[8] = {
    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessageMSG3, type_),
    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessageMSG3, size_),
    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessageMSG3, context_),
    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessageMSG3, sgx_mac_),
    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessageMSG3, gax_msg3_),
    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessageMSG3, gay_msg3_),
    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessageMSG3, sec_property_),
    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessageMSG3, quote_),
  };
  MessageMSG3_reflection_ =
    new ::google::protobuf::internal::GeneratedMessageReflection(
      MessageMSG3_descriptor_,
      MessageMSG3::default_instance_,
      MessageMSG3_offsets_,
      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessageMSG3, _has_bits_[0]),
      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessageMSG3, _unknown_fields_),
      -1,
      ::google::protobuf::DescriptorPool::generated_pool(),
      ::google::protobuf::MessageFactory::generated_factory(),
      sizeof(MessageMSG3));
  AttestationMessage_descriptor_ = file->message_type(5);
  static const int AttestationMessage_offsets_[17] = {
    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(AttestationMessage, type_),
    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(AttestationMessage, size_),
    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(AttestationMessage, context_),
    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(AttestationMessage, epid_group_status_),
    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(AttestationMessage, tcb_evaluation_status_),
    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(AttestationMessage, pse_evaluation_status_),
    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(AttestationMessage, latest_equivalent_tcb_psvn_),
    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(AttestationMessage, latest_pse_isvsvn_),
    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(AttestationMessage, latest_psda_svn_),
    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(AttestationMessage, performance_rekey_gid_),
    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(AttestationMessage, ec_sign256_x_),
    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(AttestationMessage, ec_sign256_y_),
    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(AttestationMessage, mac_smk_),
    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(AttestationMessage, result_size_),
    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(AttestationMessage, reserved_),
    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(AttestationMessage, payload_tag_),
    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(AttestationMessage, payload_),
  };
  AttestationMessage_reflection_ =
    new ::google::protobuf::internal::GeneratedMessageReflection(
      AttestationMessage_descriptor_,
      AttestationMessage::default_instance_,
      AttestationMessage_offsets_,
      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(AttestationMessage, _has_bits_[0]),
      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(AttestationMessage, _unknown_fields_),
      -1,
      ::google::protobuf::DescriptorPool::generated_pool(),
      ::google::protobuf::MessageFactory::generated_factory(),
      sizeof(AttestationMessage));
  MessagePsiSalt_descriptor_ = file->message_type(6);
  static const int MessagePsiSalt_offsets_[7] = {
    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessagePsiSalt, type_),
    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessagePsiSalt, size_),
    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessagePsiSalt, context_),
    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessagePsiSalt, id_),
    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessagePsiSalt, state_),
    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessagePsiSalt, mac_),
    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessagePsiSalt, salt_),
  };
  MessagePsiSalt_reflection_ =
    new ::google::protobuf::internal::GeneratedMessageReflection(
      MessagePsiSalt_descriptor_,
      MessagePsiSalt::default_instance_,
      MessagePsiSalt_offsets_,
      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessagePsiSalt, _has_bits_[0]),
      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessagePsiSalt, _unknown_fields_),
      -1,
      ::google::protobuf::DescriptorPool::generated_pool(),
      ::google::protobuf::MessageFactory::generated_factory(),
      sizeof(MessagePsiSalt));
  MessagePsiHashData_descriptor_ = file->message_type(7);
  static const int MessagePsiHashData_offsets_[6] = {
    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessagePsiHashData, type_),
    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessagePsiHashData, size_),
    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessagePsiHashData, context_),
    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessagePsiHashData, id_),
    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessagePsiHashData, mac_),
    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessagePsiHashData, data_),
  };
  MessagePsiHashData_reflection_ =
    new ::google::protobuf::internal::GeneratedMessageReflection(
      MessagePsiHashData_descriptor_,
      MessagePsiHashData::default_instance_,
      MessagePsiHashData_offsets_,
      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessagePsiHashData, _has_bits_[0]),
      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessagePsiHashData, _unknown_fields_),
      -1,
      ::google::protobuf::DescriptorPool::generated_pool(),
      ::google::protobuf::MessageFactory::generated_factory(),
      sizeof(MessagePsiHashData));
  MessagePsiHashDataFinished_descriptor_ = file->message_type(8);
  static const int MessagePsiHashDataFinished_offsets_[4] = {
    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessagePsiHashDataFinished, type_),
    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessagePsiHashDataFinished, size_),
    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessagePsiHashDataFinished, context_),
    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessagePsiHashDataFinished, id_),
  };
  MessagePsiHashDataFinished_reflection_ =
    new ::google::protobuf::internal::GeneratedMessageReflection(
      MessagePsiHashDataFinished_descriptor_,
      MessagePsiHashDataFinished::default_instance_,
      MessagePsiHashDataFinished_offsets_,
      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessagePsiHashDataFinished, _has_bits_[0]),
      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessagePsiHashDataFinished, _unknown_fields_),
      -1,
      ::google::protobuf::DescriptorPool::generated_pool(),
      ::google::protobuf::MessageFactory::generated_factory(),
      sizeof(MessagePsiHashDataFinished));
  MessagePsiResult_descriptor_ = file->message_type(9);
  static const int MessagePsiResult_offsets_[5] = {
    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessagePsiResult, type_),
    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessagePsiResult, size_),
    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessagePsiResult, context_),
    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessagePsiResult, id_),
    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessagePsiResult, state_),
  };
  MessagePsiResult_reflection_ =
    new ::google::protobuf::internal::GeneratedMessageReflection(
      MessagePsiResult_descriptor_,
      MessagePsiResult::default_instance_,
      MessagePsiResult_offsets_,
      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessagePsiResult, _has_bits_[0]),
      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessagePsiResult, _unknown_fields_),
      -1,
      ::google::protobuf::DescriptorPool::generated_pool(),
      ::google::protobuf::MessageFactory::generated_factory(),
      sizeof(MessagePsiResult));
  MessagePsiIntersect_descriptor_ = file->message_type(10);
  static const int MessagePsiIntersect_offsets_[6] = {
    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessagePsiIntersect, type_),
    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessagePsiIntersect, size_),
    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessagePsiIntersect, context_),
    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessagePsiIntersect, id_),
    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessagePsiIntersect, mac_),
    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessagePsiIntersect, data_),
  };
  MessagePsiIntersect_reflection_ =
    new ::google::protobuf::internal::GeneratedMessageReflection(
      MessagePsiIntersect_descriptor_,
      MessagePsiIntersect::default_instance_,
      MessagePsiIntersect_offsets_,
      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessagePsiIntersect, _has_bits_[0]),
      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessagePsiIntersect, _unknown_fields_),
      -1,
      ::google::protobuf::DescriptorPool::generated_pool(),
      ::google::protobuf::MessageFactory::generated_factory(),
      sizeof(MessagePsiIntersect));
}

namespace {

GOOGLE_PROTOBUF_DECLARE_ONCE(protobuf_AssignDescriptors_once_);
inline void protobuf_AssignDescriptorsOnce() {
  ::google::protobuf::GoogleOnceInit(&protobuf_AssignDescriptors_once_,
                 &protobuf_AssignDesc_Messages_2eproto);
}

void protobuf_RegisterTypes(const ::std::string&) {
  protobuf_AssignDescriptorsOnce();
  ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
    InitialMessage_descriptor_, &InitialMessage::default_instance());
  ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
    MessageMsg0_descriptor_, &MessageMsg0::default_instance());
  ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
    MessageMSG1_descriptor_, &MessageMSG1::default_instance());
  ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
    MessageMSG2_descriptor_, &MessageMSG2::default_instance());
  ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
    MessageMSG3_descriptor_, &MessageMSG3::default_instance());
  ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
    AttestationMessage_descriptor_, &AttestationMessage::default_instance());
  ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
    MessagePsiSalt_descriptor_, &MessagePsiSalt::default_instance());
  ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
    MessagePsiHashData_descriptor_, &MessagePsiHashData::default_instance());
  ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
    MessagePsiHashDataFinished_descriptor_, &MessagePsiHashDataFinished::default_instance());
  ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
    MessagePsiResult_descriptor_, &MessagePsiResult::default_instance());
  ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
    MessagePsiIntersect_descriptor_, &MessagePsiIntersect::default_instance());
}

}  // namespace

void protobuf_ShutdownFile_Messages_2eproto() {
  delete InitialMessage::default_instance_;
  delete InitialMessage_reflection_;
  delete MessageMsg0::default_instance_;
  delete MessageMsg0_reflection_;
  delete MessageMSG1::default_instance_;
  delete MessageMSG1_reflection_;
  delete MessageMSG2::default_instance_;
  delete MessageMSG2_reflection_;
  delete MessageMSG3::default_instance_;
  delete MessageMSG3_reflection_;
  delete AttestationMessage::default_instance_;
  delete AttestationMessage_reflection_;
  delete MessagePsiSalt::default_instance_;
  delete MessagePsiSalt_reflection_;
  delete MessagePsiHashData::default_instance_;
  delete MessagePsiHashData_reflection_;
  delete MessagePsiHashDataFinished::default_instance_;
  delete MessagePsiHashDataFinished_reflection_;
  delete MessagePsiResult::default_instance_;
  delete MessagePsiResult_reflection_;
  delete MessagePsiIntersect::default_instance_;
  delete MessagePsiIntersect_reflection_;
}

void protobuf_AddDesc_Messages_2eproto() {
  static bool already_here = false;
  if (already_here) return;
  already_here = true;
  GOOGLE_PROTOBUF_VERIFY_VERSION;

  ::google::protobuf::DescriptorPool::InternalAddGeneratedFile(
    "\n\016Messages.proto\022\010Messages\",\n\016InitialMes"
    "sage\022\014\n\004type\030\001 \002(\r\022\014\n\004size\030\002 \001(\r\"9\n\013Mess"
    "ageMsg0\022\014\n\004type\030\001 \002(\r\022\014\n\004epid\030\002 \002(\r\022\016\n\006s"
    "tatus\030\003 \001(\r\"_\n\013MessageMSG1\022\014\n\004type\030\001 \002(\r"
    "\022\017\n\007context\030\002 \002(\r\022\017\n\003GaX\030\003 \003(\rB\002\020\001\022\017\n\003Ga"
    "Y\030\004 \003(\rB\002\020\001\022\017\n\003GID\030\005 \003(\rB\002\020\001\"\226\002\n\013Message"
    "MSG2\022\014\n\004type\030\001 \002(\r\022\014\n\004size\030\002 \001(\r\022\017\n\007cont"
    "ext\030\003 \002(\r\022\031\n\rpublic_key_gx\030\004 \003(\rB\002\020\001\022\031\n\r"
    "public_key_gy\030\005 \003(\rB\002\020\001\022\022\n\nquote_type\030\006 "
    "\001(\r\022\020\n\004spid\030\007 \003(\rB\002\020\001\022\023\n\013cmac_kdf_id\030\010 \001"
    "(\r\022\027\n\013signature_x\030\t \003(\rB\002\020\001\022\027\n\013signature"
    "_y\030\n \003(\rB\002\020\001\022\020\n\004smac\030\013 \003(\rB\002\020\001\022\022\n\nsize_s"
    "igrl\030\014 \001(\r\022\021\n\005sigrl\030\r \003(\rB\002\020\001\"\250\001\n\013Messag"
    "eMSG3\022\014\n\004type\030\001 \002(\r\022\014\n\004size\030\002 \001(\r\022\017\n\007con"
    "text\030\003 \002(\r\022\023\n\007sgx_mac\030\004 \003(\rB\002\020\001\022\024\n\010gax_m"
    "sg3\030\005 \003(\rB\002\020\001\022\024\n\010gay_msg3\030\006 \003(\rB\002\020\001\022\030\n\014s"
    "ec_property\030\007 \003(\rB\002\020\001\022\021\n\005quote\030\010 \003(\rB\002\020\001"
    "\"\303\003\n\022AttestationMessage\022\014\n\004type\030\001 \002(\r\022\014\n"
    "\004size\030\002 \002(\r\022\017\n\007context\030\003 \002(\r\022\031\n\021epid_gro"
    "up_status\030\004 \001(\r\022\035\n\025tcb_evaluation_status"
    "\030\005 \001(\r\022\035\n\025pse_evaluation_status\030\006 \001(\r\022&\n"
    "\032latest_equivalent_tcb_psvn\030\007 \003(\rB\002\020\001\022\035\n"
    "\021latest_pse_isvsvn\030\010 \003(\rB\002\020\001\022\033\n\017latest_p"
    "sda_svn\030\t \003(\rB\002\020\001\022!\n\025performance_rekey_g"
    "id\030\n \003(\rB\002\020\001\022\030\n\014ec_sign256_x\030\013 \003(\rB\002\020\001\022\030"
    "\n\014ec_sign256_y\030\014 \003(\rB\002\020\001\022\023\n\007mac_smk\030\r \003("
    "\rB\002\020\001\022\023\n\013result_size\030\016 \001(\r\022\024\n\010reserved\030\017"
    " \003(\rB\002\020\001\022\027\n\013payload_tag\030\020 \003(\rB\002\020\001\022\023\n\007pay"
    "load\030\021 \003(\rB\002\020\001\"{\n\016MessagePsiSalt\022\014\n\004type"
    "\030\001 \002(\r\022\014\n\004size\030\002 \002(\r\022\017\n\007context\030\003 \002(\r\022\n\n"
    "\002id\030\004 \002(\r\022\r\n\005state\030\005 \002(\r\022\017\n\003mac\030\006 \003(\rB\002\020"
    "\001\022\020\n\004salt\030\007 \003(\rB\002\020\001\"p\n\022MessagePsiHashDat"
    "a\022\014\n\004type\030\001 \002(\r\022\014\n\004size\030\002 \002(\r\022\017\n\007context"
    "\030\003 \002(\r\022\n\n\002id\030\004 \002(\r\022\017\n\003mac\030\005 \003(\rB\002\020\001\022\020\n\004d"
    "ata\030\006 \003(\rB\002\020\001\"U\n\032MessagePsiHashDataFinis"
    "hed\022\014\n\004type\030\001 \002(\r\022\014\n\004size\030\002 \002(\r\022\017\n\007conte"
    "xt\030\003 \002(\r\022\n\n\002id\030\004 \002(\r\"Z\n\020MessagePsiResult"
    "\022\014\n\004type\030\001 \002(\r\022\014\n\004size\030\002 \002(\r\022\017\n\007context\030"
    "\003 \002(\r\022\n\n\002id\030\004 \002(\r\022\r\n\005state\030\005 \002(\r\"q\n\023Mess"
    "agePsiIntersect\022\014\n\004type\030\001 \002(\r\022\014\n\004size\030\002 "
    "\002(\r\022\017\n\007context\030\003 \002(\r\022\n\n\002id\030\004 \002(\r\022\017\n\003mac\030"
    "\005 \003(\rB\002\020\001\022\020\n\004data\030\006 \003(\rB\002\020\001", 1667);
  ::google::protobuf::MessageFactory::InternalRegisterGeneratedFile(
    "Messages.proto", &protobuf_RegisterTypes);
  InitialMessage::default_instance_ = new InitialMessage();
  MessageMsg0::default_instance_ = new MessageMsg0();
  MessageMSG1::default_instance_ = new MessageMSG1();
  MessageMSG2::default_instance_ = new MessageMSG2();
  MessageMSG3::default_instance_ = new MessageMSG3();
  AttestationMessage::default_instance_ = new AttestationMessage();
  MessagePsiSalt::default_instance_ = new MessagePsiSalt();
  MessagePsiHashData::default_instance_ = new MessagePsiHashData();
  MessagePsiHashDataFinished::default_instance_ = new MessagePsiHashDataFinished();
  MessagePsiResult::default_instance_ = new MessagePsiResult();
  MessagePsiIntersect::default_instance_ = new MessagePsiIntersect();
  InitialMessage::default_instance_->InitAsDefaultInstance();
  MessageMsg0::default_instance_->InitAsDefaultInstance();
  MessageMSG1::default_instance_->InitAsDefaultInstance();
  MessageMSG2::default_instance_->InitAsDefaultInstance();
  MessageMSG3::default_instance_->InitAsDefaultInstance();
  AttestationMessage::default_instance_->InitAsDefaultInstance();
  MessagePsiSalt::default_instance_->InitAsDefaultInstance();
  MessagePsiHashData::default_instance_->InitAsDefaultInstance();
  MessagePsiHashDataFinished::default_instance_->InitAsDefaultInstance();
  MessagePsiResult::default_instance_->InitAsDefaultInstance();
  MessagePsiIntersect::default_instance_->InitAsDefaultInstance();
  ::google::protobuf::internal::OnShutdown(&protobuf_ShutdownFile_Messages_2eproto);
}

// Force AddDescriptors() to be called at static initialization time.
struct StaticDescriptorInitializer_Messages_2eproto {
  StaticDescriptorInitializer_Messages_2eproto() {
    protobuf_AddDesc_Messages_2eproto();
  }
} static_descriptor_initializer_Messages_2eproto_;

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

#ifndef _MSC_VER
const int InitialMessage::kTypeFieldNumber;
const int InitialMessage::kSizeFieldNumber;
#endif  // !_MSC_VER

InitialMessage::InitialMessage()
  : ::google::protobuf::Message() {
  SharedCtor();
  // @@protoc_insertion_point(constructor:Messages.InitialMessage)
}

void InitialMessage::InitAsDefaultInstance() {
}

InitialMessage::InitialMessage(const InitialMessage& from)
  : ::google::protobuf::Message() {
  SharedCtor();
  MergeFrom(from);
  // @@protoc_insertion_point(copy_constructor:Messages.InitialMessage)
}

void InitialMessage::SharedCtor() {
  _cached_size_ = 0;
  type_ = 0u;
  size_ = 0u;
  ::memset(_has_bits_, 0, sizeof(_has_bits_));
}

InitialMessage::~InitialMessage() {
  // @@protoc_insertion_point(destructor:Messages.InitialMessage)
  SharedDtor();
}

void InitialMessage::SharedDtor() {
  if (this != default_instance_) {
  }
}

void InitialMessage::SetCachedSize(int size) const {
  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
  _cached_size_ = size;
  GOOGLE_SAFE_CONCURRENT_WRITES_END();
}
const ::google::protobuf::Descriptor* InitialMessage::descriptor() {
  protobuf_AssignDescriptorsOnce();
  return InitialMessage_descriptor_;
}

const InitialMessage& InitialMessage::default_instance() {
  if (default_instance_ == NULL) protobuf_AddDesc_Messages_2eproto();
  return *default_instance_;
}

InitialMessage* InitialMessage::default_instance_ = NULL;

InitialMessage* InitialMessage::New() const {
  return new InitialMessage;
}

void InitialMessage::Clear() {
#define OFFSET_OF_FIELD_(f) (reinterpret_cast<char*>(      \
  &reinterpret_cast<InitialMessage*>(16)->f) - \
   reinterpret_cast<char*>(16))

#define ZR_(first, last) do {                              \
    size_t f = OFFSET_OF_FIELD_(first);                    \
    size_t n = OFFSET_OF_FIELD_(last) - f + sizeof(last);  \
    ::memset(&first, 0, n);                                \
  } while (0)

  ZR_(type_, size_);

#undef OFFSET_OF_FIELD_
#undef ZR_

  ::memset(_has_bits_, 0, sizeof(_has_bits_));
  mutable_unknown_fields()->Clear();
}

bool InitialMessage::MergePartialFromCodedStream(
    ::google::protobuf::io::CodedInputStream* input) {
#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
  ::google::protobuf::uint32 tag;
  // @@protoc_insertion_point(parse_start:Messages.InitialMessage)
  for (;;) {
    ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127);
    tag = p.first;
    if (!p.second) goto handle_unusual;
    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
      // required uint32 type = 1;
      case 1: {
        if (tag == 8) {
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
                 input, &type_)));
          set_has_type();
        } else {
          goto handle_unusual;
        }
        if (input->ExpectTag(16)) goto parse_size;
        break;
      }

      // optional uint32 size = 2;
      case 2: {
        if (tag == 16) {
         parse_size:
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
                 input, &size_)));
          set_has_size();
        } else {
          goto handle_unusual;
        }
        if (input->ExpectAtEnd()) goto success;
        break;
      }

      default: {
      handle_unusual:
        if (tag == 0 ||
            ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
            ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
          goto success;
        }
        DO_(::google::protobuf::internal::WireFormat::SkipField(
              input, tag, mutable_unknown_fields()));
        break;
      }
    }
  }
success:
  // @@protoc_insertion_point(parse_success:Messages.InitialMessage)
  return true;
failure:
  // @@protoc_insertion_point(parse_failure:Messages.InitialMessage)
  return false;
#undef DO_
}

void InitialMessage::SerializeWithCachedSizes(
    ::google::protobuf::io::CodedOutputStream* output) const {
  // @@protoc_insertion_point(serialize_start:Messages.InitialMessage)
  // required uint32 type = 1;
  if (has_type()) {
    ::google::protobuf::internal::WireFormatLite::WriteUInt32(1, this->type(), output);
  }

  // optional uint32 size = 2;
  if (has_size()) {
    ::google::protobuf::internal::WireFormatLite::WriteUInt32(2, this->size(), output);
  }

  if (!unknown_fields().empty()) {
    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
        unknown_fields(), output);
  }
  // @@protoc_insertion_point(serialize_end:Messages.InitialMessage)
}

::google::protobuf::uint8* InitialMessage::SerializeWithCachedSizesToArray(
    ::google::protobuf::uint8* target) const {
  // @@protoc_insertion_point(serialize_to_array_start:Messages.InitialMessage)
  // required uint32 type = 1;
  if (has_type()) {
    target = ::google::protobuf::internal::WireFormatLite::WriteUInt32ToArray(1, this->type(), target);
  }

  // optional uint32 size = 2;
  if (has_size()) {
    target = ::google::protobuf::internal::WireFormatLite::WriteUInt32ToArray(2, this->size(), target);
  }

  if (!unknown_fields().empty()) {
    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
        unknown_fields(), target);
  }
  // @@protoc_insertion_point(serialize_to_array_end:Messages.InitialMessage)
  return target;
}

int InitialMessage::ByteSize() const {
  int total_size = 0;

  if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    // required uint32 type = 1;
    if (has_type()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::UInt32Size(
          this->type());
    }

    // optional uint32 size = 2;
    if (has_size()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::UInt32Size(
          this->size());
    }

  }
  if (!unknown_fields().empty()) {
    total_size +=
      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
        unknown_fields());
  }
  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
  _cached_size_ = total_size;
  GOOGLE_SAFE_CONCURRENT_WRITES_END();
  return total_size;
}

void InitialMessage::MergeFrom(const ::google::protobuf::Message& from) {
  GOOGLE_CHECK_NE(&from, this);
  const InitialMessage* source =
    ::google::protobuf::internal::dynamic_cast_if_available<const InitialMessage*>(
      &from);
  if (source == NULL) {
    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
  } else {
    MergeFrom(*source);
  }
}

void InitialMessage::MergeFrom(const InitialMessage& from) {
  GOOGLE_CHECK_NE(&from, this);
  if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    if (from.has_type()) {
      set_type(from.type());
    }
    if (from.has_size()) {
      set_size(from.size());
    }
  }
  mutable_unknown_fields()->MergeFrom(from.unknown_fields());
}

void InitialMessage::CopyFrom(const ::google::protobuf::Message& from) {
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

void InitialMessage::CopyFrom(const InitialMessage& from) {
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

bool InitialMessage::IsInitialized() const {
  if ((_has_bits_[0] & 0x00000001) != 0x00000001) return false;

  return true;
}

void InitialMessage::Swap(InitialMessage* other) {
  if (other != this) {
    std::swap(type_, other->type_);
    std::swap(size_, other->size_);
    std::swap(_has_bits_[0], other->_has_bits_[0]);
    _unknown_fields_.Swap(&other->_unknown_fields_);
    std::swap(_cached_size_, other->_cached_size_);
  }
}

::google::protobuf::Metadata InitialMessage::GetMetadata() const {
  protobuf_AssignDescriptorsOnce();
  ::google::protobuf::Metadata metadata;
  metadata.descriptor = InitialMessage_descriptor_;
  metadata.reflection = InitialMessage_reflection_;
  return metadata;
}


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

#ifndef _MSC_VER
const int MessageMsg0::kTypeFieldNumber;
const int MessageMsg0::kEpidFieldNumber;
const int MessageMsg0::kStatusFieldNumber;
#endif  // !_MSC_VER

MessageMsg0::MessageMsg0()
  : ::google::protobuf::Message() {
  SharedCtor();
  // @@protoc_insertion_point(constructor:Messages.MessageMsg0)
}

void MessageMsg0::InitAsDefaultInstance() {
}

MessageMsg0::MessageMsg0(const MessageMsg0& from)
  : ::google::protobuf::Message() {
  SharedCtor();
  MergeFrom(from);
  // @@protoc_insertion_point(copy_constructor:Messages.MessageMsg0)
}

void MessageMsg0::SharedCtor() {
  _cached_size_ = 0;
  type_ = 0u;
  epid_ = 0u;
  status_ = 0u;
  ::memset(_has_bits_, 0, sizeof(_has_bits_));
}

MessageMsg0::~MessageMsg0() {
  // @@protoc_insertion_point(destructor:Messages.MessageMsg0)
  SharedDtor();
}

void MessageMsg0::SharedDtor() {
  if (this != default_instance_) {
  }
}

void MessageMsg0::SetCachedSize(int size) const {
  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
  _cached_size_ = size;
  GOOGLE_SAFE_CONCURRENT_WRITES_END();
}
const ::google::protobuf::Descriptor* MessageMsg0::descriptor() {
  protobuf_AssignDescriptorsOnce();
  return MessageMsg0_descriptor_;
}

const MessageMsg0& MessageMsg0::default_instance() {
  if (default_instance_ == NULL) protobuf_AddDesc_Messages_2eproto();
  return *default_instance_;
}

MessageMsg0* MessageMsg0::default_instance_ = NULL;

MessageMsg0* MessageMsg0::New() const {
  return new MessageMsg0;
}

void MessageMsg0::Clear() {
#define OFFSET_OF_FIELD_(f) (reinterpret_cast<char*>(      \
  &reinterpret_cast<MessageMsg0*>(16)->f) - \
   reinterpret_cast<char*>(16))

#define ZR_(first, last) do {                              \
    size_t f = OFFSET_OF_FIELD_(first);                    \
    size_t n = OFFSET_OF_FIELD_(last) - f + sizeof(last);  \
    ::memset(&first, 0, n);                                \
  } while (0)

  ZR_(type_, status_);

#undef OFFSET_OF_FIELD_
#undef ZR_

  ::memset(_has_bits_, 0, sizeof(_has_bits_));
  mutable_unknown_fields()->Clear();
}

bool MessageMsg0::MergePartialFromCodedStream(
    ::google::protobuf::io::CodedInputStream* input) {
#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
  ::google::protobuf::uint32 tag;
  // @@protoc_insertion_point(parse_start:Messages.MessageMsg0)
  for (;;) {
    ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127);
    tag = p.first;
    if (!p.second) goto handle_unusual;
    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
      // required uint32 type = 1;
      case 1: {
        if (tag == 8) {
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
                 input, &type_)));
          set_has_type();
        } else {
          goto handle_unusual;
        }
        if (input->ExpectTag(16)) goto parse_epid;
        break;
      }

      // required uint32 epid = 2;
      case 2: {
        if (tag == 16) {
         parse_epid:
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
                 input, &epid_)));
          set_has_epid();
        } else {
          goto handle_unusual;
        }
        if (input->ExpectTag(24)) goto parse_status;
        break;
      }

      // optional uint32 status = 3;
      case 3: {
        if (tag == 24) {
         parse_status:
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
                 input, &status_)));
          set_has_status();
        } else {
          goto handle_unusual;
        }
        if (input->ExpectAtEnd()) goto success;
        break;
      }

      default: {
      handle_unusual:
        if (tag == 0 ||
            ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
            ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
          goto success;
        }
        DO_(::google::protobuf::internal::WireFormat::SkipField(
              input, tag, mutable_unknown_fields()));
        break;
      }
    }
  }
success:
  // @@protoc_insertion_point(parse_success:Messages.MessageMsg0)
  return true;
failure:
  // @@protoc_insertion_point(parse_failure:Messages.MessageMsg0)
  return false;
#undef DO_
}

void MessageMsg0::SerializeWithCachedSizes(
    ::google::protobuf::io::CodedOutputStream* output) const {
  // @@protoc_insertion_point(serialize_start:Messages.MessageMsg0)
  // required uint32 type = 1;
  if (has_type()) {
    ::google::protobuf::internal::WireFormatLite::WriteUInt32(1, this->type(), output);
  }

  // required uint32 epid = 2;
  if (has_epid()) {
    ::google::protobuf::internal::WireFormatLite::WriteUInt32(2, this->epid(), output);
  }

  // optional uint32 status = 3;
  if (has_status()) {
    ::google::protobuf::internal::WireFormatLite::WriteUInt32(3, this->status(), output);
  }

  if (!unknown_fields().empty()) {
    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
        unknown_fields(), output);
  }
  // @@protoc_insertion_point(serialize_end:Messages.MessageMsg0)
}

::google::protobuf::uint8* MessageMsg0::SerializeWithCachedSizesToArray(
    ::google::protobuf::uint8* target) const {
  // @@protoc_insertion_point(serialize_to_array_start:Messages.MessageMsg0)
  // required uint32 type = 1;
  if (has_type()) {
    target = ::google::protobuf::internal::WireFormatLite::WriteUInt32ToArray(1, this->type(), target);
  }

  // required uint32 epid = 2;
  if (has_epid()) {
    target = ::google::protobuf::internal::WireFormatLite::WriteUInt32ToArray(2, this->epid(), target);
  }

  // optional uint32 status = 3;
  if (has_status()) {
    target = ::google::protobuf::internal::WireFormatLite::WriteUInt32ToArray(3, this->status(), target);
  }

  if (!unknown_fields().empty()) {
    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
        unknown_fields(), target);
  }
  // @@protoc_insertion_point(serialize_to_array_end:Messages.MessageMsg0)
  return target;
}

int MessageMsg0::ByteSize() const {
  int total_size = 0;

  if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    // required uint32 type = 1;
    if (has_type()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::UInt32Size(
          this->type());
    }

    // required uint32 epid = 2;
    if (has_epid()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::UInt32Size(
          this->epid());
    }

    // optional uint32 status = 3;
    if (has_status()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::UInt32Size(
          this->status());
    }

  }
  if (!unknown_fields().empty()) {
    total_size +=
      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
        unknown_fields());
  }
  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
  _cached_size_ = total_size;
  GOOGLE_SAFE_CONCURRENT_WRITES_END();
  return total_size;
}

void MessageMsg0::MergeFrom(const ::google::protobuf::Message& from) {
  GOOGLE_CHECK_NE(&from, this);
  const MessageMsg0* source =
    ::google::protobuf::internal::dynamic_cast_if_available<const MessageMsg0*>(
      &from);
  if (source == NULL) {
    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
  } else {
    MergeFrom(*source);
  }
}

void MessageMsg0::MergeFrom(const MessageMsg0& from) {
  GOOGLE_CHECK_NE(&from, this);
  if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    if (from.has_type()) {
      set_type(from.type());
    }
    if (from.has_epid()) {
      set_epid(from.epid());
    }
    if (from.has_status()) {
      set_status(from.status());
    }
  }
  mutable_unknown_fields()->MergeFrom(from.unknown_fields());
}

void MessageMsg0::CopyFrom(const ::google::protobuf::Message& from) {
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

void MessageMsg0::CopyFrom(const MessageMsg0& from) {
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

bool MessageMsg0::IsInitialized() const {
  if ((_has_bits_[0] & 0x00000003) != 0x00000003) return false;

  return true;
}

void MessageMsg0::Swap(MessageMsg0* other) {
  if (other != this) {
    std::swap(type_, other->type_);
    std::swap(epid_, other->epid_);
    std::swap(status_, other->status_);
    std::swap(_has_bits_[0], other->_has_bits_[0]);
    _unknown_fields_.Swap(&other->_unknown_fields_);
    std::swap(_cached_size_, other->_cached_size_);
  }
}

::google::protobuf::Metadata MessageMsg0::GetMetadata() const {
  protobuf_AssignDescriptorsOnce();
  ::google::protobuf::Metadata metadata;
  metadata.descriptor = MessageMsg0_descriptor_;
  metadata.reflection = MessageMsg0_reflection_;
  return metadata;
}


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

#ifndef _MSC_VER
const int MessageMSG1::kTypeFieldNumber;
const int MessageMSG1::kContextFieldNumber;
const int MessageMSG1::kGaXFieldNumber;
const int MessageMSG1::kGaYFieldNumber;
const int MessageMSG1::kGIDFieldNumber;
#endif  // !_MSC_VER

MessageMSG1::MessageMSG1()
  : ::google::protobuf::Message() {
  SharedCtor();
  // @@protoc_insertion_point(constructor:Messages.MessageMSG1)
}

void MessageMSG1::InitAsDefaultInstance() {
}

MessageMSG1::MessageMSG1(const MessageMSG1& from)
  : ::google::protobuf::Message() {
  SharedCtor();
  MergeFrom(from);
  // @@protoc_insertion_point(copy_constructor:Messages.MessageMSG1)
}

void MessageMSG1::SharedCtor() {
  _cached_size_ = 0;
  type_ = 0u;
  context_ = 0u;
  ::memset(_has_bits_, 0, sizeof(_has_bits_));
}

MessageMSG1::~MessageMSG1() {
  // @@protoc_insertion_point(destructor:Messages.MessageMSG1)
  SharedDtor();
}

void MessageMSG1::SharedDtor() {
  if (this != default_instance_) {
  }
}

void MessageMSG1::SetCachedSize(int size) const {
  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
  _cached_size_ = size;
  GOOGLE_SAFE_CONCURRENT_WRITES_END();
}
const ::google::protobuf::Descriptor* MessageMSG1::descriptor() {
  protobuf_AssignDescriptorsOnce();
  return MessageMSG1_descriptor_;
}

const MessageMSG1& MessageMSG1::default_instance() {
  if (default_instance_ == NULL) protobuf_AddDesc_Messages_2eproto();
  return *default_instance_;
}

MessageMSG1* MessageMSG1::default_instance_ = NULL;

MessageMSG1* MessageMSG1::New() const {
  return new MessageMSG1;
}

void MessageMSG1::Clear() {
#define OFFSET_OF_FIELD_(f) (reinterpret_cast<char*>(      \
  &reinterpret_cast<MessageMSG1*>(16)->f) - \
   reinterpret_cast<char*>(16))

#define ZR_(first, last) do {                              \
    size_t f = OFFSET_OF_FIELD_(first);                    \
    size_t n = OFFSET_OF_FIELD_(last) - f + sizeof(last);  \
    ::memset(&first, 0, n);                                \
  } while (0)

  ZR_(type_, context_);

#undef OFFSET_OF_FIELD_
#undef ZR_

  gax_.Clear();
  gay_.Clear();
  gid_.Clear();
  ::memset(_has_bits_, 0, sizeof(_has_bits_));
  mutable_unknown_fields()->Clear();
}

bool MessageMSG1::MergePartialFromCodedStream(
    ::google::protobuf::io::CodedInputStream* input) {
#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
  ::google::protobuf::uint32 tag;
  // @@protoc_insertion_point(parse_start:Messages.MessageMSG1)
  for (;;) {
    ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127);
    tag = p.first;
    if (!p.second) goto handle_unusual;
    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
      // required uint32 type = 1;
      case 1: {
        if (tag == 8) {
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
                 input, &type_)));
          set_has_type();
        } else {
          goto handle_unusual;
        }
        if (input->ExpectTag(16)) goto parse_context;
        break;
      }

      // required uint32 context = 2;
      case 2: {
        if (tag == 16) {
         parse_context:
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
                 input, &context_)));
          set_has_context();
        } else {
          goto handle_unusual;
        }
        if (input->ExpectTag(26)) goto parse_GaX;
        break;
      }

      // repeated uint32 GaX = 3 [packed = true];
      case 3: {
        if (tag == 26) {
         parse_GaX:
          DO_((::google::protobuf::internal::WireFormatLite::ReadPackedPrimitive<
                   ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
                 input, this->mutable_gax())));
        } else if (tag == 24) {
          DO_((::google::protobuf::internal::WireFormatLite::ReadRepeatedPrimitiveNoInline<
                   ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
                 1, 26, input, this->mutable_gax())));
        } else {
          goto handle_unusual;
        }
        if (input->ExpectTag(34)) goto parse_GaY;
        break;
      }

      // repeated uint32 GaY = 4 [packed = true];
      case 4: {
        if (tag == 34) {
         parse_GaY:
          DO_((::google::protobuf::internal::WireFormatLite::ReadPackedPrimitive<
                   ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
                 input, this->mutable_gay())));
        } else if (tag == 32) {
          DO_((::google::protobuf::internal::WireFormatLite::ReadRepeatedPrimitiveNoInline<
                   ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
                 1, 34, input, this->mutable_gay())));
        } else {
          goto handle_unusual;
        }
        if (input->ExpectTag(42)) goto parse_GID;
        break;
      }

      // repeated uint32 GID = 5 [packed = true];
      case 5: {
        if (tag == 42) {
         parse_GID:
          DO_((::google::protobuf::internal::WireFormatLite::ReadPackedPrimitive<
                   ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
                 input, this->mutable_gid())));
        } else if (tag == 40) {
          DO_((::google::protobuf::internal::WireFormatLite::ReadRepeatedPrimitiveNoInline<
                   ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
                 1, 42, input, this->mutable_gid())));
        } else {
          goto handle_unusual;
        }
        if (input->ExpectAtEnd()) goto success;
        break;
      }

      default: {
      handle_unusual:
        if (tag == 0 ||
            ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
            ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
          goto success;
        }
        DO_(::google::protobuf::internal::WireFormat::SkipField(
              input, tag, mutable_unknown_fields()));
        break;
      }
    }
  }
success:
  // @@protoc_insertion_point(parse_success:Messages.MessageMSG1)
  return true;
failure:
  // @@protoc_insertion_point(parse_failure:Messages.MessageMSG1)
  return false;
#undef DO_
}

void MessageMSG1::SerializeWithCachedSizes(
    ::google::protobuf::io::CodedOutputStream* output) const {
  // @@protoc_insertion_point(serialize_start:Messages.MessageMSG1)
  // required uint32 type = 1;
  if (has_type()) {
    ::google::protobuf::internal::WireFormatLite::WriteUInt32(1, this->type(), output);
  }

  // required uint32 context = 2;
  if (has_context()) {
    ::google::protobuf::internal::WireFormatLite::WriteUInt32(2, this->context(), output);
  }

  // repeated uint32 GaX = 3 [packed = true];
  if (this->gax_size() > 0) {
    ::google::protobuf::internal::WireFormatLite::WriteTag(3, ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED, output);
    output->WriteVarint32(_gax_cached_byte_size_);
  }
  for (int i = 0; i < this->gax_size(); i++) {
    ::google::protobuf::internal::WireFormatLite::WriteUInt32NoTag(
      this->gax(i), output);
  }

  // repeated uint32 GaY = 4 [packed = true];
  if (this->gay_size() > 0) {
    ::google::protobuf::internal::WireFormatLite::WriteTag(4, ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED, output);
    output->WriteVarint32(_gay_cached_byte_size_);
  }
  for (int i = 0; i < this->gay_size(); i++) {
    ::google::protobuf::internal::WireFormatLite::WriteUInt32NoTag(
      this->gay(i), output);
  }

  // repeated uint32 GID = 5 [packed = true];
  if (this->gid_size() > 0) {
    ::google::protobuf::internal::WireFormatLite::WriteTag(5, ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED, output);
    output->WriteVarint32(_gid_cached_byte_size_);
  }
  for (int i = 0; i < this->gid_size(); i++) {
    ::google::protobuf::internal::WireFormatLite::WriteUInt32NoTag(
      this->gid(i), output);
  }

  if (!unknown_fields().empty()) {
    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
        unknown_fields(), output);
  }
  // @@protoc_insertion_point(serialize_end:Messages.MessageMSG1)
}

::google::protobuf::uint8* MessageMSG1::SerializeWithCachedSizesToArray(
    ::google::protobuf::uint8* target) const {
  // @@protoc_insertion_point(serialize_to_array_start:Messages.MessageMSG1)
  // required uint32 type = 1;
  if (has_type()) {
    target = ::google::protobuf::internal::WireFormatLite::WriteUInt32ToArray(1, this->type(), target);
  }

  // required uint32 context = 2;
  if (has_context()) {
    target = ::google::protobuf::internal::WireFormatLite::WriteUInt32ToArray(2, this->context(), target);
  }

  // repeated uint32 GaX = 3 [packed = true];
  if (this->gax_size() > 0) {
    target = ::google::protobuf::internal::WireFormatLite::WriteTagToArray(
      3,
      ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED,
      target);
    target = ::google::protobuf::io::CodedOutputStream::WriteVarint32ToArray(
      _gax_cached_byte_size_, target);
  }
  for (int i = 0; i < this->gax_size(); i++) {
    target = ::google::protobuf::internal::WireFormatLite::
      WriteUInt32NoTagToArray(this->gax(i), target);
  }

  // repeated uint32 GaY = 4 [packed = true];
  if (this->gay_size() > 0) {
    target = ::google::protobuf::internal::WireFormatLite::WriteTagToArray(
      4,
      ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED,
      target);
    target = ::google::protobuf::io::CodedOutputStream::WriteVarint32ToArray(
      _gay_cached_byte_size_, target);
  }
  for (int i = 0; i < this->gay_size(); i++) {
    target = ::google::protobuf::internal::WireFormatLite::
      WriteUInt32NoTagToArray(this->gay(i), target);
  }

  // repeated uint32 GID = 5 [packed = true];
  if (this->gid_size() > 0) {
    target = ::google::protobuf::internal::WireFormatLite::WriteTagToArray(
      5,
      ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED,
      target);
    target = ::google::protobuf::io::CodedOutputStream::WriteVarint32ToArray(
      _gid_cached_byte_size_, target);
  }
  for (int i = 0; i < this->gid_size(); i++) {
    target = ::google::protobuf::internal::WireFormatLite::
      WriteUInt32NoTagToArray(this->gid(i), target);
  }

  if (!unknown_fields().empty()) {
    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
        unknown_fields(), target);
  }
  // @@protoc_insertion_point(serialize_to_array_end:Messages.MessageMSG1)
  return target;
}

int MessageMSG1::ByteSize() const {
  int total_size = 0;

  if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    // required uint32 type = 1;
    if (has_type()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::UInt32Size(
          this->type());
    }

    // required uint32 context = 2;
    if (has_context()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::UInt32Size(
          this->context());
    }

  }
  // repeated uint32 GaX = 3 [packed = true];
  {
    int data_size = 0;
    for (int i = 0; i < this->gax_size(); i++) {
      data_size += ::google::protobuf::internal::WireFormatLite::
        UInt32Size(this->gax(i));
    }
    if (data_size > 0) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::Int32Size(data_size);
    }
    GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
    _gax_cached_byte_size_ = data_size;
    GOOGLE_SAFE_CONCURRENT_WRITES_END();
    total_size += data_size;
  }

  // repeated uint32 GaY = 4 [packed = true];
  {
    int data_size = 0;
    for (int i = 0; i < this->gay_size(); i++) {
      data_size += ::google::protobuf::internal::WireFormatLite::
        UInt32Size(this->gay(i));
    }
    if (data_size > 0) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::Int32Size(data_size);
    }
    GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
    _gay_cached_byte_size_ = data_size;
    GOOGLE_SAFE_CONCURRENT_WRITES_END();
    total_size += data_size;
  }

  // repeated uint32 GID = 5 [packed = true];
  {
    int data_size = 0;
    for (int i = 0; i < this->gid_size(); i++) {
      data_size += ::google::protobuf::internal::WireFormatLite::
        UInt32Size(this->gid(i));
    }
    if (data_size > 0) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::Int32Size(data_size);
    }
    GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
    _gid_cached_byte_size_ = data_size;
    GOOGLE_SAFE_CONCURRENT_WRITES_END();
    total_size += data_size;
  }

  if (!unknown_fields().empty()) {
    total_size +=
      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
        unknown_fields());
  }
  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
  _cached_size_ = total_size;
  GOOGLE_SAFE_CONCURRENT_WRITES_END();
  return total_size;
}

void MessageMSG1::MergeFrom(const ::google::protobuf::Message& from) {
  GOOGLE_CHECK_NE(&from, this);
  const MessageMSG1* source =
    ::google::protobuf::internal::dynamic_cast_if_available<const MessageMSG1*>(
      &from);
  if (source == NULL) {
    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
  } else {
    MergeFrom(*source);
  }
}

void MessageMSG1::MergeFrom(const MessageMSG1& from) {
  GOOGLE_CHECK_NE(&from, this);
  gax_.MergeFrom(from.gax_);
  gay_.MergeFrom(from.gay_);
  gid_.MergeFrom(from.gid_);
  if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    if (from.has_type()) {
      set_type(from.type());
    }
    if (from.has_context()) {
      set_context(from.context());
    }
  }
  mutable_unknown_fields()->MergeFrom(from.unknown_fields());
}

void MessageMSG1::CopyFrom(const ::google::protobuf::Message& from) {
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

void MessageMSG1::CopyFrom(const MessageMSG1& from) {
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

bool MessageMSG1::IsInitialized() const {
  if ((_has_bits_[0] & 0x00000003) != 0x00000003) return false;

  return true;
}

void MessageMSG1::Swap(MessageMSG1* other) {
  if (other != this) {
    std::swap(type_, other->type_);
    std::swap(context_, other->context_);
    gax_.Swap(&other->gax_);
    gay_.Swap(&other->gay_);
    gid_.Swap(&other->gid_);
    std::swap(_has_bits_[0], other->_has_bits_[0]);
    _unknown_fields_.Swap(&other->_unknown_fields_);
    std::swap(_cached_size_, other->_cached_size_);
  }
}

::google::protobuf::Metadata MessageMSG1::GetMetadata() const {
  protobuf_AssignDescriptorsOnce();
  ::google::protobuf::Metadata metadata;
  metadata.descriptor = MessageMSG1_descriptor_;
  metadata.reflection = MessageMSG1_reflection_;
  return metadata;
}


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

#ifndef _MSC_VER
const int MessageMSG2::kTypeFieldNumber;
const int MessageMSG2::kSizeFieldNumber;
const int MessageMSG2::kContextFieldNumber;
const int MessageMSG2::kPublicKeyGxFieldNumber;
const int MessageMSG2::kPublicKeyGyFieldNumber;
const int MessageMSG2::kQuoteTypeFieldNumber;
const int MessageMSG2::kSpidFieldNumber;
const int MessageMSG2::kCmacKdfIdFieldNumber;
const int MessageMSG2::kSignatureXFieldNumber;
const int MessageMSG2::kSignatureYFieldNumber;
const int MessageMSG2::kSmacFieldNumber;
const int MessageMSG2::kSizeSigrlFieldNumber;
const int MessageMSG2::kSigrlFieldNumber;
#endif  // !_MSC_VER

MessageMSG2::MessageMSG2()
  : ::google::protobuf::Message() {
  SharedCtor();
  // @@protoc_insertion_point(constructor:Messages.MessageMSG2)
}

void MessageMSG2::InitAsDefaultInstance() {
}

MessageMSG2::MessageMSG2(const MessageMSG2& from)
  : ::google::protobuf::Message() {
  SharedCtor();
  MergeFrom(from);
  // @@protoc_insertion_point(copy_constructor:Messages.MessageMSG2)
}

void MessageMSG2::SharedCtor() {
  _cached_size_ = 0;
  type_ = 0u;
  size_ = 0u;
  context_ = 0u;
  quote_type_ = 0u;
  cmac_kdf_id_ = 0u;
  size_sigrl_ = 0u;
  ::memset(_has_bits_, 0, sizeof(_has_bits_));
}

MessageMSG2::~MessageMSG2() {
  // @@protoc_insertion_point(destructor:Messages.MessageMSG2)
  SharedDtor();
}

void MessageMSG2::SharedDtor() {
  if (this != default_instance_) {
  }
}

void MessageMSG2::SetCachedSize(int size) const {
  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
  _cached_size_ = size;
  GOOGLE_SAFE_CONCURRENT_WRITES_END();
}
const ::google::protobuf::Descriptor* MessageMSG2::descriptor() {
  protobuf_AssignDescriptorsOnce();
  return MessageMSG2_descriptor_;
}

const MessageMSG2& MessageMSG2::default_instance() {
  if (default_instance_ == NULL) protobuf_AddDesc_Messages_2eproto();
  return *default_instance_;
}

MessageMSG2* MessageMSG2::default_instance_ = NULL;

MessageMSG2* MessageMSG2::New() const {
  return new MessageMSG2;
}

void MessageMSG2::Clear() {
#define OFFSET_OF_FIELD_(f) (reinterpret_cast<char*>(      \
  &reinterpret_cast<MessageMSG2*>(16)->f) - \
   reinterpret_cast<char*>(16))

#define ZR_(first, last) do {                              \
    size_t f = OFFSET_OF_FIELD_(first);                    \
    size_t n = OFFSET_OF_FIELD_(last) - f + sizeof(last);  \
    ::memset(&first, 0, n);                                \
  } while (0)

  if (_has_bits_[0 / 32] & 167) {
    ZR_(type_, size_);
    ZR_(context_, quote_type_);
    cmac_kdf_id_ = 0u;
  }
  size_sigrl_ = 0u;

#undef OFFSET_OF_FIELD_
#undef ZR_

  public_key_gx_.Clear();
  public_key_gy_.Clear();
  spid_.Clear();
  signature_x_.Clear();
  signature_y_.Clear();
  smac_.Clear();
  sigrl_.Clear();
  ::memset(_has_bits_, 0, sizeof(_has_bits_));
  mutable_unknown_fields()->Clear();
}

bool MessageMSG2::MergePartialFromCodedStream(
    ::google::protobuf::io::CodedInputStream* input) {
#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
  ::google::protobuf::uint32 tag;
  // @@protoc_insertion_point(parse_start:Messages.MessageMSG2)
  for (;;) {
    ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127);
    tag = p.first;
    if (!p.second) goto handle_unusual;
    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
      // required uint32 type = 1;
      case 1: {
        if (tag == 8) {
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
                 input, &type_)));
          set_has_type();
        } else {
          goto handle_unusual;
        }
        if (input->ExpectTag(16)) goto parse_size;
        break;
      }

      // optional uint32 size = 2;
      case 2: {
        if (tag == 16) {
         parse_size:
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
                 input, &size_)));
          set_has_size();
        } else {
          goto handle_unusual;
        }
        if (input->ExpectTag(24)) goto parse_context;
        break;
      }

      // required uint32 context = 3;
      case 3: {
        if (tag == 24) {
         parse_context:
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
                 input, &context_)));
          set_has_context();
        } else {
          goto handle_unusual;
        }
        if (input->ExpectTag(34)) goto parse_public_key_gx;
        break;
      }

      // repeated uint32 public_key_gx = 4 [packed = true];
      case 4: {
        if (tag == 34) {
         parse_public_key_gx:
          DO_((::google::protobuf::internal::WireFormatLite::ReadPackedPrimitive<
                   ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
                 input, this->mutable_public_key_gx())));
        } else if (tag == 32) {
          DO_((::google::protobuf::internal::WireFormatLite::ReadRepeatedPrimitiveNoInline<
                   ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
                 1, 34, input, this->mutable_public_key_gx())));
        } else {
          goto handle_unusual;
        }
        if (input->ExpectTag(42)) goto parse_public_key_gy;
        break;
      }

      // repeated uint32 public_key_gy = 5 [packed = true];
      case 5: {
        if (tag == 42) {
         parse_public_key_gy:
          DO_((::google::protobuf::internal::WireFormatLite::ReadPackedPrimitive<
                   ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
                 input, this->mutable_public_key_gy())));
        } else if (tag == 40) {
          DO_((::google::protobuf::internal::WireFormatLite::ReadRepeatedPrimitiveNoInline<
                   ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
                 1, 42, input, this->mutable_public_key_gy())));
        } else {
          goto handle_unusual;
        }
        if (input->ExpectTag(48)) goto parse_quote_type;
        break;
      }

      // optional uint32 quote_type = 6;
      case 6: {
        if (tag == 48) {
         parse_quote_type:
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
                 input, &quote_type_)));
          set_has_quote_type();
        } else {
          goto handle_unusual;
        }
        if (input->ExpectTag(58)) goto parse_spid;
        break;
      }

      // repeated uint32 spid = 7 [packed = true];
      case 7: {
        if (tag == 58) {
         parse_spid:
          DO_((::google::protobuf::internal::WireFormatLite::ReadPackedPrimitive<
                   ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
                 input, this->mutable_spid())));
        } else if (tag == 56) {
          DO_((::google::protobuf::internal::WireFormatLite::ReadRepeatedPrimitiveNoInline<
                   ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
                 1, 58, input, this->mutable_spid())));
        } else {
          goto handle_unusual;
        }
        if (input->ExpectTag(64)) goto parse_cmac_kdf_id;
        break;
      }

      // optional uint32 cmac_kdf_id = 8;
      case 8: {
        if (tag == 64) {
         parse_cmac_kdf_id:
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
                 input, &cmac_kdf_id_)));
          set_has_cmac_kdf_id();
        } else {
          goto handle_unusual;
        }
        if (input->ExpectTag(74)) goto parse_signature_x;
        break;
      }

      // repeated uint32 signature_x = 9 [packed = true];
      case 9: {
        if (tag == 74) {
         parse_signature_x:
          DO_((::google::protobuf::internal::WireFormatLite::ReadPackedPrimitive<
                   ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
                 input, this->mutable_signature_x())));
        } else if (tag == 72) {
          DO_((::google::protobuf::internal::WireFormatLite::ReadRepeatedPrimitiveNoInline<
                   ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
                 1, 74, input, this->mutable_signature_x())));
        } else {
          goto handle_unusual;
        }
        if (input->ExpectTag(82)) goto parse_signature_y;
        break;
      }

      // repeated uint32 signature_y = 10 [packed = true];
      case 10: {
        if (tag == 82) {
         parse_signature_y:
          DO_((::google::protobuf::internal::WireFormatLite::ReadPackedPrimitive<
                   ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
                 input, this->mutable_signature_y())));
        } else if (tag == 80) {
          DO_((::google::protobuf::internal::WireFormatLite::ReadRepeatedPrimitiveNoInline<
                   ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
                 1, 82, input, this->mutable_signature_y())));
        } else {
          goto handle_unusual;
        }
        if (input->ExpectTag(90)) goto parse_smac;
        break;
      }

      // repeated uint32 smac = 11 [packed = true];
      case 11: {
        if (tag == 90) {
         parse_smac:
          DO_((::google::protobuf::internal::WireFormatLite::ReadPackedPrimitive<
                   ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
                 input, this->mutable_smac())));
        } else if (tag == 88) {
          DO_((::google::protobuf::internal::WireFormatLite::ReadRepeatedPrimitiveNoInline<
                   ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
                 1, 90, input, this->mutable_smac())));
        } else {
          goto handle_unusual;
        }
        if (input->ExpectTag(96)) goto parse_size_sigrl;
        break;
      }

      // optional uint32 size_sigrl = 12;
      case 12: {
        if (tag == 96) {
         parse_size_sigrl:
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
                 input, &size_sigrl_)));
          set_has_size_sigrl();
        } else {
          goto handle_unusual;
        }
        if (input->ExpectTag(106)) goto parse_sigrl;
        break;
      }

      // repeated uint32 sigrl = 13 [packed = true];
      case 13: {
        if (tag == 106) {
         parse_sigrl:
          DO_((::google::protobuf::internal::WireFormatLite::ReadPackedPrimitive<
                   ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
                 input, this->mutable_sigrl())));
        } else if (tag == 104) {
          DO_((::google::protobuf::internal::WireFormatLite::ReadRepeatedPrimitiveNoInline<
                   ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
                 1, 106, input, this->mutable_sigrl())));
        } else {
          goto handle_unusual;
        }
        if (input->ExpectAtEnd()) goto success;
        break;
      }

      default: {
      handle_unusual:
        if (tag == 0 ||
            ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
            ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
          goto success;
        }
        DO_(::google::protobuf::internal::WireFormat::SkipField(
              input, tag, mutable_unknown_fields()));
        break;
      }
    }
  }
success:
  // @@protoc_insertion_point(parse_success:Messages.MessageMSG2)
  return true;
failure:
  // @@protoc_insertion_point(parse_failure:Messages.MessageMSG2)
  return false;
#undef DO_
}

void MessageMSG2::SerializeWithCachedSizes(
    ::google::protobuf::io::CodedOutputStream* output) const {
  // @@protoc_insertion_point(serialize_start:Messages.MessageMSG2)
  // required uint32 type = 1;
  if (has_type()) {
    ::google::protobuf::internal::WireFormatLite::WriteUInt32(1, this->type(), output);
  }

  // optional uint32 size = 2;
  if (has_size()) {
    ::google::protobuf::internal::WireFormatLite::WriteUInt32(2, this->size(), output);
  }

  // required uint32 context = 3;
  if (has_context()) {
    ::google::protobuf::internal::WireFormatLite::WriteUInt32(3, this->context(), output);
  }

  // repeated uint32 public_key_gx = 4 [packed = true];
  if (this->public_key_gx_size() > 0) {
    ::google::protobuf::internal::WireFormatLite::WriteTag(4, ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED, output);
    output->WriteVarint32(_public_key_gx_cached_byte_size_);
  }
  for (int i = 0; i < this->public_key_gx_size(); i++) {
    ::google::protobuf::internal::WireFormatLite::WriteUInt32NoTag(
      this->public_key_gx(i), output);
  }

  // repeated uint32 public_key_gy = 5 [packed = true];
  if (this->public_key_gy_size() > 0) {
    ::google::protobuf::internal::WireFormatLite::WriteTag(5, ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED, output);
    output->WriteVarint32(_public_key_gy_cached_byte_size_);
  }
  for (int i = 0; i < this->public_key_gy_size(); i++) {
    ::google::protobuf::internal::WireFormatLite::WriteUInt32NoTag(
      this->public_key_gy(i), output);
  }

  // optional uint32 quote_type = 6;
  if (has_quote_type()) {
    ::google::protobuf::internal::WireFormatLite::WriteUInt32(6, this->quote_type(), output);
  }

  // repeated uint32 spid = 7 [packed = true];
  if (this->spid_size() > 0) {
    ::google::protobuf::internal::WireFormatLite::WriteTag(7, ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED, output);
    output->WriteVarint32(_spid_cached_byte_size_);
  }
  for (int i = 0; i < this->spid_size(); i++) {
    ::google::protobuf::internal::WireFormatLite::WriteUInt32NoTag(
      this->spid(i), output);
  }

  // optional uint32 cmac_kdf_id = 8;
  if (has_cmac_kdf_id()) {
    ::google::protobuf::internal::WireFormatLite::WriteUInt32(8, this->cmac_kdf_id(), output);
  }

  // repeated uint32 signature_x = 9 [packed = true];
  if (this->signature_x_size() > 0) {
    ::google::protobuf::internal::WireFormatLite::WriteTag(9, ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED, output);
    output->WriteVarint32(_signature_x_cached_byte_size_);
  }
  for (int i = 0; i < this->signature_x_size(); i++) {
    ::google::protobuf::internal::WireFormatLite::WriteUInt32NoTag(
      this->signature_x(i), output);
  }

  // repeated uint32 signature_y = 10 [packed = true];
  if (this->signature_y_size() > 0) {
    ::google::protobuf::internal::WireFormatLite::WriteTag(10, ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED, output);
    output->WriteVarint32(_signature_y_cached_byte_size_);
  }
  for (int i = 0; i < this->signature_y_size(); i++) {
    ::google::protobuf::internal::WireFormatLite::WriteUInt32NoTag(
      this->signature_y(i), output);
  }

  // repeated uint32 smac = 11 [packed = true];
  if (this->smac_size() > 0) {
    ::google::protobuf::internal::WireFormatLite::WriteTag(11, ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED, output);
    output->WriteVarint32(_smac_cached_byte_size_);
  }
  for (int i = 0; i < this->smac_size(); i++) {
    ::google::protobuf::internal::WireFormatLite::WriteUInt32NoTag(
      this->smac(i), output);
  }

  // optional uint32 size_sigrl = 12;
  if (has_size_sigrl()) {
    ::google::protobuf::internal::WireFormatLite::WriteUInt32(12, this->size_sigrl(), output);
  }

  // repeated uint32 sigrl = 13 [packed = true];
  if (this->sigrl_size() > 0) {
    ::google::protobuf::internal::WireFormatLite::WriteTag(13, ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED, output);
    output->WriteVarint32(_sigrl_cached_byte_size_);
  }
  for (int i = 0; i < this->sigrl_size(); i++) {
    ::google::protobuf::internal::WireFormatLite::WriteUInt32NoTag(
      this->sigrl(i), output);
  }

  if (!unknown_fields().empty()) {
    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
        unknown_fields(), output);
  }
  // @@protoc_insertion_point(serialize_end:Messages.MessageMSG2)
}

::google::protobuf::uint8* MessageMSG2::SerializeWithCachedSizesToArray(
    ::google::protobuf::uint8* target) const {
  // @@protoc_insertion_point(serialize_to_array_start:Messages.MessageMSG2)
  // required uint32 type = 1;
  if (has_type()) {
    target = ::google::protobuf::internal::WireFormatLite::WriteUInt32ToArray(1, this->type(), target);
  }

  // optional uint32 size = 2;
  if (has_size()) {
    target = ::google::protobuf::internal::WireFormatLite::WriteUInt32ToArray(2, this->size(), target);
  }

  // required uint32 context = 3;
  if (has_context()) {
    target = ::google::protobuf::internal::WireFormatLite::WriteUInt32ToArray(3, this->context(), target);
  }

  // repeated uint32 public_key_gx = 4 [packed = true];
  if (this->public_key_gx_size() > 0) {
    target = ::google::protobuf::internal::WireFormatLite::WriteTagToArray(
      4,
      ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED,
      target);
    target = ::google::protobuf::io::CodedOutputStream::WriteVarint32ToArray(
      _public_key_gx_cached_byte_size_, target);
  }
  for (int i = 0; i < this->public_key_gx_size(); i++) {
    target = ::google::protobuf::internal::WireFormatLite::
      WriteUInt32NoTagToArray(this->public_key_gx(i), target);
  }

  // repeated uint32 public_key_gy = 5 [packed = true];
  if (this->public_key_gy_size() > 0) {
    target = ::google::protobuf::internal::WireFormatLite::WriteTagToArray(
      5,
      ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED,
      target);
    target = ::google::protobuf::io::CodedOutputStream::WriteVarint32ToArray(
      _public_key_gy_cached_byte_size_, target);
  }
  for (int i = 0; i < this->public_key_gy_size(); i++) {
    target = ::google::protobuf::internal::WireFormatLite::
      WriteUInt32NoTagToArray(this->public_key_gy(i), target);
  }

  // optional uint32 quote_type = 6;
  if (has_quote_type()) {
    target = ::google::protobuf::internal::WireFormatLite::WriteUInt32ToArray(6, this->quote_type(), target);
  }

  // repeated uint32 spid = 7 [packed = true];
  if (this->spid_size() > 0) {
    target = ::google::protobuf::internal::WireFormatLite::WriteTagToArray(
      7,
      ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED,
      target);
    target = ::google::protobuf::io::CodedOutputStream::WriteVarint32ToArray(
      _spid_cached_byte_size_, target);
  }
  for (int i = 0; i < this->spid_size(); i++) {
    target = ::google::protobuf::internal::WireFormatLite::
      WriteUInt32NoTagToArray(this->spid(i), target);
  }

  // optional uint32 cmac_kdf_id = 8;
  if (has_cmac_kdf_id()) {
    target = ::google::protobuf::internal::WireFormatLite::WriteUInt32ToArray(8, this->cmac_kdf_id(), target);
  }

  // repeated uint32 signature_x = 9 [packed = true];
  if (this->signature_x_size() > 0) {
    target = ::google::protobuf::internal::WireFormatLite::WriteTagToArray(
      9,
      ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED,
      target);
    target = ::google::protobuf::io::CodedOutputStream::WriteVarint32ToArray(
      _signature_x_cached_byte_size_, target);
  }
  for (int i = 0; i < this->signature_x_size(); i++) {
    target = ::google::protobuf::internal::WireFormatLite::
      WriteUInt32NoTagToArray(this->signature_x(i), target);
  }

  // repeated uint32 signature_y = 10 [packed = true];
  if (this->signature_y_size() > 0) {
    target = ::google::protobuf::internal::WireFormatLite::WriteTagToArray(
      10,
      ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED,
      target);
    target = ::google::protobuf::io::CodedOutputStream::WriteVarint32ToArray(
      _signature_y_cached_byte_size_, target);
  }
  for (int i = 0; i < this->signature_y_size(); i++) {
    target = ::google::protobuf::internal::WireFormatLite::
      WriteUInt32NoTagToArray(this->signature_y(i), target);
  }

  // repeated uint32 smac = 11 [packed = true];
  if (this->smac_size() > 0) {
    target = ::google::protobuf::internal::WireFormatLite::WriteTagToArray(
      11,
      ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED,
      target);
    target = ::google::protobuf::io::CodedOutputStream::WriteVarint32ToArray(
      _smac_cached_byte_size_, target);
  }
  for (int i = 0; i < this->smac_size(); i++) {
    target = ::google::protobuf::internal::WireFormatLite::
      WriteUInt32NoTagToArray(this->smac(i), target);
  }

  // optional uint32 size_sigrl = 12;
  if (has_size_sigrl()) {
    target = ::google::protobuf::internal::WireFormatLite::WriteUInt32ToArray(12, this->size_sigrl(), target);
  }

  // repeated uint32 sigrl = 13 [packed = true];
  if (this->sigrl_size() > 0) {
    target = ::google::protobuf::internal::WireFormatLite::WriteTagToArray(
      13,
      ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED,
      target);
    target = ::google::protobuf::io::CodedOutputStream::WriteVarint32ToArray(
      _sigrl_cached_byte_size_, target);
  }
  for (int i = 0; i < this->sigrl_size(); i++) {
    target = ::google::protobuf::internal::WireFormatLite::
      WriteUInt32NoTagToArray(this->sigrl(i), target);
  }

  if (!unknown_fields().empty()) {
    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
        unknown_fields(), target);
  }
  // @@protoc_insertion_point(serialize_to_array_end:Messages.MessageMSG2)
  return target;
}

int MessageMSG2::ByteSize() const {
  int total_size = 0;

  if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    // required uint32 type = 1;
    if (has_type()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::UInt32Size(
          this->type());
    }

    // optional uint32 size = 2;
    if (has_size()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::UInt32Size(
          this->size());
    }

    // required uint32 context = 3;
    if (has_context()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::UInt32Size(
          this->context());
    }

    // optional uint32 quote_type = 6;
    if (has_quote_type()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::UInt32Size(
          this->quote_type());
    }

    // optional uint32 cmac_kdf_id = 8;
    if (has_cmac_kdf_id()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::UInt32Size(
          this->cmac_kdf_id());
    }

  }
  if (_has_bits_[11 / 32] & (0xffu << (11 % 32))) {
    // optional uint32 size_sigrl = 12;
    if (has_size_sigrl()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::UInt32Size(
          this->size_sigrl());
    }

  }
  // repeated uint32 public_key_gx = 4 [packed = true];
  {
    int data_size = 0;
    for (int i = 0; i < this->public_key_gx_size(); i++) {
      data_size += ::google::protobuf::internal::WireFormatLite::
        UInt32Size(this->public_key_gx(i));
    }
    if (data_size > 0) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::Int32Size(data_size);
    }
    GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
    _public_key_gx_cached_byte_size_ = data_size;
    GOOGLE_SAFE_CONCURRENT_WRITES_END();
    total_size += data_size;
  }

  // repeated uint32 public_key_gy = 5 [packed = true];
  {
    int data_size = 0;
    for (int i = 0; i < this->public_key_gy_size(); i++) {
      data_size += ::google::protobuf::internal::WireFormatLite::
        UInt32Size(this->public_key_gy(i));
    }
    if (data_size > 0) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::Int32Size(data_size);
    }
    GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
    _public_key_gy_cached_byte_size_ = data_size;
    GOOGLE_SAFE_CONCURRENT_WRITES_END();
    total_size += data_size;
  }

  // repeated uint32 spid = 7 [packed = true];
  {
    int data_size = 0;
    for (int i = 0; i < this->spid_size(); i++) {
      data_size += ::google::protobuf::internal::WireFormatLite::
        UInt32Size(this->spid(i));
    }
    if (data_size > 0) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::Int32Size(data_size);
    }
    GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
    _spid_cached_byte_size_ = data_size;
    GOOGLE_SAFE_CONCURRENT_WRITES_END();
    total_size += data_size;
  }

  // repeated uint32 signature_x = 9 [packed = true];
  {
    int data_size = 0;
    for (int i = 0; i < this->signature_x_size(); i++) {
      data_size += ::google::protobuf::internal::WireFormatLite::
        UInt32Size(this->signature_x(i));
    }
    if (data_size > 0) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::Int32Size(data_size);
    }
    GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
    _signature_x_cached_byte_size_ = data_size;
    GOOGLE_SAFE_CONCURRENT_WRITES_END();
    total_size += data_size;
  }

  // repeated uint32 signature_y = 10 [packed = true];
  {
    int data_size = 0;
    for (int i = 0; i < this->signature_y_size(); i++) {
      data_size += ::google::protobuf::internal::WireFormatLite::
        UInt32Size(this->signature_y(i));
    }
    if (data_size > 0) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::Int32Size(data_size);
    }
    GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
    _signature_y_cached_byte_size_ = data_size;
    GOOGLE_SAFE_CONCURRENT_WRITES_END();
    total_size += data_size;
  }

  // repeated uint32 smac = 11 [packed = true];
  {
    int data_size = 0;
    for (int i = 0; i < this->smac_size(); i++) {
      data_size += ::google::protobuf::internal::WireFormatLite::
        UInt32Size(this->smac(i));
    }
    if (data_size > 0) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::Int32Size(data_size);
    }
    GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
    _smac_cached_byte_size_ = data_size;
    GOOGLE_SAFE_CONCURRENT_WRITES_END();
    total_size += data_size;
  }

  // repeated uint32 sigrl = 13 [packed = true];
  {
    int data_size = 0;
    for (int i = 0; i < this->sigrl_size(); i++) {
      data_size += ::google::protobuf::internal::WireFormatLite::
        UInt32Size(this->sigrl(i));
    }
    if (data_size > 0) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::Int32Size(data_size);
    }
    GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
    _sigrl_cached_byte_size_ = data_size;
    GOOGLE_SAFE_CONCURRENT_WRITES_END();
    total_size += data_size;
  }

  if (!unknown_fields().empty()) {
    total_size +=
      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
        unknown_fields());
  }
  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
  _cached_size_ = total_size;
  GOOGLE_SAFE_CONCURRENT_WRITES_END();
  return total_size;
}

void MessageMSG2::MergeFrom(const ::google::protobuf::Message& from) {
  GOOGLE_CHECK_NE(&from, this);
  const MessageMSG2* source =
    ::google::protobuf::internal::dynamic_cast_if_available<const MessageMSG2*>(
      &from);
  if (source == NULL) {
    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
  } else {
    MergeFrom(*source);
  }
}

void MessageMSG2::MergeFrom(const MessageMSG2& from) {
  GOOGLE_CHECK_NE(&from, this);
  public_key_gx_.MergeFrom(from.public_key_gx_);
  public_key_gy_.MergeFrom(from.public_key_gy_);
  spid_.MergeFrom(from.spid_);
  signature_x_.MergeFrom(from.signature_x_);
  signature_y_.MergeFrom(from.signature_y_);
  smac_.MergeFrom(from.smac_);
  sigrl_.MergeFrom(from.sigrl_);
  if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    if (from.has_type()) {
      set_type(from.type());
    }
    if (from.has_size()) {
      set_size(from.size());
    }
    if (from.has_context()) {
      set_context(from.context());
    }
    if (from.has_quote_type()) {
      set_quote_type(from.quote_type());
    }
    if (from.has_cmac_kdf_id()) {
      set_cmac_kdf_id(from.cmac_kdf_id());
    }
  }
  if (from._has_bits_[11 / 32] & (0xffu << (11 % 32))) {
    if (from.has_size_sigrl()) {
      set_size_sigrl(from.size_sigrl());
    }
  }
  mutable_unknown_fields()->MergeFrom(from.unknown_fields());
}

void MessageMSG2::CopyFrom(const ::google::protobuf::Message& from) {
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

void MessageMSG2::CopyFrom(const MessageMSG2& from) {
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

bool MessageMSG2::IsInitialized() const {
  if ((_has_bits_[0] & 0x00000005) != 0x00000005) return false;

  return true;
}

void MessageMSG2::Swap(MessageMSG2* other) {
  if (other != this) {
    std::swap(type_, other->type_);
    std::swap(size_, other->size_);
    std::swap(context_, other->context_);
    public_key_gx_.Swap(&other->public_key_gx_);
    public_key_gy_.Swap(&other->public_key_gy_);
    std::swap(quote_type_, other->quote_type_);
    spid_.Swap(&other->spid_);
    std::swap(cmac_kdf_id_, other->cmac_kdf_id_);
    signature_x_.Swap(&other->signature_x_);
    signature_y_.Swap(&other->signature_y_);
    smac_.Swap(&other->smac_);
    std::swap(size_sigrl_, other->size_sigrl_);
    sigrl_.Swap(&other->sigrl_);
    std::swap(_has_bits_[0], other->_has_bits_[0]);
    _unknown_fields_.Swap(&other->_unknown_fields_);
    std::swap(_cached_size_, other->_cached_size_);
  }
}

::google::protobuf::Metadata MessageMSG2::GetMetadata() const {
  protobuf_AssignDescriptorsOnce();
  ::google::protobuf::Metadata metadata;
  metadata.descriptor = MessageMSG2_descriptor_;
  metadata.reflection = MessageMSG2_reflection_;
  return metadata;
}


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

#ifndef _MSC_VER
const int MessageMSG3::kTypeFieldNumber;
const int MessageMSG3::kSizeFieldNumber;
const int MessageMSG3::kContextFieldNumber;
const int MessageMSG3::kSgxMacFieldNumber;
const int MessageMSG3::kGaxMsg3FieldNumber;
const int MessageMSG3::kGayMsg3FieldNumber;
const int MessageMSG3::kSecPropertyFieldNumber;
const int MessageMSG3::kQuoteFieldNumber;
#endif  // !_MSC_VER

MessageMSG3::MessageMSG3()
  : ::google::protobuf::Message() {
  SharedCtor();
  // @@protoc_insertion_point(constructor:Messages.MessageMSG3)
}

void MessageMSG3::InitAsDefaultInstance() {
}

MessageMSG3::MessageMSG3(const MessageMSG3& from)
  : ::google::protobuf::Message() {
  SharedCtor();
  MergeFrom(from);
  // @@protoc_insertion_point(copy_constructor:Messages.MessageMSG3)
}

void MessageMSG3::SharedCtor() {
  _cached_size_ = 0;
  type_ = 0u;
  size_ = 0u;
  context_ = 0u;
  ::memset(_has_bits_, 0, sizeof(_has_bits_));
}

MessageMSG3::~MessageMSG3() {
  // @@protoc_insertion_point(destructor:Messages.MessageMSG3)
  SharedDtor();
}

void MessageMSG3::SharedDtor() {
  if (this != default_instance_) {
  }
}

void MessageMSG3::SetCachedSize(int size) const {
  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
  _cached_size_ = size;
  GOOGLE_SAFE_CONCURRENT_WRITES_END();
}
const ::google::protobuf::Descriptor* MessageMSG3::descriptor() {
  protobuf_AssignDescriptorsOnce();
  return MessageMSG3_descriptor_;
}

const MessageMSG3& MessageMSG3::default_instance() {
  if (default_instance_ == NULL) protobuf_AddDesc_Messages_2eproto();
  return *default_instance_;
}

MessageMSG3* MessageMSG3::default_instance_ = NULL;

MessageMSG3* MessageMSG3::New() const {
  return new MessageMSG3;
}

void MessageMSG3::Clear() {
#define OFFSET_OF_FIELD_(f) (reinterpret_cast<char*>(      \
  &reinterpret_cast<MessageMSG3*>(16)->f) - \
   reinterpret_cast<char*>(16))

#define ZR_(first, last) do {                              \
    size_t f = OFFSET_OF_FIELD_(first);                    \
    size_t n = OFFSET_OF_FIELD_(last) - f + sizeof(last);  \
    ::memset(&first, 0, n);                                \
  } while (0)

  if (_has_bits_[0 / 32] & 7) {
    ZR_(type_, size_);
    context_ = 0u;
  }

#undef OFFSET_OF_FIELD_
#undef ZR_

  sgx_mac_.Clear();
  gax_msg3_.Clear();
  gay_msg3_.Clear();
  sec_property_.Clear();
  quote_.Clear();
  ::memset(_has_bits_, 0, sizeof(_has_bits_));
  mutable_unknown_fields()->Clear();
}

bool MessageMSG3::MergePartialFromCodedStream(
    ::google::protobuf::io::CodedInputStream* input) {
#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
  ::google::protobuf::uint32 tag;
  // @@protoc_insertion_point(parse_start:Messages.MessageMSG3)
  for (;;) {
    ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127);
    tag = p.first;
    if (!p.second) goto handle_unusual;
    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
      // required uint32 type = 1;
      case 1: {
        if (tag == 8) {
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
                 input, &type_)));
          set_has_type();
        } else {
          goto handle_unusual;
        }
        if (input->ExpectTag(16)) goto parse_size;
        break;
      }

      // optional uint32 size = 2;
      case 2: {
        if (tag == 16) {
         parse_size:
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
                 input, &size_)));
          set_has_size();
        } else {
          goto handle_unusual;
        }
        if (input->ExpectTag(24)) goto parse_context;
        break;
      }

      // required uint32 context = 3;
      case 3: {
        if (tag == 24) {
         parse_context:
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
                 input, &context_)));
          set_has_context();
        } else {
          goto handle_unusual;
        }
        if (input->ExpectTag(34)) goto parse_sgx_mac;
        break;
      }

      // repeated uint32 sgx_mac = 4 [packed = true];
      case 4: {
        if (tag == 34) {
         parse_sgx_mac:
          DO_((::google::protobuf::internal::WireFormatLite::ReadPackedPrimitive<
                   ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
                 input, this->mutable_sgx_mac())));
        } else if (tag == 32) {
          DO_((::google::protobuf::internal::WireFormatLite::ReadRepeatedPrimitiveNoInline<
                   ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
                 1, 34, input, this->mutable_sgx_mac())));
        } else {
          goto handle_unusual;
        }
        if (input->ExpectTag(42)) goto parse_gax_msg3;
        break;
      }

      // repeated uint32 gax_msg3 = 5 [packed = true];
      case 5: {
        if (tag == 42) {
         parse_gax_msg3:
          DO_((::google::protobuf::internal::WireFormatLite::ReadPackedPrimitive<
                   ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
                 input, this->mutable_gax_msg3())));
        } else if (tag == 40) {
          DO_((::google::protobuf::internal::WireFormatLite::ReadRepeatedPrimitiveNoInline<
                   ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
                 1, 42, input, this->mutable_gax_msg3())));
        } else {
          goto handle_unusual;
        }
        if (input->ExpectTag(50)) goto parse_gay_msg3;
        break;
      }

      // repeated uint32 gay_msg3 = 6 [packed = true];
      case 6: {
        if (tag == 50) {
         parse_gay_msg3:
          DO_((::google::protobuf::internal::WireFormatLite::ReadPackedPrimitive<
                   ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
                 input, this->mutable_gay_msg3())));
        } else if (tag == 48) {
          DO_((::google::protobuf::internal::WireFormatLite::ReadRepeatedPrimitiveNoInline<
                   ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
                 1, 50, input, this->mutable_gay_msg3())));
        } else {
          goto handle_unusual;
        }
        if (input->ExpectTag(58)) goto parse_sec_property;
        break;
      }

      // repeated uint32 sec_property = 7 [packed = true];
      case 7: {
        if (tag == 58) {
         parse_sec_property:
          DO_((::google::protobuf::internal::WireFormatLite::ReadPackedPrimitive<
                   ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
                 input, this->mutable_sec_property())));
        } else if (tag == 56) {
          DO_((::google::protobuf::internal::WireFormatLite::ReadRepeatedPrimitiveNoInline<
                   ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
                 1, 58, input, this->mutable_sec_property())));
        } else {
          goto handle_unusual;
        }
        if (input->ExpectTag(66)) goto parse_quote;
        break;
      }

      // repeated uint32 quote = 8 [packed = true];
      case 8: {
        if (tag == 66) {
         parse_quote:
          DO_((::google::protobuf::internal::WireFormatLite::ReadPackedPrimitive<
                   ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
                 input, this->mutable_quote())));
        } else if (tag == 64) {
          DO_((::google::protobuf::internal::WireFormatLite::ReadRepeatedPrimitiveNoInline<
                   ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
                 1, 66, input, this->mutable_quote())));
        } else {
          goto handle_unusual;
        }
        if (input->ExpectAtEnd()) goto success;
        break;
      }

      default: {
      handle_unusual:
        if (tag == 0 ||
            ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
            ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
          goto success;
        }
        DO_(::google::protobuf::internal::WireFormat::SkipField(
              input, tag, mutable_unknown_fields()));
        break;
      }
    }
  }
success:
  // @@protoc_insertion_point(parse_success:Messages.MessageMSG3)
  return true;
failure:
  // @@protoc_insertion_point(parse_failure:Messages.MessageMSG3)
  return false;
#undef DO_
}

void MessageMSG3::SerializeWithCachedSizes(
    ::google::protobuf::io::CodedOutputStream* output) const {
  // @@protoc_insertion_point(serialize_start:Messages.MessageMSG3)
  // required uint32 type = 1;
  if (has_type()) {
    ::google::protobuf::internal::WireFormatLite::WriteUInt32(1, this->type(), output);
  }

  // optional uint32 size = 2;
  if (has_size()) {
    ::google::protobuf::internal::WireFormatLite::WriteUInt32(2, this->size(), output);
  }

  // required uint32 context = 3;
  if (has_context()) {
    ::google::protobuf::internal::WireFormatLite::WriteUInt32(3, this->context(), output);
  }

  // repeated uint32 sgx_mac = 4 [packed = true];
  if (this->sgx_mac_size() > 0) {
    ::google::protobuf::internal::WireFormatLite::WriteTag(4, ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED, output);
    output->WriteVarint32(_sgx_mac_cached_byte_size_);
  }
  for (int i = 0; i < this->sgx_mac_size(); i++) {
    ::google::protobuf::internal::WireFormatLite::WriteUInt32NoTag(
      this->sgx_mac(i), output);
  }

  // repeated uint32 gax_msg3 = 5 [packed = true];
  if (this->gax_msg3_size() > 0) {
    ::google::protobuf::internal::WireFormatLite::WriteTag(5, ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED, output);
    output->WriteVarint32(_gax_msg3_cached_byte_size_);
  }
  for (int i = 0; i < this->gax_msg3_size(); i++) {
    ::google::protobuf::internal::WireFormatLite::WriteUInt32NoTag(
      this->gax_msg3(i), output);
  }

  // repeated uint32 gay_msg3 = 6 [packed = true];
  if (this->gay_msg3_size() > 0) {
    ::google::protobuf::internal::WireFormatLite::WriteTag(6, ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED, output);
    output->WriteVarint32(_gay_msg3_cached_byte_size_);
  }
  for (int i = 0; i < this->gay_msg3_size(); i++) {
    ::google::protobuf::internal::WireFormatLite::WriteUInt32NoTag(
      this->gay_msg3(i), output);
  }

  // repeated uint32 sec_property = 7 [packed = true];
  if (this->sec_property_size() > 0) {
    ::google::protobuf::internal::WireFormatLite::WriteTag(7, ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED, output);
    output->WriteVarint32(_sec_property_cached_byte_size_);
  }
  for (int i = 0; i < this->sec_property_size(); i++) {
    ::google::protobuf::internal::WireFormatLite::WriteUInt32NoTag(
      this->sec_property(i), output);
  }

  // repeated uint32 quote = 8 [packed = true];
  if (this->quote_size() > 0) {
    ::google::protobuf::internal::WireFormatLite::WriteTag(8, ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED, output);
    output->WriteVarint32(_quote_cached_byte_size_);
  }
  for (int i = 0; i < this->quote_size(); i++) {
    ::google::protobuf::internal::WireFormatLite::WriteUInt32NoTag(
      this->quote(i), output);
  }

  if (!unknown_fields().empty()) {
    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
        unknown_fields(), output);
  }
  // @@protoc_insertion_point(serialize_end:Messages.MessageMSG3)
}

::google::protobuf::uint8* MessageMSG3::SerializeWithCachedSizesToArray(
    ::google::protobuf::uint8* target) const {
  // @@protoc_insertion_point(serialize_to_array_start:Messages.MessageMSG3)
  // required uint32 type = 1;
  if (has_type()) {
    target = ::google::protobuf::internal::WireFormatLite::WriteUInt32ToArray(1, this->type(), target);
  }

  // optional uint32 size = 2;
  if (has_size()) {
    target = ::google::protobuf::internal::WireFormatLite::WriteUInt32ToArray(2, this->size(), target);
  }

  // required uint32 context = 3;
  if (has_context()) {
    target = ::google::protobuf::internal::WireFormatLite::WriteUInt32ToArray(3, this->context(), target);
  }

  // repeated uint32 sgx_mac = 4 [packed = true];
  if (this->sgx_mac_size() > 0) {
    target = ::google::protobuf::internal::WireFormatLite::WriteTagToArray(
      4,
      ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED,
      target);
    target = ::google::protobuf::io::CodedOutputStream::WriteVarint32ToArray(
      _sgx_mac_cached_byte_size_, target);
  }
  for (int i = 0; i < this->sgx_mac_size(); i++) {
    target = ::google::protobuf::internal::WireFormatLite::
      WriteUInt32NoTagToArray(this->sgx_mac(i), target);
  }

  // repeated uint32 gax_msg3 = 5 [packed = true];
  if (this->gax_msg3_size() > 0) {
    target = ::google::protobuf::internal::WireFormatLite::WriteTagToArray(
      5,
      ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED,
      target);
    target = ::google::protobuf::io::CodedOutputStream::WriteVarint32ToArray(
      _gax_msg3_cached_byte_size_, target);
  }
  for (int i = 0; i < this->gax_msg3_size(); i++) {
    target = ::google::protobuf::internal::WireFormatLite::
      WriteUInt32NoTagToArray(this->gax_msg3(i), target);
  }

  // repeated uint32 gay_msg3 = 6 [packed = true];
  if (this->gay_msg3_size() > 0) {
    target = ::google::protobuf::internal::WireFormatLite::WriteTagToArray(
      6,
      ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED,
      target);
    target = ::google::protobuf::io::CodedOutputStream::WriteVarint32ToArray(
      _gay_msg3_cached_byte_size_, target);
  }
  for (int i = 0; i < this->gay_msg3_size(); i++) {
    target = ::google::protobuf::internal::WireFormatLite::
      WriteUInt32NoTagToArray(this->gay_msg3(i), target);
  }

  // repeated uint32 sec_property = 7 [packed = true];
  if (this->sec_property_size() > 0) {
    target = ::google::protobuf::internal::WireFormatLite::WriteTagToArray(
      7,
      ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED,
      target);
    target = ::google::protobuf::io::CodedOutputStream::WriteVarint32ToArray(
      _sec_property_cached_byte_size_, target);
  }
  for (int i = 0; i < this->sec_property_size(); i++) {
    target = ::google::protobuf::internal::WireFormatLite::
      WriteUInt32NoTagToArray(this->sec_property(i), target);
  }

  // repeated uint32 quote = 8 [packed = true];
  if (this->quote_size() > 0) {
    target = ::google::protobuf::internal::WireFormatLite::WriteTagToArray(
      8,
      ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED,
      target);
    target = ::google::protobuf::io::CodedOutputStream::WriteVarint32ToArray(
      _quote_cached_byte_size_, target);
  }
  for (int i = 0; i < this->quote_size(); i++) {
    target = ::google::protobuf::internal::WireFormatLite::
      WriteUInt32NoTagToArray(this->quote(i), target);
  }

  if (!unknown_fields().empty()) {
    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
        unknown_fields(), target);
  }
  // @@protoc_insertion_point(serialize_to_array_end:Messages.MessageMSG3)
  return target;
}

int MessageMSG3::ByteSize() const {
  int total_size = 0;

  if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    // required uint32 type = 1;
    if (has_type()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::UInt32Size(
          this->type());
    }

    // optional uint32 size = 2;
    if (has_size()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::UInt32Size(
          this->size());
    }

    // required uint32 context = 3;
    if (has_context()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::UInt32Size(
          this->context());
    }

  }
  // repeated uint32 sgx_mac = 4 [packed = true];
  {
    int data_size = 0;
    for (int i = 0; i < this->sgx_mac_size(); i++) {
      data_size += ::google::protobuf::internal::WireFormatLite::
        UInt32Size(this->sgx_mac(i));
    }
    if (data_size > 0) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::Int32Size(data_size);
    }
    GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
    _sgx_mac_cached_byte_size_ = data_size;
    GOOGLE_SAFE_CONCURRENT_WRITES_END();
    total_size += data_size;
  }

  // repeated uint32 gax_msg3 = 5 [packed = true];
  {
    int data_size = 0;
    for (int i = 0; i < this->gax_msg3_size(); i++) {
      data_size += ::google::protobuf::internal::WireFormatLite::
        UInt32Size(this->gax_msg3(i));
    }
    if (data_size > 0) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::Int32Size(data_size);
    }
    GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
    _gax_msg3_cached_byte_size_ = data_size;
    GOOGLE_SAFE_CONCURRENT_WRITES_END();
    total_size += data_size;
  }

  // repeated uint32 gay_msg3 = 6 [packed = true];
  {
    int data_size = 0;
    for (int i = 0; i < this->gay_msg3_size(); i++) {
      data_size += ::google::protobuf::internal::WireFormatLite::
        UInt32Size(this->gay_msg3(i));
    }
    if (data_size > 0) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::Int32Size(data_size);
    }
    GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
    _gay_msg3_cached_byte_size_ = data_size;
    GOOGLE_SAFE_CONCURRENT_WRITES_END();
    total_size += data_size;
  }

  // repeated uint32 sec_property = 7 [packed = true];
  {
    int data_size = 0;
    for (int i = 0; i < this->sec_property_size(); i++) {
      data_size += ::google::protobuf::internal::WireFormatLite::
        UInt32Size(this->sec_property(i));
    }
    if (data_size > 0) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::Int32Size(data_size);
    }
    GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
    _sec_property_cached_byte_size_ = data_size;
    GOOGLE_SAFE_CONCURRENT_WRITES_END();
    total_size += data_size;
  }

  // repeated uint32 quote = 8 [packed = true];
  {
    int data_size = 0;
    for (int i = 0; i < this->quote_size(); i++) {
      data_size += ::google::protobuf::internal::WireFormatLite::
        UInt32Size(this->quote(i));
    }
    if (data_size > 0) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::Int32Size(data_size);
    }
    GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
    _quote_cached_byte_size_ = data_size;
    GOOGLE_SAFE_CONCURRENT_WRITES_END();
    total_size += data_size;
  }

  if (!unknown_fields().empty()) {
    total_size +=
      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
        unknown_fields());
  }
  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
  _cached_size_ = total_size;
  GOOGLE_SAFE_CONCURRENT_WRITES_END();
  return total_size;
}

void MessageMSG3::MergeFrom(const ::google::protobuf::Message& from) {
  GOOGLE_CHECK_NE(&from, this);
  const MessageMSG3* source =
    ::google::protobuf::internal::dynamic_cast_if_available<const MessageMSG3*>(
      &from);
  if (source == NULL) {
    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
  } else {
    MergeFrom(*source);
  }
}

void MessageMSG3::MergeFrom(const MessageMSG3& from) {
  GOOGLE_CHECK_NE(&from, this);
  sgx_mac_.MergeFrom(from.sgx_mac_);
  gax_msg3_.MergeFrom(from.gax_msg3_);
  gay_msg3_.MergeFrom(from.gay_msg3_);
  sec_property_.MergeFrom(from.sec_property_);
  quote_.MergeFrom(from.quote_);
  if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    if (from.has_type()) {
      set_type(from.type());
    }
    if (from.has_size()) {
      set_size(from.size());
    }
    if (from.has_context()) {
      set_context(from.context());
    }
  }
  mutable_unknown_fields()->MergeFrom(from.unknown_fields());
}

void MessageMSG3::CopyFrom(const ::google::protobuf::Message& from) {
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

void MessageMSG3::CopyFrom(const MessageMSG3& from) {
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

bool MessageMSG3::IsInitialized() const {
  if ((_has_bits_[0] & 0x00000005) != 0x00000005) return false;

  return true;
}

void MessageMSG3::Swap(MessageMSG3* other) {
  if (other != this) {
    std::swap(type_, other->type_);
    std::swap(size_, other->size_);
    std::swap(context_, other->context_);
    sgx_mac_.Swap(&other->sgx_mac_);
    gax_msg3_.Swap(&other->gax_msg3_);
    gay_msg3_.Swap(&other->gay_msg3_);
    sec_property_.Swap(&other->sec_property_);
    quote_.Swap(&other->quote_);
    std::swap(_has_bits_[0], other->_has_bits_[0]);
    _unknown_fields_.Swap(&other->_unknown_fields_);
    std::swap(_cached_size_, other->_cached_size_);
  }
}

::google::protobuf::Metadata MessageMSG3::GetMetadata() const {
  protobuf_AssignDescriptorsOnce();
  ::google::protobuf::Metadata metadata;
  metadata.descriptor = MessageMSG3_descriptor_;
  metadata.reflection = MessageMSG3_reflection_;
  return metadata;
}


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

#ifndef _MSC_VER
const int AttestationMessage::kTypeFieldNumber;
const int AttestationMessage::kSizeFieldNumber;
const int AttestationMessage::kContextFieldNumber;
const int AttestationMessage::kEpidGroupStatusFieldNumber;
const int AttestationMessage::kTcbEvaluationStatusFieldNumber;
const int AttestationMessage::kPseEvaluationStatusFieldNumber;
const int AttestationMessage::kLatestEquivalentTcbPsvnFieldNumber;
const int AttestationMessage::kLatestPseIsvsvnFieldNumber;
const int AttestationMessage::kLatestPsdaSvnFieldNumber;
const int AttestationMessage::kPerformanceRekeyGidFieldNumber;
const int AttestationMessage::kEcSign256XFieldNumber;
const int AttestationMessage::kEcSign256YFieldNumber;
const int AttestationMessage::kMacSmkFieldNumber;
const int AttestationMessage::kResultSizeFieldNumber;
const int AttestationMessage::kReservedFieldNumber;
const int AttestationMessage::kPayloadTagFieldNumber;
const int AttestationMessage::kPayloadFieldNumber;
#endif  // !_MSC_VER

AttestationMessage::AttestationMessage()
  : ::google::protobuf::Message() {
  SharedCtor();
  // @@protoc_insertion_point(constructor:Messages.AttestationMessage)
}

void AttestationMessage::InitAsDefaultInstance() {
}

AttestationMessage::AttestationMessage(const AttestationMessage& from)
  : ::google::protobuf::Message() {
  SharedCtor();
  MergeFrom(from);
  // @@protoc_insertion_point(copy_constructor:Messages.AttestationMessage)
}

void AttestationMessage::SharedCtor() {
  _cached_size_ = 0;
  type_ = 0u;
  size_ = 0u;
  context_ = 0u;
  epid_group_status_ = 0u;
  tcb_evaluation_status_ = 0u;
  pse_evaluation_status_ = 0u;
  result_size_ = 0u;
  ::memset(_has_bits_, 0, sizeof(_has_bits_));
}

AttestationMessage::~AttestationMessage() {
  // @@protoc_insertion_point(destructor:Messages.AttestationMessage)
  SharedDtor();
}

void AttestationMessage::SharedDtor() {
  if (this != default_instance_) {
  }
}

void AttestationMessage::SetCachedSize(int size) const {
  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
  _cached_size_ = size;
  GOOGLE_SAFE_CONCURRENT_WRITES_END();
}
const ::google::protobuf::Descriptor* AttestationMessage::descriptor() {
  protobuf_AssignDescriptorsOnce();
  return AttestationMessage_descriptor_;
}

const AttestationMessage& AttestationMessage::default_instance() {
  if (default_instance_ == NULL) protobuf_AddDesc_Messages_2eproto();
  return *default_instance_;
}

AttestationMessage* AttestationMessage::default_instance_ = NULL;

AttestationMessage* AttestationMessage::New() const {
  return new AttestationMessage;
}

void AttestationMessage::Clear() {
#define OFFSET_OF_FIELD_(f) (reinterpret_cast<char*>(      \
  &reinterpret_cast<AttestationMessage*>(16)->f) - \
   reinterpret_cast<char*>(16))

#define ZR_(first, last) do {                              \
    size_t f = OFFSET_OF_FIELD_(first);                    \
    size_t n = OFFSET_OF_FIELD_(last) - f + sizeof(last);  \
    ::memset(&first, 0, n);                                \
  } while (0)

  if (_has_bits_[0 / 32] & 63) {
    ZR_(type_, pse_evaluation_status_);
  }
  result_size_ = 0u;

#undef OFFSET_OF_FIELD_
#undef ZR_

  latest_equivalent_tcb_psvn_.Clear();
  latest_pse_isvsvn_.Clear();
  latest_psda_svn_.Clear();
  performance_rekey_gid_.Clear();
  ec_sign256_x_.Clear();
  ec_sign256_y_.Clear();
  mac_smk_.Clear();
  reserved_.Clear();
  payload_tag_.Clear();
  payload_.Clear();
  ::memset(_has_bits_, 0, sizeof(_has_bits_));
  mutable_unknown_fields()->Clear();
}

bool AttestationMessage::MergePartialFromCodedStream(
    ::google::protobuf::io::CodedInputStream* input) {
#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
  ::google::protobuf::uint32 tag;
  // @@protoc_insertion_point(parse_start:Messages.AttestationMessage)
  for (;;) {
    ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(16383);
    tag = p.first;
    if (!p.second) goto handle_unusual;
    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
      // required uint32 type = 1;
      case 1: {
        if (tag == 8) {
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
                 input, &type_)));
          set_has_type();
        } else {
          goto handle_unusual;
        }
        if (input->ExpectTag(16)) goto parse_size;
        break;
      }

      // required uint32 size = 2;
      case 2: {
        if (tag == 16) {
         parse_size:
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
                 input, &size_)));
          set_has_size();
        } else {
          goto handle_unusual;
        }
        if (input->ExpectTag(24)) goto parse_context;
        break;
      }

      // required uint32 context = 3;
      case 3: {
        if (tag == 24) {
         parse_context:
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
                 input, &context_)));
          set_has_context();
        } else {
          goto handle_unusual;
        }
        if (input->ExpectTag(32)) goto parse_epid_group_status;
        break;
      }

      // optional uint32 epid_group_status = 4;
      case 4: {
        if (tag == 32) {
         parse_epid_group_status:
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
                 input, &epid_group_status_)));
          set_has_epid_group_status();
        } else {
          goto handle_unusual;
        }
        if (input->ExpectTag(40)) goto parse_tcb_evaluation_status;
        break;
      }

      // optional uint32 tcb_evaluation_status = 5;
      case 5: {
        if (tag == 40) {
         parse_tcb_evaluation_status:
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
                 input, &tcb_evaluation_status_)));
          set_has_tcb_evaluation_status();
        } else {
          goto handle_unusual;
        }
        if (input->ExpectTag(48)) goto parse_pse_evaluation_status;
        break;
      }

      // optional uint32 pse_evaluation_status = 6;
      case 6: {
        if (tag == 48) {
         parse_pse_evaluation_status:
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
                 input, &pse_evaluation_status_)));
          set_has_pse_evaluation_status();
        } else {
          goto handle_unusual;
        }
        if (input->ExpectTag(58)) goto parse_latest_equivalent_tcb_psvn;
        break;
      }

      // repeated uint32 latest_equivalent_tcb_psvn = 7 [packed = true];
      case 7: {
        if (tag == 58) {
         parse_latest_equivalent_tcb_psvn:
          DO_((::google::protobuf::internal::WireFormatLite::ReadPackedPrimitive<
                   ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
                 input, this->mutable_latest_equivalent_tcb_psvn())));
        } else if (tag == 56) {
          DO_((::google::protobuf::internal::WireFormatLite::ReadRepeatedPrimitiveNoInline<
                   ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
                 1, 58, input, this->mutable_latest_equivalent_tcb_psvn())));
        } else {
          goto handle_unusual;
        }
        if (input->ExpectTag(66)) goto parse_latest_pse_isvsvn;
        break;
      }

      // repeated uint32 latest_pse_isvsvn = 8 [packed = true];
      case 8: {
        if (tag == 66) {
         parse_latest_pse_isvsvn:
          DO_((::google::protobuf::internal::WireFormatLite::ReadPackedPrimitive<
                   ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
                 input, this->mutable_latest_pse_isvsvn())));
        } else if (tag == 64) {
          DO_((::google::protobuf::internal::WireFormatLite::ReadRepeatedPrimitiveNoInline<
                   ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
                 1, 66, input, this->mutable_latest_pse_isvsvn())));
        } else {
          goto handle_unusual;
        }
        if (input->ExpectTag(74)) goto parse_latest_psda_svn;
        break;
      }

      // repeated uint32 latest_psda_svn = 9 [packed = true];
      case 9: {
        if (tag == 74) {
         parse_latest_psda_svn:
          DO_((::google::protobuf::internal::WireFormatLite::ReadPackedPrimitive<
                   ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
                 input, this->mutable_latest_psda_svn())));
        } else if (tag == 72) {
          DO_((::google::protobuf::internal::WireFormatLite::ReadRepeatedPrimitiveNoInline<
                   ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
                 1, 74, input, this->mutable_latest_psda_svn())));
        } else {
          goto handle_unusual;
        }
        if (input->ExpectTag(82)) goto parse_performance_rekey_gid;
        break;
      }

      // repeated uint32 performance_rekey_gid = 10 [packed = true];
      case 10: {
        if (tag == 82) {
         parse_performance_rekey_gid:
          DO_((::google::protobuf::internal::WireFormatLite::ReadPackedPrimitive<
                   ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
                 input, this->mutable_performance_rekey_gid())));
        } else if (tag == 80) {
          DO_((::google::protobuf::internal::WireFormatLite::ReadRepeatedPrimitiveNoInline<
                   ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
                 1, 82, input, this->mutable_performance_rekey_gid())));
        } else {
          goto handle_unusual;
        }
        if (input->ExpectTag(90)) goto parse_ec_sign256_x;
        break;
      }

      // repeated uint32 ec_sign256_x = 11 [packed = true];
      case 11: {
        if (tag == 90) {
         parse_ec_sign256_x:
          DO_((::google::protobuf::internal::WireFormatLite::ReadPackedPrimitive<
                   ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
                 input, this->mutable_ec_sign256_x())));
        } else if (tag == 88) {
          DO_((::google::protobuf::internal::WireFormatLite::ReadRepeatedPrimitiveNoInline<
                   ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
                 1, 90, input, this->mutable_ec_sign256_x())));
        } else {
          goto handle_unusual;
        }
        if (input->ExpectTag(98)) goto parse_ec_sign256_y;
        break;
      }

      // repeated uint32 ec_sign256_y = 12 [packed = true];
      case 12: {
        if (tag == 98) {
         parse_ec_sign256_y:
          DO_((::google::protobuf::internal::WireFormatLite::ReadPackedPrimitive<
                   ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
                 input, this->mutable_ec_sign256_y())));
        } else if (tag == 96) {
          DO_((::google::protobuf::internal::WireFormatLite::ReadRepeatedPrimitiveNoInline<
                   ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
                 1, 98, input, this->mutable_ec_sign256_y())));
        } else {
          goto handle_unusual;
        }
        if (input->ExpectTag(106)) goto parse_mac_smk;
        break;
      }

      // repeated uint32 mac_smk = 13 [packed = true];
      case 13: {
        if (tag == 106) {
         parse_mac_smk:
          DO_((::google::protobuf::internal::WireFormatLite::ReadPackedPrimitive<
                   ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
                 input, this->mutable_mac_smk())));
        } else if (tag == 104) {
          DO_((::google::protobuf::internal::WireFormatLite::ReadRepeatedPrimitiveNoInline<
                   ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
                 1, 106, input, this->mutable_mac_smk())));
        } else {
          goto handle_unusual;
        }
        if (input->ExpectTag(112)) goto parse_result_size;
        break;
      }

      // optional uint32 result_size = 14;
      case 14: {
        if (tag == 112) {
         parse_result_size:
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
                 input, &result_size_)));
          set_has_result_size();
        } else {
          goto handle_unusual;
        }
        if (input->ExpectTag(122)) goto parse_reserved;
        break;
      }

      // repeated uint32 reserved = 15 [packed = true];
      case 15: {
        if (tag == 122) {
         parse_reserved:
          DO_((::google::protobuf::internal::WireFormatLite::ReadPackedPrimitive<
                   ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
                 input, this->mutable_reserved())));
        } else if (tag == 120) {
          DO_((::google::protobuf::internal::WireFormatLite::ReadRepeatedPrimitiveNoInline<
                   ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
                 1, 122, input, this->mutable_reserved())));
        } else {
          goto handle_unusual;
        }
        if (input->ExpectTag(130)) goto parse_payload_tag;
        break;
      }

      // repeated uint32 payload_tag = 16 [packed = true];
      case 16: {
        if (tag == 130) {
         parse_payload_tag:
          DO_((::google::protobuf::internal::WireFormatLite::ReadPackedPrimitive<
                   ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
                 input, this->mutable_payload_tag())));
        } else if (tag == 128) {
          DO_((::google::protobuf::internal::WireFormatLite::ReadRepeatedPrimitiveNoInline<
                   ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
                 2, 130, input, this->mutable_payload_tag())));
        } else {
          goto handle_unusual;
        }
        if (input->ExpectTag(138)) goto parse_payload;
        break;
      }

      // repeated uint32 payload = 17 [packed = true];
      case 17: {
        if (tag == 138) {
         parse_payload:
          DO_((::google::protobuf::internal::WireFormatLite::ReadPackedPrimitive<
                   ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
                 input, this->mutable_payload())));
        } else if (tag == 136) {
          DO_((::google::protobuf::internal::WireFormatLite::ReadRepeatedPrimitiveNoInline<
                   ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
                 2, 138, input, this->mutable_payload())));
        } else {
          goto handle_unusual;
        }
        if (input->ExpectAtEnd()) goto success;
        break;
      }

      default: {
      handle_unusual:
        if (tag == 0 ||
            ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
            ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
          goto success;
        }
        DO_(::google::protobuf::internal::WireFormat::SkipField(
              input, tag, mutable_unknown_fields()));
        break;
      }
    }
  }
success:
  // @@protoc_insertion_point(parse_success:Messages.AttestationMessage)
  return true;
failure:
  // @@protoc_insertion_point(parse_failure:Messages.AttestationMessage)
  return false;
#undef DO_
}

void AttestationMessage::SerializeWithCachedSizes(
    ::google::protobuf::io::CodedOutputStream* output) const {
  // @@protoc_insertion_point(serialize_start:Messages.AttestationMessage)
  // required uint32 type = 1;
  if (has_type()) {
    ::google::protobuf::internal::WireFormatLite::WriteUInt32(1, this->type(), output);
  }

  // required uint32 size = 2;
  if (has_size()) {
    ::google::protobuf::internal::WireFormatLite::WriteUInt32(2, this->size(), output);
  }

  // required uint32 context = 3;
  if (has_context()) {
    ::google::protobuf::internal::WireFormatLite::WriteUInt32(3, this->context(), output);
  }

  // optional uint32 epid_group_status = 4;
  if (has_epid_group_status()) {
    ::google::protobuf::internal::WireFormatLite::WriteUInt32(4, this->epid_group_status(), output);
  }

  // optional uint32 tcb_evaluation_status = 5;
  if (has_tcb_evaluation_status()) {
    ::google::protobuf::internal::WireFormatLite::WriteUInt32(5, this->tcb_evaluation_status(), output);
  }

  // optional uint32 pse_evaluation_status = 6;
  if (has_pse_evaluation_status()) {
    ::google::protobuf::internal::WireFormatLite::WriteUInt32(6, this->pse_evaluation_status(), output);
  }

  // repeated uint32 latest_equivalent_tcb_psvn = 7 [packed = true];
  if (this->latest_equivalent_tcb_psvn_size() > 0) {
    ::google::protobuf::internal::WireFormatLite::WriteTag(7, ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED, output);
    output->WriteVarint32(_latest_equivalent_tcb_psvn_cached_byte_size_);
  }
  for (int i = 0; i < this->latest_equivalent_tcb_psvn_size(); i++) {
    ::google::protobuf::internal::WireFormatLite::WriteUInt32NoTag(
      this->latest_equivalent_tcb_psvn(i), output);
  }

  // repeated uint32 latest_pse_isvsvn = 8 [packed = true];
  if (this->latest_pse_isvsvn_size() > 0) {
    ::google::protobuf::internal::WireFormatLite::WriteTag(8, ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED, output);
    output->WriteVarint32(_latest_pse_isvsvn_cached_byte_size_);
  }
  for (int i = 0; i < this->latest_pse_isvsvn_size(); i++) {
    ::google::protobuf::internal::WireFormatLite::WriteUInt32NoTag(
      this->latest_pse_isvsvn(i), output);
  }

  // repeated uint32 latest_psda_svn = 9 [packed = true];
  if (this->latest_psda_svn_size() > 0) {
    ::google::protobuf::internal::WireFormatLite::WriteTag(9, ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED, output);
    output->WriteVarint32(_latest_psda_svn_cached_byte_size_);
  }
  for (int i = 0; i < this->latest_psda_svn_size(); i++) {
    ::google::protobuf::internal::WireFormatLite::WriteUInt32NoTag(
      this->latest_psda_svn(i), output);
  }

  // repeated uint32 performance_rekey_gid = 10 [packed = true];
  if (this->performance_rekey_gid_size() > 0) {
    ::google::protobuf::internal::WireFormatLite::WriteTag(10, ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED, output);
    output->WriteVarint32(_performance_rekey_gid_cached_byte_size_);
  }
  for (int i = 0; i < this->performance_rekey_gid_size(); i++) {
    ::google::protobuf::internal::WireFormatLite::WriteUInt32NoTag(
      this->performance_rekey_gid(i), output);
  }

  // repeated uint32 ec_sign256_x = 11 [packed = true];
  if (this->ec_sign256_x_size() > 0) {
    ::google::protobuf::internal::WireFormatLite::WriteTag(11, ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED, output);
    output->WriteVarint32(_ec_sign256_x_cached_byte_size_);
  }
  for (int i = 0; i < this->ec_sign256_x_size(); i++) {
    ::google::protobuf::internal::WireFormatLite::WriteUInt32NoTag(
      this->ec_sign256_x(i), output);
  }

  // repeated uint32 ec_sign256_y = 12 [packed = true];
  if (this->ec_sign256_y_size() > 0) {
    ::google::protobuf::internal::WireFormatLite::WriteTag(12, ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED, output);
    output->WriteVarint32(_ec_sign256_y_cached_byte_size_);
  }
  for (int i = 0; i < this->ec_sign256_y_size(); i++) {
    ::google::protobuf::internal::WireFormatLite::WriteUInt32NoTag(
      this->ec_sign256_y(i), output);
  }

  // repeated uint32 mac_smk = 13 [packed = true];
  if (this->mac_smk_size() > 0) {
    ::google::protobuf::internal::WireFormatLite::WriteTag(13, ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED, output);
    output->WriteVarint32(_mac_smk_cached_byte_size_);
  }
  for (int i = 0; i < this->mac_smk_size(); i++) {
    ::google::protobuf::internal::WireFormatLite::WriteUInt32NoTag(
      this->mac_smk(i), output);
  }

  // optional uint32 result_size = 14;
  if (has_result_size()) {
    ::google::protobuf::internal::WireFormatLite::WriteUInt32(14, this->result_size(), output);
  }

  // repeated uint32 reserved = 15 [packed = true];
  if (this->reserved_size() > 0) {
    ::google::protobuf::internal::WireFormatLite::WriteTag(15, ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED, output);
    output->WriteVarint32(_reserved_cached_byte_size_);
  }
  for (int i = 0; i < this->reserved_size(); i++) {
    ::google::protobuf::internal::WireFormatLite::WriteUInt32NoTag(
      this->reserved(i), output);
  }

  // repeated uint32 payload_tag = 16 [packed = true];
  if (this->payload_tag_size() > 0) {
    ::google::protobuf::internal::WireFormatLite::WriteTag(16, ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED, output);
    output->WriteVarint32(_payload_tag_cached_byte_size_);
  }
  for (int i = 0; i < this->payload_tag_size(); i++) {
    ::google::protobuf::internal::WireFormatLite::WriteUInt32NoTag(
      this->payload_tag(i), output);
  }

  // repeated uint32 payload = 17 [packed = true];
  if (this->payload_size() > 0) {
    ::google::protobuf::internal::WireFormatLite::WriteTag(17, ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED, output);
    output->WriteVarint32(_payload_cached_byte_size_);
  }
  for (int i = 0; i < this->payload_size(); i++) {
    ::google::protobuf::internal::WireFormatLite::WriteUInt32NoTag(
      this->payload(i), output);
  }

  if (!unknown_fields().empty()) {
    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
        unknown_fields(), output);
  }
  // @@protoc_insertion_point(serialize_end:Messages.AttestationMessage)
}

::google::protobuf::uint8* AttestationMessage::SerializeWithCachedSizesToArray(
    ::google::protobuf::uint8* target) const {
  // @@protoc_insertion_point(serialize_to_array_start:Messages.AttestationMessage)
  // required uint32 type = 1;
  if (has_type()) {
    target = ::google::protobuf::internal::WireFormatLite::WriteUInt32ToArray(1, this->type(), target);
  }

  // required uint32 size = 2;
  if (has_size()) {
    target = ::google::protobuf::internal::WireFormatLite::WriteUInt32ToArray(2, this->size(), target);
  }

  // required uint32 context = 3;
  if (has_context()) {
    target = ::google::protobuf::internal::WireFormatLite::WriteUInt32ToArray(3, this->context(), target);
  }

  // optional uint32 epid_group_status = 4;
  if (has_epid_group_status()) {
    target = ::google::protobuf::internal::WireFormatLite::WriteUInt32ToArray(4, this->epid_group_status(), target);
  }

  // optional uint32 tcb_evaluation_status = 5;
  if (has_tcb_evaluation_status()) {
    target = ::google::protobuf::internal::WireFormatLite::WriteUInt32ToArray(5, this->tcb_evaluation_status(), target);
  }

  // optional uint32 pse_evaluation_status = 6;
  if (has_pse_evaluation_status()) {
    target = ::google::protobuf::internal::WireFormatLite::WriteUInt32ToArray(6, this->pse_evaluation_status(), target);
  }

  // repeated uint32 latest_equivalent_tcb_psvn = 7 [packed = true];
  if (this->latest_equivalent_tcb_psvn_size() > 0) {
    target = ::google::protobuf::internal::WireFormatLite::WriteTagToArray(
      7,
      ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED,
      target);
    target = ::google::protobuf::io::CodedOutputStream::WriteVarint32ToArray(
      _latest_equivalent_tcb_psvn_cached_byte_size_, target);
  }
  for (int i = 0; i < this->latest_equivalent_tcb_psvn_size(); i++) {
    target = ::google::protobuf::internal::WireFormatLite::
      WriteUInt32NoTagToArray(this->latest_equivalent_tcb_psvn(i), target);
  }

  // repeated uint32 latest_pse_isvsvn = 8 [packed = true];
  if (this->latest_pse_isvsvn_size() > 0) {
    target = ::google::protobuf::internal::WireFormatLite::WriteTagToArray(
      8,
      ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED,
      target);
    target = ::google::protobuf::io::CodedOutputStream::WriteVarint32ToArray(
      _latest_pse_isvsvn_cached_byte_size_, target);
  }
  for (int i = 0; i < this->latest_pse_isvsvn_size(); i++) {
    target = ::google::protobuf::internal::WireFormatLite::
      WriteUInt32NoTagToArray(this->latest_pse_isvsvn(i), target);
  }

  // repeated uint32 latest_psda_svn = 9 [packed = true];
  if (this->latest_psda_svn_size() > 0) {
    target = ::google::protobuf::internal::WireFormatLite::WriteTagToArray(
      9,
      ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED,
      target);
    target = ::google::protobuf::io::CodedOutputStream::WriteVarint32ToArray(
      _latest_psda_svn_cached_byte_size_, target);
  }
  for (int i = 0; i < this->latest_psda_svn_size(); i++) {
    target = ::google::protobuf::internal::WireFormatLite::
      WriteUInt32NoTagToArray(this->latest_psda_svn(i), target);
  }

  // repeated uint32 performance_rekey_gid = 10 [packed = true];
  if (this->performance_rekey_gid_size() > 0) {
    target = ::google::protobuf::internal::WireFormatLite::WriteTagToArray(
      10,
      ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED,
      target);
    target = ::google::protobuf::io::CodedOutputStream::WriteVarint32ToArray(
      _performance_rekey_gid_cached_byte_size_, target);
  }
  for (int i = 0; i < this->performance_rekey_gid_size(); i++) {
    target = ::google::protobuf::internal::WireFormatLite::
      WriteUInt32NoTagToArray(this->performance_rekey_gid(i), target);
  }

  // repeated uint32 ec_sign256_x = 11 [packed = true];
  if (this->ec_sign256_x_size() > 0) {
    target = ::google::protobuf::internal::WireFormatLite::WriteTagToArray(
      11,
      ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED,
      target);
    target = ::google::protobuf::io::CodedOutputStream::WriteVarint32ToArray(
      _ec_sign256_x_cached_byte_size_, target);
  }
  for (int i = 0; i < this->ec_sign256_x_size(); i++) {
    target = ::google::protobuf::internal::WireFormatLite::
      WriteUInt32NoTagToArray(this->ec_sign256_x(i), target);
  }

  // repeated uint32 ec_sign256_y = 12 [packed = true];
  if (this->ec_sign256_y_size() > 0) {
    target = ::google::protobuf::internal::WireFormatLite::WriteTagToArray(
      12,
      ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED,
      target);
    target = ::google::protobuf::io::CodedOutputStream::WriteVarint32ToArray(
      _ec_sign256_y_cached_byte_size_, target);
  }
  for (int i = 0; i < this->ec_sign256_y_size(); i++) {
    target = ::google::protobuf::internal::WireFormatLite::
      WriteUInt32NoTagToArray(this->ec_sign256_y(i), target);
  }

  // repeated uint32 mac_smk = 13 [packed = true];
  if (this->mac_smk_size() > 0) {
    target = ::google::protobuf::internal::WireFormatLite::WriteTagToArray(
      13,
      ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED,
      target);
    target = ::google::protobuf::io::CodedOutputStream::WriteVarint32ToArray(
      _mac_smk_cached_byte_size_, target);
  }
  for (int i = 0; i < this->mac_smk_size(); i++) {
    target = ::google::protobuf::internal::WireFormatLite::
      WriteUInt32NoTagToArray(this->mac_smk(i), target);
  }

  // optional uint32 result_size = 14;
  if (has_result_size()) {
    target = ::google::protobuf::internal::WireFormatLite::WriteUInt32ToArray(14, this->result_size(), target);
  }

  // repeated uint32 reserved = 15 [packed = true];
  if (this->reserved_size() > 0) {
    target = ::google::protobuf::internal::WireFormatLite::WriteTagToArray(
      15,
      ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED,
      target);
    target = ::google::protobuf::io::CodedOutputStream::WriteVarint32ToArray(
      _reserved_cached_byte_size_, target);
  }
  for (int i = 0; i < this->reserved_size(); i++) {
    target = ::google::protobuf::internal::WireFormatLite::
      WriteUInt32NoTagToArray(this->reserved(i), target);
  }

  // repeated uint32 payload_tag = 16 [packed = true];
  if (this->payload_tag_size() > 0) {
    target = ::google::protobuf::internal::WireFormatLite::WriteTagToArray(
      16,
      ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED,
      target);
    target = ::google::protobuf::io::CodedOutputStream::WriteVarint32ToArray(
      _payload_tag_cached_byte_size_, target);
  }
  for (int i = 0; i < this->payload_tag_size(); i++) {
    target = ::google::protobuf::internal::WireFormatLite::
      WriteUInt32NoTagToArray(this->payload_tag(i), target);
  }

  // repeated uint32 payload = 17 [packed = true];
  if (this->payload_size() > 0) {
    target = ::google::protobuf::internal::WireFormatLite::WriteTagToArray(
      17,
      ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED,
      target);
    target = ::google::protobuf::io::CodedOutputStream::WriteVarint32ToArray(
      _payload_cached_byte_size_, target);
  }
  for (int i = 0; i < this->payload_size(); i++) {
    target = ::google::protobuf::internal::WireFormatLite::
      WriteUInt32NoTagToArray(this->payload(i), target);
  }

  if (!unknown_fields().empty()) {
    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
        unknown_fields(), target);
  }
  // @@protoc_insertion_point(serialize_to_array_end:Messages.AttestationMessage)
  return target;
}

int AttestationMessage::ByteSize() const {
  int total_size = 0;

  if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    // required uint32 type = 1;
    if (has_type()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::UInt32Size(
          this->type());
    }

    // required uint32 size = 2;
    if (has_size()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::UInt32Size(
          this->size());
    }

    // required uint32 context = 3;
    if (has_context()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::UInt32Size(
          this->context());
    }

    // optional uint32 epid_group_status = 4;
    if (has_epid_group_status()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::UInt32Size(
          this->epid_group_status());
    }

    // optional uint32 tcb_evaluation_status = 5;
    if (has_tcb_evaluation_status()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::UInt32Size(
          this->tcb_evaluation_status());
    }

    // optional uint32 pse_evaluation_status = 6;
    if (has_pse_evaluation_status()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::UInt32Size(
          this->pse_evaluation_status());
    }

  }
  if (_has_bits_[13 / 32] & (0xffu << (13 % 32))) {
    // optional uint32 result_size = 14;
    if (has_result_size()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::UInt32Size(
          this->result_size());
    }

  }
  // repeated uint32 latest_equivalent_tcb_psvn = 7 [packed = true];
  {
    int data_size = 0;
    for (int i = 0; i < this->latest_equivalent_tcb_psvn_size(); i++) {
      data_size += ::google::protobuf::internal::WireFormatLite::
        UInt32Size(this->latest_equivalent_tcb_psvn(i));
    }
    if (data_size > 0) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::Int32Size(data_size);
    }
    GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
    _latest_equivalent_tcb_psvn_cached_byte_size_ = data_size;
    GOOGLE_SAFE_CONCURRENT_WRITES_END();
    total_size += data_size;
  }

  // repeated uint32 latest_pse_isvsvn = 8 [packed = true];
  {
    int data_size = 0;
    for (int i = 0; i < this->latest_pse_isvsvn_size(); i++) {
      data_size += ::google::protobuf::internal::WireFormatLite::
        UInt32Size(this->latest_pse_isvsvn(i));
    }
    if (data_size > 0) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::Int32Size(data_size);
    }
    GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
    _latest_pse_isvsvn_cached_byte_size_ = data_size;
    GOOGLE_SAFE_CONCURRENT_WRITES_END();
    total_size += data_size;
  }

  // repeated uint32 latest_psda_svn = 9 [packed = true];
  {
    int data_size = 0;
    for (int i = 0; i < this->latest_psda_svn_size(); i++) {
      data_size += ::google::protobuf::internal::WireFormatLite::
        UInt32Size(this->latest_psda_svn(i));
    }
    if (data_size > 0) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::Int32Size(data_size);
    }
    GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
    _latest_psda_svn_cached_byte_size_ = data_size;
    GOOGLE_SAFE_CONCURRENT_WRITES_END();
    total_size += data_size;
  }

  // repeated uint32 performance_rekey_gid = 10 [packed = true];
  {
    int data_size = 0;
    for (int i = 0; i < this->performance_rekey_gid_size(); i++) {
      data_size += ::google::protobuf::internal::WireFormatLite::
        UInt32Size(this->performance_rekey_gid(i));
    }
    if (data_size > 0) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::Int32Size(data_size);
    }
    GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
    _performance_rekey_gid_cached_byte_size_ = data_size;
    GOOGLE_SAFE_CONCURRENT_WRITES_END();
    total_size += data_size;
  }

  // repeated uint32 ec_sign256_x = 11 [packed = true];
  {
    int data_size = 0;
    for (int i = 0; i < this->ec_sign256_x_size(); i++) {
      data_size += ::google::protobuf::internal::WireFormatLite::
        UInt32Size(this->ec_sign256_x(i));
    }
    if (data_size > 0) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::Int32Size(data_size);
    }
    GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
    _ec_sign256_x_cached_byte_size_ = data_size;
    GOOGLE_SAFE_CONCURRENT_WRITES_END();
    total_size += data_size;
  }

  // repeated uint32 ec_sign256_y = 12 [packed = true];
  {
    int data_size = 0;
    for (int i = 0; i < this->ec_sign256_y_size(); i++) {
      data_size += ::google::protobuf::internal::WireFormatLite::
        UInt32Size(this->ec_sign256_y(i));
    }
    if (data_size > 0) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::Int32Size(data_size);
    }
    GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
    _ec_sign256_y_cached_byte_size_ = data_size;
    GOOGLE_SAFE_CONCURRENT_WRITES_END();
    total_size += data_size;
  }

  // repeated uint32 mac_smk = 13 [packed = true];
  {
    int data_size = 0;
    for (int i = 0; i < this->mac_smk_size(); i++) {
      data_size += ::google::protobuf::internal::WireFormatLite::
        UInt32Size(this->mac_smk(i));
    }
    if (data_size > 0) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::Int32Size(data_size);
    }
    GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
    _mac_smk_cached_byte_size_ = data_size;
    GOOGLE_SAFE_CONCURRENT_WRITES_END();
    total_size += data_size;
  }

  // repeated uint32 reserved = 15 [packed = true];
  {
    int data_size = 0;
    for (int i = 0; i < this->reserved_size(); i++) {
      data_size += ::google::protobuf::internal::WireFormatLite::
        UInt32Size(this->reserved(i));
    }
    if (data_size > 0) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::Int32Size(data_size);
    }
    GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
    _reserved_cached_byte_size_ = data_size;
    GOOGLE_SAFE_CONCURRENT_WRITES_END();
    total_size += data_size;
  }

  // repeated uint32 payload_tag = 16 [packed = true];
  {
    int data_size = 0;
    for (int i = 0; i < this->payload_tag_size(); i++) {
      data_size += ::google::protobuf::internal::WireFormatLite::
        UInt32Size(this->payload_tag(i));
    }
    if (data_size > 0) {
      total_size += 2 +
        ::google::protobuf::internal::WireFormatLite::Int32Size(data_size);
    }
    GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
    _payload_tag_cached_byte_size_ = data_size;
    GOOGLE_SAFE_CONCURRENT_WRITES_END();
    total_size += data_size;
  }

  // repeated uint32 payload = 17 [packed = true];
  {
    int data_size = 0;
    for (int i = 0; i < this->payload_size(); i++) {
      data_size += ::google::protobuf::internal::WireFormatLite::
        UInt32Size(this->payload(i));
    }
    if (data_size > 0) {
      total_size += 2 +
        ::google::protobuf::internal::WireFormatLite::Int32Size(data_size);
    }
    GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
    _payload_cached_byte_size_ = data_size;
    GOOGLE_SAFE_CONCURRENT_WRITES_END();
    total_size += data_size;
  }

  if (!unknown_fields().empty()) {
    total_size +=
      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
        unknown_fields());
  }
  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
  _cached_size_ = total_size;
  GOOGLE_SAFE_CONCURRENT_WRITES_END();
  return total_size;
}

void AttestationMessage::MergeFrom(const ::google::protobuf::Message& from) {
  GOOGLE_CHECK_NE(&from, this);
  const AttestationMessage* source =
    ::google::protobuf::internal::dynamic_cast_if_available<const AttestationMessage*>(
      &from);
  if (source == NULL) {
    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
  } else {
    MergeFrom(*source);
  }
}

void AttestationMessage::MergeFrom(const AttestationMessage& from) {
  GOOGLE_CHECK_NE(&from, this);
  latest_equivalent_tcb_psvn_.MergeFrom(from.latest_equivalent_tcb_psvn_);
  latest_pse_isvsvn_.MergeFrom(from.latest_pse_isvsvn_);
  latest_psda_svn_.MergeFrom(from.latest_psda_svn_);
  performance_rekey_gid_.MergeFrom(from.performance_rekey_gid_);
  ec_sign256_x_.MergeFrom(from.ec_sign256_x_);
  ec_sign256_y_.MergeFrom(from.ec_sign256_y_);
  mac_smk_.MergeFrom(from.mac_smk_);
  reserved_.MergeFrom(from.reserved_);
  payload_tag_.MergeFrom(from.payload_tag_);
  payload_.MergeFrom(from.payload_);
  if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    if (from.has_type()) {
      set_type(from.type());
    }
    if (from.has_size()) {
      set_size(from.size());
    }
    if (from.has_context()) {
      set_context(from.context());
    }
    if (from.has_epid_group_status()) {
      set_epid_group_status(from.epid_group_status());
    }
    if (from.has_tcb_evaluation_status()) {
      set_tcb_evaluation_status(from.tcb_evaluation_status());
    }
    if (from.has_pse_evaluation_status()) {
      set_pse_evaluation_status(from.pse_evaluation_status());
    }
  }
  if (from._has_bits_[13 / 32] & (0xffu << (13 % 32))) {
    if (from.has_result_size()) {
      set_result_size(from.result_size());
    }
  }
  mutable_unknown_fields()->MergeFrom(from.unknown_fields());
}

void AttestationMessage::CopyFrom(const ::google::protobuf::Message& from) {
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

void AttestationMessage::CopyFrom(const AttestationMessage& from) {
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

bool AttestationMessage::IsInitialized() const {
  if ((_has_bits_[0] & 0x00000007) != 0x00000007) return false;

  return true;
}

void AttestationMessage::Swap(AttestationMessage* other) {
  if (other != this) {
    std::swap(type_, other->type_);
    std::swap(size_, other->size_);
    std::swap(context_, other->context_);
    std::swap(epid_group_status_, other->epid_group_status_);
    std::swap(tcb_evaluation_status_, other->tcb_evaluation_status_);
    std::swap(pse_evaluation_status_, other->pse_evaluation_status_);
    latest_equivalent_tcb_psvn_.Swap(&other->latest_equivalent_tcb_psvn_);
    latest_pse_isvsvn_.Swap(&other->latest_pse_isvsvn_);
    latest_psda_svn_.Swap(&other->latest_psda_svn_);
    performance_rekey_gid_.Swap(&other->performance_rekey_gid_);
    ec_sign256_x_.Swap(&other->ec_sign256_x_);
    ec_sign256_y_.Swap(&other->ec_sign256_y_);
    mac_smk_.Swap(&other->mac_smk_);
    std::swap(result_size_, other->result_size_);
    reserved_.Swap(&other->reserved_);
    payload_tag_.Swap(&other->payload_tag_);
    payload_.Swap(&other->payload_);
    std::swap(_has_bits_[0], other->_has_bits_[0]);
    _unknown_fields_.Swap(&other->_unknown_fields_);
    std::swap(_cached_size_, other->_cached_size_);
  }
}

::google::protobuf::Metadata AttestationMessage::GetMetadata() const {
  protobuf_AssignDescriptorsOnce();
  ::google::protobuf::Metadata metadata;
  metadata.descriptor = AttestationMessage_descriptor_;
  metadata.reflection = AttestationMessage_reflection_;
  return metadata;
}


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

#ifndef _MSC_VER
const int MessagePsiSalt::kTypeFieldNumber;
const int MessagePsiSalt::kSizeFieldNumber;
const int MessagePsiSalt::kContextFieldNumber;
const int MessagePsiSalt::kIdFieldNumber;
const int MessagePsiSalt::kStateFieldNumber;
const int MessagePsiSalt::kMacFieldNumber;
const int MessagePsiSalt::kSaltFieldNumber;
#endif  // !_MSC_VER

MessagePsiSalt::MessagePsiSalt()
  : ::google::protobuf::Message() {
  SharedCtor();
  // @@protoc_insertion_point(constructor:Messages.MessagePsiSalt)
}

void MessagePsiSalt::InitAsDefaultInstance() {
}

MessagePsiSalt::MessagePsiSalt(const MessagePsiSalt& from)
  : ::google::protobuf::Message() {
  SharedCtor();
  MergeFrom(from);
  // @@protoc_insertion_point(copy_constructor:Messages.MessagePsiSalt)
}

void MessagePsiSalt::SharedCtor() {
  _cached_size_ = 0;
  type_ = 0u;
  size_ = 0u;
  context_ = 0u;
  id_ = 0u;
  state_ = 0u;
  ::memset(_has_bits_, 0, sizeof(_has_bits_));
}

MessagePsiSalt::~MessagePsiSalt() {
  // @@protoc_insertion_point(destructor:Messages.MessagePsiSalt)
  SharedDtor();
}

void MessagePsiSalt::SharedDtor() {
  if (this != default_instance_) {
  }
}

void MessagePsiSalt::SetCachedSize(int size) const {
  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
  _cached_size_ = size;
  GOOGLE_SAFE_CONCURRENT_WRITES_END();
}
const ::google::protobuf::Descriptor* MessagePsiSalt::descriptor() {
  protobuf_AssignDescriptorsOnce();
  return MessagePsiSalt_descriptor_;
}

const MessagePsiSalt& MessagePsiSalt::default_instance() {
  if (default_instance_ == NULL) protobuf_AddDesc_Messages_2eproto();
  return *default_instance_;
}

MessagePsiSalt* MessagePsiSalt::default_instance_ = NULL;

MessagePsiSalt* MessagePsiSalt::New() const {
  return new MessagePsiSalt;
}

void MessagePsiSalt::Clear() {
#define OFFSET_OF_FIELD_(f) (reinterpret_cast<char*>(      \
  &reinterpret_cast<MessagePsiSalt*>(16)->f) - \
   reinterpret_cast<char*>(16))

#define ZR_(first, last) do {                              \
    size_t f = OFFSET_OF_FIELD_(first);                    \
    size_t n = OFFSET_OF_FIELD_(last) - f + sizeof(last);  \
    ::memset(&first, 0, n);                                \
  } while (0)

  if (_has_bits_[0 / 32] & 31) {
    ZR_(type_, id_);
    state_ = 0u;
  }

#undef OFFSET_OF_FIELD_
#undef ZR_

  mac_.Clear();
  salt_.Clear();
  ::memset(_has_bits_, 0, sizeof(_has_bits_));
  mutable_unknown_fields()->Clear();
}

bool MessagePsiSalt::MergePartialFromCodedStream(
    ::google::protobuf::io::CodedInputStream* input) {
#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
  ::google::protobuf::uint32 tag;
  // @@protoc_insertion_point(parse_start:Messages.MessagePsiSalt)
  for (;;) {
    ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127);
    tag = p.first;
    if (!p.second) goto handle_unusual;
    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
      // required uint32 type = 1;
      case 1: {
        if (tag == 8) {
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
                 input, &type_)));
          set_has_type();
        } else {
          goto handle_unusual;
        }
        if (input->ExpectTag(16)) goto parse_size;
        break;
      }

      // required uint32 size = 2;
      case 2: {
        if (tag == 16) {
         parse_size:
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
                 input, &size_)));
          set_has_size();
        } else {
          goto handle_unusual;
        }
        if (input->ExpectTag(24)) goto parse_context;
        break;
      }

      // required uint32 context = 3;
      case 3: {
        if (tag == 24) {
         parse_context:
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
                 input, &context_)));
          set_has_context();
        } else {
          goto handle_unusual;
        }
        if (input->ExpectTag(32)) goto parse_id;
        break;
      }

      // required uint32 id = 4;
      case 4: {
        if (tag == 32) {
         parse_id:
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
                 input, &id_)));
          set_has_id();
        } else {
          goto handle_unusual;
        }
        if (input->ExpectTag(40)) goto parse_state;
        break;
      }

      // required uint32 state = 5;
      case 5: {
        if (tag == 40) {
         parse_state:
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
                 input, &state_)));
          set_has_state();
        } else {
          goto handle_unusual;
        }
        if (input->ExpectTag(50)) goto parse_mac;
        break;
      }

      // repeated uint32 mac = 6 [packed = true];
      case 6: {
        if (tag == 50) {
         parse_mac:
          DO_((::google::protobuf::internal::WireFormatLite::ReadPackedPrimitive<
                   ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
                 input, this->mutable_mac())));
        } else if (tag == 48) {
          DO_((::google::protobuf::internal::WireFormatLite::ReadRepeatedPrimitiveNoInline<
                   ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
                 1, 50, input, this->mutable_mac())));
        } else {
          goto handle_unusual;
        }
        if (input->ExpectTag(58)) goto parse_salt;
        break;
      }

      // repeated uint32 salt = 7 [packed = true];
      case 7: {
        if (tag == 58) {
         parse_salt:
          DO_((::google::protobuf::internal::WireFormatLite::ReadPackedPrimitive<
                   ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
                 input, this->mutable_salt())));
        } else if (tag == 56) {
          DO_((::google::protobuf::internal::WireFormatLite::ReadRepeatedPrimitiveNoInline<
                   ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
                 1, 58, input, this->mutable_salt())));
        } else {
          goto handle_unusual;
        }
        if (input->ExpectAtEnd()) goto success;
        break;
      }

      default: {
      handle_unusual:
        if (tag == 0 ||
            ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
            ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
          goto success;
        }
        DO_(::google::protobuf::internal::WireFormat::SkipField(
              input, tag, mutable_unknown_fields()));
        break;
      }
    }
  }
success:
  // @@protoc_insertion_point(parse_success:Messages.MessagePsiSalt)
  return true;
failure:
  // @@protoc_insertion_point(parse_failure:Messages.MessagePsiSalt)
  return false;
#undef DO_
}

void MessagePsiSalt::SerializeWithCachedSizes(
    ::google::protobuf::io::CodedOutputStream* output) const {
  // @@protoc_insertion_point(serialize_start:Messages.MessagePsiSalt)
  // required uint32 type = 1;
  if (has_type()) {
    ::google::protobuf::internal::WireFormatLite::WriteUInt32(1, this->type(), output);
  }

  // required uint32 size = 2;
  if (has_size()) {
    ::google::protobuf::internal::WireFormatLite::WriteUInt32(2, this->size(), output);
  }

  // required uint32 context = 3;
  if (has_context()) {
    ::google::protobuf::internal::WireFormatLite::WriteUInt32(3, this->context(), output);
  }

  // required uint32 id = 4;
  if (has_id()) {
    ::google::protobuf::internal::WireFormatLite::WriteUInt32(4, this->id(), output);
  }

  // required uint32 state = 5;
  if (has_state()) {
    ::google::protobuf::internal::WireFormatLite::WriteUInt32(5, this->state(), output);
  }

  // repeated uint32 mac = 6 [packed = true];
  if (this->mac_size() > 0) {
    ::google::protobuf::internal::WireFormatLite::WriteTag(6, ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED, output);
    output->WriteVarint32(_mac_cached_byte_size_);
  }
  for (int i = 0; i < this->mac_size(); i++) {
    ::google::protobuf::internal::WireFormatLite::WriteUInt32NoTag(
      this->mac(i), output);
  }

  // repeated uint32 salt = 7 [packed = true];
  if (this->salt_size() > 0) {
    ::google::protobuf::internal::WireFormatLite::WriteTag(7, ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED, output);
    output->WriteVarint32(_salt_cached_byte_size_);
  }
  for (int i = 0; i < this->salt_size(); i++) {
    ::google::protobuf::internal::WireFormatLite::WriteUInt32NoTag(
      this->salt(i), output);
  }

  if (!unknown_fields().empty()) {
    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
        unknown_fields(), output);
  }
  // @@protoc_insertion_point(serialize_end:Messages.MessagePsiSalt)
}

::google::protobuf::uint8* MessagePsiSalt::SerializeWithCachedSizesToArray(
    ::google::protobuf::uint8* target) const {
  // @@protoc_insertion_point(serialize_to_array_start:Messages.MessagePsiSalt)
  // required uint32 type = 1;
  if (has_type()) {
    target = ::google::protobuf::internal::WireFormatLite::WriteUInt32ToArray(1, this->type(), target);
  }

  // required uint32 size = 2;
  if (has_size()) {
    target = ::google::protobuf::internal::WireFormatLite::WriteUInt32ToArray(2, this->size(), target);
  }

  // required uint32 context = 3;
  if (has_context()) {
    target = ::google::protobuf::internal::WireFormatLite::WriteUInt32ToArray(3, this->context(), target);
  }

  // required uint32 id = 4;
  if (has_id()) {
    target = ::google::protobuf::internal::WireFormatLite::WriteUInt32ToArray(4, this->id(), target);
  }

  // required uint32 state = 5;
  if (has_state()) {
    target = ::google::protobuf::internal::WireFormatLite::WriteUInt32ToArray(5, this->state(), target);
  }

  // repeated uint32 mac = 6 [packed = true];
  if (this->mac_size() > 0) {
    target = ::google::protobuf::internal::WireFormatLite::WriteTagToArray(
      6,
      ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED,
      target);
    target = ::google::protobuf::io::CodedOutputStream::WriteVarint32ToArray(
      _mac_cached_byte_size_, target);
  }
  for (int i = 0; i < this->mac_size(); i++) {
    target = ::google::protobuf::internal::WireFormatLite::
      WriteUInt32NoTagToArray(this->mac(i), target);
  }

  // repeated uint32 salt = 7 [packed = true];
  if (this->salt_size() > 0) {
    target = ::google::protobuf::internal::WireFormatLite::WriteTagToArray(
      7,
      ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED,
      target);
    target = ::google::protobuf::io::CodedOutputStream::WriteVarint32ToArray(
      _salt_cached_byte_size_, target);
  }
  for (int i = 0; i < this->salt_size(); i++) {
    target = ::google::protobuf::internal::WireFormatLite::
      WriteUInt32NoTagToArray(this->salt(i), target);
  }

  if (!unknown_fields().empty()) {
    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
        unknown_fields(), target);
  }
  // @@protoc_insertion_point(serialize_to_array_end:Messages.MessagePsiSalt)
  return target;
}

int MessagePsiSalt::ByteSize() const {
  int total_size = 0;

  if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    // required uint32 type = 1;
    if (has_type()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::UInt32Size(
          this->type());
    }

    // required uint32 size = 2;
    if (has_size()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::UInt32Size(
          this->size());
    }

    // required uint32 context = 3;
    if (has_context()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::UInt32Size(
          this->context());
    }

    // required uint32 id = 4;
    if (has_id()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::UInt32Size(
          this->id());
    }

    // required uint32 state = 5;
    if (has_state()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::UInt32Size(
          this->state());
    }

  }
  // repeated uint32 mac = 6 [packed = true];
  {
    int data_size = 0;
    for (int i = 0; i < this->mac_size(); i++) {
      data_size += ::google::protobuf::internal::WireFormatLite::
        UInt32Size(this->mac(i));
    }
    if (data_size > 0) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::Int32Size(data_size);
    }
    GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
    _mac_cached_byte_size_ = data_size;
    GOOGLE_SAFE_CONCURRENT_WRITES_END();
    total_size += data_size;
  }

  // repeated uint32 salt = 7 [packed = true];
  {
    int data_size = 0;
    for (int i = 0; i < this->salt_size(); i++) {
      data_size += ::google::protobuf::internal::WireFormatLite::
        UInt32Size(this->salt(i));
    }
    if (data_size > 0) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::Int32Size(data_size);
    }
    GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
    _salt_cached_byte_size_ = data_size;
    GOOGLE_SAFE_CONCURRENT_WRITES_END();
    total_size += data_size;
  }

  if (!unknown_fields().empty()) {
    total_size +=
      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
        unknown_fields());
  }
  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
  _cached_size_ = total_size;
  GOOGLE_SAFE_CONCURRENT_WRITES_END();
  return total_size;
}

void MessagePsiSalt::MergeFrom(const ::google::protobuf::Message& from) {
  GOOGLE_CHECK_NE(&from, this);
  const MessagePsiSalt* source =
    ::google::protobuf::internal::dynamic_cast_if_available<const MessagePsiSalt*>(
      &from);
  if (source == NULL) {
    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
  } else {
    MergeFrom(*source);
  }
}

void MessagePsiSalt::MergeFrom(const MessagePsiSalt& from) {
  GOOGLE_CHECK_NE(&from, this);
  mac_.MergeFrom(from.mac_);
  salt_.MergeFrom(from.salt_);
  if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    if (from.has_type()) {
      set_type(from.type());
    }
    if (from.has_size()) {
      set_size(from.size());
    }
    if (from.has_context()) {
      set_context(from.context());
    }
    if (from.has_id()) {
      set_id(from.id());
    }
    if (from.has_state()) {
      set_state(from.state());
    }
  }
  mutable_unknown_fields()->MergeFrom(from.unknown_fields());
}

void MessagePsiSalt::CopyFrom(const ::google::protobuf::Message& from) {
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

void MessagePsiSalt::CopyFrom(const MessagePsiSalt& from) {
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

bool MessagePsiSalt::IsInitialized() const {
  if ((_has_bits_[0] & 0x0000001f) != 0x0000001f) return false;

  return true;
}

void MessagePsiSalt::Swap(MessagePsiSalt* other) {
  if (other != this) {
    std::swap(type_, other->type_);
    std::swap(size_, other->size_);
    std::swap(context_, other->context_);
    std::swap(id_, other->id_);
    std::swap(state_, other->state_);
    mac_.Swap(&other->mac_);
    salt_.Swap(&other->salt_);
    std::swap(_has_bits_[0], other->_has_bits_[0]);
    _unknown_fields_.Swap(&other->_unknown_fields_);
    std::swap(_cached_size_, other->_cached_size_);
  }
}

::google::protobuf::Metadata MessagePsiSalt::GetMetadata() const {
  protobuf_AssignDescriptorsOnce();
  ::google::protobuf::Metadata metadata;
  metadata.descriptor = MessagePsiSalt_descriptor_;
  metadata.reflection = MessagePsiSalt_reflection_;
  return metadata;
}


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

#ifndef _MSC_VER
const int MessagePsiHashData::kTypeFieldNumber;
const int MessagePsiHashData::kSizeFieldNumber;
const int MessagePsiHashData::kContextFieldNumber;
const int MessagePsiHashData::kIdFieldNumber;
const int MessagePsiHashData::kMacFieldNumber;
const int MessagePsiHashData::kDataFieldNumber;
#endif  // !_MSC_VER

MessagePsiHashData::MessagePsiHashData()
  : ::google::protobuf::Message() {
  SharedCtor();
  // @@protoc_insertion_point(constructor:Messages.MessagePsiHashData)
}

void MessagePsiHashData::InitAsDefaultInstance() {
}

MessagePsiHashData::MessagePsiHashData(const MessagePsiHashData& from)
  : ::google::protobuf::Message() {
  SharedCtor();
  MergeFrom(from);
  // @@protoc_insertion_point(copy_constructor:Messages.MessagePsiHashData)
}

void MessagePsiHashData::SharedCtor() {
  _cached_size_ = 0;
  type_ = 0u;
  size_ = 0u;
  context_ = 0u;
  id_ = 0u;
  ::memset(_has_bits_, 0, sizeof(_has_bits_));
}

MessagePsiHashData::~MessagePsiHashData() {
  // @@protoc_insertion_point(destructor:Messages.MessagePsiHashData)
  SharedDtor();
}

void MessagePsiHashData::SharedDtor() {
  if (this != default_instance_) {
  }
}

void MessagePsiHashData::SetCachedSize(int size) const {
  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
  _cached_size_ = size;
  GOOGLE_SAFE_CONCURRENT_WRITES_END();
}
const ::google::protobuf::Descriptor* MessagePsiHashData::descriptor() {
  protobuf_AssignDescriptorsOnce();
  return MessagePsiHashData_descriptor_;
}

const MessagePsiHashData& MessagePsiHashData::default_instance() {
  if (default_instance_ == NULL) protobuf_AddDesc_Messages_2eproto();
  return *default_instance_;
}

MessagePsiHashData* MessagePsiHashData::default_instance_ = NULL;

MessagePsiHashData* MessagePsiHashData::New() const {
  return new MessagePsiHashData;
}

void MessagePsiHashData::Clear() {
#define OFFSET_OF_FIELD_(f) (reinterpret_cast<char*>(      \
  &reinterpret_cast<MessagePsiHashData*>(16)->f) - \
   reinterpret_cast<char*>(16))

#define ZR_(first, last) do {                              \
    size_t f = OFFSET_OF_FIELD_(first);                    \
    size_t n = OFFSET_OF_FIELD_(last) - f + sizeof(last);  \
    ::memset(&first, 0, n);                                \
  } while (0)

  ZR_(type_, id_);

#undef OFFSET_OF_FIELD_
#undef ZR_

  mac_.Clear();
  data_.Clear();
  ::memset(_has_bits_, 0, sizeof(_has_bits_));
  mutable_unknown_fields()->Clear();
}

bool MessagePsiHashData::MergePartialFromCodedStream(
    ::google::protobuf::io::CodedInputStream* input) {
#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
  ::google::protobuf::uint32 tag;
  // @@protoc_insertion_point(parse_start:Messages.MessagePsiHashData)
  for (;;) {
    ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127);
    tag = p.first;
    if (!p.second) goto handle_unusual;
    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
      // required uint32 type = 1;
      case 1: {
        if (tag == 8) {
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
                 input, &type_)));
          set_has_type();
        } else {
          goto handle_unusual;
        }
        if (input->ExpectTag(16)) goto parse_size;
        break;
      }

      // required uint32 size = 2;
      case 2: {
        if (tag == 16) {
         parse_size:
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
                 input, &size_)));
          set_has_size();
        } else {
          goto handle_unusual;
        }
        if (input->ExpectTag(24)) goto parse_context;
        break;
      }

      // required uint32 context = 3;
      case 3: {
        if (tag == 24) {
         parse_context:
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
                 input, &context_)));
          set_has_context();
        } else {
          goto handle_unusual;
        }
        if (input->ExpectTag(32)) goto parse_id;
        break;
      }

      // required uint32 id = 4;
      case 4: {
        if (tag == 32) {
         parse_id:
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
                 input, &id_)));
          set_has_id();
        } else {
          goto handle_unusual;
        }
        if (input->ExpectTag(42)) goto parse_mac;
        break;
      }

      // repeated uint32 mac = 5 [packed = true];
      case 5: {
        if (tag == 42) {
         parse_mac:
          DO_((::google::protobuf::internal::WireFormatLite::ReadPackedPrimitive<
                   ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
                 input, this->mutable_mac())));
        } else if (tag == 40) {
          DO_((::google::protobuf::internal::WireFormatLite::ReadRepeatedPrimitiveNoInline<
                   ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
                 1, 42, input, this->mutable_mac())));
        } else {
          goto handle_unusual;
        }
        if (input->ExpectTag(50)) goto parse_data;
        break;
      }

      // repeated uint32 data = 6 [packed = true];
      case 6: {
        if (tag == 50) {
         parse_data:
          DO_((::google::protobuf::internal::WireFormatLite::ReadPackedPrimitive<
                   ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
                 input, this->mutable_data())));
        } else if (tag == 48) {
          DO_((::google::protobuf::internal::WireFormatLite::ReadRepeatedPrimitiveNoInline<
                   ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
                 1, 50, input, this->mutable_data())));
        } else {
          goto handle_unusual;
        }
        if (input->ExpectAtEnd()) goto success;
        break;
      }

      default: {
      handle_unusual:
        if (tag == 0 ||
            ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
            ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
          goto success;
        }
        DO_(::google::protobuf::internal::WireFormat::SkipField(
              input, tag, mutable_unknown_fields()));
        break;
      }
    }
  }
success:
  // @@protoc_insertion_point(parse_success:Messages.MessagePsiHashData)
  return true;
failure:
  // @@protoc_insertion_point(parse_failure:Messages.MessagePsiHashData)
  return false;
#undef DO_
}

void MessagePsiHashData::SerializeWithCachedSizes(
    ::google::protobuf::io::CodedOutputStream* output) const {
  // @@protoc_insertion_point(serialize_start:Messages.MessagePsiHashData)
  // required uint32 type = 1;
  if (has_type()) {
    ::google::protobuf::internal::WireFormatLite::WriteUInt32(1, this->type(), output);
  }

  // required uint32 size = 2;
  if (has_size()) {
    ::google::protobuf::internal::WireFormatLite::WriteUInt32(2, this->size(), output);
  }

  // required uint32 context = 3;
  if (has_context()) {
    ::google::protobuf::internal::WireFormatLite::WriteUInt32(3, this->context(), output);
  }

  // required uint32 id = 4;
  if (has_id()) {
    ::google::protobuf::internal::WireFormatLite::WriteUInt32(4, this->id(), output);
  }

  // repeated uint32 mac = 5 [packed = true];
  if (this->mac_size() > 0) {
    ::google::protobuf::internal::WireFormatLite::WriteTag(5, ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED, output);
    output->WriteVarint32(_mac_cached_byte_size_);
  }
  for (int i = 0; i < this->mac_size(); i++) {
    ::google::protobuf::internal::WireFormatLite::WriteUInt32NoTag(
      this->mac(i), output);
  }

  // repeated uint32 data = 6 [packed = true];
  if (this->data_size() > 0) {
    ::google::protobuf::internal::WireFormatLite::WriteTag(6, ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED, output);
    output->WriteVarint32(_data_cached_byte_size_);
  }
  for (int i = 0; i < this->data_size(); i++) {
    ::google::protobuf::internal::WireFormatLite::WriteUInt32NoTag(
      this->data(i), output);
  }

  if (!unknown_fields().empty()) {
    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
        unknown_fields(), output);
  }
  // @@protoc_insertion_point(serialize_end:Messages.MessagePsiHashData)
}

::google::protobuf::uint8* MessagePsiHashData::SerializeWithCachedSizesToArray(
    ::google::protobuf::uint8* target) const {
  // @@protoc_insertion_point(serialize_to_array_start:Messages.MessagePsiHashData)
  // required uint32 type = 1;
  if (has_type()) {
    target = ::google::protobuf::internal::WireFormatLite::WriteUInt32ToArray(1, this->type(), target);
  }

  // required uint32 size = 2;
  if (has_size()) {
    target = ::google::protobuf::internal::WireFormatLite::WriteUInt32ToArray(2, this->size(), target);
  }

  // required uint32 context = 3;
  if (has_context()) {
    target = ::google::protobuf::internal::WireFormatLite::WriteUInt32ToArray(3, this->context(), target);
  }

  // required uint32 id = 4;
  if (has_id()) {
    target = ::google::protobuf::internal::WireFormatLite::WriteUInt32ToArray(4, this->id(), target);
  }

  // repeated uint32 mac = 5 [packed = true];
  if (this->mac_size() > 0) {
    target = ::google::protobuf::internal::WireFormatLite::WriteTagToArray(
      5,
      ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED,
      target);
    target = ::google::protobuf::io::CodedOutputStream::WriteVarint32ToArray(
      _mac_cached_byte_size_, target);
  }
  for (int i = 0; i < this->mac_size(); i++) {
    target = ::google::protobuf::internal::WireFormatLite::
      WriteUInt32NoTagToArray(this->mac(i), target);
  }

  // repeated uint32 data = 6 [packed = true];
  if (this->data_size() > 0) {
    target = ::google::protobuf::internal::WireFormatLite::WriteTagToArray(
      6,
      ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED,
      target);
    target = ::google::protobuf::io::CodedOutputStream::WriteVarint32ToArray(
      _data_cached_byte_size_, target);
  }
  for (int i = 0; i < this->data_size(); i++) {
    target = ::google::protobuf::internal::WireFormatLite::
      WriteUInt32NoTagToArray(this->data(i), target);
  }

  if (!unknown_fields().empty()) {
    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
        unknown_fields(), target);
  }
  // @@protoc_insertion_point(serialize_to_array_end:Messages.MessagePsiHashData)
  return target;
}

int MessagePsiHashData::ByteSize() const {
  int total_size = 0;

  if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    // required uint32 type = 1;
    if (has_type()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::UInt32Size(
          this->type());
    }

    // required uint32 size = 2;
    if (has_size()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::UInt32Size(
          this->size());
    }

    // required uint32 context = 3;
    if (has_context()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::UInt32Size(
          this->context());
    }

    // required uint32 id = 4;
    if (has_id()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::UInt32Size(
          this->id());
    }

  }
  // repeated uint32 mac = 5 [packed = true];
  {
    int data_size = 0;
    for (int i = 0; i < this->mac_size(); i++) {
      data_size += ::google::protobuf::internal::WireFormatLite::
        UInt32Size(this->mac(i));
    }
    if (data_size > 0) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::Int32Size(data_size);
    }
    GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
    _mac_cached_byte_size_ = data_size;
    GOOGLE_SAFE_CONCURRENT_WRITES_END();
    total_size += data_size;
  }

  // repeated uint32 data = 6 [packed = true];
  {
    int data_size = 0;
    for (int i = 0; i < this->data_size(); i++) {
      data_size += ::google::protobuf::internal::WireFormatLite::
        UInt32Size(this->data(i));
    }
    if (data_size > 0) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::Int32Size(data_size);
    }
    GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
    _data_cached_byte_size_ = data_size;
    GOOGLE_SAFE_CONCURRENT_WRITES_END();
    total_size += data_size;
  }

  if (!unknown_fields().empty()) {
    total_size +=
      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
        unknown_fields());
  }
  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
  _cached_size_ = total_size;
  GOOGLE_SAFE_CONCURRENT_WRITES_END();
  return total_size;
}

void MessagePsiHashData::MergeFrom(const ::google::protobuf::Message& from) {
  GOOGLE_CHECK_NE(&from, this);
  const MessagePsiHashData* source =
    ::google::protobuf::internal::dynamic_cast_if_available<const MessagePsiHashData*>(
      &from);
  if (source == NULL) {
    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
  } else {
    MergeFrom(*source);
  }
}

void MessagePsiHashData::MergeFrom(const MessagePsiHashData& from) {
  GOOGLE_CHECK_NE(&from, this);
  mac_.MergeFrom(from.mac_);
  data_.MergeFrom(from.data_);
  if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    if (from.has_type()) {
      set_type(from.type());
    }
    if (from.has_size()) {
      set_size(from.size());
    }
    if (from.has_context()) {
      set_context(from.context());
    }
    if (from.has_id()) {
      set_id(from.id());
    }
  }
  mutable_unknown_fields()->MergeFrom(from.unknown_fields());
}

void MessagePsiHashData::CopyFrom(const ::google::protobuf::Message& from) {
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

void MessagePsiHashData::CopyFrom(const MessagePsiHashData& from) {
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

bool MessagePsiHashData::IsInitialized() const {
  if ((_has_bits_[0] & 0x0000000f) != 0x0000000f) return false;

  return true;
}

void MessagePsiHashData::Swap(MessagePsiHashData* other) {
  if (other != this) {
    std::swap(type_, other->type_);
    std::swap(size_, other->size_);
    std::swap(context_, other->context_);
    std::swap(id_, other->id_);
    mac_.Swap(&other->mac_);
    data_.Swap(&other->data_);
    std::swap(_has_bits_[0], other->_has_bits_[0]);
    _unknown_fields_.Swap(&other->_unknown_fields_);
    std::swap(_cached_size_, other->_cached_size_);
  }
}

::google::protobuf::Metadata MessagePsiHashData::GetMetadata() const {
  protobuf_AssignDescriptorsOnce();
  ::google::protobuf::Metadata metadata;
  metadata.descriptor = MessagePsiHashData_descriptor_;
  metadata.reflection = MessagePsiHashData_reflection_;
  return metadata;
}


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

#ifndef _MSC_VER
const int MessagePsiHashDataFinished::kTypeFieldNumber;
const int MessagePsiHashDataFinished::kSizeFieldNumber;
const int MessagePsiHashDataFinished::kContextFieldNumber;
const int MessagePsiHashDataFinished::kIdFieldNumber;
#endif  // !_MSC_VER

MessagePsiHashDataFinished::MessagePsiHashDataFinished()
  : ::google::protobuf::Message() {
  SharedCtor();
  // @@protoc_insertion_point(constructor:Messages.MessagePsiHashDataFinished)
}

void MessagePsiHashDataFinished::InitAsDefaultInstance() {
}

MessagePsiHashDataFinished::MessagePsiHashDataFinished(const MessagePsiHashDataFinished& from)
  : ::google::protobuf::Message() {
  SharedCtor();
  MergeFrom(from);
  // @@protoc_insertion_point(copy_constructor:Messages.MessagePsiHashDataFinished)
}

void MessagePsiHashDataFinished::SharedCtor() {
  _cached_size_ = 0;
  type_ = 0u;
  size_ = 0u;
  context_ = 0u;
  id_ = 0u;
  ::memset(_has_bits_, 0, sizeof(_has_bits_));
}

MessagePsiHashDataFinished::~MessagePsiHashDataFinished() {
  // @@protoc_insertion_point(destructor:Messages.MessagePsiHashDataFinished)
  SharedDtor();
}

void MessagePsiHashDataFinished::SharedDtor() {
  if (this != default_instance_) {
  }
}

void MessagePsiHashDataFinished::SetCachedSize(int size) const {
  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
  _cached_size_ = size;
  GOOGLE_SAFE_CONCURRENT_WRITES_END();
}
const ::google::protobuf::Descriptor* MessagePsiHashDataFinished::descriptor() {
  protobuf_AssignDescriptorsOnce();
  return MessagePsiHashDataFinished_descriptor_;
}

const MessagePsiHashDataFinished& MessagePsiHashDataFinished::default_instance() {
  if (default_instance_ == NULL) protobuf_AddDesc_Messages_2eproto();
  return *default_instance_;
}

MessagePsiHashDataFinished* MessagePsiHashDataFinished::default_instance_ = NULL;

MessagePsiHashDataFinished* MessagePsiHashDataFinished::New() const {
  return new MessagePsiHashDataFinished;
}

void MessagePsiHashDataFinished::Clear() {
#define OFFSET_OF_FIELD_(f) (reinterpret_cast<char*>(      \
  &reinterpret_cast<MessagePsiHashDataFinished*>(16)->f) - \
   reinterpret_cast<char*>(16))

#define ZR_(first, last) do {                              \
    size_t f = OFFSET_OF_FIELD_(first);                    \
    size_t n = OFFSET_OF_FIELD_(last) - f + sizeof(last);  \
    ::memset(&first, 0, n);                                \
  } while (0)

  ZR_(type_, id_);

#undef OFFSET_OF_FIELD_
#undef ZR_

  ::memset(_has_bits_, 0, sizeof(_has_bits_));
  mutable_unknown_fields()->Clear();
}

bool MessagePsiHashDataFinished::MergePartialFromCodedStream(
    ::google::protobuf::io::CodedInputStream* input) {
#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
  ::google::protobuf::uint32 tag;
  // @@protoc_insertion_point(parse_start:Messages.MessagePsiHashDataFinished)
  for (;;) {
    ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127);
    tag = p.first;
    if (!p.second) goto handle_unusual;
    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
      // required uint32 type = 1;
      case 1: {
        if (tag == 8) {
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
                 input, &type_)));
          set_has_type();
        } else {
          goto handle_unusual;
        }
        if (input->ExpectTag(16)) goto parse_size;
        break;
      }

      // required uint32 size = 2;
      case 2: {
        if (tag == 16) {
         parse_size:
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
                 input, &size_)));
          set_has_size();
        } else {
          goto handle_unusual;
        }
        if (input->ExpectTag(24)) goto parse_context;
        break;
      }

      // required uint32 context = 3;
      case 3: {
        if (tag == 24) {
         parse_context:
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
                 input, &context_)));
          set_has_context();
        } else {
          goto handle_unusual;
        }
        if (input->ExpectTag(32)) goto parse_id;
        break;
      }

      // required uint32 id = 4;
      case 4: {
        if (tag == 32) {
         parse_id:
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
                 input, &id_)));
          set_has_id();
        } else {
          goto handle_unusual;
        }
        if (input->ExpectAtEnd()) goto success;
        break;
      }

      default: {
      handle_unusual:
        if (tag == 0 ||
            ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
            ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
          goto success;
        }
        DO_(::google::protobuf::internal::WireFormat::SkipField(
              input, tag, mutable_unknown_fields()));
        break;
      }
    }
  }
success:
  // @@protoc_insertion_point(parse_success:Messages.MessagePsiHashDataFinished)
  return true;
failure:
  // @@protoc_insertion_point(parse_failure:Messages.MessagePsiHashDataFinished)
  return false;
#undef DO_
}

void MessagePsiHashDataFinished::SerializeWithCachedSizes(
    ::google::protobuf::io::CodedOutputStream* output) const {
  // @@protoc_insertion_point(serialize_start:Messages.MessagePsiHashDataFinished)
  // required uint32 type = 1;
  if (has_type()) {
    ::google::protobuf::internal::WireFormatLite::WriteUInt32(1, this->type(), output);
  }

  // required uint32 size = 2;
  if (has_size()) {
    ::google::protobuf::internal::WireFormatLite::WriteUInt32(2, this->size(), output);
  }

  // required uint32 context = 3;
  if (has_context()) {
    ::google::protobuf::internal::WireFormatLite::WriteUInt32(3, this->context(), output);
  }

  // required uint32 id = 4;
  if (has_id()) {
    ::google::protobuf::internal::WireFormatLite::WriteUInt32(4, this->id(), output);
  }

  if (!unknown_fields().empty()) {
    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
        unknown_fields(), output);
  }
  // @@protoc_insertion_point(serialize_end:Messages.MessagePsiHashDataFinished)
}

::google::protobuf::uint8* MessagePsiHashDataFinished::SerializeWithCachedSizesToArray(
    ::google::protobuf::uint8* target) const {
  // @@protoc_insertion_point(serialize_to_array_start:Messages.MessagePsiHashDataFinished)
  // required uint32 type = 1;
  if (has_type()) {
    target = ::google::protobuf::internal::WireFormatLite::WriteUInt32ToArray(1, this->type(), target);
  }

  // required uint32 size = 2;
  if (has_size()) {
    target = ::google::protobuf::internal::WireFormatLite::WriteUInt32ToArray(2, this->size(), target);
  }

  // required uint32 context = 3;
  if (has_context()) {
    target = ::google::protobuf::internal::WireFormatLite::WriteUInt32ToArray(3, this->context(), target);
  }

  // required uint32 id = 4;
  if (has_id()) {
    target = ::google::protobuf::internal::WireFormatLite::WriteUInt32ToArray(4, this->id(), target);
  }

  if (!unknown_fields().empty()) {
    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
        unknown_fields(), target);
  }
  // @@protoc_insertion_point(serialize_to_array_end:Messages.MessagePsiHashDataFinished)
  return target;
}

int MessagePsiHashDataFinished::ByteSize() const {
  int total_size = 0;

  if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    // required uint32 type = 1;
    if (has_type()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::UInt32Size(
          this->type());
    }

    // required uint32 size = 2;
    if (has_size()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::UInt32Size(
          this->size());
    }

    // required uint32 context = 3;
    if (has_context()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::UInt32Size(
          this->context());
    }

    // required uint32 id = 4;
    if (has_id()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::UInt32Size(
          this->id());
    }

  }
  if (!unknown_fields().empty()) {
    total_size +=
      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
        unknown_fields());
  }
  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
  _cached_size_ = total_size;
  GOOGLE_SAFE_CONCURRENT_WRITES_END();
  return total_size;
}

void MessagePsiHashDataFinished::MergeFrom(const ::google::protobuf::Message& from) {
  GOOGLE_CHECK_NE(&from, this);
  const MessagePsiHashDataFinished* source =
    ::google::protobuf::internal::dynamic_cast_if_available<const MessagePsiHashDataFinished*>(
      &from);
  if (source == NULL) {
    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
  } else {
    MergeFrom(*source);
  }
}

void MessagePsiHashDataFinished::MergeFrom(const MessagePsiHashDataFinished& from) {
  GOOGLE_CHECK_NE(&from, this);
  if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    if (from.has_type()) {
      set_type(from.type());
    }
    if (from.has_size()) {
      set_size(from.size());
    }
    if (from.has_context()) {
      set_context(from.context());
    }
    if (from.has_id()) {
      set_id(from.id());
    }
  }
  mutable_unknown_fields()->MergeFrom(from.unknown_fields());
}

void MessagePsiHashDataFinished::CopyFrom(const ::google::protobuf::Message& from) {
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

void MessagePsiHashDataFinished::CopyFrom(const MessagePsiHashDataFinished& from) {
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

bool MessagePsiHashDataFinished::IsInitialized() const {
  if ((_has_bits_[0] & 0x0000000f) != 0x0000000f) return false;

  return true;
}

void MessagePsiHashDataFinished::Swap(MessagePsiHashDataFinished* other) {
  if (other != this) {
    std::swap(type_, other->type_);
    std::swap(size_, other->size_);
    std::swap(context_, other->context_);
    std::swap(id_, other->id_);
    std::swap(_has_bits_[0], other->_has_bits_[0]);
    _unknown_fields_.Swap(&other->_unknown_fields_);
    std::swap(_cached_size_, other->_cached_size_);
  }
}

::google::protobuf::Metadata MessagePsiHashDataFinished::GetMetadata() const {
  protobuf_AssignDescriptorsOnce();
  ::google::protobuf::Metadata metadata;
  metadata.descriptor = MessagePsiHashDataFinished_descriptor_;
  metadata.reflection = MessagePsiHashDataFinished_reflection_;
  return metadata;
}


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

#ifndef _MSC_VER
const int MessagePsiResult::kTypeFieldNumber;
const int MessagePsiResult::kSizeFieldNumber;
const int MessagePsiResult::kContextFieldNumber;
const int MessagePsiResult::kIdFieldNumber;
const int MessagePsiResult::kStateFieldNumber;
#endif  // !_MSC_VER

MessagePsiResult::MessagePsiResult()
  : ::google::protobuf::Message() {
  SharedCtor();
  // @@protoc_insertion_point(constructor:Messages.MessagePsiResult)
}

void MessagePsiResult::InitAsDefaultInstance() {
}

MessagePsiResult::MessagePsiResult(const MessagePsiResult& from)
  : ::google::protobuf::Message() {
  SharedCtor();
  MergeFrom(from);
  // @@protoc_insertion_point(copy_constructor:Messages.MessagePsiResult)
}

void MessagePsiResult::SharedCtor() {
  _cached_size_ = 0;
  type_ = 0u;
  size_ = 0u;
  context_ = 0u;
  id_ = 0u;
  state_ = 0u;
  ::memset(_has_bits_, 0, sizeof(_has_bits_));
}

MessagePsiResult::~MessagePsiResult() {
  // @@protoc_insertion_point(destructor:Messages.MessagePsiResult)
  SharedDtor();
}

void MessagePsiResult::SharedDtor() {
  if (this != default_instance_) {
  }
}

void MessagePsiResult::SetCachedSize(int size) const {
  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
  _cached_size_ = size;
  GOOGLE_SAFE_CONCURRENT_WRITES_END();
}
const ::google::protobuf::Descriptor* MessagePsiResult::descriptor() {
  protobuf_AssignDescriptorsOnce();
  return MessagePsiResult_descriptor_;
}

const MessagePsiResult& MessagePsiResult::default_instance() {
  if (default_instance_ == NULL) protobuf_AddDesc_Messages_2eproto();
  return *default_instance_;
}

MessagePsiResult* MessagePsiResult::default_instance_ = NULL;

MessagePsiResult* MessagePsiResult::New() const {
  return new MessagePsiResult;
}

void MessagePsiResult::Clear() {
#define OFFSET_OF_FIELD_(f) (reinterpret_cast<char*>(      \
  &reinterpret_cast<MessagePsiResult*>(16)->f) - \
   reinterpret_cast<char*>(16))

#define ZR_(first, last) do {                              \
    size_t f = OFFSET_OF_FIELD_(first);                    \
    size_t n = OFFSET_OF_FIELD_(last) - f + sizeof(last);  \
    ::memset(&first, 0, n);                                \
  } while (0)

  if (_has_bits_[0 / 32] & 31) {
    ZR_(type_, state_);
  }

#undef OFFSET_OF_FIELD_
#undef ZR_

  ::memset(_has_bits_, 0, sizeof(_has_bits_));
  mutable_unknown_fields()->Clear();
}

bool MessagePsiResult::MergePartialFromCodedStream(
    ::google::protobuf::io::CodedInputStream* input) {
#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
  ::google::protobuf::uint32 tag;
  // @@protoc_insertion_point(parse_start:Messages.MessagePsiResult)
  for (;;) {
    ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127);
    tag = p.first;
    if (!p.second) goto handle_unusual;
    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
      // required uint32 type = 1;
      case 1: {
        if (tag == 8) {
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
                 input, &type_)));
          set_has_type();
        } else {
          goto handle_unusual;
        }
        if (input->ExpectTag(16)) goto parse_size;
        break;
      }

      // required uint32 size = 2;
      case 2: {
        if (tag == 16) {
         parse_size:
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
                 input, &size_)));
          set_has_size();
        } else {
          goto handle_unusual;
        }
        if (input->ExpectTag(24)) goto parse_context;
        break;
      }

      // required uint32 context = 3;
      case 3: {
        if (tag == 24) {
         parse_context:
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
                 input, &context_)));
          set_has_context();
        } else {
          goto handle_unusual;
        }
        if (input->ExpectTag(32)) goto parse_id;
        break;
      }

      // required uint32 id = 4;
      case 4: {
        if (tag == 32) {
         parse_id:
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
                 input, &id_)));
          set_has_id();
        } else {
          goto handle_unusual;
        }
        if (input->ExpectTag(40)) goto parse_state;
        break;
      }

      // required uint32 state = 5;
      case 5: {
        if (tag == 40) {
         parse_state:
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
                 input, &state_)));
          set_has_state();
        } else {
          goto handle_unusual;
        }
        if (input->ExpectAtEnd()) goto success;
        break;
      }

      default: {
      handle_unusual:
        if (tag == 0 ||
            ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
            ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
          goto success;
        }
        DO_(::google::protobuf::internal::WireFormat::SkipField(
              input, tag, mutable_unknown_fields()));
        break;
      }
    }
  }
success:
  // @@protoc_insertion_point(parse_success:Messages.MessagePsiResult)
  return true;
failure:
  // @@protoc_insertion_point(parse_failure:Messages.MessagePsiResult)
  return false;
#undef DO_
}

void MessagePsiResult::SerializeWithCachedSizes(
    ::google::protobuf::io::CodedOutputStream* output) const {
  // @@protoc_insertion_point(serialize_start:Messages.MessagePsiResult)
  // required uint32 type = 1;
  if (has_type()) {
    ::google::protobuf::internal::WireFormatLite::WriteUInt32(1, this->type(), output);
  }

  // required uint32 size = 2;
  if (has_size()) {
    ::google::protobuf::internal::WireFormatLite::WriteUInt32(2, this->size(), output);
  }

  // required uint32 context = 3;
  if (has_context()) {
    ::google::protobuf::internal::WireFormatLite::WriteUInt32(3, this->context(), output);
  }

  // required uint32 id = 4;
  if (has_id()) {
    ::google::protobuf::internal::WireFormatLite::WriteUInt32(4, this->id(), output);
  }

  // required uint32 state = 5;
  if (has_state()) {
    ::google::protobuf::internal::WireFormatLite::WriteUInt32(5, this->state(), output);
  }

  if (!unknown_fields().empty()) {
    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
        unknown_fields(), output);
  }
  // @@protoc_insertion_point(serialize_end:Messages.MessagePsiResult)
}

::google::protobuf::uint8* MessagePsiResult::SerializeWithCachedSizesToArray(
    ::google::protobuf::uint8* target) const {
  // @@protoc_insertion_point(serialize_to_array_start:Messages.MessagePsiResult)
  // required uint32 type = 1;
  if (has_type()) {
    target = ::google::protobuf::internal::WireFormatLite::WriteUInt32ToArray(1, this->type(), target);
  }

  // required uint32 size = 2;
  if (has_size()) {
    target = ::google::protobuf::internal::WireFormatLite::WriteUInt32ToArray(2, this->size(), target);
  }

  // required uint32 context = 3;
  if (has_context()) {
    target = ::google::protobuf::internal::WireFormatLite::WriteUInt32ToArray(3, this->context(), target);
  }

  // required uint32 id = 4;
  if (has_id()) {
    target = ::google::protobuf::internal::WireFormatLite::WriteUInt32ToArray(4, this->id(), target);
  }

  // required uint32 state = 5;
  if (has_state()) {
    target = ::google::protobuf::internal::WireFormatLite::WriteUInt32ToArray(5, this->state(), target);
  }

  if (!unknown_fields().empty()) {
    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
        unknown_fields(), target);
  }
  // @@protoc_insertion_point(serialize_to_array_end:Messages.MessagePsiResult)
  return target;
}

int MessagePsiResult::ByteSize() const {
  int total_size = 0;

  if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    // required uint32 type = 1;
    if (has_type()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::UInt32Size(
          this->type());
    }

    // required uint32 size = 2;
    if (has_size()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::UInt32Size(
          this->size());
    }

    // required uint32 context = 3;
    if (has_context()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::UInt32Size(
          this->context());
    }

    // required uint32 id = 4;
    if (has_id()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::UInt32Size(
          this->id());
    }

    // required uint32 state = 5;
    if (has_state()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::UInt32Size(
          this->state());
    }

  }
  if (!unknown_fields().empty()) {
    total_size +=
      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
        unknown_fields());
  }
  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
  _cached_size_ = total_size;
  GOOGLE_SAFE_CONCURRENT_WRITES_END();
  return total_size;
}

void MessagePsiResult::MergeFrom(const ::google::protobuf::Message& from) {
  GOOGLE_CHECK_NE(&from, this);
  const MessagePsiResult* source =
    ::google::protobuf::internal::dynamic_cast_if_available<const MessagePsiResult*>(
      &from);
  if (source == NULL) {
    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
  } else {
    MergeFrom(*source);
  }
}

void MessagePsiResult::MergeFrom(const MessagePsiResult& from) {
  GOOGLE_CHECK_NE(&from, this);
  if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    if (from.has_type()) {
      set_type(from.type());
    }
    if (from.has_size()) {
      set_size(from.size());
    }
    if (from.has_context()) {
      set_context(from.context());
    }
    if (from.has_id()) {
      set_id(from.id());
    }
    if (from.has_state()) {
      set_state(from.state());
    }
  }
  mutable_unknown_fields()->MergeFrom(from.unknown_fields());
}

void MessagePsiResult::CopyFrom(const ::google::protobuf::Message& from) {
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

void MessagePsiResult::CopyFrom(const MessagePsiResult& from) {
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

bool MessagePsiResult::IsInitialized() const {
  if ((_has_bits_[0] & 0x0000001f) != 0x0000001f) return false;

  return true;
}

void MessagePsiResult::Swap(MessagePsiResult* other) {
  if (other != this) {
    std::swap(type_, other->type_);
    std::swap(size_, other->size_);
    std::swap(context_, other->context_);
    std::swap(id_, other->id_);
    std::swap(state_, other->state_);
    std::swap(_has_bits_[0], other->_has_bits_[0]);
    _unknown_fields_.Swap(&other->_unknown_fields_);
    std::swap(_cached_size_, other->_cached_size_);
  }
}

::google::protobuf::Metadata MessagePsiResult::GetMetadata() const {
  protobuf_AssignDescriptorsOnce();
  ::google::protobuf::Metadata metadata;
  metadata.descriptor = MessagePsiResult_descriptor_;
  metadata.reflection = MessagePsiResult_reflection_;
  return metadata;
}


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

#ifndef _MSC_VER
const int MessagePsiIntersect::kTypeFieldNumber;
const int MessagePsiIntersect::kSizeFieldNumber;
const int MessagePsiIntersect::kContextFieldNumber;
const int MessagePsiIntersect::kIdFieldNumber;
const int MessagePsiIntersect::kMacFieldNumber;
const int MessagePsiIntersect::kDataFieldNumber;
#endif  // !_MSC_VER

MessagePsiIntersect::MessagePsiIntersect()
  : ::google::protobuf::Message() {
  SharedCtor();
  // @@protoc_insertion_point(constructor:Messages.MessagePsiIntersect)
}

void MessagePsiIntersect::InitAsDefaultInstance() {
}

MessagePsiIntersect::MessagePsiIntersect(const MessagePsiIntersect& from)
  : ::google::protobuf::Message() {
  SharedCtor();
  MergeFrom(from);
  // @@protoc_insertion_point(copy_constructor:Messages.MessagePsiIntersect)
}

void MessagePsiIntersect::SharedCtor() {
  _cached_size_ = 0;
  type_ = 0u;
  size_ = 0u;
  context_ = 0u;
  id_ = 0u;
  ::memset(_has_bits_, 0, sizeof(_has_bits_));
}

MessagePsiIntersect::~MessagePsiIntersect() {
  // @@protoc_insertion_point(destructor:Messages.MessagePsiIntersect)
  SharedDtor();
}

void MessagePsiIntersect::SharedDtor() {
  if (this != default_instance_) {
  }
}

void MessagePsiIntersect::SetCachedSize(int size) const {
  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
  _cached_size_ = size;
  GOOGLE_SAFE_CONCURRENT_WRITES_END();
}
const ::google::protobuf::Descriptor* MessagePsiIntersect::descriptor() {
  protobuf_AssignDescriptorsOnce();
  return MessagePsiIntersect_descriptor_;
}

const MessagePsiIntersect& MessagePsiIntersect::default_instance() {
  if (default_instance_ == NULL) protobuf_AddDesc_Messages_2eproto();
  return *default_instance_;
}

MessagePsiIntersect* MessagePsiIntersect::default_instance_ = NULL;

MessagePsiIntersect* MessagePsiIntersect::New() const {
  return new MessagePsiIntersect;
}

void MessagePsiIntersect::Clear() {
#define OFFSET_OF_FIELD_(f) (reinterpret_cast<char*>(      \
  &reinterpret_cast<MessagePsiIntersect*>(16)->f) - \
   reinterpret_cast<char*>(16))

#define ZR_(first, last) do {                              \
    size_t f = OFFSET_OF_FIELD_(first);                    \
    size_t n = OFFSET_OF_FIELD_(last) - f + sizeof(last);  \
    ::memset(&first, 0, n);                                \
  } while (0)

  ZR_(type_, id_);

#undef OFFSET_OF_FIELD_
#undef ZR_

  mac_.Clear();
  data_.Clear();
  ::memset(_has_bits_, 0, sizeof(_has_bits_));
  mutable_unknown_fields()->Clear();
}

bool MessagePsiIntersect::MergePartialFromCodedStream(
    ::google::protobuf::io::CodedInputStream* input) {
#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
  ::google::protobuf::uint32 tag;
  // @@protoc_insertion_point(parse_start:Messages.MessagePsiIntersect)
  for (;;) {
    ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127);
    tag = p.first;
    if (!p.second) goto handle_unusual;
    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
      // required uint32 type = 1;
      case 1: {
        if (tag == 8) {
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
                 input, &type_)));
          set_has_type();
        } else {
          goto handle_unusual;
        }
        if (input->ExpectTag(16)) goto parse_size;
        break;
      }

      // required uint32 size = 2;
      case 2: {
        if (tag == 16) {
         parse_size:
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
                 input, &size_)));
          set_has_size();
        } else {
          goto handle_unusual;
        }
        if (input->ExpectTag(24)) goto parse_context;
        break;
      }

      // required uint32 context = 3;
      case 3: {
        if (tag == 24) {
         parse_context:
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
                 input, &context_)));
          set_has_context();
        } else {
          goto handle_unusual;
        }
        if (input->ExpectTag(32)) goto parse_id;
        break;
      }

      // required uint32 id = 4;
      case 4: {
        if (tag == 32) {
         parse_id:
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
                 input, &id_)));
          set_has_id();
        } else {
          goto handle_unusual;
        }
        if (input->ExpectTag(42)) goto parse_mac;
        break;
      }

      // repeated uint32 mac = 5 [packed = true];
      case 5: {
        if (tag == 42) {
         parse_mac:
          DO_((::google::protobuf::internal::WireFormatLite::ReadPackedPrimitive<
                   ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
                 input, this->mutable_mac())));
        } else if (tag == 40) {
          DO_((::google::protobuf::internal::WireFormatLite::ReadRepeatedPrimitiveNoInline<
                   ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
                 1, 42, input, this->mutable_mac())));
        } else {
          goto handle_unusual;
        }
        if (input->ExpectTag(50)) goto parse_data;
        break;
      }

      // repeated uint32 data = 6 [packed = true];
      case 6: {
        if (tag == 50) {
         parse_data:
          DO_((::google::protobuf::internal::WireFormatLite::ReadPackedPrimitive<
                   ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
                 input, this->mutable_data())));
        } else if (tag == 48) {
          DO_((::google::protobuf::internal::WireFormatLite::ReadRepeatedPrimitiveNoInline<
                   ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
                 1, 50, input, this->mutable_data())));
        } else {
          goto handle_unusual;
        }
        if (input->ExpectAtEnd()) goto success;
        break;
      }

      default: {
      handle_unusual:
        if (tag == 0 ||
            ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
            ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
          goto success;
        }
        DO_(::google::protobuf::internal::WireFormat::SkipField(
              input, tag, mutable_unknown_fields()));
        break;
      }
    }
  }
success:
  // @@protoc_insertion_point(parse_success:Messages.MessagePsiIntersect)
  return true;
failure:
  // @@protoc_insertion_point(parse_failure:Messages.MessagePsiIntersect)
  return false;
#undef DO_
}

void MessagePsiIntersect::SerializeWithCachedSizes(
    ::google::protobuf::io::CodedOutputStream* output) const {
  // @@protoc_insertion_point(serialize_start:Messages.MessagePsiIntersect)
  // required uint32 type = 1;
  if (has_type()) {
    ::google::protobuf::internal::WireFormatLite::WriteUInt32(1, this->type(), output);
  }

  // required uint32 size = 2;
  if (has_size()) {
    ::google::protobuf::internal::WireFormatLite::WriteUInt32(2, this->size(), output);
  }

  // required uint32 context = 3;
  if (has_context()) {
    ::google::protobuf::internal::WireFormatLite::WriteUInt32(3, this->context(), output);
  }

  // required uint32 id = 4;
  if (has_id()) {
    ::google::protobuf::internal::WireFormatLite::WriteUInt32(4, this->id(), output);
  }

  // repeated uint32 mac = 5 [packed = true];
  if (this->mac_size() > 0) {
    ::google::protobuf::internal::WireFormatLite::WriteTag(5, ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED, output);
    output->WriteVarint32(_mac_cached_byte_size_);
  }
  for (int i = 0; i < this->mac_size(); i++) {
    ::google::protobuf::internal::WireFormatLite::WriteUInt32NoTag(
      this->mac(i), output);
  }

  // repeated uint32 data = 6 [packed = true];
  if (this->data_size() > 0) {
    ::google::protobuf::internal::WireFormatLite::WriteTag(6, ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED, output);
    output->WriteVarint32(_data_cached_byte_size_);
  }
  for (int i = 0; i < this->data_size(); i++) {
    ::google::protobuf::internal::WireFormatLite::WriteUInt32NoTag(
      this->data(i), output);
  }

  if (!unknown_fields().empty()) {
    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
        unknown_fields(), output);
  }
  // @@protoc_insertion_point(serialize_end:Messages.MessagePsiIntersect)
}

::google::protobuf::uint8* MessagePsiIntersect::SerializeWithCachedSizesToArray(
    ::google::protobuf::uint8* target) const {
  // @@protoc_insertion_point(serialize_to_array_start:Messages.MessagePsiIntersect)
  // required uint32 type = 1;
  if (has_type()) {
    target = ::google::protobuf::internal::WireFormatLite::WriteUInt32ToArray(1, this->type(), target);
  }

  // required uint32 size = 2;
  if (has_size()) {
    target = ::google::protobuf::internal::WireFormatLite::WriteUInt32ToArray(2, this->size(), target);
  }

  // required uint32 context = 3;
  if (has_context()) {
    target = ::google::protobuf::internal::WireFormatLite::WriteUInt32ToArray(3, this->context(), target);
  }

  // required uint32 id = 4;
  if (has_id()) {
    target = ::google::protobuf::internal::WireFormatLite::WriteUInt32ToArray(4, this->id(), target);
  }

  // repeated uint32 mac = 5 [packed = true];
  if (this->mac_size() > 0) {
    target = ::google::protobuf::internal::WireFormatLite::WriteTagToArray(
      5,
      ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED,
      target);
    target = ::google::protobuf::io::CodedOutputStream::WriteVarint32ToArray(
      _mac_cached_byte_size_, target);
  }
  for (int i = 0; i < this->mac_size(); i++) {
    target = ::google::protobuf::internal::WireFormatLite::
      WriteUInt32NoTagToArray(this->mac(i), target);
  }

  // repeated uint32 data = 6 [packed = true];
  if (this->data_size() > 0) {
    target = ::google::protobuf::internal::WireFormatLite::WriteTagToArray(
      6,
      ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED,
      target);
    target = ::google::protobuf::io::CodedOutputStream::WriteVarint32ToArray(
      _data_cached_byte_size_, target);
  }
  for (int i = 0; i < this->data_size(); i++) {
    target = ::google::protobuf::internal::WireFormatLite::
      WriteUInt32NoTagToArray(this->data(i), target);
  }

  if (!unknown_fields().empty()) {
    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
        unknown_fields(), target);
  }
  // @@protoc_insertion_point(serialize_to_array_end:Messages.MessagePsiIntersect)
  return target;
}

int MessagePsiIntersect::ByteSize() const {
  int total_size = 0;

  if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    // required uint32 type = 1;
    if (has_type()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::UInt32Size(
          this->type());
    }

    // required uint32 size = 2;
    if (has_size()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::UInt32Size(
          this->size());
    }

    // required uint32 context = 3;
    if (has_context()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::UInt32Size(
          this->context());
    }

    // required uint32 id = 4;
    if (has_id()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::UInt32Size(
          this->id());
    }

  }
  // repeated uint32 mac = 5 [packed = true];
  {
    int data_size = 0;
    for (int i = 0; i < this->mac_size(); i++) {
      data_size += ::google::protobuf::internal::WireFormatLite::
        UInt32Size(this->mac(i));
    }
    if (data_size > 0) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::Int32Size(data_size);
    }
    GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
    _mac_cached_byte_size_ = data_size;
    GOOGLE_SAFE_CONCURRENT_WRITES_END();
    total_size += data_size;
  }

  // repeated uint32 data = 6 [packed = true];
  {
    int data_size = 0;
    for (int i = 0; i < this->data_size(); i++) {
      data_size += ::google::protobuf::internal::WireFormatLite::
        UInt32Size(this->data(i));
    }
    if (data_size > 0) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::Int32Size(data_size);
    }
    GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
    _data_cached_byte_size_ = data_size;
    GOOGLE_SAFE_CONCURRENT_WRITES_END();
    total_size += data_size;
  }

  if (!unknown_fields().empty()) {
    total_size +=
      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
        unknown_fields());
  }
  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
  _cached_size_ = total_size;
  GOOGLE_SAFE_CONCURRENT_WRITES_END();
  return total_size;
}

void MessagePsiIntersect::MergeFrom(const ::google::protobuf::Message& from) {
  GOOGLE_CHECK_NE(&from, this);
  const MessagePsiIntersect* source =
    ::google::protobuf::internal::dynamic_cast_if_available<const MessagePsiIntersect*>(
      &from);
  if (source == NULL) {
    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
  } else {
    MergeFrom(*source);
  }
}

void MessagePsiIntersect::MergeFrom(const MessagePsiIntersect& from) {
  GOOGLE_CHECK_NE(&from, this);
  mac_.MergeFrom(from.mac_);
  data_.MergeFrom(from.data_);
  if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    if (from.has_type()) {
      set_type(from.type());
    }
    if (from.has_size()) {
      set_size(from.size());
    }
    if (from.has_context()) {
      set_context(from.context());
    }
    if (from.has_id()) {
      set_id(from.id());
    }
  }
  mutable_unknown_fields()->MergeFrom(from.unknown_fields());
}

void MessagePsiIntersect::CopyFrom(const ::google::protobuf::Message& from) {
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

void MessagePsiIntersect::CopyFrom(const MessagePsiIntersect& from) {
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

bool MessagePsiIntersect::IsInitialized() const {
  if ((_has_bits_[0] & 0x0000000f) != 0x0000000f) return false;

  return true;
}

void MessagePsiIntersect::Swap(MessagePsiIntersect* other) {
  if (other != this) {
    std::swap(type_, other->type_);
    std::swap(size_, other->size_);
    std::swap(context_, other->context_);
    std::swap(id_, other->id_);
    mac_.Swap(&other->mac_);
    data_.Swap(&other->data_);
    std::swap(_has_bits_[0], other->_has_bits_[0]);
    _unknown_fields_.Swap(&other->_unknown_fields_);
    std::swap(_cached_size_, other->_cached_size_);
  }
}

::google::protobuf::Metadata MessagePsiIntersect::GetMetadata() const {
  protobuf_AssignDescriptorsOnce();
  ::google::protobuf::Metadata metadata;
  metadata.descriptor = MessagePsiIntersect_descriptor_;
  metadata.reflection = MessagePsiIntersect_reflection_;
  return metadata;
}


// @@protoc_insertion_point(namespace_scope)

}  // namespace Messages

// @@protoc_insertion_point(global_scope)
