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