1 use std::collections::HashMap; 2 use std::sync::Arc; 3 4 use crate::descriptor::FileDescriptorProto; 5 use crate::owning_ref::OwningRef; 6 use crate::reflect::error::ReflectError; 7 use crate::reflect::file::index::FileDescriptorCommon; 8 use crate::reflect::FileDescriptor; 9 10 #[derive(Debug)] 11 pub(crate) struct DynamicFileDescriptor { 12 pub(crate) proto: Arc<FileDescriptorProto>, 13 pub(crate) common: FileDescriptorCommon, 14 } 15 16 impl DynamicFileDescriptor { new( proto: FileDescriptorProto, dependencies: &[FileDescriptor], ) -> crate::Result<DynamicFileDescriptor>17 pub(crate) fn new( 18 proto: FileDescriptorProto, 19 dependencies: &[FileDescriptor], 20 ) -> crate::Result<DynamicFileDescriptor> { 21 // Remove undeclared dependencies. 22 let dependencies_index: HashMap<_, &FileDescriptor> = 23 dependencies.iter().map(|d| (d.proto().name(), d)).collect(); 24 25 if dependencies_index.len() != dependencies.len() { 26 return Err(ReflectError::NonUniqueDependencies( 27 dependencies 28 .iter() 29 .map(|d| d.proto().name()) 30 .collect::<Vec<_>>() 31 .join(", "), 32 ) 33 .into()); 34 } 35 36 let dependencies: Vec<FileDescriptor> = proto 37 .dependency 38 .iter() 39 .map(|d| { 40 let dep = dependencies_index.get(d.as_str()); 41 match dep { 42 Some(dep) => Ok((*dep).clone()), 43 None => Err(ReflectError::DependencyNotFound( 44 d.clone(), 45 proto.name().to_owned(), 46 dependencies 47 .iter() 48 .map(|d| d.proto().name()) 49 .collect::<Vec<_>>() 50 .join(", "), 51 ) 52 .into()), 53 } 54 }) 55 .collect::<crate::Result<Vec<_>>>()?; 56 57 let proto = Arc::new(proto); 58 59 let common = FileDescriptorCommon::new(OwningRef::new_arc(proto.clone()), dependencies)?; 60 61 Ok(DynamicFileDescriptor { proto, common }) 62 } 63 } 64