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