// 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/port.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;

}  // namespace


void protobuf_AssignDesc_Messages_2eproto() GOOGLE_ATTRIBUTE_COLD;
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_ =
    ::google::protobuf::internal::GeneratedMessageReflection::NewGeneratedMessageReflection(
      InitialMessage_descriptor_,
      InitialMessage::default_instance_,
      InitialMessage_offsets_,
      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(InitialMessage, _has_bits_[0]),
      -1,
      -1,
      sizeof(InitialMessage),
      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(InitialMessage, _internal_metadata_),
      -1);
  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_ =
    ::google::protobuf::internal::GeneratedMessageReflection::NewGeneratedMessageReflection(
      MessageMsg0_descriptor_,
      MessageMsg0::default_instance_,
      MessageMsg0_offsets_,
      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessageMsg0, _has_bits_[0]),
      -1,
      -1,
      sizeof(MessageMsg0),
      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessageMsg0, _internal_metadata_),
      -1);
  MessageMSG1_descriptor_ = file->message_type(2);
  static const int MessageMSG1_offsets_[4] = {
    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessageMSG1, type_),
    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_ =
    ::google::protobuf::internal::GeneratedMessageReflection::NewGeneratedMessageReflection(
      MessageMSG1_descriptor_,
      MessageMSG1::default_instance_,
      MessageMSG1_offsets_,
      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessageMSG1, _has_bits_[0]),
      -1,
      -1,
      sizeof(MessageMSG1),
      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessageMSG1, _internal_metadata_),
      -1);
  MessageMSG2_descriptor_ = file->message_type(3);
  static const int MessageMSG2_offsets_[12] = {
    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessageMSG2, type_),
    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessageMSG2, size_),
    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_ =
    ::google::protobuf::internal::GeneratedMessageReflection::NewGeneratedMessageReflection(
      MessageMSG2_descriptor_,
      MessageMSG2::default_instance_,
      MessageMSG2_offsets_,
      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessageMSG2, _has_bits_[0]),
      -1,
      -1,
      sizeof(MessageMSG2),
      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessageMSG2, _internal_metadata_),
      -1);
  MessageMSG3_descriptor_ = file->message_type(4);
  static const int MessageMSG3_offsets_[7] = {
    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessageMSG3, type_),
    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessageMSG3, size_),
    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_ =
    ::google::protobuf::internal::GeneratedMessageReflection::NewGeneratedMessageReflection(
      MessageMSG3_descriptor_,
      MessageMSG3::default_instance_,
      MessageMSG3_offsets_,
      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessageMSG3, _has_bits_[0]),
      -1,
      -1,
      sizeof(MessageMSG3),
      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessageMSG3, _internal_metadata_),
      -1);
  AttestationMessage_descriptor_ = file->message_type(5);
  static const int AttestationMessage_offsets_[16] = {
    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(AttestationMessage, type_),
    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(AttestationMessage, size_),
    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_ =
    ::google::protobuf::internal::GeneratedMessageReflection::NewGeneratedMessageReflection(
      AttestationMessage_descriptor_,
      AttestationMessage::default_instance_,
      AttestationMessage_offsets_,
      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(AttestationMessage, _has_bits_[0]),
      -1,
      -1,
      sizeof(AttestationMessage),
      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(AttestationMessage, _internal_metadata_),
      -1);
}

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&) GOOGLE_ATTRIBUTE_COLD;
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());
}

}  // 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_;
}

void protobuf_AddDesc_Messages_2eproto() GOOGLE_ATTRIBUTE_COLD;
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\n\013MessageMSG1\022\014\n\004type\030\001 \002(\r"
    "\022\017\n\003GaX\030\002 \003(\rB\002\020\001\022\017\n\003GaY\030\003 \003(\rB\002\020\001\022\017\n\003GI"
    "D\030\004 \003(\rB\002\020\001\"\205\002\n\013MessageMSG2\022\014\n\004type\030\001 \002("
    "\r\022\014\n\004size\030\002 \001(\r\022\031\n\rpublic_key_gx\030\003 \003(\rB\002"
    "\020\001\022\031\n\rpublic_key_gy\030\004 \003(\rB\002\020\001\022\022\n\nquote_t"
    "ype\030\005 \001(\r\022\020\n\004spid\030\006 \003(\rB\002\020\001\022\023\n\013cmac_kdf_"
    "id\030\007 \001(\r\022\027\n\013signature_x\030\010 \003(\rB\002\020\001\022\027\n\013sig"
    "nature_y\030\t \003(\rB\002\020\001\022\020\n\004smac\030\n \003(\rB\002\020\001\022\022\n\n"
    "size_sigrl\030\013 \001(\r\022\021\n\005sigrl\030\014 \003(\rB\002\020\001\"\227\001\n\013"
    "MessageMSG3\022\014\n\004type\030\001 \002(\r\022\014\n\004size\030\002 \001(\r\022"
    "\023\n\007sgx_mac\030\003 \003(\rB\002\020\001\022\024\n\010gax_msg3\030\004 \003(\rB\002"
    "\020\001\022\024\n\010gay_msg3\030\005 \003(\rB\002\020\001\022\030\n\014sec_property"
    "\030\006 \003(\rB\002\020\001\022\021\n\005quote\030\007 \003(\rB\002\020\001\"\262\003\n\022Attest"
    "ationMessage\022\014\n\004type\030\001 \002(\r\022\014\n\004size\030\002 \002(\r"
    "\022\031\n\021epid_group_status\030\003 \001(\r\022\035\n\025tcb_evalu"
    "ation_status\030\004 \001(\r\022\035\n\025pse_evaluation_sta"
    "tus\030\005 \001(\r\022&\n\032latest_equivalent_tcb_psvn\030"
    "\006 \003(\rB\002\020\001\022\035\n\021latest_pse_isvsvn\030\007 \003(\rB\002\020\001"
    "\022\033\n\017latest_psda_svn\030\010 \003(\rB\002\020\001\022!\n\025perform"
    "ance_rekey_gid\030\t \003(\rB\002\020\001\022\030\n\014ec_sign256_x"
    "\030\n \003(\rB\002\020\001\022\030\n\014ec_sign256_y\030\013 \003(\rB\002\020\001\022\023\n\007"
    "mac_smk\030\014 \003(\rB\002\020\001\022\023\n\013result_size\030\r \001(\r\022\024"
    "\n\010reserved\030\016 \003(\rB\002\020\001\022\027\n\013payload_tag\030\017 \003("
    "\rB\002\020\001\022\023\n\007payload\030\020 \003(\rB\002\020\001", 1066);
  ::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();
  InitialMessage::default_instance_->InitAsDefaultInstance();
  MessageMsg0::default_instance_->InitAsDefaultInstance();
  MessageMSG1::default_instance_->InitAsDefaultInstance();
  MessageMSG2::default_instance_->InitAsDefaultInstance();
  MessageMSG3::default_instance_->InitAsDefaultInstance();
  AttestationMessage::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_;

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

#if !defined(_MSC_VER) || _MSC_VER >= 1900
const int InitialMessage::kTypeFieldNumber;
const int InitialMessage::kSizeFieldNumber;
#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900

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

void InitialMessage::InitAsDefaultInstance() {
}

