// This file is generated by rust-protobuf 2.27.1. Do not edit
// @generated

// https://github.com/rust-lang/rust-clippy/issues/702
#![allow(unknown_lints)]
#![allow(clippy::all)]

#![allow(unused_attributes)]
#![cfg_attr(rustfmt, rustfmt::skip)]

#![allow(box_pointers)]
#![allow(dead_code)]
#![allow(missing_docs)]
#![allow(non_camel_case_types)]
#![allow(non_snake_case)]
#![allow(non_upper_case_globals)]
#![allow(trivial_casts)]
#![allow(unused_imports)]
#![allow(unused_results)]
//! Generated file from `keymaster_attributes.proto`

/// Generated files are compatible only with the same version
/// of protobuf runtime.
// const _PROTOBUF_VERSION_CHECK: () = ::protobuf::VERSION_2_27_1;

#[derive(PartialEq,Clone,Default)]
pub struct KeymasterAttributes {
    // message fields
    uuid: ::protobuf::SingularField<::std::vec::Vec<u8>>,
    product_id: ::protobuf::SingularField<::std::vec::Vec<u8>>,
    // special fields
    pub unknown_fields: ::protobuf::UnknownFields,
    pub cached_size: ::protobuf::CachedSize,
}

impl<'a> ::std::default::Default for &'a KeymasterAttributes {
    fn default() -> &'a KeymasterAttributes {
        <KeymasterAttributes as ::protobuf::Message>::default_instance()
    }
}

impl KeymasterAttributes {
    pub fn new() -> KeymasterAttributes {
        ::std::default::Default::default()
    }

    // optional bytes uuid = 1;


    pub fn get_uuid(&self) -> &[u8] {
        match self.uuid.as_ref() {
            Some(v) => &v,
            None => &[],
        }
    }
    pub fn clear_uuid(&mut self) {
        self.uuid.clear();
    }

    pub fn has_uuid(&self) -> bool {
        self.uuid.is_some()
    }

    // Param is passed by value, moved
    pub fn set_uuid(&mut self, v: ::std::vec::Vec<u8>) {
        self.uuid = ::protobuf::SingularField::some(v);
    }

    // Mutable pointer to the field.
    // If field is not initialized, it is initialized with default value first.
    pub fn mut_uuid(&mut self) -> &mut ::std::vec::Vec<u8> {
        if self.uuid.is_none() {
            self.uuid.set_default();
        }
        self.uuid.as_mut().unwrap()
    }

    // Take field
    pub fn take_uuid(&mut self) -> ::std::vec::Vec<u8> {
        self.uuid.take().unwrap_or_else(|| ::std::vec::Vec::new())
    }

    // optional bytes product_id = 2;


    pub fn get_product_id(&self) -> &[u8] {
        match self.product_id.as_ref() {
            Some(v) => &v,
            None => &[],
        }
    }
    pub fn clear_product_id(&mut self) {
        self.product_id.clear();
    }

    pub fn has_product_id(&self) -> bool {
        self.product_id.is_some()
    }

    // Param is passed by value, moved
    pub fn set_product_id(&mut self, v: ::std::vec::Vec<u8>) {
        self.product_id = ::protobuf::SingularField::some(v);
    }

    // Mutable pointer to the field.
    // If field is not initialized, it is initialized with default value first.
    pub fn mut_product_id(&mut self) -> &mut ::std::vec::Vec<u8> {
        if self.product_id.is_none() {
            self.product_id.set_default();
        }
        self.product_id.as_mut().unwrap()
    }

    // Take field
    pub fn take_product_id(&mut self) -> ::std::vec::Vec<u8> {
        self.product_id.take().unwrap_or_else(|| ::std::vec::Vec::new())
    }
}

impl ::protobuf::Message for KeymasterAttributes {
    fn is_initialized(&self) -> bool {
        true
    }

    fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> {
        while !is.eof()? {
            let (field_number, wire_type) = is.read_tag_unpack()?;
            match field_number {
                1 => {
                    ::protobuf::rt::read_singular_bytes_into(wire_type, is, &mut self.uuid)?;
                },
                2 => {
                    ::protobuf::rt::read_singular_bytes_into(wire_type, is, &mut self.product_id)?;
                },
                _ => {
                    ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?;
                },
            };
        }
        ::std::result::Result::Ok(())
    }

    // Compute sizes of nested messages
    #[allow(unused_variables)]
    fn compute_size(&self) -> u32 {
        let mut my_size = 0;
        if let Some(ref v) = self.uuid.as_ref() {
            my_size += ::protobuf::rt::bytes_size(1, &v);
        }
        if let Some(ref v) = self.product_id.as_ref() {
            my_size += ::protobuf::rt::bytes_size(2, &v);
        }
        my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields());
        self.cached_size.set(my_size);
        my_size
    }

    fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> {
        if let Some(ref v) = self.uuid.as_ref() {
            os.write_bytes(1, &v)?;
        }
        if let Some(ref v) = self.product_id.as_ref() {
            os.write_bytes(2, &v)?;
        }
        os.write_unknown_fields(self.get_unknown_fields())?;
        ::std::result::Result::Ok(())
    }

    fn get_cached_size(&self) -> u32 {
        self.cached_size.get()
    }

    fn get_unknown_fields(&self) -> &::protobuf::UnknownFields {
        &self.unknown_fields
    }

    fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields {
        &mut self.unknown_fields
    }

    fn as_any(&self) -> &dyn (::std::any::Any) {
        self as &dyn (::std::any::Any)
    }
    fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) {
        self as &mut dyn (::std::any::Any)
    }
    fn into_any(self: ::std::boxed::Box<Self>) -> ::std::boxed::Box<dyn (::std::any::Any)> {
        self
    }

    fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor {
        Self::descriptor_static()
    }

    fn new() -> KeymasterAttributes {
        KeymasterAttributes::new()
    }

    fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor {
        static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT;
        descriptor.get(|| {
            let mut fields = ::std::vec::Vec::new();
            fields.push(::protobuf::reflect::accessor::make_singular_field_accessor::<_, ::protobuf::types::ProtobufTypeBytes>(
                "uuid",
                |m: &KeymasterAttributes| { &m.uuid },
                |m: &mut KeymasterAttributes| { &mut m.uuid },
            ));
            fields.push(::protobuf::reflect::accessor::make_singular_field_accessor::<_, ::protobuf::types::ProtobufTypeBytes>(
                "product_id",
                |m: &KeymasterAttributes| { &m.product_id },
                |m: &mut KeymasterAttributes| { &mut m.product_id },
            ));
            ::protobuf::reflect::MessageDescriptor::new_pb_name::<KeymasterAttributes>(
                "KeymasterAttributes",
                fields,
                file_descriptor_proto()
            )
        })
    }

    fn default_instance() -> &'static KeymasterAttributes {
        static instance: ::protobuf::rt::LazyV2<KeymasterAttributes> = ::protobuf::rt::LazyV2::INIT;
        instance.get(KeymasterAttributes::new)
    }
}

