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