// 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>>,
    second_imei: ::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())
    }

    // optional bytes second_imei = 9;


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

    pub fn has_second_imei(&self) -> bool {
        self.second_imei.is_some()
    }

    // Param is passed by value, moved
    pub fn set_second_imei(&mut self, v: ::std::vec::Vec<u8>) {
        self.second_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_second_imei(&mut self) -> &mut ::std::vec::Vec<u8> {
        if self.second_imei.is_none() {
            self.second_imei.set_default();
        }
        self.second_imei.as_mut().unwrap()
    }

    // Take field
    pub fn take_second_imei(&mut self) -> ::std::vec::Vec<u8> {
        self.second_imei.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)?;
                },
                9 => {
                    ::protobuf::rt::read_singular_bytes_into(wire_type, is, &mut self.second_imei)?;
                },
                _ => {
                    ::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);
        }
        if let Some(ref v) = self.second_imei.as_ref() {
            my_size += ::protobuf::rt::bytes_size(9, &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)?;
        }
        if let Some(ref v) = self.second_imei.as_ref() {
            os.write_bytes(9, &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 },
            ));
            fields.push(::protobuf::reflect::accessor::make_singular_field_accessor::<_, ::protobuf::types::ProtobufTypeBytes>(
                "second_imei",
                |m: &AttestationIds| { &m.second_imei },
                |m: &mut AttestationIds| { &mut m.second_imei },
            ));
            ::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.second_imei.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\"\xb2\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@\x12&\n\x0bsecond_imei\x18\t\
    \x20\x01(\x0cR\nsecondImeiB\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\x94\x18\n\x06\x12\
    \x04%\0A\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'\0\x16\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.\08\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\x0b\n\x04\x04\x01\x02\x08\x12\x037\x04:\n\x0c\n\
    \x05\x04\x01\x02\x08\x04\x12\x037\x04\x0c\n\x0c\n\x05\x04\x01\x02\x08\
    \x05\x12\x037\r\x12\n\x0c\n\x05\x04\x01\x02\x08\x01\x12\x037\x13\x1e\n\
    \x0c\n\x05\x04\x01\x02\x08\x03\x12\x037!\"\n\x0c\n\x05\x04\x01\x02\x08\
    \x08\x12\x037#9\n\x0f\n\x08\x04\x01\x02\x08\x08\xf2\x07\x01\x12\x037$8\n\
    \n\n\x02\x04\x02\x12\x04:\0=\x01\n\n\n\x03\x04\x02\x01\x12\x03:\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?\0A\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()
    })
}