impl ::protobuf::Clear for KeymasterAttributes {
    fn clear(&mut self) {
        self.uuid.clear();
        self.product_id.clear();
        self.unknown_fields.clear();
    }
}

impl ::std::fmt::Debug for KeymasterAttributes {
    fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
        ::protobuf::text_format::fmt(self, f)
    }
}

impl ::protobuf::reflect::ProtobufValue for KeymasterAttributes {
    fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef {
        ::protobuf::reflect::ReflectValueRef::Message(self)
    }
}

#[derive(PartialEq,Clone,Default)]
pub struct AttestationIds {
    // message fields
    brand: ::protobuf::SingularField<::std::vec::Vec<u8>>,
    device: ::protobuf::SingularField<::std::vec::Vec<u8>>,
    product: ::protobuf::SingularField<::std::vec::Vec<u8>>,
    serial: ::protobuf::SingularField<::std::vec::Vec<u8>>,
    imei: ::protobuf::SingularField<::std::vec::Vec<u8>>,
    meid: ::protobuf::SingularField<::std::vec::Vec<u8>>,
    manufacturer: ::protobuf::SingularField<::std::vec::Vec<u8>>,
    model: ::protobuf::SingularField<::std::vec::Vec<u8>>,
    // special fields
    pub unknown_fields: ::protobuf::UnknownFields,
    pub cached_size: ::protobuf::CachedSize,
}

impl<'a> ::std::default::Default for &'a AttestationIds {
    fn default() -> &'a AttestationIds {
        <AttestationIds as ::protobuf::Message>::default_instance()
    }
}

impl AttestationIds {
    pub fn new() -> AttestationIds {
        ::std::default::Default::default()
    }

    // optional bytes brand = 1;


    pub fn get_brand(&self) -> &[u8] {
        match self.brand.as_ref() {
            Some(v) => &v,
            None => &[],
        }
    }
    pub fn clear_brand(&mut self) {
        self.brand.clear();
    }

    pub fn has_brand(&self) -> bool {
        self.brand.is_some()
    }

    // Param is passed by value, moved
    pub fn set_brand(&mut self, v: ::std::vec::Vec<u8>) {
        self.brand = ::protobuf::SingularField::some(v);
    }

    // Mutable pointer to the field.
    // If field is not initialized, it is initialized with default value first.
    pub fn mut_brand(&mut self) -> &mut ::std::vec::Vec<u8> {
        if self.brand.is_none() {
            self.brand.set_default();
        }
        self.brand.as_mut().unwrap()
    }

    // Take field
    pub fn take_brand(&mut self) -> ::std::vec::Vec<u8> {
        self.brand.take().unwrap_or_else(|| ::std::vec::Vec::new())
    }

    // optional bytes device = 2;


    pub fn get_device(&self) -> &[u8] {
        match self.device.as_ref() {
            Some(v) => &v,
            None => &[],
        }
    }
    pub fn clear_device(&mut self) {
        self.device.clear();
    }

    pub fn has_device(&self) -> bool {
        self.device.is_some()
    }

    // Param is passed by value, moved
    pub fn set_device(&mut self, v: ::std::vec::Vec<u8>) {
        self.device = ::protobuf::SingularField::some(v);
    }

    // Mutable pointer to the field.
    // If field is not initialized, it is initialized with default value first.
    pub fn mut_device(&mut self) -> &mut ::std::vec::Vec<u8> {
        if self.device.is_none() {
            self.device.set_default();
        }
        self.device.as_mut().unwrap()
    }

    // Take field
    pub fn take_device(&mut self) -> ::std::vec::Vec<u8> {
        self.device.take().unwrap_or_else(|| ::std::vec::Vec::new())
    }

    // optional bytes product = 3;


    pub fn get_product(&self) -> &[u8] {
        match self.product.as_ref() {
            Some(v) => &v,
            None => &[],
        }
    }
    pub fn clear_product(&mut self) {
        self.product.clear();
    }

    pub fn has_product(&self) -> bool {
        self.product.is_some()
    }

    // Param is passed by value, moved
    pub fn set_product(&mut self, v: ::std::vec::Vec<u8>) {
        self.product = ::protobuf::SingularField::some(v);
    }

    // Mutable pointer to the field.
    // If field is not initialized, it is initialized with default value first.
    pub fn mut_product(&mut self) -> &mut ::std::vec::Vec<u8> {
        if self.product.is_none() {
            self.product.set_default();
        }
        self.product.as_mut().unwrap()
    }

    // Take field
    pub fn take_product(&mut self) -> ::std::vec::Vec<u8> {
        self.product.take().unwrap_or_else(|| ::std::vec::Vec::new())
    }

    // optional bytes serial = 4;


    pub fn get_serial(&self) -> &[u8] {
        match self.serial.as_ref() {
            Some(v) => &v,
            None => &[],
        }
    }
    pub fn clear_serial(&mut self) {
        self.serial.clear();
    }

    pub fn has_serial(&self) -> bool {
        self.serial.is_some()
    }

    // Param is passed by value, moved
    pub fn set_serial(&mut self, v: ::std::vec::Vec<u8>) {
        self.serial = ::protobuf::SingularField::some(v);
    }

    // Mutable pointer to the field.
    // If field is not initialized, it is initialized with default value first.
    pub fn mut_serial(&mut self) -> &mut ::std::vec::Vec<u8> {
        if self.serial.is_none() {
            self.serial.set_default();
        }
        self.serial.as_mut().unwrap()
    }

    // Take field
    pub fn take_serial(&mut self) -> ::std::vec::Vec<u8> {
        self.serial.take().unwrap_or_else(|| ::std::vec::Vec::new())
    }

    // optional bytes imei = 5;


    pub fn get_imei(&self) -> &[u8] {
        match self.imei.as_ref() {
            Some(v) => &v,
            None => &[],
        }
    }
    pub fn clear_imei(&mut self) {
        self.imei.clear();
    }

