1 use std::fmt;
2 use std::io::Read;
3 
4 use crate::descriptor::DescriptorProto;
5 use crate::descriptor::FileDescriptorProto;
6 use crate::message_dyn::MessageDyn;
7 use crate::message_full::MessageFull;
8 use crate::reflect::dynamic::DynamicMessage;
9 use crate::reflect::file::index::MessageIndices;
10 use crate::reflect::file::FileDescriptorImpl;
11 use crate::reflect::message::generated::GeneratedMessageDescriptor;
12 use crate::reflect::reflect_eq::ReflectEq;
13 use crate::reflect::reflect_eq::ReflectEqMode;
14 use crate::reflect::EnumDescriptor;
15 use crate::reflect::FieldDescriptor;
16 use crate::reflect::FileDescriptor;
17 use crate::reflect::OneofDescriptor;
18 use crate::CodedInputStream;
19 
20 pub(crate) mod generated;
21 pub(crate) mod is_initialized_is_always_true;
22 pub(crate) mod message_ref;
23 
24 /// Dynamic representation of message type.
25 ///
26 /// Used for reflection.
27 #[derive(Clone, Eq, PartialEq, Hash)]
28 pub struct MessageDescriptor {
29     pub(crate) file_descriptor: FileDescriptor,
30     pub(crate) index: usize,
31 }
32 
33 impl fmt::Display for MessageDescriptor {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result34     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
35         write!(f, "{}", self.full_name())
36     }
37 }
38 
39 impl fmt::Debug for MessageDescriptor {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result40     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
41         f.debug_struct("MessageDescriptor").finish_non_exhaustive()
42     }
43 }
44 
45 impl MessageDescriptor {
new(file_descriptor: FileDescriptor, index: usize) -> MessageDescriptor46     pub(crate) fn new(file_descriptor: FileDescriptor, index: usize) -> MessageDescriptor {
47         MessageDescriptor {
48             file_descriptor,
49             index,
50         }
51     }
52 
53     /// Get underlying `DescriptorProto` object.
proto(&self) -> &DescriptorProto54     pub fn proto(&self) -> &DescriptorProto {
55         self.file_descriptor.message_proto_by_index(self.index)
56     }
57 
58     /// Message name as specified in `.proto` file.
name(&self) -> &str59     pub fn name(&self) -> &str {
60         self.proto().name()
61     }
62 
index_entry(&self) -> &MessageIndices63     fn index_entry(&self) -> &MessageIndices {
64         self.file_descriptor.message_indices(self.index)
65     }
66 
67     /// Get a message descriptor for given message type
for_type<M: MessageFull>() -> MessageDescriptor68     pub fn for_type<M: MessageFull>() -> MessageDescriptor {
69         M::descriptor()
70     }
71 
72     /// Messages declared in this messages.
nested_messages(&self) -> impl Iterator<Item = MessageDescriptor> + '_73     pub fn nested_messages(&self) -> impl Iterator<Item = MessageDescriptor> + '_ {
74         self.index_entry()
75             .nested_messages
76             .iter()
77             .map(|i| MessageDescriptor::new(self.file_descriptor.clone(), *i))
78     }
79 
80     /// Get enums declared in this message.
nested_enums(&self) -> impl Iterator<Item = EnumDescriptor> + '_81     pub fn nested_enums(&self) -> impl Iterator<Item = EnumDescriptor> + '_ {
82         self.index_entry()
83             .nested_enums
84             .clone()
85             .map(|i| EnumDescriptor::new(self.file_descriptor.clone(), i))
86     }
87 
88     /// Get a message containing this message, or `None` if this message is declared at file level.
enclosing_message(&self) -> Option<MessageDescriptor>89     pub fn enclosing_message(&self) -> Option<MessageDescriptor> {
90         self.index_entry()
91             .enclosing_message
92             .map(|i| MessageDescriptor::new(self.file_descriptor.clone(), i))
93     }
94 
get_impl(&self) -> MessageDescriptorImplRef95     pub(crate) fn get_impl(&self) -> MessageDescriptorImplRef {
96         match &self.file_descriptor.imp {
97             FileDescriptorImpl::Generated(g) => {
98                 MessageDescriptorImplRef::Generated(&g.messages[self.index])
99             }
100             FileDescriptorImpl::Dynamic(..) => MessageDescriptorImplRef::Dynamic,
101         }
102     }
103 
104     /// [`FileDescriptor`] containing this message.
file_descriptor(&self) -> &FileDescriptor105     pub fn file_descriptor(&self) -> &FileDescriptor {
106         &self.file_descriptor
107     }
108 
109     /// `FileDescriptorProto` containg this message type
file_descriptor_proto(&self) -> &FileDescriptorProto110     pub fn file_descriptor_proto(&self) -> &FileDescriptorProto {
111         self.file_descriptor().proto()
112     }
113 
114     /// This message descriptor is a map entry.
is_map_entry(&self) -> bool115     pub fn is_map_entry(&self) -> bool {
116         self.index().map_entry
117     }
118 
assert_not_map_entry(&self)119     fn assert_not_map_entry(&self) {
120         assert!(
121             !self.is_map_entry(),
122             "message is map entry: {}",
123             self.full_name()
124         );
125     }
126 
127     /// Message is considered always initialized.
128     #[doc(hidden)]
is_initialized_is_always_true(&self) -> bool129     pub fn is_initialized_is_always_true(&self) -> bool {
130         self.index().is_initialized_is_always_true
131     }
132 
133     /// New empty message.
134     ///
135     /// # Panics
136     ///
137     /// If this message is a map entry message.
new_instance(&self) -> Box<dyn MessageDyn>138     pub fn new_instance(&self) -> Box<dyn MessageDyn> {
139         self.assert_not_map_entry();
140         match self.get_impl() {
141             MessageDescriptorImplRef::Generated(g) => g.non_map().factory.new_instance(),
142             MessageDescriptorImplRef::Dynamic => Box::new(DynamicMessage::new(self.clone())),
143         }
144     }
145 
146     /// Shared immutable empty message.
147     ///
148     /// Returns `None` for dynamic message.
149     ///
150     /// # Panics
151     ///
152     /// If this message is a map entry message.
default_instance(&self) -> Option<&'static dyn MessageDyn>153     pub fn default_instance(&self) -> Option<&'static dyn MessageDyn> {
154         self.assert_not_map_entry();
155         match self.get_impl() {
156             MessageDescriptorImplRef::Generated(g) => Some(g.non_map().factory.default_instance()),
157             MessageDescriptorImplRef::Dynamic => None,
158         }
159     }
160 
161     /// Clone a message
clone_message(&self, message: &dyn MessageDyn) -> Box<dyn MessageDyn>162     pub(crate) fn clone_message(&self, message: &dyn MessageDyn) -> Box<dyn MessageDyn> {
163         assert!(&message.descriptor_dyn() == self);
164         match self.get_impl() {
165             MessageDescriptorImplRef::Generated(g) => g.non_map().factory.clone(message),
166             MessageDescriptorImplRef::Dynamic => {
167                 let message: &DynamicMessage = DynamicMessage::downcast_ref(message);
168                 Box::new(message.clone())
169             }
170         }
171     }
172 
173     /// Check if two messages equal.
174     ///
175     /// # Panics
176     ///
177     /// Is any message has different type than this descriptor.
eq(&self, a: &dyn MessageDyn, b: &dyn MessageDyn) -> bool178     pub fn eq(&self, a: &dyn MessageDyn, b: &dyn MessageDyn) -> bool {
179         match self.get_impl() {
180             MessageDescriptorImplRef::Generated(g) => g.non_map().factory.eq(a, b),
181             MessageDescriptorImplRef::Dynamic => unimplemented!(),
182         }
183     }
184 
185     /// Similar to `eq`, but considers `NaN` values equal.
186     ///
187     /// # Panics
188     ///
189     /// Is any message has different type than this descriptor.
reflect_eq( &self, a: &dyn MessageDyn, b: &dyn MessageDyn, mode: &ReflectEqMode, ) -> bool190     pub(crate) fn reflect_eq(
191         &self,
192         a: &dyn MessageDyn,
193         b: &dyn MessageDyn,
194         mode: &ReflectEqMode,
195     ) -> bool {
196         // Explicitly force panic even if field list is empty
197         assert_eq!(self, &a.descriptor_dyn());
198         assert_eq!(self, &b.descriptor_dyn());
199 
200         for field in self.fields() {
201             let af = field.get_reflect(a);
202             let bf = field.get_reflect(b);
203             if !af.reflect_eq(&bf, mode) {
204                 return false;
205             }
206         }
207         true
208     }
209 
reflect_eq_maybe_unrelated( a: &dyn MessageDyn, b: &dyn MessageDyn, mode: &ReflectEqMode, ) -> bool210     pub(crate) fn reflect_eq_maybe_unrelated(
211         a: &dyn MessageDyn,
212         b: &dyn MessageDyn,
213         mode: &ReflectEqMode,
214     ) -> bool {
215         let ad = a.descriptor_dyn();
216         let bd = b.descriptor_dyn();
217         ad == bd && ad.reflect_eq(a, b, mode)
218     }
219 
220     /// Fully qualified protobuf message name
full_name(&self) -> &str221     pub fn full_name(&self) -> &str {
222         &self.index_entry().full_name
223     }
224 
225     /// Name relative to the package where the message is declared.
name_to_package(&self) -> &str226     pub fn name_to_package(&self) -> &str {
227         &self.index_entry().name_to_package
228     }
229 
230     /// Nested oneofs including synthetic.
all_oneofs<'a>(&'a self) -> impl Iterator<Item = OneofDescriptor> + 'a231     pub fn all_oneofs<'a>(&'a self) -> impl Iterator<Item = OneofDescriptor> + 'a {
232         self.index_entry()
233             .oneofs
234             .clone()
235             .map(move |i| OneofDescriptor {
236                 file_descriptor: self.file_descriptor.clone(),
237                 index: i,
238             })
239     }
240 
241     /// Non-synthetic oneofs.
oneofs<'a>(&'a self) -> impl Iterator<Item = OneofDescriptor> + 'a242     pub fn oneofs<'a>(&'a self) -> impl Iterator<Item = OneofDescriptor> + 'a {
243         self.all_oneofs().filter(|oneof| !oneof.is_synthetic())
244     }
245 
246     /// Get message oneof by name (**not implemented**).
oneof_by_name(&self, name: &str) -> Option<OneofDescriptor>247     pub fn oneof_by_name(&self, name: &str) -> Option<OneofDescriptor> {
248         self.all_oneofs().find(|oneof| oneof.name() == name)
249     }
250 
251     /// Message field descriptors.
fields<'a>(&'a self) -> impl Iterator<Item = FieldDescriptor> + 'a252     pub fn fields<'a>(&'a self) -> impl Iterator<Item = FieldDescriptor> + 'a {
253         self.index()
254             .message_index
255             .regular_field_range()
256             .map(move |index| FieldDescriptor {
257                 file_descriptor: self.file_descriptor.clone(),
258                 index,
259             })
260     }
261 
262     /// Extension fields.
extensions(&self) -> impl Iterator<Item = FieldDescriptor> + '_263     pub fn extensions(&self) -> impl Iterator<Item = FieldDescriptor> + '_ {
264         self.index()
265             .message_index
266             .extension_field_range()
267             .map(move |index| FieldDescriptor {
268                 file_descriptor: self.file_descriptor.clone(),
269                 index,
270             })
271     }
272 
index(&self) -> &MessageIndices273     pub(crate) fn index(&self) -> &MessageIndices {
274         &self.file_descriptor.common().messages[self.index]
275     }
276 
field_by_index(&self, index: usize) -> FieldDescriptor277     pub(crate) fn field_by_index(&self, index: usize) -> FieldDescriptor {
278         FieldDescriptor {
279             file_descriptor: self.file_descriptor.clone(),
280             index: self.index().message_index.first_field_index + index,
281         }
282     }
283 
284     /// Find message field by protobuf field name
285     ///
286     /// Note: protobuf field name might be different for Rust field name.
287     // TODO: return value, not pointer, pointer is not compatible with dynamic message
field_by_name(&self, name: &str) -> Option<FieldDescriptor>288     pub fn field_by_name(&self, name: &str) -> Option<FieldDescriptor> {
289         let &index = self.index().message_index.field_index_by_name.get(name)?;
290         Some(self.field_by_index(index))
291     }
292 
293     /// Find message field by field name or field JSON name
field_by_name_or_json_name<'a>(&'a self, name: &str) -> Option<FieldDescriptor>294     pub fn field_by_name_or_json_name<'a>(&'a self, name: &str) -> Option<FieldDescriptor> {
295         let &index = self
296             .index()
297             .message_index
298             .field_index_by_name_or_json_name
299             .get(name)?;
300         Some(self.field_by_index(index))
301     }
302 
303     /// Find message field by field name
field_by_number(&self, number: u32) -> Option<FieldDescriptor>304     pub fn field_by_number(&self, number: u32) -> Option<FieldDescriptor> {
305         let &index = self
306             .index()
307             .message_index
308             .field_index_by_number
309             .get(&number)?;
310         Some(self.field_by_index(index))
311     }
312 
313     /// Parse message from stream.
parse_from(&self, is: &mut CodedInputStream) -> crate::Result<Box<dyn MessageDyn>>314     pub fn parse_from(&self, is: &mut CodedInputStream) -> crate::Result<Box<dyn MessageDyn>> {
315         let mut r = self.new_instance();
316         r.merge_from_dyn(is)?;
317         r.check_initialized_dyn()?;
318         Ok(r)
319     }
320 
321     /// Parse message from reader.
322     /// Parse stops on EOF or when error encountered.
parse_from_reader(&self, reader: &mut dyn Read) -> crate::Result<Box<dyn MessageDyn>>323     pub fn parse_from_reader(&self, reader: &mut dyn Read) -> crate::Result<Box<dyn MessageDyn>> {
324         let mut is = CodedInputStream::new(reader);
325         let r = self.parse_from(&mut is)?;
326         is.check_eof()?;
327         Ok(r)
328     }
329 
330     /// Parse message from byte array.
parse_from_bytes(&self, bytes: &[u8]) -> crate::Result<Box<dyn MessageDyn>>331     pub fn parse_from_bytes(&self, bytes: &[u8]) -> crate::Result<Box<dyn MessageDyn>> {
332         let mut is = CodedInputStream::from_bytes(bytes);
333         let r = self.parse_from(&mut is)?;
334         is.check_eof()?;
335         Ok(r)
336     }
337 }
338 
339 pub(crate) enum MessageDescriptorImplRef {
340     Generated(&'static GeneratedMessageDescriptor),
341     Dynamic,
342 }
343 
344 #[cfg(test)]
345 mod test {
346     use crate::descriptor::descriptor_proto::ExtensionRange;
347     use crate::descriptor::field_descriptor_proto::Type;
348     use crate::descriptor::DescriptorProto;
349     use crate::descriptor::FieldDescriptorProto;
350     use crate::EnumFull;
351     use crate::MessageFull;
352 
353     #[test]
354     #[cfg_attr(miri, ignore)] // Too slow on Miri.
nested_messages()355     fn nested_messages() {
356         assert!(DescriptorProto::descriptor()
357             .nested_messages()
358             .collect::<Vec<_>>()
359             .contains(&ExtensionRange::descriptor()));
360     }
361 
362     #[test]
363     #[cfg_attr(miri, ignore)] // Too slow on Miri.
nested_enums()364     fn nested_enums() {
365         assert!(FieldDescriptorProto::descriptor()
366             .nested_enums()
367             .collect::<Vec<_>>()
368             .contains(&Type::enum_descriptor()));
369     }
370 
371     #[test]
372     #[cfg_attr(miri, ignore)] // Too slow on Miri.
enclosing_message()373     fn enclosing_message() {
374         assert_eq!(
375             Some(DescriptorProto::descriptor()),
376             ExtensionRange::descriptor().enclosing_message()
377         );
378         assert_eq!(None, DescriptorProto::descriptor().enclosing_message());
379     }
380 }
381