1 //! Generated messages reflection support. 2 3 use std::fmt; 4 use std::marker; 5 6 use crate::descriptor::FileDescriptorProto; 7 use crate::message_dyn::MessageDyn; 8 use crate::message_full::MessageFull; 9 use crate::reflect::acc::FieldAccessor; 10 use crate::reflect::file::index::FileDescriptorCommon; 11 use crate::reflect::find_message_or_enum::find_message_or_enum; 12 use crate::reflect::find_message_or_enum::MessageOrEnum; 13 use crate::reflect::GeneratedOneofDescriptorData; 14 15 /// Sized to dynamic reflection operations. 16 pub(crate) trait MessageFactory: Send + Sync + 'static { new_instance(&self) -> Box<dyn MessageDyn>17 fn new_instance(&self) -> Box<dyn MessageDyn>; default_instance(&self) -> &dyn MessageDyn18 fn default_instance(&self) -> &dyn MessageDyn; clone(&self, message: &dyn MessageDyn) -> Box<dyn MessageDyn>19 fn clone(&self, message: &dyn MessageDyn) -> Box<dyn MessageDyn>; eq(&self, a: &dyn MessageDyn, b: &dyn MessageDyn) -> bool20 fn eq(&self, a: &dyn MessageDyn, b: &dyn MessageDyn) -> bool; 21 } 22 23 impl<'a> fmt::Debug for &'a dyn MessageFactory { fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result24 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 25 f.debug_struct("MessageFactory").finish() 26 } 27 } 28 29 /// The only message factory implementation. 30 pub(crate) struct MessageFactoryImpl<M>(pub marker::PhantomData<M>); 31 32 impl<M> MessageFactory for MessageFactoryImpl<M> 33 where 34 M: MessageFull, 35 { new_instance(&self) -> Box<dyn MessageDyn>36 fn new_instance(&self) -> Box<dyn MessageDyn> { 37 let m: M = Default::default(); 38 Box::new(m) 39 } 40 default_instance(&self) -> &dyn MessageDyn41 fn default_instance(&self) -> &dyn MessageDyn { 42 M::default_instance() as &dyn MessageDyn 43 } 44 clone(&self, message: &dyn MessageDyn) -> Box<dyn MessageDyn>45 fn clone(&self, message: &dyn MessageDyn) -> Box<dyn MessageDyn> { 46 let m: &M = message.downcast_ref().expect("wrong message type"); 47 Box::new(m.clone()) 48 } 49 eq(&self, a: &dyn MessageDyn, b: &dyn MessageDyn) -> bool50 fn eq(&self, a: &dyn MessageDyn, b: &dyn MessageDyn) -> bool { 51 let a: &M = a.downcast_ref().expect("wrong message type"); 52 let b: &M = b.downcast_ref().expect("wrong message type"); 53 a == b 54 } 55 } 56 57 #[doc(hidden)] 58 pub struct GeneratedMessageDescriptorData { 59 pub(crate) protobuf_name_to_package: &'static str, 60 pub(crate) fields: Vec<FieldAccessor>, 61 pub(crate) factory: &'static dyn MessageFactory, 62 pub(crate) oneofs: Vec<GeneratedOneofDescriptorData>, 63 } 64 65 impl GeneratedMessageDescriptorData { 66 /// Construct a new message descriptor. 67 /// 68 /// This operation is called from generated code and rarely 69 /// need to be called directly. 70 /// 71 /// This function is not a part of public API. 72 #[doc(hidden)] new_2<M: MessageFull>( protobuf_name_to_package: &'static str, fields: Vec<FieldAccessor>, oneofs: Vec<GeneratedOneofDescriptorData>, ) -> GeneratedMessageDescriptorData73 pub fn new_2<M: MessageFull>( 74 protobuf_name_to_package: &'static str, 75 fields: Vec<FieldAccessor>, 76 oneofs: Vec<GeneratedOneofDescriptorData>, 77 ) -> GeneratedMessageDescriptorData { 78 let factory = &MessageFactoryImpl(marker::PhantomData::<M>); 79 GeneratedMessageDescriptorData { 80 protobuf_name_to_package, 81 fields, 82 factory, 83 oneofs, 84 } 85 } 86 } 87 88 #[derive(Debug)] 89 pub(crate) struct NonMapMessageDescriptor { 90 pub(crate) factory: &'static dyn MessageFactory, 91 92 pub(crate) fields: Vec<FieldAccessor>, 93 } 94 95 #[derive(Debug)] 96 pub(crate) struct GeneratedMessageDescriptor { 97 pub(crate) non_map: Option<NonMapMessageDescriptor>, 98 } 99 100 impl GeneratedMessageDescriptor { new_map_entry() -> GeneratedMessageDescriptor101 pub(crate) fn new_map_entry() -> GeneratedMessageDescriptor { 102 GeneratedMessageDescriptor { non_map: None } 103 } 104 new( data: GeneratedMessageDescriptorData, file_descriptor_proto: &'static FileDescriptorProto, _file_index: &FileDescriptorCommon, ) -> GeneratedMessageDescriptor105 pub(crate) fn new( 106 data: GeneratedMessageDescriptorData, 107 file_descriptor_proto: &'static FileDescriptorProto, 108 _file_index: &FileDescriptorCommon, 109 ) -> GeneratedMessageDescriptor { 110 let GeneratedMessageDescriptorData { 111 protobuf_name_to_package, 112 fields, 113 factory, 114 oneofs: _, 115 } = data; 116 117 let (_path_to_package, _proto) = 118 match find_message_or_enum(file_descriptor_proto, protobuf_name_to_package) { 119 Some((path_to_package, MessageOrEnum::Message(m))) => (path_to_package, m), 120 Some((_, MessageOrEnum::Enum(_))) => panic!("not a message"), 121 None => panic!("not found"), 122 }; 123 124 GeneratedMessageDescriptor { 125 non_map: Some(NonMapMessageDescriptor { factory, fields }), 126 } 127 } 128 non_map(&self) -> &NonMapMessageDescriptor129 pub(crate) fn non_map(&self) -> &NonMapMessageDescriptor { 130 match &self.non_map { 131 Some(non_map) => non_map, 132 None => panic!("map message"), 133 } 134 } 135 } 136