    pub fn has_imei(&self) -> bool {
        self.imei.is_some()
    }

    // Param is passed by value, moved
    pub fn set_imei(&mut self, v: ::std::vec::Vec<u8>) {
        self.imei = ::protobuf::SingularField::some(v);
    }

    // Mutable pointer to the field.
    // If field is not initialized, it is initialized with default value first.
    pub fn mut_imei(&mut self) -> &mut ::std::vec::Vec<u8> {
        if self.imei.is_none() {
            self.imei.set_default();
        }
        self.imei.as_mut().unwrap()
    }

    // Take field
    pub fn take_imei(&mut self) -> ::std::vec::Vec<u8> {
        self.imei.take().unwrap_or_else(|| ::std::vec::Vec::new())
    }

    // optional bytes meid = 6;


    pub fn get_meid(&self) -> &[u8] {
        match self.meid.as_ref() {
            Some(v) => &v,
            None => &[],
        }
    }
    pub fn clear_meid(&mut self) {
        self.meid.clear();
    }

    pub fn has_meid(&self) -> bool {
        self.meid.is_some()
    }

    // Param is passed by value, moved
    pub fn set_meid(&mut self, v: ::std::vec::Vec<u8>) {
        self.meid = ::protobuf::SingularField::some(v);
    }

    // Mutable pointer to the field.
    // If field is not initialized, it is initialized with default value first.
    pub fn mut_meid(&mut self) -> &mut ::std::vec::Vec<u8> {
        if self.meid.is_none() {
            self.meid.set_default();
        }
        self.meid.as_mut().unwrap()
    }

    // Take field
    pub fn take_meid(&mut self) -> ::std::vec::Vec<u8> {
        self.meid.take().unwrap_or_else(|| ::std::vec::Vec::new())
    }

    // optional bytes manufacturer = 7;


    pub fn get_manufacturer(&self) -> &[u8] {
        match self.manufacturer.as_ref() {
            Some(v) => &v,
            None => &[],
        }
    }
    pub fn clear_manufacturer(&mut self) {
        self.manufacturer.clear();
    }

    pub fn has_manufacturer(&self) -> bool {
        self.manufacturer.is_some()
    }

    // Param is passed by value, moved
    pub fn set_manufacturer(&mut self, v: ::std::vec::Vec<u8>) {
        self.manufacturer = ::protobuf::SingularField::some(v);
    }

    // Mutable pointer to the field.
    // If field is not initialized, it is initialized with default value first.
    pub fn mut_manufacturer(&mut self) -> &mut ::std::vec::Vec<u8> {
        if self.manufacturer.is_none() {
            self.manufacturer.set_default();
        }
        self.manufacturer.as_mut().unwrap()
    }

    // Take field
    pub fn take_manufacturer(&mut self) -> ::std::vec::Vec<u8> {
        self.manufacturer.take().unwrap_or_else(|| ::std::vec::Vec::new())
    }

    // optional bytes model = 8;


    pub fn get_model(&self) -> &[u8] {
        match self.model.as_ref() {
            Some(v) => &v,
            None => &[],
        }
    }
    pub fn clear_model(&mut self) {
        self.model.clear();
    }

    pub fn has_model(&self) -> bool {
        self.model.is_some()
    }

    // Param is passed by value, moved
    pub fn set_model(&mut self, v: ::std::vec::Vec<u8>) {
        self.model = ::protobuf::SingularField::some(v);
    }

    // Mutable pointer to the field.
    // If field is not initialized, it is initialized with default value first.
    pub fn mut_model(&mut self) -> &mut ::std::vec::Vec<u8> {
        if self.model.is_none() {
            self.model.set_default();
        }
        self.model.as_mut().unwrap()
    }

    // Take field
    pub fn take_model(&mut self) -> ::std::vec::Vec<u8> {
        self.model.take().unwrap_or_else(|| ::std::vec::Vec::new())
    }
}

impl ::protobuf::Message for AttestationIds {
    fn is_initialized(&self) -> bool {
        true
    }

    fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> {
        while !is.eof()? {
            let (field_number, wire_type) = is.read_tag_unpack()?;
            match field_number {
                1 => {
                    ::protobuf::rt::read_singular_bytes_into(wire_type, is, &mut self.brand)?;
                },
                2 => {
                    ::protobuf::rt::read_singular_bytes_into(wire_type, is, &mut self.device)?;
                },
                3 => {
                    ::protobuf::rt::read_singular_bytes_into(wire_type, is, &mut self.product)?;
                },
                4 => {
                    ::protobuf::rt::read_singular_bytes_into(wire_type, is, &mut self.serial)?;
                },
                5 => {
                    ::protobuf::rt::read_singular_bytes_into(wire_type, is, &mut self.imei)?;
                },
                6 => {
                    ::protobuf::rt::read_singular_bytes_into(wire_type, is, &mut self.meid)?;
                },
                7 => {
                    ::protobuf::rt::read_singular_bytes_into(wire_type, is, &mut self.manufacturer)?;
                },
                8 => {
                    ::protobuf::rt::read_singular_bytes_into(wire_type, is, &mut self.model)?;
                },
                _ => {
                    ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?;
                },
            };
        }
        ::std::result::Result::Ok(())
    }

