1 use std::any::Any;
2 use std::any::TypeId;
3 use std::fmt;
4 use std::io::Write;
5 
6 use crate::coded_output_stream::with::WithCodedOutputStream;
7 use crate::error::ProtobufError;
8 use crate::reflect::MessageDescriptor;
9 use crate::reflect::ReflectEqMode;
10 use crate::wire_format::check_message_size;
11 use crate::CodedInputStream;
12 use crate::CodedOutputStream;
13 use crate::MessageFull;
14 use crate::SpecialFields;
15 use crate::UnknownFields;
16 
17 /// Dynamic-dispatch version of either generated message or dynamic message.
18 ///
19 /// Generated messages implement [`MessageFull`](crate::MessageFull) unless lite runtime requested.
20 /// Dynamic messages can be created with
21 /// [`FileDescriptor::new_dynamic`](crate::reflect::FileDescriptor::new_dynamic).
22 pub trait MessageDyn: Any + fmt::Debug + fmt::Display + Send + Sync + 'static {
23     /// Message descriptor for this message, used for reflection.
descriptor_dyn(&self) -> MessageDescriptor24     fn descriptor_dyn(&self) -> MessageDescriptor;
25 
26     /// Update this message fields with contents of given stream.
merge_from_dyn(&mut self, is: &mut CodedInputStream) -> crate::Result<()>27     fn merge_from_dyn(&mut self, is: &mut CodedInputStream) -> crate::Result<()>;
28 
29     /// Write the message.
write_to_with_cached_sizes_dyn(&self, os: &mut CodedOutputStream) -> crate::Result<()>30     fn write_to_with_cached_sizes_dyn(&self, os: &mut CodedOutputStream) -> crate::Result<()>;
31 
32     /// Compute (and cache) the message size.
compute_size_dyn(&self) -> u6433     fn compute_size_dyn(&self) -> u64;
34 
35     /// True iff all required fields are initialized.
36     /// Always returns `true` for protobuf 3.
is_initialized_dyn(&self) -> bool37     fn is_initialized_dyn(&self) -> bool;
38 
39     /// Get a reference to special fields.
special_fields_dyn(&self) -> &SpecialFields40     fn special_fields_dyn(&self) -> &SpecialFields;
41     /// Get a mutable reference to special fields.
mut_special_fields_dyn(&mut self) -> &mut SpecialFields42     fn mut_special_fields_dyn(&mut self) -> &mut SpecialFields;
43 }
44 
45 impl<M: MessageFull> MessageDyn for M {
descriptor_dyn(&self) -> MessageDescriptor46     fn descriptor_dyn(&self) -> MessageDescriptor {
47         M::descriptor()
48     }
49 
merge_from_dyn(&mut self, is: &mut CodedInputStream) -> crate::Result<()>50     fn merge_from_dyn(&mut self, is: &mut CodedInputStream) -> crate::Result<()> {
51         self.merge_from(is)
52     }
53 
write_to_with_cached_sizes_dyn(&self, os: &mut CodedOutputStream) -> crate::Result<()>54     fn write_to_with_cached_sizes_dyn(&self, os: &mut CodedOutputStream) -> crate::Result<()> {
55         self.write_to_with_cached_sizes(os)
56     }
57 
compute_size_dyn(&self) -> u6458     fn compute_size_dyn(&self) -> u64 {
59         self.compute_size()
60     }
61 
is_initialized_dyn(&self) -> bool62     fn is_initialized_dyn(&self) -> bool {
63         self.is_initialized()
64     }
65 
special_fields_dyn(&self) -> &SpecialFields66     fn special_fields_dyn(&self) -> &SpecialFields {
67         self.special_fields()
68     }
69 
mut_special_fields_dyn(&mut self) -> &mut SpecialFields70     fn mut_special_fields_dyn(&mut self) -> &mut SpecialFields {
71         self.mut_special_fields()
72     }
73 }
74 
75 impl dyn MessageDyn {
76     /// Check if all required fields of this object are initialized.
check_initialized_dyn(&self) -> crate::Result<()>77     pub fn check_initialized_dyn(&self) -> crate::Result<()> {
78         if !self.is_initialized_dyn() {
79             Err(
80                 ProtobufError::MessageNotInitialized(self.descriptor_dyn().name().to_owned())
81                     .into(),
82             )
83         } else {
84             Ok(())
85         }
86     }
87 
88     /// Write the message to the writer.
write_to_writer_dyn(&self, w: &mut dyn Write) -> crate::Result<()>89     pub fn write_to_writer_dyn(&self, w: &mut dyn Write) -> crate::Result<()> {
90         w.with_coded_output_stream(|os| self.write_to_dyn(os))
91     }
92 
93     /// Write the message to bytes vec.
write_to_vec_dyn(&self, v: &mut Vec<u8>) -> crate::Result<()>94     pub fn write_to_vec_dyn(&self, v: &mut Vec<u8>) -> crate::Result<()> {
95         v.with_coded_output_stream(|os| self.write_to_dyn(os))
96     }
97 
98     /// Write the message to the stream.
99     ///
100     /// Results in error if message is not fully initialized.
write_to_dyn(&self, os: &mut CodedOutputStream) -> crate::Result<()>101     pub fn write_to_dyn(&self, os: &mut CodedOutputStream) -> crate::Result<()> {
102         self.check_initialized_dyn()?;
103 
104         // cache sizes
105         let size = self.compute_size_dyn();
106         let size = check_message_size(size)?;
107         os.reserve_additional(size, self.descriptor_dyn().name())?;
108         self.write_to_with_cached_sizes_dyn(os)?;
109 
110         Ok(())
111     }
112 
113     /// Write the message to the vec, prepend the message with message length
114     /// encoded as varint.
write_length_delimited_to_vec_dyn(&self, vec: &mut Vec<u8>) -> crate::Result<()>115     pub fn write_length_delimited_to_vec_dyn(&self, vec: &mut Vec<u8>) -> crate::Result<()> {
116         let mut os = CodedOutputStream::vec(vec);
117         self.write_length_delimited_to_dyn(&mut os)?;
118         os.flush()?;
119         Ok(())
120     }
121 
122     /// Update this message object with fields read from given stream.
merge_from_bytes_dyn(&mut self, bytes: &[u8]) -> crate::Result<()>123     pub fn merge_from_bytes_dyn(&mut self, bytes: &[u8]) -> crate::Result<()> {
124         let mut is = CodedInputStream::from_bytes(bytes);
125         self.merge_from_dyn(&mut is)
126     }
127 
128     /// Write the message to bytes vec.
129     ///
130     /// > **Note**: You can use [`Message::parse_from_bytes`](crate::Message::parse_from_bytes)
131     /// to do the reverse.
write_to_bytes_dyn(&self) -> crate::Result<Vec<u8>>132     pub fn write_to_bytes_dyn(&self) -> crate::Result<Vec<u8>> {
133         self.check_initialized_dyn()?;
134 
135         let size = self.compute_size_dyn();
136         let size = check_message_size(size)?;
137         let mut v = Vec::new();
138         let mut os = CodedOutputStream::vec(&mut v);
139         os.reserve_additional(size, self.descriptor_dyn().name())?;
140         self.write_to_with_cached_sizes_dyn(&mut os)?;
141         os.flush()?;
142         drop(os);
143         Ok(v)
144     }
145 
146     /// Write the message to the stream prepending the message with message length
147     /// encoded as varint.
write_length_delimited_to_dyn(&self, os: &mut CodedOutputStream) -> crate::Result<()>148     pub fn write_length_delimited_to_dyn(&self, os: &mut CodedOutputStream) -> crate::Result<()> {
149         let size = self.compute_size_dyn();
150         let size = check_message_size(size)?;
151         os.reserve_additional_for_length_delimited(size, self.descriptor_dyn().name())?;
152         os.write_raw_varint32(size)?;
153 
154         let pos = os.total_bytes_written();
155 
156         self.write_to_with_cached_sizes_dyn(os)?;
157 
158         // Cheap self-check.
159         assert_eq!(os.total_bytes_written() - pos, size as u64);
160 
161         Ok(())
162     }
163 
164     /// Write the message to the writer, prepend the message with message length
165     /// encoded as varint.
write_length_delimited_to_writer_dyn(&self, w: &mut dyn Write) -> crate::Result<()>166     pub fn write_length_delimited_to_writer_dyn(&self, w: &mut dyn Write) -> crate::Result<()> {
167         w.with_coded_output_stream(|os| self.write_length_delimited_to_dyn(os))
168     }
169 
170     /// Write the message to the bytes vec, prepend the message with message length
171     /// encoded as varint.
write_length_delimited_to_bytes_dyn(&self) -> crate::Result<Vec<u8>>172     pub fn write_length_delimited_to_bytes_dyn(&self) -> crate::Result<Vec<u8>> {
173         let mut v = Vec::new();
174         v.with_coded_output_stream(|os| self.write_length_delimited_to_dyn(os))?;
175         Ok(v)
176     }
177 
178     /// Get a reference to unknown fields.
unknown_fields_dyn(&self) -> &UnknownFields179     pub fn unknown_fields_dyn(&self) -> &UnknownFields {
180         self.special_fields_dyn().unknown_fields()
181     }
182     /// Get a mutable reference to unknown fields.
mut_unknown_fields_dyn(&mut self) -> &mut UnknownFields183     pub fn mut_unknown_fields_dyn(&mut self) -> &mut UnknownFields {
184         self.mut_special_fields_dyn().mut_unknown_fields()
185     }
186 
187     /// Downcast `Box<dyn Message>` to specific message type.
188     ///
189     /// ```
190     /// # use protobuf::{MessageFull, MessageDyn};
191     /// # fn foo<MyMessage: MessageFull>(message: Box<dyn MessageDyn>) {
192     /// let m: Box<dyn MessageDyn> = message;
193     /// let m: Box<MyMessage> = <dyn MessageDyn>::downcast_box(m).unwrap();
194     /// # }
195     /// ```
downcast_box<T: Any>( self: Box<dyn MessageDyn>, ) -> std::result::Result<Box<T>, Box<dyn MessageDyn>>196     pub fn downcast_box<T: Any>(
197         self: Box<dyn MessageDyn>,
198     ) -> std::result::Result<Box<T>, Box<dyn MessageDyn>> {
199         if Any::type_id(&*self) == TypeId::of::<T>() {
200             unsafe {
201                 let raw: *mut dyn MessageDyn = Box::into_raw(self);
202                 Ok(Box::from_raw(raw as *mut T))
203             }
204         } else {
205             Err(self)
206         }
207     }
208 
209     /// Downcast `&dyn Message` to specific message type.
210     ///
211     /// ```
212     /// # use protobuf::{MessageFull, MessageDyn};
213     /// # fn foo<MyMessage: MessageFull>(message: &dyn MessageDyn) {
214     /// let m: &dyn MessageDyn = message;
215     /// let m: &MyMessage = <dyn MessageDyn>::downcast_ref(m).unwrap();
216     /// # }
217     /// ```
downcast_ref<'a, M: MessageFull + 'a>(&'a self) -> Option<&'a M>218     pub fn downcast_ref<'a, M: MessageFull + 'a>(&'a self) -> Option<&'a M> {
219         if Any::type_id(&*self) == TypeId::of::<M>() {
220             unsafe { Some(&*(self as *const dyn MessageDyn as *const M)) }
221         } else {
222             None
223         }
224     }
225 
226     /// Downcast `&mut dyn Message` to specific message type.
227     ///
228     /// ```
229     /// # use protobuf::{MessageFull, MessageDyn};
230     /// # fn foo<MyMessage: MessageFull>(message: &mut dyn MessageDyn) {
231     /// let m: &mut dyn MessageDyn = message;
232     /// let m: &mut MyMessage = <dyn MessageDyn>::downcast_mut(m).unwrap();
233     /// # }
234     /// ```
downcast_mut<'a, M: MessageFull + 'a>(&'a mut self) -> Option<&'a mut M>235     pub fn downcast_mut<'a, M: MessageFull + 'a>(&'a mut self) -> Option<&'a mut M> {
236         if Any::type_id(&*self) == TypeId::of::<M>() {
237             unsafe { Some(&mut *(self as *mut dyn MessageDyn as *mut M)) }
238         } else {
239             None
240         }
241     }
242 
243     /// Clone from a `dyn Message` reference.
clone_box(&self) -> Box<dyn MessageDyn>244     pub fn clone_box(&self) -> Box<dyn MessageDyn> {
245         self.descriptor_dyn().clone_message(self)
246     }
247 
248     /// Reflectively compare the messages.
reflect_eq_dyn(&self, other: &dyn MessageDyn, mode: &ReflectEqMode) -> bool249     pub fn reflect_eq_dyn(&self, other: &dyn MessageDyn, mode: &ReflectEqMode) -> bool {
250         MessageDescriptor::reflect_eq_maybe_unrelated(self, other, mode)
251     }
252 }
253 
254 impl Clone for Box<dyn MessageDyn> {
clone(&self) -> Self255     fn clone(&self) -> Self {
256         (*self).clone_box()
257     }
258 }
259 
260 impl PartialEq for Box<dyn MessageDyn> {
eq(&self, other: &Box<dyn MessageDyn>) -> bool261     fn eq(&self, other: &Box<dyn MessageDyn>) -> bool {
262         MessageDescriptor::reflect_eq_maybe_unrelated(&**self, &**other, &ReflectEqMode::default())
263     }
264 }
265 
266 #[cfg(test)]
267 mod test {
268     use crate::descriptor::FileDescriptorProto;
269     use crate::MessageDyn;
270 
271     #[test]
downcast_ref()272     fn downcast_ref() {
273         let m = FileDescriptorProto::new();
274         let d = &m as &dyn MessageDyn;
275         let c: &FileDescriptorProto = d.downcast_ref().unwrap();
276         assert_eq!(
277             c as *const FileDescriptorProto,
278             &m as *const FileDescriptorProto
279         );
280     }
281 
282     #[test]
downcast_mut()283     fn downcast_mut() {
284         let mut m = FileDescriptorProto::new();
285         let d = &mut m as &mut dyn MessageDyn;
286         let c: &mut FileDescriptorProto = d.downcast_mut().unwrap();
287         assert_eq!(
288             c as *const FileDescriptorProto,
289             &m as *const FileDescriptorProto
290         );
291     }
292 
293     #[test]
downcast_box()294     fn downcast_box() {
295         let m = FileDescriptorProto::new();
296         let d: Box<dyn MessageDyn> = Box::new(m);
297         let mut _c: Box<FileDescriptorProto> = d.downcast_box().unwrap();
298     }
299 }
300