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

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

#include <algorithm>

#include <google/protobuf/io/coded_stream.h>
#include <google/protobuf/io/zero_copy_stream_impl_lite.h>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/stubs/once.h>
#include <google/protobuf/stubs/port.h>
#include <google/protobuf/stubs/starboard_poem.h>
#include <google/protobuf/wire_format_lite_inl.h>
// @@protoc_insertion_point(includes)

namespace crx_file {

void protobuf_ShutdownFile_crx3_2eproto() {
  delete CrxFileHeader::default_instance_;
  delete AsymmetricKeyProof::default_instance_;
  delete SignedData::default_instance_;
}

#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
void protobuf_AddDesc_crx3_2eproto_impl() {
  GOOGLE_PROTOBUF_VERIFY_VERSION;

#else
void protobuf_AddDesc_crx3_2eproto() {
  static bool already_here = false;
  if (already_here)
    return;
  already_here = true;
  GOOGLE_PROTOBUF_VERIFY_VERSION;

#endif
  CrxFileHeader::default_instance_ = new CrxFileHeader();
  AsymmetricKeyProof::default_instance_ = new AsymmetricKeyProof();
  SignedData::default_instance_ = new SignedData();
  CrxFileHeader::default_instance_->InitAsDefaultInstance();
  AsymmetricKeyProof::default_instance_->InitAsDefaultInstance();
  SignedData::default_instance_->InitAsDefaultInstance();
  ::google::protobuf::internal::OnShutdown(&protobuf_ShutdownFile_crx3_2eproto);
}

#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
GOOGLE_PROTOBUF_DECLARE_ONCE(protobuf_AddDesc_crx3_2eproto_once_);
void protobuf_AddDesc_crx3_2eproto() {
  ::google::protobuf::GoogleOnceInit(&protobuf_AddDesc_crx3_2eproto_once_,
                                     &protobuf_AddDesc_crx3_2eproto_impl);
}
#else
// Force AddDescriptors() to be called at static initialization time.
struct StaticDescriptorInitializer_crx3_2eproto {
  StaticDescriptorInitializer_crx3_2eproto() {
    protobuf_AddDesc_crx3_2eproto();
  }
} static_descriptor_initializer_crx3_2eproto_;
#endif

namespace {

static void MergeFromFail(int line) GOOGLE_ATTRIBUTE_COLD;
GOOGLE_ATTRIBUTE_NOINLINE static void MergeFromFail(int line) {
  GOOGLE_CHECK(false) << __FILE__ << ":" << line;
}

}  // namespace

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

static ::std::string* MutableUnknownFieldsForCrxFileHeader(CrxFileHeader* ptr) {
  return ptr->mutable_unknown_fields();
}

#if !defined(_MSC_VER) || _MSC_VER >= 1900
const int CrxFileHeader::kSha256WithRsaFieldNumber;
const int CrxFileHeader::kSha256WithEcdsaFieldNumber;
const int CrxFileHeader::kSignedHeaderDataFieldNumber;
#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900

CrxFileHeader::CrxFileHeader()
    : ::google::protobuf::MessageLite(), _arena_ptr_(NULL) {
  SharedCtor();
  // @@protoc_insertion_point(constructor:crx_file.CrxFileHeader)
}

void CrxFileHeader::InitAsDefaultInstance() {}

CrxFileHeader::CrxFileHeader(const CrxFileHeader& from)
    : ::google::protobuf::MessageLite(), _arena_ptr_(NULL) {
  SharedCtor();
  MergeFrom(from);
  // @@protoc_insertion_point(copy_constructor:crx_file.CrxFileHeader)
}

void CrxFileHeader::SharedCtor() {
  ::google::protobuf::internal::GetEmptyString();
  _cached_size_ = 0;
  _unknown_fields_.UnsafeSetDefault(
      &::google::protobuf::internal::GetEmptyStringAlreadyInited());
  signed_header_data_.UnsafeSetDefault(
      &::google::protobuf::internal::GetEmptyStringAlreadyInited());
  ::memset(_has_bits_, 0, sizeof(_has_bits_));
}

CrxFileHeader::~CrxFileHeader() {
  // @@protoc_insertion_point(destructor:crx_file.CrxFileHeader)
  SharedDtor();
}

void CrxFileHeader::SharedDtor() {
  _unknown_fields_.DestroyNoArena(
      &::google::protobuf::internal::GetEmptyStringAlreadyInited());
  signed_header_data_.DestroyNoArena(
      &::google::protobuf::internal::GetEmptyStringAlreadyInited());
#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
  if (this != &default_instance()) {
#else
  if (this != default_instance_) {
#endif
  }
}

void CrxFileHeader::SetCachedSize(int size) const {
  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
  _cached_size_ = size;
  GOOGLE_SAFE_CONCURRENT_WRITES_END();
}
const CrxFileHeader& CrxFileHeader::default_instance() {
#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
  protobuf_AddDesc_crx3_2eproto();
#else
  if (default_instance_ == NULL)
    protobuf_AddDesc_crx3_2eproto();
#endif
  return *default_instance_;
}

CrxFileHeader* CrxFileHeader::default_instance_ = NULL;

CrxFileHeader* CrxFileHeader::New(::google::protobuf::Arena* arena) const {
  CrxFileHeader* n = new CrxFileHeader;
  if (arena != NULL) {
    arena->Own(n);
  }
  return n;
}

void CrxFileHeader::Clear() {
  // @@protoc_insertion_point(message_clear_start:crx_file.CrxFileHeader)
  if (has_signed_header_data()) {
    signed_header_data_.ClearToEmptyNoArena(
        &::google::protobuf::internal::GetEmptyStringAlreadyInited());
  }
  sha256_with_rsa_.Clear();
  sha256_with_ecdsa_.Clear();
  ::memset(_has_bits_, 0, sizeof(_has_bits_));
  _unknown_fields_.ClearToEmptyNoArena(
      &::google::protobuf::internal::GetEmptyStringAlreadyInited());
}

bool CrxFileHeader::MergePartialFromCodedStream(
    ::google::protobuf::io::CodedInputStream* input) {
#define DO_(EXPRESSION)                 \
  if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) \
  goto failure
  ::google::protobuf::uint32 tag;
  ::google::protobuf::io::LazyStringOutputStream unknown_fields_string(
      ::google::protobuf::internal::NewPermanentCallback(
          &MutableUnknownFieldsForCrxFileHeader, this));
  ::google::protobuf::io::CodedOutputStream unknown_fields_stream(
      &unknown_fields_string, false);
  // @@protoc_insertion_point(parse_start:crx_file.CrxFileHeader)
  for (;;) {
    ::std::pair< ::google::protobuf::uint32, bool> p =
        input->ReadTagWithCutoff(80002);
    tag = p.first;
    if (!p.second)
      goto handle_unusual;
    switch (
        ::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
      // repeated .crx_file.AsymmetricKeyProof sha256_with_rsa = 2;
      case 2: {
        if (tag == 18) {
          DO_(input->IncrementRecursionDepth());
        parse_loop_sha256_with_rsa:
          DO_(::google::protobuf::internal::WireFormatLite::
                  ReadMessageNoVirtualNoRecursionDepth(input,
                                                       add_sha256_with_rsa()));
        } else {
          goto handle_unusual;
        }
        if (input->ExpectTag(18))
          goto parse_loop_sha256_with_rsa;
        if (input->ExpectTag(26))
          goto parse_loop_sha256_with_ecdsa;
        input->UnsafeDecrementRecursionDepth();
        break;
      }

      // repeated .crx_file.AsymmetricKeyProof sha256_with_ecdsa = 3;
      case 3: {
        if (tag == 26) {
          DO_(input->IncrementRecursionDepth());
        parse_loop_sha256_with_ecdsa:
          DO_(::google::protobuf::internal::WireFormatLite::
                  ReadMessageNoVirtualNoRecursionDepth(
                      input, add_sha256_with_ecdsa()));
        } else {
          goto handle_unusual;
        }
        if (input->ExpectTag(26))
          goto parse_loop_sha256_with_ecdsa;
        input->UnsafeDecrementRecursionDepth();
        if (input->ExpectTag(80002))
          goto parse_signed_header_data;
        break;
      }

      // optional bytes signed_header_data = 10000;
      case 10000: {
        if (tag == 80002) {
        parse_signed_header_data:
          DO_(::google::protobuf::internal::WireFormatLite::ReadBytes(
              input, this->mutable_signed_header_data()));
        } else {
          goto handle_unusual;
        }
        if (input->ExpectAtEnd())
          goto success;
        break;
      }

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

void CrxFileHeader::SerializeWithCachedSizes(
    ::google::protobuf::io::CodedOutputStream* output) const {
  // @@protoc_insertion_point(serialize_start:crx_file.CrxFileHeader)
  // repeated .crx_file.AsymmetricKeyProof sha256_with_rsa = 2;
  for (unsigned int i = 0, n = this->sha256_with_rsa_size(); i < n; i++) {
    ::google::protobuf::internal::WireFormatLite::WriteMessage(
        2, this->sha256_with_rsa(i), output);
  }

  // repeated .crx_file.AsymmetricKeyProof sha256_with_ecdsa = 3;
  for (unsigned int i = 0, n = this->sha256_with_ecdsa_size(); i < n; i++) {
    ::google::protobuf::internal::WireFormatLite::WriteMessage(
        3, this->sha256_with_ecdsa(i), output);
  }

  // optional bytes signed_header_data = 10000;
  if (has_signed_header_data()) {
    ::google::protobuf::internal::WireFormatLite::WriteBytesMaybeAliased(
        10000, this->signed_header_data(), output);
  }

  output->WriteRaw(unknown_fields().data(),
                   static_cast<int>(unknown_fields().size()));
  // @@protoc_insertion_point(serialize_end:crx_file.CrxFileHeader)
}

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

  // optional bytes signed_header_data = 10000;
  if (has_signed_header_data()) {
    total_size += 3 + ::google::protobuf::internal::WireFormatLite::BytesSize(
                          this->signed_header_data());
  }

  // repeated .crx_file.AsymmetricKeyProof sha256_with_rsa = 2;
  total_size += 1 * this->sha256_with_rsa_size();
  for (int i = 0; i < this->sha256_with_rsa_size(); i++) {
    total_size +=
        ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
            this->sha256_with_rsa(i));
  }

  // repeated .crx_file.AsymmetricKeyProof sha256_with_ecdsa = 3;
  total_size += 1 * this->sha256_with_ecdsa_size();
  for (int i = 0; i < this->sha256_with_ecdsa_size(); i++) {
    total_size +=
        ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
            this->sha256_with_ecdsa(i));
  }

  total_size += unknown_fields().size();

  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
  _cached_size_ = total_size;
  GOOGLE_SAFE_CONCURRENT_WRITES_END();
  return total_size;
}

void CrxFileHeader::CheckTypeAndMergeFrom(
    const ::google::protobuf::MessageLite& from) {
  MergeFrom(*::google::protobuf::down_cast<const CrxFileHeader*>(&from));
}

void CrxFileHeader::MergeFrom(const CrxFileHeader& from) {
  // @@protoc_insertion_point(class_specific_merge_from_start:crx_file.CrxFileHeader)
  if (GOOGLE_PREDICT_FALSE(&from == this))
    MergeFromFail(__LINE__);
  sha256_with_rsa_.MergeFrom(from.sha256_with_rsa_);
  sha256_with_ecdsa_.MergeFrom(from.sha256_with_ecdsa_);
  if (from._has_bits_[2 / 32] & (0xffu << (2 % 32))) {
    if (from.has_signed_header_data()) {
      set_has_signed_header_data();
      signed_header_data_.AssignWithDefault(
          &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
          from.signed_header_data_);
    }
  }
  if (!from.unknown_fields().empty()) {
    mutable_unknown_fields()->append(from.unknown_fields());
  }
}

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

bool CrxFileHeader::IsInitialized() const {
  return true;
}

void CrxFileHeader::Swap(CrxFileHeader* other) {
  if (other == this)
    return;
  InternalSwap(other);
}
void CrxFileHeader::InternalSwap(CrxFileHeader* other) {
  sha256_with_rsa_.UnsafeArenaSwap(&other->sha256_with_rsa_);
  sha256_with_ecdsa_.UnsafeArenaSwap(&other->sha256_with_ecdsa_);
  signed_header_data_.Swap(&other->signed_header_data_);
  std::swap(_has_bits_[0], other->_has_bits_[0]);
  _unknown_fields_.Swap(&other->_unknown_fields_);
  std::swap(_cached_size_, other->_cached_size_);
}

::std::string CrxFileHeader::GetTypeName() const {
  return "crx_file.CrxFileHeader";
}

#if PROTOBUF_INLINE_NOT_IN_HEADERS
// CrxFileHeader

// repeated .crx_file.AsymmetricKeyProof sha256_with_rsa = 2;
int CrxFileHeader::sha256_with_rsa_size() const {
  return sha256_with_rsa_.size();
}
void CrxFileHeader::clear_sha256_with_rsa() {
  sha256_with_rsa_.Clear();
}
const ::crx_file::AsymmetricKeyProof& CrxFileHeader::sha256_with_rsa(
    int index) const {
  // @@protoc_insertion_point(field_get:crx_file.CrxFileHeader.sha256_with_rsa)
  return sha256_with_rsa_.Get(index);
}
::crx_file::AsymmetricKeyProof* CrxFileHeader::mutable_sha256_with_rsa(
    int index) {
  // @@protoc_insertion_point(field_mutable:crx_file.CrxFileHeader.sha256_with_rsa)
  return sha256_with_rsa_.Mutable(index);
}
::crx_file::AsymmetricKeyProof* CrxFileHeader::add_sha256_with_rsa() {
  // @@protoc_insertion_point(field_add:crx_file.CrxFileHeader.sha256_with_rsa)
  return sha256_with_rsa_.Add();
}
::google::protobuf::RepeatedPtrField< ::crx_file::AsymmetricKeyProof>*
CrxFileHeader::mutable_sha256_with_rsa() {
  // @@protoc_insertion_point(field_mutable_list:crx_file.CrxFileHeader.sha256_with_rsa)
  return &sha256_with_rsa_;
}
const ::google::protobuf::RepeatedPtrField< ::crx_file::AsymmetricKeyProof>&
CrxFileHeader::sha256_with_rsa() const {
  // @@protoc_insertion_point(field_list:crx_file.CrxFileHeader.sha256_with_rsa)
  return sha256_with_rsa_;
}

// repeated .crx_file.AsymmetricKeyProof sha256_with_ecdsa = 3;
int CrxFileHeader::sha256_with_ecdsa_size() const {
  return sha256_with_ecdsa_.size();
}
void CrxFileHeader::clear_sha256_with_ecdsa() {
  sha256_with_ecdsa_.Clear();
}
const ::crx_file::AsymmetricKeyProof& CrxFileHeader::sha256_with_ecdsa(
    int index) const {
  // @@protoc_insertion_point(field_get:crx_file.CrxFileHeader.sha256_with_ecdsa)
  return sha256_with_ecdsa_.Get(index);
}
::crx_file::AsymmetricKeyProof* CrxFileHeader::mutable_sha256_with_ecdsa(
    int index) {
  // @@protoc_insertion_point(field_mutable:crx_file.CrxFileHeader.sha256_with_ecdsa)
  return sha256_with_ecdsa_.Mutable(index);
}
::crx_file::AsymmetricKeyProof* CrxFileHeader::add_sha256_with_ecdsa() {
  // @@protoc_insertion_point(field_add:crx_file.CrxFileHeader.sha256_with_ecdsa)
  return sha256_with_ecdsa_.Add();
}
::google::protobuf::RepeatedPtrField< ::crx_file::AsymmetricKeyProof>*
CrxFileHeader::mutable_sha256_with_ecdsa() {
  // @@protoc_insertion_point(field_mutable_list:crx_file.CrxFileHeader.sha256_with_ecdsa)
  return &sha256_with_ecdsa_;
}
const ::google::protobuf::RepeatedPtrField< ::crx_file::AsymmetricKeyProof>&
CrxFileHeader::sha256_with_ecdsa() const {
  // @@protoc_insertion_point(field_list:crx_file.CrxFileHeader.sha256_with_ecdsa)
  return sha256_with_ecdsa_;
}

// optional bytes signed_header_data = 10000;
bool CrxFileHeader::has_signed_header_data() const {
  return (_has_bits_[0] & 0x00000004u) != 0;
}
void CrxFileHeader::set_has_signed_header_data() {
  _has_bits_[0] |= 0x00000004u;
}
void CrxFileHeader::clear_has_signed_header_data() {
  _has_bits_[0] &= ~0x00000004u;
}
void CrxFileHeader::clear_signed_header_data() {
  signed_header_data_.ClearToEmptyNoArena(
      &::google::protobuf::internal::GetEmptyStringAlreadyInited());
  clear_has_signed_header_data();
}
const ::std::string& CrxFileHeader::signed_header_data() const {
  // @@protoc_insertion_point(field_get:crx_file.CrxFileHeader.signed_header_data)
  return signed_header_data_.GetNoArena(
      &::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
void CrxFileHeader::set_signed_header_data(const ::std::string& value) {
  set_has_signed_header_data();
  signed_header_data_.SetNoArena(
      &::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
  // @@protoc_insertion_point(field_set:crx_file.CrxFileHeader.signed_header_data)
}
void CrxFileHeader::set_signed_header_data(const char* value) {
  set_has_signed_header_data();
  signed_header_data_.SetNoArena(
      &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
      ::std::string(value));
  // @@protoc_insertion_point(field_set_char:crx_file.CrxFileHeader.signed_header_data)
}
void CrxFileHeader::set_signed_header_data(const void* value, size_t size) {
  set_has_signed_header_data();
  signed_header_data_.SetNoArena(
      &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
      ::std::string(reinterpret_cast<const char*>(value), size));
  // @@protoc_insertion_point(field_set_pointer:crx_file.CrxFileHeader.signed_header_data)
}
::std::string* CrxFileHeader::mutable_signed_header_data() {
  set_has_signed_header_data();
  // @@protoc_insertion_point(field_mutable:crx_file.CrxFileHeader.signed_header_data)
  return signed_header_data_.MutableNoArena(
      &::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
::std::string* CrxFileHeader::release_signed_header_data() {
  // @@protoc_insertion_point(field_release:crx_file.CrxFileHeader.signed_header_data)
  clear_has_signed_header_data();
  return signed_header_data_.ReleaseNoArena(
      &::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
void CrxFileHeader::set_allocated_signed_header_data(
    ::std::string* signed_header_data) {
  if (signed_header_data != NULL) {
    set_has_signed_header_data();
  } else {
    clear_has_signed_header_data();
  }
  signed_header_data_.SetAllocatedNoArena(
      &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
      signed_header_data);
  // @@protoc_insertion_point(field_set_allocated:crx_file.CrxFileHeader.signed_header_data)
}

#endif  // PROTOBUF_INLINE_NOT_IN_HEADERS

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

static ::std::string* MutableUnknownFieldsForAsymmetricKeyProof(
    AsymmetricKeyProof* ptr) {
  return ptr->mutable_unknown_fields();
}

#if !defined(_MSC_VER) || _MSC_VER >= 1900
const int AsymmetricKeyProof::kPublicKeyFieldNumber;
const int AsymmetricKeyProof::kSignatureFieldNumber;
#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900

AsymmetricKeyProof::AsymmetricKeyProof()
    : ::google::protobuf::MessageLite(), _arena_ptr_(NULL) {
  SharedCtor();
  // @@protoc_insertion_point(constructor:crx_file.AsymmetricKeyProof)
}

void AsymmetricKeyProof::InitAsDefaultInstance() {}

AsymmetricKeyProof::AsymmetricKeyProof(const AsymmetricKeyProof& from)
    : ::google::protobuf::MessageLite(), _arena_ptr_(NULL) {
  SharedCtor();
  MergeFrom(from);
  // @@protoc_insertion_point(copy_constructor:crx_file.AsymmetricKeyProof)
}

void AsymmetricKeyProof::SharedCtor() {
  ::google::protobuf::internal::GetEmptyString();
  _cached_size_ = 0;
  _unknown_fields_.UnsafeSetDefault(
      &::google::protobuf::internal::GetEmptyStringAlreadyInited());
  public_key_.UnsafeSetDefault(
      &::google::protobuf::internal::GetEmptyStringAlreadyInited());
  signature_.UnsafeSetDefault(
      &::google::protobuf::internal::GetEmptyStringAlreadyInited());
  ::memset(_has_bits_, 0, sizeof(_has_bits_));
}

AsymmetricKeyProof::~AsymmetricKeyProof() {
  // @@protoc_insertion_point(destructor:crx_file.AsymmetricKeyProof)
  SharedDtor();
}

void AsymmetricKeyProof::SharedDtor() {
  _unknown_fields_.DestroyNoArena(
      &::google::protobuf::internal::GetEmptyStringAlreadyInited());
  public_key_.DestroyNoArena(
      &::google::protobuf::internal::GetEmptyStringAlreadyInited());
  signature_.DestroyNoArena(
      &::google::protobuf::internal::GetEmptyStringAlreadyInited());
#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
  if (this != &default_instance()) {
#else
  if (this != default_instance_) {
#endif
  }
}

void AsymmetricKeyProof::SetCachedSize(int size) const {
  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
  _cached_size_ = size;
  GOOGLE_SAFE_CONCURRENT_WRITES_END();
}
const AsymmetricKeyProof& AsymmetricKeyProof::default_instance() {
#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
  protobuf_AddDesc_crx3_2eproto();
#else
  if (default_instance_ == NULL)
    protobuf_AddDesc_crx3_2eproto();
#endif
  return *default_instance_;
}

AsymmetricKeyProof* AsymmetricKeyProof::default_instance_ = NULL;

AsymmetricKeyProof* AsymmetricKeyProof::New(
    ::google::protobuf::Arena* arena) const {
  AsymmetricKeyProof* n = new AsymmetricKeyProof;
  if (arena != NULL) {
    arena->Own(n);
  }
  return n;
}

void AsymmetricKeyProof::Clear() {
  // @@protoc_insertion_point(message_clear_start:crx_file.AsymmetricKeyProof)
  if (_has_bits_[0 / 32] & 3u) {
    if (has_public_key()) {
      public_key_.ClearToEmptyNoArena(
          &::google::protobuf::internal::GetEmptyStringAlreadyInited());
    }
    if (has_signature()) {
      signature_.ClearToEmptyNoArena(
          &::google::protobuf::internal::GetEmptyStringAlreadyInited());
    }
  }
  ::memset(_has_bits_, 0, sizeof(_has_bits_));
  _unknown_fields_.ClearToEmptyNoArena(
      &::google::protobuf::internal::GetEmptyStringAlreadyInited());
}

bool AsymmetricKeyProof::MergePartialFromCodedStream(
    ::google::protobuf::io::CodedInputStream* input) {
#define DO_(EXPRESSION)                 \
  if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) \
  goto failure
  ::google::protobuf::uint32 tag;
  ::google::protobuf::io::LazyStringOutputStream unknown_fields_string(
      ::google::protobuf::internal::NewPermanentCallback(
          &MutableUnknownFieldsForAsymmetricKeyProof, this));
  ::google::protobuf::io::CodedOutputStream unknown_fields_stream(
      &unknown_fields_string, false);
  // @@protoc_insertion_point(parse_start:crx_file.AsymmetricKeyProof)
  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)) {
      // optional bytes public_key = 1;
      case 1: {
        if (tag == 10) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadBytes(
              input, this->mutable_public_key()));
        } else {
          goto handle_unusual;
        }
        if (input->ExpectTag(18))
          goto parse_signature;
        break;
      }

      // optional bytes signature = 2;
      case 2: {
        if (tag == 18) {
        parse_signature:
          DO_(::google::protobuf::internal::WireFormatLite::ReadBytes(
              input, this->mutable_signature()));
        } 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::WireFormatLite::SkipField(
            input, tag, &unknown_fields_stream));
        break;
      }
    }
  }
success:
  // @@protoc_insertion_point(parse_success:crx_file.AsymmetricKeyProof)
  return true;
failure:
  // @@protoc_insertion_point(parse_failure:crx_file.AsymmetricKeyProof)
  return false;
#undef DO_
}

void AsymmetricKeyProof::SerializeWithCachedSizes(
    ::google::protobuf::io::CodedOutputStream* output) const {
  // @@protoc_insertion_point(serialize_start:crx_file.AsymmetricKeyProof)
  // optional bytes public_key = 1;
  if (has_public_key()) {
    ::google::protobuf::internal::WireFormatLite::WriteBytesMaybeAliased(
        1, this->public_key(), output);
  }

  // optional bytes signature = 2;
  if (has_signature()) {
    ::google::protobuf::internal::WireFormatLite::WriteBytesMaybeAliased(
        2, this->signature(), output);
  }

  output->WriteRaw(unknown_fields().data(),
                   static_cast<int>(unknown_fields().size()));
  // @@protoc_insertion_point(serialize_end:crx_file.AsymmetricKeyProof)
}

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

  if (_has_bits_[0 / 32] & 3u) {
    // optional bytes public_key = 1;
    if (has_public_key()) {
      total_size += 1 + ::google::protobuf::internal::WireFormatLite::BytesSize(
                            this->public_key());
    }

    // optional bytes signature = 2;
    if (has_signature()) {
      total_size += 1 + ::google::protobuf::internal::WireFormatLite::BytesSize(
                            this->signature());
    }
  }
  total_size += unknown_fields().size();

  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
  _cached_size_ = total_size;
  GOOGLE_SAFE_CONCURRENT_WRITES_END();
  return total_size;
}

void AsymmetricKeyProof::CheckTypeAndMergeFrom(
    const ::google::protobuf::MessageLite& from) {
  MergeFrom(*::google::protobuf::down_cast<const AsymmetricKeyProof*>(&from));
}

void AsymmetricKeyProof::MergeFrom(const AsymmetricKeyProof& from) {
  // @@protoc_insertion_point(class_specific_merge_from_start:crx_file.AsymmetricKeyProof)
  if (GOOGLE_PREDICT_FALSE(&from == this))
    MergeFromFail(__LINE__);
  if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    if (from.has_public_key()) {
      set_has_public_key();
      public_key_.AssignWithDefault(
          &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
          from.public_key_);
    }
    if (from.has_signature()) {
      set_has_signature();
      signature_.AssignWithDefault(
          &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
          from.signature_);
    }
  }
  if (!from.unknown_fields().empty()) {
    mutable_unknown_fields()->append(from.unknown_fields());
  }
}

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

bool AsymmetricKeyProof::IsInitialized() const {
  return true;
}

void AsymmetricKeyProof::Swap(AsymmetricKeyProof* other) {
  if (other == this)
    return;
  InternalSwap(other);
}
void AsymmetricKeyProof::InternalSwap(AsymmetricKeyProof* other) {
  public_key_.Swap(&other->public_key_);
  signature_.Swap(&other->signature_);
  std::swap(_has_bits_[0], other->_has_bits_[0]);
  _unknown_fields_.Swap(&other->_unknown_fields_);
  std::swap(_cached_size_, other->_cached_size_);
}

::std::string AsymmetricKeyProof::GetTypeName() const {
  return "crx_file.AsymmetricKeyProof";
}

#if PROTOBUF_INLINE_NOT_IN_HEADERS
// AsymmetricKeyProof

// optional bytes public_key = 1;
bool AsymmetricKeyProof::has_public_key() const {
  return (_has_bits_[0] & 0x00000001u) != 0;
}
void AsymmetricKeyProof::set_has_public_key() {
  _has_bits_[0] |= 0x00000001u;
}
void AsymmetricKeyProof::clear_has_public_key() {
  _has_bits_[0] &= ~0x00000001u;
}
void AsymmetricKeyProof::clear_public_key() {
  public_key_.ClearToEmptyNoArena(
      &::google::protobuf::internal::GetEmptyStringAlreadyInited());
  clear_has_public_key();
}
const ::std::string& AsymmetricKeyProof::public_key() const {
  // @@protoc_insertion_point(field_get:crx_file.AsymmetricKeyProof.public_key)
  return public_key_.GetNoArena(
      &::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
void AsymmetricKeyProof::set_public_key(const ::std::string& value) {
  set_has_public_key();
  public_key_.SetNoArena(
      &::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
  // @@protoc_insertion_point(field_set:crx_file.AsymmetricKeyProof.public_key)
}
void AsymmetricKeyProof::set_public_key(const char* value) {
  set_has_public_key();
  public_key_.SetNoArena(
      &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
      ::std::string(value));
  // @@protoc_insertion_point(field_set_char:crx_file.AsymmetricKeyProof.public_key)
}
void AsymmetricKeyProof::set_public_key(const void* value, size_t size) {
  set_has_public_key();
  public_key_.SetNoArena(
      &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
      ::std::string(reinterpret_cast<const char*>(value), size));
  // @@protoc_insertion_point(field_set_pointer:crx_file.AsymmetricKeyProof.public_key)
}
::std::string* AsymmetricKeyProof::mutable_public_key() {
  set_has_public_key();
  // @@protoc_insertion_point(field_mutable:crx_file.AsymmetricKeyProof.public_key)
  return public_key_.MutableNoArena(
      &::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
::std::string* AsymmetricKeyProof::release_public_key() {
  // @@protoc_insertion_point(field_release:crx_file.AsymmetricKeyProof.public_key)
  clear_has_public_key();
  return public_key_.ReleaseNoArena(
      &::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
void AsymmetricKeyProof::set_allocated_public_key(::std::string* public_key) {
  if (public_key != NULL) {
    set_has_public_key();
  } else {
    clear_has_public_key();
  }
  public_key_.SetAllocatedNoArena(
      &::google::protobuf::internal::GetEmptyStringAlreadyInited(), public_key);
  // @@protoc_insertion_point(field_set_allocated:crx_file.AsymmetricKeyProof.public_key)
}

// optional bytes signature = 2;
bool AsymmetricKeyProof::has_signature() const {
  return (_has_bits_[0] & 0x00000002u) != 0;
}
void AsymmetricKeyProof::set_has_signature() {
  _has_bits_[0] |= 0x00000002u;
}
void AsymmetricKeyProof::clear_has_signature() {
  _has_bits_[0] &= ~0x00000002u;
}
void AsymmetricKeyProof::clear_signature() {
  signature_.ClearToEmptyNoArena(
      &::google::protobuf::internal::GetEmptyStringAlreadyInited());
  clear_has_signature();
}
const ::std::string& AsymmetricKeyProof::signature() const {
  // @@protoc_insertion_point(field_get:crx_file.AsymmetricKeyProof.signature)
  return signature_.GetNoArena(
      &::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
void AsymmetricKeyProof::set_signature(const ::std::string& value) {
  set_has_signature();
  signature_.SetNoArena(
      &::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
  // @@protoc_insertion_point(field_set:crx_file.AsymmetricKeyProof.signature)
}
void AsymmetricKeyProof::set_signature(const char* value) {
  set_has_signature();
  signature_.SetNoArena(
      &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
      ::std::string(value));
  // @@protoc_insertion_point(field_set_char:crx_file.AsymmetricKeyProof.signature)
}
void AsymmetricKeyProof::set_signature(const void* value, size_t size) {
  set_has_signature();
  signature_.SetNoArena(
      &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
      ::std::string(reinterpret_cast<const char*>(value), size));
  // @@protoc_insertion_point(field_set_pointer:crx_file.AsymmetricKeyProof.signature)
}
::std::string* AsymmetricKeyProof::mutable_signature() {
  set_has_signature();
  // @@protoc_insertion_point(field_mutable:crx_file.AsymmetricKeyProof.signature)
  return signature_.MutableNoArena(
      &::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
::std::string* AsymmetricKeyProof::release_signature() {
  // @@protoc_insertion_point(field_release:crx_file.AsymmetricKeyProof.signature)
  clear_has_signature();
  return signature_.ReleaseNoArena(
      &::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
void AsymmetricKeyProof::set_allocated_signature(::std::string* signature) {
  if (signature != NULL) {
    set_has_signature();
  } else {
    clear_has_signature();
  }
  signature_.SetAllocatedNoArena(
      &::google::protobuf::internal::GetEmptyStringAlreadyInited(), signature);
  // @@protoc_insertion_point(field_set_allocated:crx_file.AsymmetricKeyProof.signature)
}

#endif  // PROTOBUF_INLINE_NOT_IN_HEADERS

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

static ::std::string* MutableUnknownFieldsForSignedData(SignedData* ptr) {
  return ptr->mutable_unknown_fields();
}

#if !defined(_MSC_VER) || _MSC_VER >= 1900
const int SignedData::kCrxIdFieldNumber;
#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900

SignedData::SignedData()
    : ::google::protobuf::MessageLite(), _arena_ptr_(NULL) {
  SharedCtor();
  // @@protoc_insertion_point(constructor:crx_file.SignedData)
}

void SignedData::InitAsDefaultInstance() {}

SignedData::SignedData(const SignedData& from)
    : ::google::protobuf::MessageLite(), _arena_ptr_(NULL) {
  SharedCtor();
  MergeFrom(from);
  // @@protoc_insertion_point(copy_constructor:crx_file.SignedData)
}

void SignedData::SharedCtor() {
  ::google::protobuf::internal::GetEmptyString();
  _cached_size_ = 0;
  _unknown_fields_.UnsafeSetDefault(
      &::google::protobuf::internal::GetEmptyStringAlreadyInited());
  crx_id_.UnsafeSetDefault(
      &::google::protobuf::internal::GetEmptyStringAlreadyInited());
  ::memset(_has_bits_, 0, sizeof(_has_bits_));
}

SignedData::~SignedData() {
  // @@protoc_insertion_point(destructor:crx_file.SignedData)
  SharedDtor();
}

void SignedData::SharedDtor() {
  _unknown_fields_.DestroyNoArena(
      &::google::protobuf::internal::GetEmptyStringAlreadyInited());
  crx_id_.DestroyNoArena(
      &::google::protobuf::internal::GetEmptyStringAlreadyInited());
#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
  if (this != &default_instance()) {
#else
  if (this != default_instance_) {
#endif
  }
}

void SignedData::SetCachedSize(int size) const {
  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
  _cached_size_ = size;
  GOOGLE_SAFE_CONCURRENT_WRITES_END();
}
const SignedData& SignedData::default_instance() {
#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
  protobuf_AddDesc_crx3_2eproto();
#else
  if (default_instance_ == NULL)
    protobuf_AddDesc_crx3_2eproto();
#endif
  return *default_instance_;
}

SignedData* SignedData::default_instance_ = NULL;

SignedData* SignedData::New(::google::protobuf::Arena* arena) const {
  SignedData* n = new SignedData;
  if (arena != NULL) {
    arena->Own(n);
  }
  return n;
}

void SignedData::Clear() {
  // @@protoc_insertion_point(message_clear_start:crx_file.SignedData)
  if (has_crx_id()) {
    crx_id_.ClearToEmptyNoArena(
        &::google::protobuf::internal::GetEmptyStringAlreadyInited());
  }
  ::memset(_has_bits_, 0, sizeof(_has_bits_));
  _unknown_fields_.ClearToEmptyNoArena(
      &::google::protobuf::internal::GetEmptyStringAlreadyInited());
}

bool SignedData::MergePartialFromCodedStream(
    ::google::protobuf::io::CodedInputStream* input) {
#define DO_(EXPRESSION)                 \
  if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) \
  goto failure
  ::google::protobuf::uint32 tag;
  ::google::protobuf::io::LazyStringOutputStream unknown_fields_string(
      ::google::protobuf::internal::NewPermanentCallback(
          &MutableUnknownFieldsForSignedData, this));
  ::google::protobuf::io::CodedOutputStream unknown_fields_stream(
      &unknown_fields_string, false);
  // @@protoc_insertion_point(parse_start:crx_file.SignedData)
  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)) {
      // optional bytes crx_id = 1;
      case 1: {
        if (tag == 10) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadBytes(
              input, this->mutable_crx_id()));
        } else {
          goto handle_unusual;
        }
        if (input->ExpectAtEnd())
          goto success;
        break;
      }

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

void SignedData::SerializeWithCachedSizes(
    ::google::protobuf::io::CodedOutputStream* output) const {
  // @@protoc_insertion_point(serialize_start:crx_file.SignedData)
  // optional bytes crx_id = 1;
  if (has_crx_id()) {
    ::google::protobuf::internal::WireFormatLite::WriteBytesMaybeAliased(
        1, this->crx_id(), output);
  }

  output->WriteRaw(unknown_fields().data(),
                   static_cast<int>(unknown_fields().size()));
  // @@protoc_insertion_point(serialize_end:crx_file.SignedData)
}

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

  // optional bytes crx_id = 1;
  if (has_crx_id()) {
    total_size += 1 + ::google::protobuf::internal::WireFormatLite::BytesSize(
                          this->crx_id());
  }

  total_size += unknown_fields().size();

  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
  _cached_size_ = total_size;
  GOOGLE_SAFE_CONCURRENT_WRITES_END();
  return total_size;
}

void SignedData::CheckTypeAndMergeFrom(
    const ::google::protobuf::MessageLite& from) {
  MergeFrom(*::google::protobuf::down_cast<const SignedData*>(&from));
}

void SignedData::MergeFrom(const SignedData& from) {
  // @@protoc_insertion_point(class_specific_merge_from_start:crx_file.SignedData)
  if (GOOGLE_PREDICT_FALSE(&from == this))
    MergeFromFail(__LINE__);
  if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    if (from.has_crx_id()) {
      set_has_crx_id();
      crx_id_.AssignWithDefault(
          &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
          from.crx_id_);
    }
  }
  if (!from.unknown_fields().empty()) {
    mutable_unknown_fields()->append(from.unknown_fields());
  }
}

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

bool SignedData::IsInitialized() const {
  return true;
}

void SignedData::Swap(SignedData* other) {
  if (other == this)
    return;
  InternalSwap(other);
}
void SignedData::InternalSwap(SignedData* other) {
  crx_id_.Swap(&other->crx_id_);
  std::swap(_has_bits_[0], other->_has_bits_[0]);
  _unknown_fields_.Swap(&other->_unknown_fields_);
  std::swap(_cached_size_, other->_cached_size_);
}

::std::string SignedData::GetTypeName() const {
  return "crx_file.SignedData";
}

#if PROTOBUF_INLINE_NOT_IN_HEADERS
// SignedData

// optional bytes crx_id = 1;
bool SignedData::has_crx_id() const {
  return (_has_bits_[0] & 0x00000001u) != 0;
}
void SignedData::set_has_crx_id() {
  _has_bits_[0] |= 0x00000001u;
}
void SignedData::clear_has_crx_id() {
  _has_bits_[0] &= ~0x00000001u;
}
void SignedData::clear_crx_id() {
  crx_id_.ClearToEmptyNoArena(
      &::google::protobuf::internal::GetEmptyStringAlreadyInited());
  clear_has_crx_id();
}
const ::std::string& SignedData::crx_id() const {
  // @@protoc_insertion_point(field_get:crx_file.SignedData.crx_id)
  return crx_id_.GetNoArena(
      &::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
void SignedData::set_crx_id(const ::std::string& value) {
  set_has_crx_id();
  crx_id_.SetNoArena(
      &::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
  // @@protoc_insertion_point(field_set:crx_file.SignedData.crx_id)
}
void SignedData::set_crx_id(const char* value) {
  set_has_crx_id();
  crx_id_.SetNoArena(
      &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
      ::std::string(value));
  // @@protoc_insertion_point(field_set_char:crx_file.SignedData.crx_id)
}
void SignedData::set_crx_id(const void* value, size_t size) {
  set_has_crx_id();
  crx_id_.SetNoArena(
      &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
      ::std::string(reinterpret_cast<const char*>(value), size));
  // @@protoc_insertion_point(field_set_pointer:crx_file.SignedData.crx_id)
}
::std::string* SignedData::mutable_crx_id() {
  set_has_crx_id();
  // @@protoc_insertion_point(field_mutable:crx_file.SignedData.crx_id)
  return crx_id_.MutableNoArena(
      &::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
::std::string* SignedData::release_crx_id() {
  // @@protoc_insertion_point(field_release:crx_file.SignedData.crx_id)
  clear_has_crx_id();
  return crx_id_.ReleaseNoArena(
      &::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
void SignedData::set_allocated_crx_id(::std::string* crx_id) {
  if (crx_id != NULL) {
    set_has_crx_id();
  } else {
    clear_has_crx_id();
  }
  crx_id_.SetAllocatedNoArena(
      &::google::protobuf::internal::GetEmptyStringAlreadyInited(), crx_id);
  // @@protoc_insertion_point(field_set_allocated:crx_file.SignedData.crx_id)
}

#endif  // PROTOBUF_INLINE_NOT_IN_HEADERS

// @@protoc_insertion_point(namespace_scope)

}  // namespace crx_file

// @@protoc_insertion_point(global_scope)