    // Compute sizes of nested messages
    #[allow(unused_variables)]
    fn compute_size(&self) -> u32 {
        let mut my_size = 0;
        if let Some(ref v) = self.brand.as_ref() {
            my_size += ::protobuf::rt::bytes_size(1, &v);
        }
        if let Some(ref v) = self.device.as_ref() {
            my_size += ::protobuf::rt::bytes_size(2, &v);
        }
        if let Some(ref v) = self.product.as_ref() {
            my_size += ::protobuf::rt::bytes_size(3, &v);
        }
        if let Some(ref v) = self.serial.as_ref() {
            my_size += ::protobuf::rt::bytes_size(4, &v);
        }
        if let Some(ref v) = self.imei.as_ref() {
            my_size += ::protobuf::rt::bytes_size(5, &v);
        }
        if let Some(ref v) = self.meid.as_ref() {
            my_size += ::protobuf::rt::bytes_size(6, &v);
        }
        if let Some(ref v) = self.manufacturer.as_ref() {
            my_size += ::protobuf::rt::bytes_size(7, &v);
        }
        if let Some(ref v) = self.model.as_ref() {
            my_size += ::protobuf::rt::bytes_size(8, &v);
        }
        my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields());
        self.cached_size.set(my_size);
        my_size
    }

    fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> {
        if let Some(ref v) = self.brand.as_ref() {
            os.write_bytes(1, &v)?;
        }
        if let Some(ref v) = self.device.as_ref() {
            os.write_bytes(2, &v)?;
        }
        if let Some(ref v) = self.product.as_ref() {
            os.write_bytes(3, &v)?;
        }
        if let Some(ref v) = self.serial.as_ref() {
            os.write_bytes(4, &v)?;
        }
        if let Some(ref v) = self.imei.as_ref() {
            os.write_bytes(5, &v)?;
        }
        if let Some(ref v) = self.meid.as_ref() {
            os.write_bytes(6, &v)?;
        }
        if let Some(ref v) = self.manufacturer.as_ref() {
            os.write_bytes(7, &v)?;
        }
        if let Some(ref v) = self.model.as_ref() {
            os.write_bytes(8, &v)?;
        }
        os.write_unknown_fields(self.get_unknown_fields())?;
        ::std::result::Result::Ok(())
    }

    fn get_cached_size(&self) -> u32 {
        self.cached_size.get()
    }

    fn get_unknown_fields(&self) -> &::protobuf::UnknownFields {
        &self.unknown_fields
    }

    fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields {
        &mut self.unknown_fields
    }

    fn as_any(&self) -> &dyn (::std::any::Any) {
        self as &dyn (::std::any::Any)
    }
    fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) {
        self as &mut dyn (::std::any::Any)
    }
    fn into_any(self: ::std::boxed::Box<Self>) -> ::std::boxed::Box<dyn (::std::any::Any)> {
        self
    }

    fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor {
        Self::descriptor_static()
    }

    fn new() -> AttestationIds {
        AttestationIds::new()
    }

    fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor {
        static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT;
        descriptor.get(|| {
            let mut fields = ::std::vec::Vec::new();
            fields.push(::protobuf::reflect::accessor::make_singular_field_accessor::<_, ::protobuf::types::ProtobufTypeBytes>(
                "brand",
                |m: &AttestationIds| { &m.brand },
                |m: &mut AttestationIds| { &mut m.brand },
            ));
            fields.push(::protobuf::reflect::accessor::make_singular_field_accessor::<_, ::protobuf::types::ProtobufTypeBytes>(
                "device",
                |m: &AttestationIds| { &m.device },
                |m: &mut AttestationIds| { &mut m.device },
            ));
            fields.push(::protobuf::reflect::accessor::make_singular_field_accessor::<_, ::protobuf::types::ProtobufTypeBytes>(
                "product",
                |m: &AttestationIds| { &m.product },
                |m: &mut AttestationIds| { &mut m.product },
            ));
            fields.push(::protobuf::reflect::accessor::make_singular_field_accessor::<_, ::protobuf::types::ProtobufTypeBytes>(
                "serial",
                |m: &AttestationIds| { &m.serial },
                |m: &mut AttestationIds| { &mut m.serial },
            ));
            fields.push(::protobuf::reflect::accessor::make_singular_field_accessor::<_, ::protobuf::types::ProtobufTypeBytes>(
                "imei",
                |m: &AttestationIds| { &m.imei },
                |m: &mut AttestationIds| { &mut m.imei },
            ));
            fields.push(::protobuf::reflect::accessor::make_singular_field_accessor::<_, ::protobuf::types::ProtobufTypeBytes>(
                "meid",
                |m: &AttestationIds| { &m.meid },
                |m: &mut AttestationIds| { &mut m.meid },
            ));
            fields.push(::protobuf::reflect::accessor::make_singular_field_accessor::<_, ::protobuf::types::ProtobufTypeBytes>(
                "manufacturer",
                |m: &AttestationIds| { &m.manufacturer },
                |m: &mut AttestationIds| { &mut m.manufacturer },
            ));
            fields.push(::protobuf::reflect::accessor::make_singular_field_accessor::<_, ::protobuf::types::ProtobufTypeBytes>(
                "model",
                |m: &AttestationIds| { &m.model },
                |m: &mut AttestationIds| { &mut m.model },
            ));
            ::protobuf::reflect::MessageDescriptor::new_pb_name::<AttestationIds>(
                "AttestationIds",
                fields,
                file_descriptor_proto()
            )
        })
    }

    fn default_instance() -> &'static AttestationIds {
        static instance: ::protobuf::rt::LazyV2<AttestationIds> = ::protobuf::rt::LazyV2::INIT;
        instance.get(AttestationIds::new)
    }
}

impl ::protobuf::Clear for AttestationIds {
    fn clear(&mut self) {
        self.brand.clear();
        self.device.clear();
        self.product.clear();
        self.serial.clear();
        self.imei.clear();
        self.meid.clear();
        self.manufacturer.clear();
        self.model.clear();
        self.unknown_fields.clear();
    }
}

impl ::std::fmt::Debug for AttestationIds {
    fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
        ::protobuf::text_format::fmt(self, f)
    }
}

impl ::protobuf::reflect::ProtobufValue for AttestationIds {
    fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef {
        ::protobuf::reflect::ReflectValueRef::Message(self)
    }
}

#[derive(PartialEq,Clone,Default)]
pub struct AttestationKey {
    // message fields
    key: ::protobuf::SingularField<::std::vec::Vec<u8>>,
    pub certs: ::protobuf::RepeatedField<AttestationCert>,
    // special fields
    pub unknown_fields: ::protobuf::UnknownFields,
    pub cached_size: ::protobuf::CachedSize,
}

impl<'a> ::std::default::Default for &'a AttestationKey {
    fn default() -> &'a AttestationKey {
        <AttestationKey as ::protobuf::Message>::default_instance()
    }
}

impl AttestationKey {
    pub fn new() -> AttestationKey {
        ::std::default::Default::default()
    }

    // optional bytes key = 1;


    pub fn get_key(&self) -> &[u8] {
        match self.key.as_ref() {
            Some(v) => &v,
            None => &[],
        }
    }
    pub fn clear_key(&mut self) {
        self.key.clear();
    }

    pub fn has_key(&self) -> bool {
        self.key.is_some()
    }

    // Param is passed by value, moved
    pub fn set_key(&mut self, v: ::std::vec::Vec<u8>) {
        self.key = ::protobuf::SingularField::some(v);
    }

