1 use std::collections::HashMap;
2 use std::fmt;
3 use std::fmt::Formatter;
4 
5 use crate::descriptor::FileDescriptorProto;
6 use crate::owning_ref::OwningRef;
7 use crate::reflect::enums::generated::GeneratedEnumDescriptor;
8 use crate::reflect::file::index::FileDescriptorCommon;
9 use crate::reflect::message::generated::GeneratedMessageDescriptor;
10 use crate::reflect::oneof::generated::GeneratedOneofDescriptor;
11 use crate::reflect::FileDescriptor;
12 use crate::reflect::GeneratedEnumDescriptorData;
13 use crate::reflect::GeneratedMessageDescriptorData;
14 
15 /// Reflection for objects defined in `.proto` file (messages, enums, etc).
16 #[doc(hidden)]
17 pub struct GeneratedFileDescriptor {
18     pub(crate) proto: &'static FileDescriptorProto,
19     pub(crate) messages: Vec<GeneratedMessageDescriptor>,
20     pub(crate) enums: Vec<GeneratedEnumDescriptor>,
21     pub(crate) oneofs: Vec<GeneratedOneofDescriptor>,
22     pub(crate) common: FileDescriptorCommon,
23 }
24 
25 impl fmt::Debug for GeneratedFileDescriptor {
fmt(&self, f: &mut Formatter<'_>) -> fmt::Result26     fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
27         f.debug_struct("GeneratedFileDescriptor")
28             .field("proto.name", &self.proto.name())
29             .finish_non_exhaustive()
30     }
31 }
32 
33 impl GeneratedFileDescriptor {
34     /// This function is called from generated code.
new_generated( file_descriptor_proto: &'static FileDescriptorProto, dependencies: Vec<FileDescriptor>, messages: Vec<GeneratedMessageDescriptorData>, enums: Vec<GeneratedEnumDescriptorData>, ) -> GeneratedFileDescriptor35     pub fn new_generated(
36         file_descriptor_proto: &'static FileDescriptorProto,
37         dependencies: Vec<FileDescriptor>,
38         messages: Vec<GeneratedMessageDescriptorData>,
39         enums: Vec<GeneratedEnumDescriptorData>,
40     ) -> GeneratedFileDescriptor {
41         let common =
42             FileDescriptorCommon::new(OwningRef::new_static(file_descriptor_proto), dependencies)
43                 .unwrap();
44 
45         let mut messages: HashMap<&str, GeneratedMessageDescriptorData> = messages
46             .into_iter()
47             .map(|m| (m.protobuf_name_to_package, m))
48             .collect();
49 
50         let mut enums: HashMap<&str, GeneratedEnumDescriptorData> =
51             enums.into_iter().map(|e| (e.name_in_file, e)).collect();
52 
53         let mut oneofs = Vec::new();
54         for oneof in &common.oneofs {
55             let message = &common.messages[oneof.containing_message];
56             let message_proto = &message.proto;
57             let oneof_proto = &message_proto.oneof_decl[oneof.index_in_containing_message];
58             let message = messages.get(message.name_to_package.as_str()).unwrap();
59             let oneof_data = &message.oneofs.iter().find(|o| o.name == oneof_proto.name());
60             if oneof.synthetic {
61                 assert!(oneof_data.is_none());
62                 oneofs.push(GeneratedOneofDescriptor::new_synthetic())
63             } else {
64                 let oneof = GeneratedOneofDescriptor::new(oneof_data.unwrap());
65                 oneofs.push(oneof);
66             }
67         }
68 
69         let messages = common
70             .messages
71             .iter()
72             .map(|message_index| {
73                 if message_index.proto.options.map_entry() {
74                     GeneratedMessageDescriptor::new_map_entry()
75                 } else {
76                     let message = messages
77                         .remove(message_index.name_to_package.as_str())
78                         .unwrap();
79                     GeneratedMessageDescriptor::new(message, file_descriptor_proto, &common)
80                 }
81             })
82             .collect();
83 
84         let enums = common
85             .enums
86             .iter()
87             .map(|enum_index| {
88                 let en = enums.remove(enum_index.name_to_package.as_str()).unwrap();
89                 GeneratedEnumDescriptor::new(en, file_descriptor_proto)
90             })
91             .collect();
92 
93         GeneratedFileDescriptor {
94             proto: file_descriptor_proto,
95             messages,
96             enums,
97             oneofs,
98             common,
99         }
100     }
101 }
102