protobuf/reflect/message/
mod.rs
1use std::fmt;
2use std::io::Read;
3
4use crate::descriptor::DescriptorProto;
5use crate::descriptor::FileDescriptorProto;
6use crate::message_dyn::MessageDyn;
7use crate::message_full::MessageFull;
8use crate::reflect::dynamic::DynamicMessage;
9use crate::reflect::file::index::MessageIndices;
10use crate::reflect::file::FileDescriptorImpl;
11use crate::reflect::message::generated::GeneratedMessageDescriptor;
12use crate::reflect::reflect_eq::ReflectEq;
13use crate::reflect::reflect_eq::ReflectEqMode;
14use crate::reflect::EnumDescriptor;
15use crate::reflect::FieldDescriptor;
16use crate::reflect::FileDescriptor;
17use crate::reflect::OneofDescriptor;
18use crate::CodedInputStream;
19
20pub(crate) mod generated;
21pub(crate) mod is_initialized_is_always_true;
22pub(crate) mod message_ref;
23
24#[derive(Clone, Eq, PartialEq, Hash)]
28pub struct MessageDescriptor {
29 pub(crate) file_descriptor: FileDescriptor,
30 pub(crate) index: usize,
31}
32
33impl fmt::Display for MessageDescriptor {
34 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
35 write!(f, "{}", self.full_name())
36 }
37}
38
39impl fmt::Debug for MessageDescriptor {
40 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
41 f.debug_struct("MessageDescriptor").finish_non_exhaustive()
42 }
43}
44
45impl MessageDescriptor {
46 pub(crate) fn new(file_descriptor: FileDescriptor, index: usize) -> MessageDescriptor {
47 MessageDescriptor {
48 file_descriptor,
49 index,
50 }
51 }
52
53 pub fn proto(&self) -> &DescriptorProto {
55 self.file_descriptor.message_proto_by_index(self.index)
56 }
57
58 pub fn name(&self) -> &str {
60 self.proto().name()
61 }
62
63 fn index_entry(&self) -> &MessageIndices {
64 self.file_descriptor.message_indices(self.index)
65 }
66
67 pub fn for_type<M: MessageFull>() -> MessageDescriptor {
69 M::descriptor()
70 }
71
72 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 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 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
95 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 pub fn file_descriptor(&self) -> &FileDescriptor {
106 &self.file_descriptor
107 }
108
109 pub fn file_descriptor_proto(&self) -> &FileDescriptorProto {
111 self.file_descriptor().proto()
112 }
113
114 pub fn is_map_entry(&self) -> bool {
116 self.index().map_entry
117 }
118
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 #[doc(hidden)]
129 pub fn is_initialized_is_always_true(&self) -> bool {
130 self.index().is_initialized_is_always_true
131 }
132
133 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 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 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 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 pub(crate) fn reflect_eq(
191 &self,
192 a: &dyn MessageDyn,
193 b: &dyn MessageDyn,
194 mode: &ReflectEqMode,
195 ) -> bool {
196 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
210 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 pub fn full_name(&self) -> &str {
222 &self.index_entry().full_name
223 }
224
225 pub fn name_to_package(&self) -> &str {
227 &self.index_entry().name_to_package
228 }
229
230 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 pub fn oneofs<'a>(&'a self) -> impl Iterator<Item = OneofDescriptor> + 'a {
243 self.all_oneofs().filter(|oneof| !oneof.is_synthetic())
244 }
245
246 pub fn oneof_by_name(&self, name: &str) -> Option<OneofDescriptor> {
248 self.all_oneofs().find(|oneof| oneof.name() == name)
249 }
250
251 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 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
273 pub(crate) fn index(&self) -> &MessageIndices {
274 &self.file_descriptor.common().messages[self.index]
275 }
276
277 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 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 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 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 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 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 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
339pub(crate) enum MessageDescriptorImplRef {
340 Generated(&'static GeneratedMessageDescriptor),
341 Dynamic,
342}
343
344#[cfg(test)]
345mod 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)] 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)] 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)] 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}