    // Mutable pointer to the field.
    // If field is not initialized, it is initialized with default value first.
    pub fn mut_key(&mut self) -> &mut ::std::vec::Vec<u8> {
        if self.key.is_none() {
            self.key.set_default();
        }
        self.key.as_mut().unwrap()
    }

    // Take field
    pub fn take_key(&mut self) -> ::std::vec::Vec<u8> {
        self.key.take().unwrap_or_else(|| ::std::vec::Vec::new())
    }

    // repeated .AttestationCert certs = 2;


    pub fn get_certs(&self) -> &[AttestationCert] {
        &self.certs
    }
    pub fn clear_certs(&mut self) {
        self.certs.clear();
    }

    // Param is passed by value, moved
    pub fn set_certs(&mut self, v: ::protobuf::RepeatedField<AttestationCert>) {
        self.certs = v;
    }

    // Mutable pointer to the field.
    pub fn mut_certs(&mut self) -> &mut ::protobuf::RepeatedField<AttestationCert> {
        &mut self.certs
    }

    // Take field
    pub fn take_certs(&mut self) -> ::protobuf::RepeatedField<AttestationCert> {
        ::std::mem::replace(&mut self.certs, ::protobuf::RepeatedField::new())
    }
}

impl ::protobuf::Message for AttestationKey {
    fn is_initialized(&self) -> bool {
        for v in &self.certs {
            if !v.is_initialized() {
                return false;
            }
        };
        true
    }

    fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> {
        while !is.eof()? {
            let (field_number, wire_type) = is.read_tag_unpack()?;
            match field_number {
                1 => {
                    ::protobuf::rt::read_singular_bytes_into(wire_type, is, &mut self.key)?;
                },
                2 => {
                    ::protobuf::rt::read_repeated_message_into(wire_type, is, &mut self.certs)?;
                },
                _ => {
                    ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?;
                },
            };
        }
        ::std::result::Result::Ok(())
    }

    // Compute sizes of nested messages
    #[allow(unused_variables)]
    fn compute_size(&self) -> u32 {
        let mut my_size = 0;
        if let Some(ref v) = self.key.as_ref() {
            my_size += ::protobuf::rt::bytes_size(1, &v);
        }
        for value in &self.certs {
            let len = value.compute_size();
            my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len;
        };
        my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields());
        self.cached_size.set(my_size);
        my_size
    }

    fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> {
        if let Some(ref v) = self.key.as_ref() {
            os.write_bytes(1, &v)?;
        }
        for v in &self.certs {
            os.write_tag(2, ::protobuf::wire_format::WireTypeLengthDelimited)?;
            os.write_raw_varint32(v.get_cached_size())?;
            v.write_to_with_cached_sizes(os)?;
        };
        os.write_unknown_fields(self.get_unknown_fields())?;
        ::std::result::Result::Ok(())
    }

    fn get_cached_size(&self) -> u32 {
        self.cached_size.get()
    }

    fn get_unknown_fields(&self) -> &::protobuf::UnknownFields {
        &self.unknown_fields
    }

    fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields {
        &mut self.unknown_fields
    }

    fn as_any(&self) -> &dyn (::std::any::Any) {
        self as &dyn (::std::any::Any)
    }
    fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) {
        self as &mut dyn (::std::any::Any)
    }
    fn into_any(self: ::std::boxed::Box<Self>) -> ::std::boxed::Box<dyn (::std::any::Any)> {
        self
    }

    fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor {
        Self::descriptor_static()
    }

    fn new() -> AttestationKey {
        AttestationKey::new()
    }

    fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor {
        static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT;
        descriptor.get(|| {
            let mut fields = ::std::vec::Vec::new();
            fields.push(::protobuf::reflect::accessor::make_singular_field_accessor::<_, ::protobuf::types::ProtobufTypeBytes>(
                "key",
                |m: &AttestationKey| { &m.key },
                |m: &mut AttestationKey| { &mut m.key },
            ));
            fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage<AttestationCert>>(
                "certs",
                |m: &AttestationKey| { &m.certs },
                |m: &mut AttestationKey| { &mut m.certs },
            ));
            ::protobuf::reflect::MessageDescriptor::new_pb_name::<AttestationKey>(
                "AttestationKey",
                fields,
                file_descriptor_proto()
            )
        })
    }

    fn default_instance() -> &'static AttestationKey {
        static instance: ::protobuf::rt::LazyV2<AttestationKey> = ::protobuf::rt::LazyV2::INIT;
        instance.get(AttestationKey::new)
    }
}

impl ::protobuf::Clear for AttestationKey {
    fn clear(&mut self) {
        self.key.clear();
        self.certs.clear();
        self.unknown_fields.clear();
    }
}

impl ::std::fmt::Debug for AttestationKey {
    fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
        ::protobuf::text_format::fmt(self, f)
    }
}

impl ::protobuf::reflect::ProtobufValue for AttestationKey {
    fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef {
        ::protobuf::reflect::ReflectValueRef::Message(self)
    }
}

#[derive(PartialEq,Clone,Default)]
pub struct AttestationCert {
    // message fields
    content: ::protobuf::SingularField<::std::vec::Vec<u8>>,
    // special fields
    pub unknown_fields: ::protobuf::UnknownFields,
    pub cached_size: ::protobuf::CachedSize,
}

impl<'a> ::std::default::Default for &'a AttestationCert {
    fn default() -> &'a AttestationCert {
        <AttestationCert as ::protobuf::Message>::default_instance()
    }
}

impl AttestationCert {
    pub fn new() -> AttestationCert {
        ::std::default::Default::default()
    }

    // required bytes content = 1;


    pub fn get_content(&self) -> &[u8] {
        match self.content.as_ref() {
            Some(v) => &v,
            None => &[],
        }
    }
    pub fn clear_content(&mut self) {
        self.content.clear();
    }

    pub fn has_content(&self) -> bool {
        self.content.is_some()
    }

    // Param is passed by value, moved
    pub fn set_content(&mut self, v: ::std::vec::Vec<u8>) {
        self.content = ::protobuf::SingularField::some(v);
    }

    // Mutable pointer to the field.
    // If field is not initialized, it is initialized with default value first.
    pub fn mut_content(&mut self) -> &mut ::std::vec::Vec<u8> {
        if self.content.is_none() {
            self.content.set_default();
        }
        self.content.as_mut().unwrap()
    }

