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