InitialMessage::InitialMessage(const InitialMessage& from)
  : ::google::protobuf::Message(),
    _internal_metadata_(NULL) {
  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(::google::protobuf::Arena* arena) const {
  InitialMessage* n = new InitialMessage;
  if (arena != NULL) {
    arena->Own(n);
  }
  return n;
}

void InitialMessage::Clear() {
// @@protoc_insertion_point(message_clear_start:Messages.InitialMessage)
#if defined(__clang__)
#define ZR_HELPER_(f) \
  _Pragma("clang diagnostic push") \
  _Pragma("clang diagnostic ignored \"-Winvalid-offsetof\"") \
  __builtin_offsetof(InitialMessage, f) \
  _Pragma("clang diagnostic pop")
#else
#define ZR_HELPER_(f) reinterpret_cast<char*>(\
  &reinterpret_cast<InitialMessage*>(16)->f)
#endif

#define ZR_(first, last) do {\
  ::memset(&first, 0,\
           ZR_HELPER_(last) - ZR_HELPER_(first) + sizeof(last));\
} while (0)

  ZR_(type_, size_);

#undef ZR_HELPER_
#undef ZR_

  ::memset(_has_bits_, 0, sizeof(_has_bits_));
  if (_internal_metadata_.have_unknown_fields()) {
    mutable_unknown_fields()->Clear();
  }
}

bool InitialMessage::MergePartialFromCodedStream(
    ::google::protobuf::io::CodedInputStream* input) {
#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(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 (_internal_metadata_.have_unknown_fields()) {
    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
        unknown_fields(), output);
  }
  // @@protoc_insertion_point(serialize_end:Messages.InitialMessage)
}

::google::protobuf::uint8* InitialMessage::InternalSerializeWithCachedSizesToArray(
    bool deterministic, ::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 (_internal_metadata_.have_unknown_fields()) {
    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
        unknown_fields(), target);
  }
  // @@protoc_insertion_point(serialize_to_array_end:Messages.InitialMessage)
  return target;
}

int InitialMessage::ByteSize() const {
// @@protoc_insertion_point(message_byte_size_start:Messages.InitialMessage)
  int total_size = 0;

  // 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 (_internal_metadata_.have_unknown_fields()) {
    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) {
// @@protoc_insertion_point(generalized_merge_from_start:Messages.InitialMessage)
  if (GOOGLE_PREDICT_FALSE(&from == this)) {
    ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
  }
  const InitialMessage* source = 
      ::google::protobuf::internal::DynamicCastToGenerated<const InitialMessage>(
          &from);
  if (source == NULL) {
  // @@protoc_insertion_point(generalized_merge_from_cast_fail:Messages.InitialMessage)
    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
  } else {
  // @@protoc_insertion_point(generalized_merge_from_cast_success:Messages.InitialMessage)
    MergeFrom(*source);
  }
}

void InitialMessage::MergeFrom(const InitialMessage& from) {
// @@protoc_insertion_point(class_specific_merge_from_start:Messages.InitialMessage)
  if (GOOGLE_PREDICT_FALSE(&from == this)) {
    ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
  }
  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._internal_metadata_.have_unknown_fields()) {
    mutable_unknown_fields()->MergeFrom(from.unknown_fields());
  }
}

void InitialMessage::CopyFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_copy_from_start:Messages.InitialMessage)
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

void InitialMessage::CopyFrom(const InitialMessage& from) {
// @@protoc_insertion_point(class_specific_copy_from_start:Messages.InitialMessage)
  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) return;
  InternalSwap(other);
}
void InitialMessage::InternalSwap(InitialMessage* other) {
  std::swap(type_, other->type_);
  std::swap(size_, other->size_);
  std::swap(_has_bits_[0], other->_has_bits_[0]);
  _internal_metadata_.Swap(&other->_internal_metadata_);
  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;
}

#if PROTOBUF_INLINE_NOT_IN_HEADERS
// InitialMessage

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

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

#endif  // PROTOBUF_INLINE_NOT_IN_HEADERS

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

#if !defined(_MSC_VER) || _MSC_VER >= 1900
const int MessageMsg0::kTypeFieldNumber;
const int MessageMsg0::kEpidFieldNumber;
const int MessageMsg0::kStatusFieldNumber;
#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900

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

void MessageMsg0::InitAsDefaultInstance() {
}

MessageMsg0::MessageMsg0(const MessageMsg0& from)
  : ::google::protobuf::Message(),
    _internal_metadata_(NULL) {
  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(::google::protobuf::Arena* arena) const {
  MessageMsg0* n = new MessageMsg0;
  if (arena != NULL) {
    arena->Own(n);
  }
  return n;
}

void MessageMsg0::Clear() {
// @@protoc_insertion_point(message_clear_start:Messages.MessageMsg0)
#if defined(__clang__)
#define ZR_HELPER_(f) \
  _Pragma("clang diagnostic push") \
  _Pragma("clang diagnostic ignored \"-Winvalid-offsetof\"") \
  __builtin_offsetof(MessageMsg0, f) \
  _Pragma("clang diagnostic pop")
#else
#define ZR_HELPER_(f) reinterpret_cast<char*>(\
  &reinterpret_cast<MessageMsg0*>(16)->f)
#endif

#define ZR_(first, last) do {\
  ::memset(&first, 0,\
           ZR_HELPER_(last) - ZR_HELPER_(first) + sizeof(last));\
} while (0)

  ZR_(type_, status_);

#undef ZR_HELPER_
#undef ZR_

  ::memset(_has_bits_, 0, sizeof(_has_bits_));
  if (_internal_metadata_.have_unknown_fields()) {
    mutable_unknown_fields()->Clear();
  }
}

bool MessageMsg0::MergePartialFromCodedStream(
    ::google::protobuf::io::CodedInputStream* input) {
#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(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 (_internal_metadata_.have_unknown_fields()) {
    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
        unknown_fields(), output);
  }
  // @@protoc_insertion_point(serialize_end:Messages.MessageMsg0)
}

::google::protobuf::uint8* MessageMsg0::InternalSerializeWithCachedSizesToArray(
    bool deterministic, ::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 (_internal_metadata_.have_unknown_fields()) {
    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
        unknown_fields(), target);
  }
  // @@protoc_insertion_point(serialize_to_array_end:Messages.MessageMsg0)
  return target;
}

int MessageMsg0::RequiredFieldsByteSizeFallback() const {
// @@protoc_insertion_point(required_fields_byte_size_fallback_start:Messages.MessageMsg0)
  int total_size = 0;

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

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

  return total_size;
}
int MessageMsg0::ByteSize() const {
// @@protoc_insertion_point(message_byte_size_start:Messages.MessageMsg0)
  int total_size = 0;

  if (((_has_bits_[0] & 0x00000003) ^ 0x00000003) == 0) {  // All required fields are present.
    // required uint32 type = 1;
    total_size += 1 +
      ::google::protobuf::internal::WireFormatLite::UInt32Size(
        this->type());

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

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

  if (_internal_metadata_.have_unknown_fields()) {
    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) {
// @@protoc_insertion_point(generalized_merge_from_start:Messages.MessageMsg0)
  if (GOOGLE_PREDICT_FALSE(&from == this)) {
    ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
  }
  const MessageMsg0* source = 
      ::google::protobuf::internal::DynamicCastToGenerated<const MessageMsg0>(
          &from);
  if (source == NULL) {
  // @@protoc_insertion_point(generalized_merge_from_cast_fail:Messages.MessageMsg0)
    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
  } else {
  // @@protoc_insertion_point(generalized_merge_from_cast_success:Messages.MessageMsg0)
    MergeFrom(*source);
  }
}

void MessageMsg0::MergeFrom(const MessageMsg0& from) {
// @@protoc_insertion_point(class_specific_merge_from_start:Messages.MessageMsg0)
  if (GOOGLE_PREDICT_FALSE(&from == this)) {
    ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
  }
  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());
    }
  }
  if (from._internal_metadata_.have_unknown_fields()) {
    mutable_unknown_fields()->MergeFrom(from.unknown_fields());
  }
}