    // Take field
    pub fn take_content(&mut self) -> ::std::vec::Vec<u8> {
        self.content.take().unwrap_or_else(|| ::std::vec::Vec::new())
    }
}

impl ::protobuf::Message for AttestationCert {
    fn is_initialized(&self) -> bool {
        if self.content.is_none() {
            return false;
        }
        true
    }

    fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> {
        while !is.eof()? {
            let (field_number, wire_type) = is.read_tag_unpack()?;
            match field_number {
                1 => {
                    ::protobuf::rt::read_singular_bytes_into(wire_type, is, &mut self.content)?;
                },
                _ => {
                    ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?;
                },
            };
        }
        ::std::result::Result::Ok(())
    }

    // Compute sizes of nested messages
    #[allow(unused_variables)]
    fn compute_size(&self) -> u32 {
        let mut my_size = 0;
        if let Some(ref v) = self.content.as_ref() {
            my_size += ::protobuf::rt::bytes_size(1, &v);
        }
        my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields());
        self.cached_size.set(my_size);
        my_size
    }

    fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> {
        if let Some(ref v) = self.content.as_ref() {
            os.write_bytes(1, &v)?;
        }
        os.write_unknown_fields(self.get_unknown_fields())?;
        ::std::result::Result::Ok(())
    }

    fn get_cached_size(&self) -> u32 {
        self.cached_size.get()
    }

    fn get_unknown_fields(&self) -> &::protobuf::UnknownFields {
        &self.unknown_fields
    }

    fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields {
        &mut self.unknown_fields
    }

    fn as_any(&self) -> &dyn (::std::any::Any) {
        self as &dyn (::std::any::Any)
    }
    fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) {
        self as &mut dyn (::std::any::Any)
    }
    fn into_any(self: ::std::boxed::Box<Self>) -> ::std::boxed::Box<dyn (::std::any::Any)> {
        self
    }

    fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor {
        Self::descriptor_static()
    }

    fn new() -> AttestationCert {
        AttestationCert::new()
    }

    fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor {
        static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT;
        descriptor.get(|| {
            let mut fields = ::std::vec::Vec::new();
            fields.push(::protobuf::reflect::accessor::make_singular_field_accessor::<_, ::protobuf::types::ProtobufTypeBytes>(
                "content",
                |m: &AttestationCert| { &m.content },
                |m: &mut AttestationCert| { &mut m.content },
            ));
            ::protobuf::reflect::MessageDescriptor::new_pb_name::<AttestationCert>(
                "AttestationCert",
                fields,
                file_descriptor_proto()
            )
        })
    }

    fn default_instance() -> &'static AttestationCert {
        static instance: ::protobuf::rt::LazyV2<AttestationCert> = ::protobuf::rt::LazyV2::INIT;
        instance.get(AttestationCert::new)
    }
}

impl ::protobuf::Clear for AttestationCert {
    fn clear(&mut self) {
        self.content.clear();
        self.unknown_fields.clear();
    }
}

impl ::std::fmt::Debug for AttestationCert {
    fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
        ::protobuf::text_format::fmt(self, f)
    }
}

impl ::protobuf::reflect::ProtobufValue for AttestationCert {
    fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef {
        ::protobuf::reflect::ReflectValueRef::Message(self)
    }
}

