protobuf/reflect/file/
dynamic.rs
1use std::collections::HashMap;
2use std::sync::Arc;
3
4use crate::descriptor::FileDescriptorProto;
5use crate::owning_ref::OwningRef;
6use crate::reflect::error::ReflectError;
7use crate::reflect::file::index::FileDescriptorCommon;
8use crate::reflect::FileDescriptor;
9
10#[derive(Debug)]
11pub(crate) struct DynamicFileDescriptor {
12 pub(crate) proto: Arc<FileDescriptorProto>,
13 pub(crate) common: FileDescriptorCommon,
14}
15
16impl DynamicFileDescriptor {
17 pub(crate) fn new(
18 proto: FileDescriptorProto,
19 dependencies: &[FileDescriptor],
20 ) -> crate::Result<DynamicFileDescriptor> {
21 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}