void MessageMsg0::CopyFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_copy_from_start:Messages.MessageMsg0)
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

void MessageMsg0::CopyFrom(const MessageMsg0& from) {
// @@protoc_insertion_point(class_specific_copy_from_start:Messages.MessageMsg0)
  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) return;
  InternalSwap(other);
}
void MessageMsg0::InternalSwap(MessageMsg0* other) {
  std::swap(type_, other->type_);
  std::swap(epid_, other->epid_);
  std::swap(status_, other->status_);
  std::swap(_has_bits_[0], other->_has_bits_[0]);
  _internal_metadata_.Swap(&other->_internal_metadata_);
  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;
}

#if PROTOBUF_INLINE_NOT_IN_HEADERS
// MessageMsg0

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

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

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

#endif  // PROTOBUF_INLINE_NOT_IN_HEADERS

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

#if !defined(_MSC_VER) || _MSC_VER >= 1900
const int MessageMSG1::kTypeFieldNumber;
const int MessageMSG1::kGaXFieldNumber;
const int MessageMSG1::kGaYFieldNumber;
const int MessageMSG1::kGIDFieldNumber;
#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900

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

void MessageMSG1::InitAsDefaultInstance() {
}

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

void MessageMSG1::SharedCtor() {
  _cached_size_ = 0;
  type_ = 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(::google::protobuf::Arena* arena) const {
  MessageMSG1* n = new MessageMSG1;
  if (arena != NULL) {
    arena->Own(n);
  }
  return n;
}

void MessageMSG1::Clear() {
// @@protoc_insertion_point(message_clear_start:Messages.MessageMSG1)
  type_ = 0u;
  gax_.Clear();
  gay_.Clear();
  gid_.Clear();
  ::memset(_has_bits_, 0, sizeof(_has_bits_));
  if (_internal_metadata_.have_unknown_fields()) {
    mutable_unknown_fields()->Clear();
  }
}

bool MessageMSG1::MergePartialFromCodedStream(
    ::google::protobuf::io::CodedInputStream* input) {
#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(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(18)) goto parse_GaX;
        break;
      }

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

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

      // repeated uint32 GID = 4 [packed = true];
      case 4: {
        if (tag == 34) {
         parse_GID:
          DO_((::google::protobuf::internal::WireFormatLite::ReadPackedPrimitive<
                   ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
                 input, this->mutable_gid())));
        } else if (tag == 32) {
          DO_((::google::protobuf::internal::WireFormatLite::ReadRepeatedPrimitiveNoInline<
                   ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
                 1, 34, 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);
  }

  // repeated uint32 GaX = 2 [packed = true];
  if (this->gax_size() > 0) {
    ::google::protobuf::internal::WireFormatLite::WriteTag(2, ::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 = 3 [packed = true];
  if (this->gay_size() > 0) {
    ::google::protobuf::internal::WireFormatLite::WriteTag(3, ::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 = 4 [packed = true];
  if (this->gid_size() > 0) {
    ::google::protobuf::internal::WireFormatLite::WriteTag(4, ::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 (_internal_metadata_.have_unknown_fields()) {
    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
        unknown_fields(), output);
  }
  // @@protoc_insertion_point(serialize_end:Messages.MessageMSG1)
}

::google::protobuf::uint8* MessageMSG1::InternalSerializeWithCachedSizesToArray(
    bool deterministic, ::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);
  }

  // repeated uint32 GaX = 2 [packed = true];
  if (this->gax_size() > 0) {
    target = ::google::protobuf::internal::WireFormatLite::WriteTagToArray(
      2,
      ::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 = 3 [packed = true];
  if (this->gay_size() > 0) {
    target = ::google::protobuf::internal::WireFormatLite::WriteTagToArray(
      3,
      ::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 = 4 [packed = true];
  if (this->gid_size() > 0) {
    target = ::google::protobuf::internal::WireFormatLite::WriteTagToArray(
      4,
      ::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 (_internal_metadata_.have_unknown_fields()) {
    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
        unknown_fields(), target);
  }
  // @@protoc_insertion_point(serialize_to_array_end:Messages.MessageMSG1)
  return target;
}

int MessageMSG1::ByteSize() const {
// @@protoc_insertion_point(message_byte_size_start:Messages.MessageMSG1)
  int total_size = 0;

  // required uint32 type = 1;
  if (has_type()) {
    total_size += 1 +
      ::google::protobuf::internal::WireFormatLite::UInt32Size(
        this->type());
  }
  // repeated uint32 GaX = 2 [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 = 3 [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 = 4 [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 (_internal_metadata_.have_unknown_fields()) {
    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) {
// @@protoc_insertion_point(generalized_merge_from_start:Messages.MessageMSG1)
  if (GOOGLE_PREDICT_FALSE(&from == this)) {
    ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
  }
  const MessageMSG1* source = 
      ::google::protobuf::internal::DynamicCastToGenerated<const MessageMSG1>(
          &from);
  if (source == NULL) {
  // @@protoc_insertion_point(generalized_merge_from_cast_fail:Messages.MessageMSG1)
    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
  } else {
  // @@protoc_insertion_point(generalized_merge_from_cast_success:Messages.MessageMSG1)
    MergeFrom(*source);
  }
}

void MessageMSG1::MergeFrom(const MessageMSG1& from) {
// @@protoc_insertion_point(class_specific_merge_from_start:Messages.MessageMSG1)
  if (GOOGLE_PREDICT_FALSE(&from == this)) {
    ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
  }
  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._internal_metadata_.have_unknown_fields()) {
    mutable_unknown_fields()->MergeFrom(from.unknown_fields());
  }
}

void MessageMSG1::CopyFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_copy_from_start:Messages.MessageMSG1)
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

void MessageMSG1::CopyFrom(const MessageMSG1& from) {
// @@protoc_insertion_point(class_specific_copy_from_start:Messages.MessageMSG1)
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

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

  return true;
}

void MessageMSG1::Swap(MessageMSG1* other) {
  if (other == this) return;
  InternalSwap(other);
}
void MessageMSG1::InternalSwap(MessageMSG1* other) {
  std::swap(type_, other->type_);
  gax_.UnsafeArenaSwap(&other->gax_);
  gay_.UnsafeArenaSwap(&other->gay_);
  gid_.UnsafeArenaSwap(&other->gid_);
  std::swap(_has_bits_[0], other->_has_bits_[0]);
  _internal_metadata_.Swap(&other->_internal_metadata_);
  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;
}

#if PROTOBUF_INLINE_NOT_IN_HEADERS
// MessageMSG1

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

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

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

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

#endif  // PROTOBUF_INLINE_NOT_IN_HEADERS

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

#if !defined(_MSC_VER) || _MSC_VER >= 1900
const int MessageMSG2::kTypeFieldNumber;
const int MessageMSG2::kSizeFieldNumber;
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  // !defined(_MSC_VER) || _MSC_VER >= 1900

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

void MessageMSG2::InitAsDefaultInstance() {
}

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

void MessageMSG2::SharedCtor() {
  _cached_size_ = 0;
  type_ = 0u;
  size_ = 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(::google::protobuf::Arena* arena) const {
  MessageMSG2* n = new MessageMSG2;
  if (arena != NULL) {
    arena->Own(n);
  }
  return n;
}

void MessageMSG2::Clear() {
// @@protoc_insertion_point(message_clear_start:Messages.MessageMSG2)
#if defined(__clang__)
#define ZR_HELPER_(f) \
  _Pragma("clang diagnostic push") \
  _Pragma("clang diagnostic ignored \"-Winvalid-offsetof\"") \
  __builtin_offsetof(MessageMSG2, f) \
  _Pragma("clang diagnostic pop")
#else
#define ZR_HELPER_(f) reinterpret_cast<char*>(\
  &reinterpret_cast<MessageMSG2*>(16)->f)
#endif

#define ZR_(first, last) do {\
  ::memset(&first, 0,\
           ZR_HELPER_(last) - ZR_HELPER_(first) + sizeof(last));\
} while (0)

  ZR_(type_, size_);
  ZR_(quote_type_, cmac_kdf_id_);
  size_sigrl_ = 0u;

#undef ZR_HELPER_
#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_));
  if (_internal_metadata_.have_unknown_fields()) {
    mutable_unknown_fields()->Clear();
  }
}

bool MessageMSG2::MergePartialFromCodedStream(
    ::google::protobuf::io::CodedInputStream* input) {
#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(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(26)) goto parse_public_key_gx;
        break;
      }

      // repeated uint32 public_key_gx = 3 [packed = true];
      case 3: {
        if (tag == 26) {
         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 == 24) {
          DO_((::google::protobuf::internal::WireFormatLite::ReadRepeatedPrimitiveNoInline<
                   ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
                 1, 26, input, this->mutable_public_key_gx())));
        } else {
          goto handle_unusual;
        }
        if (input->ExpectTag(34)) goto parse_public_key_gy;
        break;
      }

      // repeated uint32 public_key_gy = 4 [packed = true];
      case 4: {
        if (tag == 34) {
         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 == 32) {
          DO_((::google::protobuf::internal::WireFormatLite::ReadRepeatedPrimitiveNoInline<
                   ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
                 1, 34, input, this->mutable_public_key_gy())));
        } else {
          goto handle_unusual;
        }
        if (input->ExpectTag(40)) goto parse_quote_type;
        break;
      }

      // optional uint32 quote_type = 5;
      case 5: {
        if (tag == 40) {
         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(50)) goto parse_spid;
        break;
      }

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

      // optional uint32 cmac_kdf_id = 7;
      case 7: {
        if (tag == 56) {
         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(66)) goto parse_signature_x;
        break;
      }

      // repeated uint32 signature_x = 8 [packed = true];
      case 8: {
        if (tag == 66) {
         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 == 64) {
          DO_((::google::protobuf::internal::WireFormatLite::ReadRepeatedPrimitiveNoInline<
                   ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
                 1, 66, input, this->mutable_signature_x())));
        } else {
          goto handle_unusual;
        }
        if (input->ExpectTag(74)) goto parse_signature_y;
        break;
      }

      // repeated uint32 signature_y = 9 [packed = true];
      case 9: {
        if (tag == 74) {
         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 == 72) {
          DO_((::google::protobuf::internal::WireFormatLite::ReadRepeatedPrimitiveNoInline<
                   ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
                 1, 74, input, this->mutable_signature_y())));
        } else {
          goto handle_unusual;
        }
        if (input->ExpectTag(82)) goto parse_smac;
        break;
      }

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

      // optional uint32 size_sigrl = 11;
      case 11: {
        if (tag == 88) {
         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(98)) goto parse_sigrl;
        break;
      }

      // repeated uint32 sigrl = 12 [packed = true];
      case 12: {
        if (tag == 98) {
         parse_sigrl:
          DO_((::google::protobuf::internal::WireFormatLite::ReadPackedPrimitive<
                   ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
                 input, this->mutable_sigrl())));
        } else if (tag == 96) {
          DO_((::google::protobuf::internal::WireFormatLite::ReadRepeatedPrimitiveNoInline<
                   ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
                 1, 98, 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);
  }

  // repeated uint32 public_key_gx = 3 [packed = true];
  if (this->public_key_gx_size() > 0) {
    ::google::protobuf::internal::WireFormatLite::WriteTag(3, ::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 = 4 [packed = true];
  if (this->public_key_gy_size() > 0) {
    ::google::protobuf::internal::WireFormatLite::WriteTag(4, ::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 = 5;
  if (has_quote_type()) {
    ::google::protobuf::internal::WireFormatLite::WriteUInt32(5, this->quote_type(), output);
  }

  // repeated uint32 spid = 6 [packed = true];
  if (this->spid_size() > 0) {
    ::google::protobuf::internal::WireFormatLite::WriteTag(6, ::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 = 7;
  if (has_cmac_kdf_id()) {
    ::google::protobuf::internal::WireFormatLite::WriteUInt32(7, this->cmac_kdf_id(), output);
  }

  // repeated uint32 signature_x = 8 [packed = true];
  if (this->signature_x_size() > 0) {
    ::google::protobuf::internal::WireFormatLite::WriteTag(8, ::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 = 9 [packed = true];
  if (this->signature_y_size() > 0) {
    ::google::protobuf::internal::WireFormatLite::WriteTag(9, ::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 = 10 [packed = true];
  if (this->smac_size() > 0) {
    ::google::protobuf::internal::WireFormatLite::WriteTag(10, ::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 = 11;
  if (has_size_sigrl()) {
    ::google::protobuf::internal::WireFormatLite::WriteUInt32(11, this->size_sigrl(), output);
  }

  // repeated uint32 sigrl = 12 [packed = true];
  if (this->sigrl_size() > 0) {
    ::google::protobuf::internal::WireFormatLite::WriteTag(12, ::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 (_internal_metadata_.have_unknown_fields()) {
    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
        unknown_fields(), output);
  }
  // @@protoc_insertion_point(serialize_end:Messages.MessageMSG2)
}

::google::protobuf::uint8* MessageMSG2::InternalSerializeWithCachedSizesToArray(
    bool deterministic, ::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);
  }

  // repeated uint32 public_key_gx = 3 [packed = true];
  if (this->public_key_gx_size() > 0) {
    target = ::google::protobuf::internal::WireFormatLite::WriteTagToArray(
      3,
      ::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 = 4 [packed = true];
  if (this->public_key_gy_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_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 = 5;
  if (has_quote_type()) {
    target = ::google::protobuf::internal::WireFormatLite::WriteUInt32ToArray(5, this->quote_type(), target);
  }

  // repeated uint32 spid = 6 [packed = true];
  if (this->spid_size() > 0) {
    target = ::google::protobuf::internal::WireFormatLite::WriteTagToArray(
      6,
      ::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 = 7;
  if (has_cmac_kdf_id()) {
    target = ::google::protobuf::internal::WireFormatLite::WriteUInt32ToArray(7, this->cmac_kdf_id(), target);
  }

  // repeated uint32 signature_x = 8 [packed = true];
  if (this->signature_x_size() > 0) {
    target = ::google::protobuf::internal::WireFormatLite::WriteTagToArray(
      8,
      ::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 = 9 [packed = true];
  if (this->signature_y_size() > 0) {
    target = ::google::protobuf::internal::WireFormatLite::WriteTagToArray(
      9,
      ::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 = 10 [packed = true];
  if (this->smac_size() > 0) {
    target = ::google::protobuf::internal::WireFormatLite::WriteTagToArray(
      10,
      ::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 = 11;
  if (has_size_sigrl()) {
    target = ::google::protobuf::internal::WireFormatLite::WriteUInt32ToArray(11, this->size_sigrl(), target);
  }

  // repeated uint32 sigrl = 12 [packed = true];
  if (this->sigrl_size() > 0) {
    target = ::google::protobuf::internal::WireFormatLite::WriteTagToArray(
      12,
      ::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 (_internal_metadata_.have_unknown_fields()) {
    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
        unknown_fields(), target);
  }
  // @@protoc_insertion_point(serialize_to_array_end:Messages.MessageMSG2)
  return target;
}

int MessageMSG2::ByteSize() const {
// @@protoc_insertion_point(message_byte_size_start:Messages.MessageMSG2)
  int total_size = 0;

  // required uint32 type = 1;
  if (has_type()) {
    total_size += 1 +
      ::google::protobuf::internal::WireFormatLite::UInt32Size(
        this->type());
  }
  if (_has_bits_[1 / 32] & 82u) {
    // optional uint32 size = 2;
    if (has_size()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::UInt32Size(
          this->size());
    }

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

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

  }
  // optional uint32 size_sigrl = 11;
  if (has_size_sigrl()) {
    total_size += 1 +
      ::google::protobuf::internal::WireFormatLite::UInt32Size(
        this->size_sigrl());
  }

  // repeated uint32 public_key_gx = 3 [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 = 4 [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 = 6 [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 = 8 [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 = 9 [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 = 10 [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 = 12 [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 (_internal_metadata_.have_unknown_fields()) {
    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) {
// @@protoc_insertion_point(generalized_merge_from_start:Messages.MessageMSG2)
  if (GOOGLE_PREDICT_FALSE(&from == this)) {
    ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
  }
  const MessageMSG2* source = 
      ::google::protobuf::internal::DynamicCastToGenerated<const MessageMSG2>(
          &from);
  if (source == NULL) {
  // @@protoc_insertion_point(generalized_merge_from_cast_fail:Messages.MessageMSG2)
    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
  } else {
  // @@protoc_insertion_point(generalized_merge_from_cast_success:Messages.MessageMSG2)
    MergeFrom(*source);
  }
}

void MessageMSG2::MergeFrom(const MessageMSG2& from) {
// @@protoc_insertion_point(class_specific_merge_from_start:Messages.MessageMSG2)
  if (GOOGLE_PREDICT_FALSE(&from == this)) {
    ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
  }
  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_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_[10 / 32] & (0xffu << (10 % 32))) {
    if (from.has_size_sigrl()) {
      set_size_sigrl(from.size_sigrl());
    }
  }
  if (from._internal_metadata_.have_unknown_fields()) {
    mutable_unknown_fields()->MergeFrom(from.unknown_fields());
  }
}

void MessageMSG2::CopyFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_copy_from_start:Messages.MessageMSG2)
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

void MessageMSG2::CopyFrom(const MessageMSG2& from) {
// @@protoc_insertion_point(class_specific_copy_from_start:Messages.MessageMSG2)
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

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

  return true;
}

void MessageMSG2::Swap(MessageMSG2* other) {
  if (other == this) return;
  InternalSwap(other);
}
void MessageMSG2::InternalSwap(MessageMSG2* other) {
  std::swap(type_, other->type_);
  std::swap(size_, other->size_);
  public_key_gx_.UnsafeArenaSwap(&other->public_key_gx_);
  public_key_gy_.UnsafeArenaSwap(&other->public_key_gy_);
  std::swap(quote_type_, other->quote_type_);
  spid_.UnsafeArenaSwap(&other->spid_);
  std::swap(cmac_kdf_id_, other->cmac_kdf_id_);
  signature_x_.UnsafeArenaSwap(&other->signature_x_);
  signature_y_.UnsafeArenaSwap(&other->signature_y_);
  smac_.UnsafeArenaSwap(&other->smac_);
  std::swap(size_sigrl_, other->size_sigrl_);
  sigrl_.UnsafeArenaSwap(&other->sigrl_);
  std::swap(_has_bits_[0], other->_has_bits_[0]);
  _internal_metadata_.Swap(&other->_internal_metadata_);
  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;
}

#if PROTOBUF_INLINE_NOT_IN_HEADERS
// MessageMSG2

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

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

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

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

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

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

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

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

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

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

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

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

#endif  // PROTOBUF_INLINE_NOT_IN_HEADERS

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

#if !defined(_MSC_VER) || _MSC_VER >= 1900
const int MessageMSG3::kTypeFieldNumber;
const int MessageMSG3::kSizeFieldNumber;
const int MessageMSG3::kSgxMacFieldNumber;
const int MessageMSG3::kGaxMsg3FieldNumber;
const int MessageMSG3::kGayMsg3FieldNumber;
const int MessageMSG3::kSecPropertyFieldNumber;
const int MessageMSG3::kQuoteFieldNumber;
#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900

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

void MessageMSG3::InitAsDefaultInstance() {
}

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

void MessageMSG3::SharedCtor() {
  _cached_size_ = 0;
  type_ = 0u;
  size_ = 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(::google::protobuf::Arena* arena) const {
  MessageMSG3* n = new MessageMSG3;
  if (arena != NULL) {
    arena->Own(n);
  }
  return n;
}

void MessageMSG3::Clear() {
// @@protoc_insertion_point(message_clear_start:Messages.MessageMSG3)
#if defined(__clang__)
#define ZR_HELPER_(f) \
  _Pragma("clang diagnostic push") \
  _Pragma("clang diagnostic ignored \"-Winvalid-offsetof\"") \
  __builtin_offsetof(MessageMSG3, f) \
  _Pragma("clang diagnostic pop")
#else
#define ZR_HELPER_(f) reinterpret_cast<char*>(\
  &reinterpret_cast<MessageMSG3*>(16)->f)
#endif

#define ZR_(first, last) do {\
  ::memset(&first, 0,\
           ZR_HELPER_(last) - ZR_HELPER_(first) + sizeof(last));\
} while (0)

  ZR_(type_, size_);

#undef ZR_HELPER_
#undef ZR_

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

bool MessageMSG3::MergePartialFromCodedStream(
    ::google::protobuf::io::CodedInputStream* input) {
#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(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(26)) goto parse_sgx_mac;
        break;
      }

      // repeated uint32 sgx_mac = 3 [packed = true];
      case 3: {
        if (tag == 26) {
         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 == 24) {
          DO_((::google::protobuf::internal::WireFormatLite::ReadRepeatedPrimitiveNoInline<
                   ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
                 1, 26, input, this->mutable_sgx_mac())));
        } else {
          goto handle_unusual;
        }
        if (input->ExpectTag(34)) goto parse_gax_msg3;
        break;
      }

      // repeated uint32 gax_msg3 = 4 [packed = true];
      case 4: {
        if (tag == 34) {
         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 == 32) {
          DO_((::google::protobuf::internal::WireFormatLite::ReadRepeatedPrimitiveNoInline<
                   ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
                 1, 34, input, this->mutable_gax_msg3())));
        } else {
          goto handle_unusual;
        }
        if (input->ExpectTag(42)) goto parse_gay_msg3;
        break;
      }

      // repeated uint32 gay_msg3 = 5 [packed = true];
      case 5: {
        if (tag == 42) {
         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 == 40) {
          DO_((::google::protobuf::internal::WireFormatLite::ReadRepeatedPrimitiveNoInline<
                   ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
                 1, 42, input, this->mutable_gay_msg3())));
        } else {
          goto handle_unusual;
        }
        if (input->ExpectTag(50)) goto parse_sec_property;
        break;
      }

      // repeated uint32 sec_property = 6 [packed = true];
      case 6: {
        if (tag == 50) {
         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 == 48) {
          DO_((::google::protobuf::internal::WireFormatLite::ReadRepeatedPrimitiveNoInline<
                   ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
                 1, 50, input, this->mutable_sec_property())));
        } else {
          goto handle_unusual;
        }
        if (input->ExpectTag(58)) goto parse_quote;
        break;
      }

      // repeated uint32 quote = 7 [packed = true];
      case 7: {
        if (tag == 58) {
         parse_quote:
          DO_((::google::protobuf::internal::WireFormatLite::ReadPackedPrimitive<
                   ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
                 input, this->mutable_quote())));
        } else if (tag == 56) {
          DO_((::google::protobuf::internal::WireFormatLite::ReadRepeatedPrimitiveNoInline<
                   ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
                 1, 58, 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);
  }

  // repeated uint32 sgx_mac = 3 [packed = true];
  if (this->sgx_mac_size() > 0) {
    ::google::protobuf::internal::WireFormatLite::WriteTag(3, ::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 = 4 [packed = true];
  if (this->gax_msg3_size() > 0) {
    ::google::protobuf::internal::WireFormatLite::WriteTag(4, ::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 = 5 [packed = true];
  if (this->gay_msg3_size() > 0) {
    ::google::protobuf::internal::WireFormatLite::WriteTag(5, ::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 = 6 [packed = true];
  if (this->sec_property_size() > 0) {
    ::google::protobuf::internal::WireFormatLite::WriteTag(6, ::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 = 7 [packed = true];
  if (this->quote_size() > 0) {
    ::google::protobuf::internal::WireFormatLite::WriteTag(7, ::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 (_internal_metadata_.have_unknown_fields()) {
    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
        unknown_fields(), output);
  }
  // @@protoc_insertion_point(serialize_end:Messages.MessageMSG3)
}

::google::protobuf::uint8* MessageMSG3::InternalSerializeWithCachedSizesToArray(
    bool deterministic, ::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);
  }

  // repeated uint32 sgx_mac = 3 [packed = true];
  if (this->sgx_mac_size() > 0) {
    target = ::google::protobuf::internal::WireFormatLite::WriteTagToArray(
      3,
      ::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 = 4 [packed = true];
  if (this->gax_msg3_size() > 0) {
    target = ::google::protobuf::internal::WireFormatLite::WriteTagToArray(
      4,
      ::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 = 5 [packed = true];
  if (this->gay_msg3_size() > 0) {
    target = ::google::protobuf::internal::WireFormatLite::WriteTagToArray(
      5,
      ::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 = 6 [packed = true];
  if (this->sec_property_size() > 0) {
    target = ::google::protobuf::internal::WireFormatLite::WriteTagToArray(
      6,
      ::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 = 7 [packed = true];
  if (this->quote_size() > 0) {
    target = ::google::protobuf::internal::WireFormatLite::WriteTagToArray(
      7,
      ::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 (_internal_metadata_.have_unknown_fields()) {
    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
        unknown_fields(), target);
  }
  // @@protoc_insertion_point(serialize_to_array_end:Messages.MessageMSG3)
  return target;
}

int MessageMSG3::ByteSize() const {
// @@protoc_insertion_point(message_byte_size_start:Messages.MessageMSG3)
  int total_size = 0;

  // 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());
  }

  // repeated uint32 sgx_mac = 3 [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 = 4 [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 = 5 [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 = 6 [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 = 7 [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 (_internal_metadata_.have_unknown_fields()) {
    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) {
// @@protoc_insertion_point(generalized_merge_from_start:Messages.MessageMSG3)
  if (GOOGLE_PREDICT_FALSE(&from == this)) {
    ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
  }
  const MessageMSG3* source = 
      ::google::protobuf::internal::DynamicCastToGenerated<const MessageMSG3>(
          &from);
  if (source == NULL) {
  // @@protoc_insertion_point(generalized_merge_from_cast_fail:Messages.MessageMSG3)
    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
  } else {
  // @@protoc_insertion_point(generalized_merge_from_cast_success:Messages.MessageMSG3)
    MergeFrom(*source);
  }
}

void MessageMSG3::MergeFrom(const MessageMSG3& from) {
// @@protoc_insertion_point(class_specific_merge_from_start:Messages.MessageMSG3)
  if (GOOGLE_PREDICT_FALSE(&from == this)) {
    ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
  }
  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._internal_metadata_.have_unknown_fields()) {
    mutable_unknown_fields()->MergeFrom(from.unknown_fields());
  }
}

void MessageMSG3::CopyFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_copy_from_start:Messages.MessageMSG3)
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

void MessageMSG3::CopyFrom(const MessageMSG3& from) {
// @@protoc_insertion_point(class_specific_copy_from_start:Messages.MessageMSG3)
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

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

  return true;
}

void MessageMSG3::Swap(MessageMSG3* other) {
  if (other == this) return;
  InternalSwap(other);
}
void MessageMSG3::InternalSwap(MessageMSG3* other) {
  std::swap(type_, other->type_);
  std::swap(size_, other->size_);
  sgx_mac_.UnsafeArenaSwap(&other->sgx_mac_);
  gax_msg3_.UnsafeArenaSwap(&other->gax_msg3_);
  gay_msg3_.UnsafeArenaSwap(&other->gay_msg3_);
  sec_property_.UnsafeArenaSwap(&other->sec_property_);
  quote_.UnsafeArenaSwap(&other->quote_);
  std::swap(_has_bits_[0], other->_has_bits_[0]);
  _internal_metadata_.Swap(&other->_internal_metadata_);
  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;
}

#if PROTOBUF_INLINE_NOT_IN_HEADERS
// MessageMSG3

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

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

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

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

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

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

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

#endif  // PROTOBUF_INLINE_NOT_IN_HEADERS

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

#if !defined(_MSC_VER) || _MSC_VER >= 1900
const int AttestationMessage::kTypeFieldNumber;
const int AttestationMessage::kSizeFieldNumber;
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  // !defined(_MSC_VER) || _MSC_VER >= 1900

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

void AttestationMessage::InitAsDefaultInstance() {
}

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

void AttestationMessage::SharedCtor() {
  _cached_size_ = 0;
  type_ = 0u;
  size_ = 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(::google::protobuf::Arena* arena) const {
  AttestationMessage* n = new AttestationMessage;
  if (arena != NULL) {
    arena->Own(n);
  }
  return n;
}

void AttestationMessage::Clear() {
// @@protoc_insertion_point(message_clear_start:Messages.AttestationMessage)
#if defined(__clang__)
#define ZR_HELPER_(f) \
  _Pragma("clang diagnostic push") \
  _Pragma("clang diagnostic ignored \"-Winvalid-offsetof\"") \
  __builtin_offsetof(AttestationMessage, f) \
  _Pragma("clang diagnostic pop")
#else
#define ZR_HELPER_(f) reinterpret_cast<char*>(\
  &reinterpret_cast<AttestationMessage*>(16)->f)
#endif

#define ZR_(first, last) do {\
  ::memset(&first, 0,\
           ZR_HELPER_(last) - ZR_HELPER_(first) + sizeof(last));\
} while (0)

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

#undef ZR_HELPER_
#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_));
  if (_internal_metadata_.have_unknown_fields()) {
    mutable_unknown_fields()->Clear();
  }
}

bool AttestationMessage::MergePartialFromCodedStream(
    ::google::protobuf::io::CodedInputStream* input) {
#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(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_epid_group_status;
        break;
      }

      // optional uint32 epid_group_status = 3;
      case 3: {
        if (tag == 24) {
         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(32)) goto parse_tcb_evaluation_status;
        break;
      }

      // optional uint32 tcb_evaluation_status = 4;
      case 4: {
        if (tag == 32) {
         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(40)) goto parse_pse_evaluation_status;
        break;
      }

      // optional uint32 pse_evaluation_status = 5;
      case 5: {
        if (tag == 40) {
         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(50)) goto parse_latest_equivalent_tcb_psvn;
        break;
      }

      // repeated uint32 latest_equivalent_tcb_psvn = 6 [packed = true];
      case 6: {
        if (tag == 50) {
         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 == 48) {
          DO_((::google::protobuf::internal::WireFormatLite::ReadRepeatedPrimitiveNoInline<
                   ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
                 1, 50, input, this->mutable_latest_equivalent_tcb_psvn())));
        } else {
          goto handle_unusual;
        }
        if (input->ExpectTag(58)) goto parse_latest_pse_isvsvn;
        break;
      }

      // repeated uint32 latest_pse_isvsvn = 7 [packed = true];
      case 7: {
        if (tag == 58) {
         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 == 56) {
          DO_((::google::protobuf::internal::WireFormatLite::ReadRepeatedPrimitiveNoInline<
                   ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
                 1, 58, input, this->mutable_latest_pse_isvsvn())));
        } else {
          goto handle_unusual;
        }
        if (input->ExpectTag(66)) goto parse_latest_psda_svn;
        break;
      }

      // repeated uint32 latest_psda_svn = 8 [packed = true];
      case 8: {
        if (tag == 66) {
         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 == 64) {
          DO_((::google::protobuf::internal::WireFormatLite::ReadRepeatedPrimitiveNoInline<
                   ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
                 1, 66, input, this->mutable_latest_psda_svn())));
        } else {
          goto handle_unusual;
        }
        if (input->ExpectTag(74)) goto parse_performance_rekey_gid;
        break;
      }

      // repeated uint32 performance_rekey_gid = 9 [packed = true];
      case 9: {
        if (tag == 74) {
         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 == 72) {
          DO_((::google::protobuf::internal::WireFormatLite::ReadRepeatedPrimitiveNoInline<
                   ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
                 1, 74, input, this->mutable_performance_rekey_gid())));
        } else {
          goto handle_unusual;
        }
        if (input->ExpectTag(82)) goto parse_ec_sign256_x;
        break;
      }

      // repeated uint32 ec_sign256_x = 10 [packed = true];
      case 10: {
        if (tag == 82) {
         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 == 80) {
          DO_((::google::protobuf::internal::WireFormatLite::ReadRepeatedPrimitiveNoInline<
                   ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
                 1, 82, input, this->mutable_ec_sign256_x())));
        } else {
          goto handle_unusual;
        }
        if (input->ExpectTag(90)) goto parse_ec_sign256_y;
        break;
      }

      // repeated uint32 ec_sign256_y = 11 [packed = true];
      case 11: {
        if (tag == 90) {
         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 == 88) {
          DO_((::google::protobuf::internal::WireFormatLite::ReadRepeatedPrimitiveNoInline<
                   ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
                 1, 90, input, this->mutable_ec_sign256_y())));
        } else {
          goto handle_unusual;
        }
        if (input->ExpectTag(98)) goto parse_mac_smk;
        break;
      }

      // repeated uint32 mac_smk = 12 [packed = true];
      case 12: {
        if (tag == 98) {
         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 == 96) {
          DO_((::google::protobuf::internal::WireFormatLite::ReadRepeatedPrimitiveNoInline<
                   ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
                 1, 98, input, this->mutable_mac_smk())));
        } else {
          goto handle_unusual;
        }
        if (input->ExpectTag(104)) goto parse_result_size;
        break;
      }

      // optional uint32 result_size = 13;
      case 13: {
        if (tag == 104) {
         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(114)) goto parse_reserved;
        break;
      }

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

      // repeated uint32 payload_tag = 15 [packed = true];
      case 15: {
        if (tag == 122) {
         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 == 120) {
          DO_((::google::protobuf::internal::WireFormatLite::ReadRepeatedPrimitiveNoInline<
                   ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
                 1, 122, input, this->mutable_payload_tag())));
        } else {
          goto handle_unusual;
        }
        if (input->ExpectTag(130)) goto parse_payload;
        break;
      }

      // repeated uint32 payload = 16 [packed = true];
      case 16: {
        if (tag == 130) {
         parse_payload:
          DO_((::google::protobuf::internal::WireFormatLite::ReadPackedPrimitive<
                   ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
                 input, this->mutable_payload())));
        } 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())));
        } 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);
  }

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

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

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

  // repeated uint32 latest_equivalent_tcb_psvn = 6 [packed = true];
  if (this->latest_equivalent_tcb_psvn_size() > 0) {
    ::google::protobuf::internal::WireFormatLite::WriteTag(6, ::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 = 7 [packed = true];
  if (this->latest_pse_isvsvn_size() > 0) {
    ::google::protobuf::internal::WireFormatLite::WriteTag(7, ::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 = 8 [packed = true];
  if (this->latest_psda_svn_size() > 0) {
    ::google::protobuf::internal::WireFormatLite::WriteTag(8, ::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 = 9 [packed = true];
  if (this->performance_rekey_gid_size() > 0) {
    ::google::protobuf::internal::WireFormatLite::WriteTag(9, ::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 = 10 [packed = true];
  if (this->ec_sign256_x_size() > 0) {
    ::google::protobuf::internal::WireFormatLite::WriteTag(10, ::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 = 11 [packed = true];
  if (this->ec_sign256_y_size() > 0) {
    ::google::protobuf::internal::WireFormatLite::WriteTag(11, ::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 = 12 [packed = true];
  if (this->mac_smk_size() > 0) {
    ::google::protobuf::internal::WireFormatLite::WriteTag(12, ::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 = 13;
  if (has_result_size()) {
    ::google::protobuf::internal::WireFormatLite::WriteUInt32(13, this->result_size(), output);
  }

  // repeated uint32 reserved = 14 [packed = true];
  if (this->reserved_size() > 0) {
    ::google::protobuf::internal::WireFormatLite::WriteTag(14, ::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 = 15 [packed = true];
  if (this->payload_tag_size() > 0) {
    ::google::protobuf::internal::WireFormatLite::WriteTag(15, ::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 = 16 [packed = true];
  if (this->payload_size() > 0) {
    ::google::protobuf::internal::WireFormatLite::WriteTag(16, ::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 (_internal_metadata_.have_unknown_fields()) {
    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
        unknown_fields(), output);
  }
  // @@protoc_insertion_point(serialize_end:Messages.AttestationMessage)
}

::google::protobuf::uint8* AttestationMessage::InternalSerializeWithCachedSizesToArray(
    bool deterministic, ::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);
  }

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

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

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

  // repeated uint32 latest_equivalent_tcb_psvn = 6 [packed = true];
  if (this->latest_equivalent_tcb_psvn_size() > 0) {
    target = ::google::protobuf::internal::WireFormatLite::WriteTagToArray(
      6,
      ::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 = 7 [packed = true];
  if (this->latest_pse_isvsvn_size() > 0) {
    target = ::google::protobuf::internal::WireFormatLite::WriteTagToArray(
      7,
      ::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 = 8 [packed = true];
  if (this->latest_psda_svn_size() > 0) {
    target = ::google::protobuf::internal::WireFormatLite::WriteTagToArray(
      8,
      ::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 = 9 [packed = true];
  if (this->performance_rekey_gid_size() > 0) {
    target = ::google::protobuf::internal::WireFormatLite::WriteTagToArray(
      9,
      ::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 = 10 [packed = true];
  if (this->ec_sign256_x_size() > 0) {
    target = ::google::protobuf::internal::WireFormatLite::WriteTagToArray(
      10,
      ::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 = 11 [packed = true];
  if (this->ec_sign256_y_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_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 = 12 [packed = true];
  if (this->mac_smk_size() > 0) {
    target = ::google::protobuf::internal::WireFormatLite::WriteTagToArray(
      12,
      ::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 = 13;
  if (has_result_size()) {
    target = ::google::protobuf::internal::WireFormatLite::WriteUInt32ToArray(13, this->result_size(), target);
  }

  // repeated uint32 reserved = 14 [packed = true];
  if (this->reserved_size() > 0) {
    target = ::google::protobuf::internal::WireFormatLite::WriteTagToArray(
      14,
      ::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 = 15 [packed = true];
  if (this->payload_tag_size() > 0) {
    target = ::google::protobuf::internal::WireFormatLite::WriteTagToArray(
      15,
      ::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 = 16 [packed = true];
  if (this->payload_size() > 0) {
    target = ::google::protobuf::internal::WireFormatLite::WriteTagToArray(
      16,
      ::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 (_internal_metadata_.have_unknown_fields()) {
    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
        unknown_fields(), target);
  }
  // @@protoc_insertion_point(serialize_to_array_end:Messages.AttestationMessage)
  return target;
}

int AttestationMessage::RequiredFieldsByteSizeFallback() const {
// @@protoc_insertion_point(required_fields_byte_size_fallback_start:Messages.AttestationMessage)
  int total_size = 0;

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

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

  return total_size;
}
int AttestationMessage::ByteSize() const {
// @@protoc_insertion_point(message_byte_size_start:Messages.AttestationMessage)
  int total_size = 0;

  if (((_has_bits_[0] & 0x00000003) ^ 0x00000003) == 0) {  // All required fields are present.
    // required uint32 type = 1;
    total_size += 1 +
      ::google::protobuf::internal::WireFormatLite::UInt32Size(
        this->type());

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

  } else {
    total_size += RequiredFieldsByteSizeFallback();
  }
  if (_has_bits_[2 / 32] & 28u) {
    // optional uint32 epid_group_status = 3;
    if (has_epid_group_status()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::UInt32Size(
          this->epid_group_status());
    }

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

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

  }
  // optional uint32 result_size = 13;
  if (has_result_size()) {
    total_size += 1 +
      ::google::protobuf::internal::WireFormatLite::UInt32Size(
        this->result_size());
  }

  // repeated uint32 latest_equivalent_tcb_psvn = 6 [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 = 7 [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 = 8 [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 = 9 [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 = 10 [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 = 11 [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 = 12 [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 = 14 [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 = 15 [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 += 1 +
        ::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 = 16 [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 (_internal_metadata_.have_unknown_fields()) {
    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) {
// @@protoc_insertion_point(generalized_merge_from_start:Messages.AttestationMessage)
  if (GOOGLE_PREDICT_FALSE(&from == this)) {
    ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
  }
  const AttestationMessage* source = 
      ::google::protobuf::internal::DynamicCastToGenerated<const AttestationMessage>(
          &from);
  if (source == NULL) {
  // @@protoc_insertion_point(generalized_merge_from_cast_fail:Messages.AttestationMessage)
    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
  } else {
  // @@protoc_insertion_point(generalized_merge_from_cast_success:Messages.AttestationMessage)
    MergeFrom(*source);
  }
}

void AttestationMessage::MergeFrom(const AttestationMessage& from) {
// @@protoc_insertion_point(class_specific_merge_from_start:Messages.AttestationMessage)
  if (GOOGLE_PREDICT_FALSE(&from == this)) {
    ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
  }
  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_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_[12 / 32] & (0xffu << (12 % 32))) {
    if (from.has_result_size()) {
      set_result_size(from.result_size());
    }
  }
  if (from._internal_metadata_.have_unknown_fields()) {
    mutable_unknown_fields()->MergeFrom(from.unknown_fields());
  }
}

void AttestationMessage::CopyFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_copy_from_start:Messages.AttestationMessage)
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

void AttestationMessage::CopyFrom(const AttestationMessage& from) {
// @@protoc_insertion_point(class_specific_copy_from_start:Messages.AttestationMessage)
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

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

  return true;
}

void AttestationMessage::Swap(AttestationMessage* other) {
  if (other == this) return;
  InternalSwap(other);
}
void AttestationMessage::InternalSwap(AttestationMessage* other) {
  std::swap(type_, other->type_);
  std::swap(size_, other->size_);
  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_.UnsafeArenaSwap(&other->latest_equivalent_tcb_psvn_);
  latest_pse_isvsvn_.UnsafeArenaSwap(&other->latest_pse_isvsvn_);
  latest_psda_svn_.UnsafeArenaSwap(&other->latest_psda_svn_);
  performance_rekey_gid_.UnsafeArenaSwap(&other->performance_rekey_gid_);
  ec_sign256_x_.UnsafeArenaSwap(&other->ec_sign256_x_);
  ec_sign256_y_.UnsafeArenaSwap(&other->ec_sign256_y_);
  mac_smk_.UnsafeArenaSwap(&other->mac_smk_);
  std::swap(result_size_, other->result_size_);
  reserved_.UnsafeArenaSwap(&other->reserved_);
  payload_tag_.UnsafeArenaSwap(&other->payload_tag_);
  payload_.UnsafeArenaSwap(&other->payload_);
  std::swap(_has_bits_[0], other->_has_bits_[0]);
  _internal_metadata_.Swap(&other->_internal_metadata_);
  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;
}

#if PROTOBUF_INLINE_NOT_IN_HEADERS
// AttestationMessage

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

#endif  // PROTOBUF_INLINE_NOT_IN_HEADERS

// @@protoc_insertion_point(namespace_scope)

}  // namespace Messages

// @@protoc_insertion_point(global_scope)