static file_descriptor_proto_data: &'static [u8] = b"\
    \n\x1akeymaster_attributes.proto\x1a\x0cnanopb.proto\"V\n\x13KeymasterAt\
    tributes\x12\x19\n\x04uuid\x18\x01\x20\x01(\x0cR\x04uuidB\x05\x92?\x02\
    \x08\x20\x12$\n\nproduct_id\x18\x02\x20\x01(\x0cR\tproductIdB\x05\x92?\
    \x02\x08\x10\"\x8a\x02\n\x0eAttestationIds\x12\x1b\n\x05brand\x18\x01\
    \x20\x01(\x0cR\x05brandB\x05\x92?\x02\x08@\x12\x1d\n\x06device\x18\x02\
    \x20\x01(\x0cR\x06deviceB\x05\x92?\x02\x08@\x12\x1f\n\x07product\x18\x03\
    \x20\x01(\x0cR\x07productB\x05\x92?\x02\x08@\x12\x1d\n\x06serial\x18\x04\
    \x20\x01(\x0cR\x06serialB\x05\x92?\x02\x08@\x12\x19\n\x04imei\x18\x05\
    \x20\x01(\x0cR\x04imeiB\x05\x92?\x02\x08@\x12\x19\n\x04meid\x18\x06\x20\
    \x01(\x0cR\x04meidB\x05\x92?\x02\x08@\x12)\n\x0cmanufacturer\x18\x07\x20\
    \x01(\x0cR\x0cmanufacturerB\x05\x92?\x02\x08@\x12\x1b\n\x05model\x18\x08\
    \x20\x01(\x0cR\x05modelB\x05\x92?\x02\x08@\"Y\n\x0eAttestationKey\x12\
    \x18\n\x03key\x18\x01\x20\x01(\x0cR\x03keyB\x06\x92?\x03\x08\x80\x10\x12\
    -\n\x05certs\x18\x02\x20\x03(\x0b2\x10.AttestationCertR\x05certsB\x05\
    \x92?\x02\x10\x03\"3\n\x0fAttestationCert\x12\x20\n\x07content\x18\x01\
    \x20\x02(\x0cR\x07contentB\x06\x92?\x03\x08\x80\x10J\xb0\x17\n\x06\x12\
    \x04%\0@\x02\n\xa6\x0c\n\x01\x0c\x12\x03%\0\x122\xcc\x04\n\x20Copyright\
    \x20(C)\x202018\x20The\x20Android\x20Open\x20Source\x20Project\n\n\x20Li\
    censed\x20under\x20the\x20Apache\x20License,\x20Version\x202.0\x20(the\
    \x20\"License\");\n\x20you\x20may\x20not\x20use\x20this\x20file\x20excep\
    t\x20in\x20compliance\x20with\x20the\x20License.\n\x20You\x20may\x20obta\
    in\x20a\x20copy\x20of\x20the\x20License\x20at\n\n\x20\x20\x20\x20\x20\
    \x20http://www.apache.org/licenses/LICENSE-2.0\n\n\x20Unless\x20required\
    \x20by\x20applicable\x20law\x20or\x20agreed\x20to\x20in\x20writing,\x20s\
    oftware\n\x20distributed\x20under\x20the\x20License\x20is\x20distributed\
    \x20on\x20an\x20\"AS\x20IS\"\x20BASIS,\n\x20WITHOUT\x20WARRANTIES\x20OR\
    \x20CONDITIONS\x20OF\x20ANY\x20KIND,\x20either\x20express\x20or\x20impli\
    ed.\n\x20See\x20the\x20License\x20for\x20the\x20specific\x20language\x20\
    governing\x20permissions\x20and\n\x20limitations\x20under\x20the\x20Lice\
    nse.\n2\xcc\x07\x20We\x20check\x20in\x20the\x20prebuilt\x20nanopb\x20pro\
    tobuf\x20file\x20under\x20the\x20current\x20folder\n\x20because\x20the\
    \x20compile\x20tool\x20chain\x20using\x20trusty/user/base/make/compile_p\
    roto.mk\n\x20might\x20not\x20work\x20under\x20certain\x20environment\x20\
    with\x20lower\x20version\x20of\x20python\n\x20protobuf\x20installed.\x20\
    You\x20need\x20to\x20generate\x20and\x20check\x20in\x20the\x20new\x20pro\
    tobuf\x20file\n\x20if\x20you\x20change\x20this\x20file\x20in\x20order\
    \x20for\x20the\x20change\x20to\x20take\x20effect!\n\n\x20To\x20generate\
    \x20the\x20file\x20using\x20the\x20tool\x20chain\x20in\x20trusty\x20tree\
    ,\x20add\x20the\x20following\n\x20command\x20to\x20rules.mk:\n\n\x20PB_G\
    EN_DIR\x20:=\x20[Your\x20generation\x20folder]\n\x20include\x20trusty/us\
    er/base/make/compile_proto.mk\n\x20$(eval\x20$(call\x20compile_proto,$(K\
    EYMASTER_DIR)/keymaster_attributes.proto,$(PB_GEN_DIR)))\n\n\x20The\x20g\
    enerated\x20.pb.c\x20and\x20.pb.h\x20file\x20would\x20be\x20under\x20PB_\
    GEN_DIR,\x20include\x20them\n\x20to\x20the\x20source\x20path.\n\n\x20To\
    \x20generate\x20the\x20file\x20using\x20your\x20own\x20tool\x20chain,\
    \x20please\x20follow\x20the\x20guide\x20at\n\x20https://github.com/nanop\
    b/nanopb.\n\x20Please\x20check\x20the\x20nanopb\x20version\x20in\x20trus\
    ty\x20tree\x20at\x20external/nanopb-c\x20to\x20make\n\x20sure\x20you\x20\
    are\x20using\x20the\x20same\x20nanopb\x20version.\n\n\t\n\x02\x03\0\x12\
    \x03'\x07\x15\n\n\n\x02\x04\0\x12\x04)\0,\x01\n\n\n\x03\x04\0\x01\x12\
    \x03)\x08\x1b\n\x0b\n\x04\x04\0\x02\0\x12\x03*\x021\n\x0c\n\x05\x04\0\
    \x02\0\x04\x12\x03*\x02\n\n\x0c\n\x05\x04\0\x02\0\x05\x12\x03*\x0b\x10\n\
    \x0c\n\x05\x04\0\x02\0\x01\x12\x03*\x11\x15\n\x0c\n\x05\x04\0\x02\0\x03\
    \x12\x03*\x18\x19\n\x0c\n\x05\x04\0\x02\0\x08\x12\x03*\x1a0\n\x0f\n\x08\
    \x04\0\x02\0\x08\xf2\x07\x01\x12\x03*\x1b/\n\x0b\n\x04\x04\0\x02\x01\x12\
    \x03+\x027\n\x0c\n\x05\x04\0\x02\x01\x04\x12\x03+\x02\n\n\x0c\n\x05\x04\
    \0\x02\x01\x05\x12\x03+\x0b\x10\n\x0c\n\x05\x04\0\x02\x01\x01\x12\x03+\
    \x11\x1b\n\x0c\n\x05\x04\0\x02\x01\x03\x12\x03+\x1e\x1f\n\x0c\n\x05\x04\
    \0\x02\x01\x08\x12\x03+\x206\n\x0f\n\x08\x04\0\x02\x01\x08\xf2\x07\x01\
    \x12\x03+!5\n\n\n\x02\x04\x01\x12\x04.\07\x01\n\n\n\x03\x04\x01\x01\x12\
    \x03.\x08\x16\n\x0b\n\x04\x04\x01\x02\0\x12\x03/\x044\n\x0c\n\x05\x04\
    \x01\x02\0\x04\x12\x03/\x04\x0c\n\x0c\n\x05\x04\x01\x02\0\x05\x12\x03/\r\
    \x12\n\x0c\n\x05\x04\x01\x02\0\x01\x12\x03/\x13\x18\n\x0c\n\x05\x04\x01\
    \x02\0\x03\x12\x03/\x1b\x1c\n\x0c\n\x05\x04\x01\x02\0\x08\x12\x03/\x1d3\
    \n\x0f\n\x08\x04\x01\x02\0\x08\xf2\x07\x01\x12\x03/\x1e2\n\x0b\n\x04\x04\
    \x01\x02\x01\x12\x030\x045\n\x0c\n\x05\x04\x01\x02\x01\x04\x12\x030\x04\
    \x0c\n\x0c\n\x05\x04\x01\x02\x01\x05\x12\x030\r\x12\n\x0c\n\x05\x04\x01\
    \x02\x01\x01\x12\x030\x13\x19\n\x0c\n\x05\x04\x01\x02\x01\x03\x12\x030\
    \x1c\x1d\n\x0c\n\x05\x04\x01\x02\x01\x08\x12\x030\x1e4\n\x0f\n\x08\x04\
    \x01\x02\x01\x08\xf2\x07\x01\x12\x030\x1f3\n\x0b\n\x04\x04\x01\x02\x02\
    \x12\x031\x046\n\x0c\n\x05\x04\x01\x02\x02\x04\x12\x031\x04\x0c\n\x0c\n\
    \x05\x04\x01\x02\x02\x05\x12\x031\r\x12\n\x0c\n\x05\x04\x01\x02\x02\x01\
    \x12\x031\x13\x1a\n\x0c\n\x05\x04\x01\x02\x02\x03\x12\x031\x1d\x1e\n\x0c\
    \n\x05\x04\x01\x02\x02\x08\x12\x031\x1f5\n\x0f\n\x08\x04\x01\x02\x02\x08\
    \xf2\x07\x01\x12\x031\x204\n\x0b\n\x04\x04\x01\x02\x03\x12\x032\x045\n\
    \x0c\n\x05\x04\x01\x02\x03\x04\x12\x032\x04\x0c\n\x0c\n\x05\x04\x01\x02\
    \x03\x05\x12\x032\r\x12\n\x0c\n\x05\x04\x01\x02\x03\x01\x12\x032\x13\x19\
    \n\x0c\n\x05\x04\x01\x02\x03\x03\x12\x032\x1c\x1d\n\x0c\n\x05\x04\x01\
    \x02\x03\x08\x12\x032\x1e4\n\x0f\n\x08\x04\x01\x02\x03\x08\xf2\x07\x01\
    \x12\x032\x1f3\n\x0b\n\x04\x04\x01\x02\x04\x12\x033\x043\n\x0c\n\x05\x04\
    \x01\x02\x04\x04\x12\x033\x04\x0c\n\x0c\n\x05\x04\x01\x02\x04\x05\x12\
    \x033\r\x12\n\x0c\n\x05\x04\x01\x02\x04\x01\x12\x033\x13\x17\n\x0c\n\x05\
    \x04\x01\x02\x04\x03\x12\x033\x1a\x1b\n\x0c\n\x05\x04\x01\x02\x04\x08\
    \x12\x033\x1c2\n\x0f\n\x08\x04\x01\x02\x04\x08\xf2\x07\x01\x12\x033\x1d1\
    \n\x0b\n\x04\x04\x01\x02\x05\x12\x034\x043\n\x0c\n\x05\x04\x01\x02\x05\
    \x04\x12\x034\x04\x0c\n\x0c\n\x05\x04\x01\x02\x05\x05\x12\x034\r\x12\n\
    \x0c\n\x05\x04\x01\x02\x05\x01\x12\x034\x13\x17\n\x0c\n\x05\x04\x01\x02\
    \x05\x03\x12\x034\x1a\x1b\n\x0c\n\x05\x04\x01\x02\x05\x08\x12\x034\x1c2\
    \n\x0f\n\x08\x04\x01\x02\x05\x08\xf2\x07\x01\x12\x034\x1d1\n\x0b\n\x04\
    \x04\x01\x02\x06\x12\x035\x04;\n\x0c\n\x05\x04\x01\x02\x06\x04\x12\x035\
    \x04\x0c\n\x0c\n\x05\x04\x01\x02\x06\x05\x12\x035\r\x12\n\x0c\n\x05\x04\
    \x01\x02\x06\x01\x12\x035\x13\x1f\n\x0c\n\x05\x04\x01\x02\x06\x03\x12\
    \x035\"#\n\x0c\n\x05\x04\x01\x02\x06\x08\x12\x035$:\n\x0f\n\x08\x04\x01\
    \x02\x06\x08\xf2\x07\x01\x12\x035%9\n\x0b\n\x04\x04\x01\x02\x07\x12\x036\
    \x044\n\x0c\n\x05\x04\x01\x02\x07\x04\x12\x036\x04\x0c\n\x0c\n\x05\x04\
    \x01\x02\x07\x05\x12\x036\r\x12\n\x0c\n\x05\x04\x01\x02\x07\x01\x12\x036\
    \x13\x18\n\x0c\n\x05\x04\x01\x02\x07\x03\x12\x036\x1b\x1c\n\x0c\n\x05\
    \x04\x01\x02\x07\x08\x12\x036\x1d3\n\x0f\n\x08\x04\x01\x02\x07\x08\xf2\
    \x07\x01\x12\x036\x1e2\n\n\n\x02\x04\x02\x12\x049\0<\x01\n\n\n\x03\x04\
    \x02\x01\x12\x039\x08\x16\n\x0b\n\x04\x04\x02\x02\0\x12\x03:\x022\n\x0c\
    \n\x05\x04\x02\x02\0\x04\x12\x03:\x02\n\n\x0c\n\x05\x04\x02\x02\0\x05\
    \x12\x03:\x0b\x10\n\x0c\n\x05\x04\x02\x02\0\x01\x12\x03:\x11\x14\n\x0c\n\
    \x05\x04\x02\x02\0\x03\x12\x03:\x17\x18\n\x0c\n\x05\x04\x02\x02\0\x08\
    \x12\x03:\x191\n\x0f\n\x08\x04\x02\x02\0\x08\xf2\x07\x01\x12\x03:\x1a0\n\
    \x0b\n\x04\x04\x02\x02\x01\x12\x03;\x02<\n\x0c\n\x05\x04\x02\x02\x01\x04\
    \x12\x03;\x02\n\n\x0c\n\x05\x04\x02\x02\x01\x06\x12\x03;\x0b\x1a\n\x0c\n\
    \x05\x04\x02\x02\x01\x01\x12\x03;\x1b\x20\n\x0c\n\x05\x04\x02\x02\x01\
    \x03\x12\x03;#$\n\x0c\n\x05\x04\x02\x02\x01\x08\x12\x03;%;\n\x0f\n\x08\
    \x04\x02\x02\x01\x08\xf2\x07\x02\x12\x03;&:\n\n\n\x02\x04\x03\x12\x04>\0\
    @\x01\n\n\n\x03\x04\x03\x01\x12\x03>\x08\x17\n\x0b\n\x04\x04\x03\x02\0\
    \x12\x03?\x026\n\x0c\n\x05\x04\x03\x02\0\x04\x12\x03?\x02\n\n\x0c\n\x05\
    \x04\x03\x02\0\x05\x12\x03?\x0b\x10\n\x0c\n\x05\x04\x03\x02\0\x01\x12\
    \x03?\x11\x18\n\x0c\n\x05\x04\x03\x02\0\x03\x12\x03?\x1b\x1c\n\x0c\n\x05\
    \x04\x03\x02\0\x08\x12\x03?\x1d5\n\x0f\n\x08\x04\x03\x02\0\x08\xf2\x07\
    \x01\x12\x03?\x1e4\
";

static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT;

fn parse_descriptor_proto() -> ::protobuf::descriptor::FileDescriptorProto {
    ::protobuf::Message::parse_from_bytes(file_descriptor_proto_data).unwrap()
}

pub fn file_descriptor_proto() -> &'static ::protobuf::descriptor::FileDescriptorProto {
    file_descriptor_proto_lazy.get(|| {
        parse_descriptor_proto()
    })
}
