protobuf/reflect/message/
generated.rs
1use std::fmt;
4use std::marker;
5
6use crate::descriptor::FileDescriptorProto;
7use crate::message_dyn::MessageDyn;
8use crate::message_full::MessageFull;
9use crate::reflect::acc::FieldAccessor;
10use crate::reflect::file::index::FileDescriptorCommon;
11use crate::reflect::find_message_or_enum::find_message_or_enum;
12use crate::reflect::find_message_or_enum::MessageOrEnum;
13use crate::reflect::GeneratedOneofDescriptorData;
14
15pub(crate) trait MessageFactory: Send + Sync + 'static {
17 fn new_instance(&self) -> Box<dyn MessageDyn>;
18 fn default_instance(&self) -> &dyn MessageDyn;
19 fn clone(&self, message: &dyn MessageDyn) -> Box<dyn MessageDyn>;
20 fn eq(&self, a: &dyn MessageDyn, b: &dyn MessageDyn) -> bool;
21}
22
23impl<'a> fmt::Debug for &'a dyn MessageFactory {
24 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
25 f.debug_struct("MessageFactory").finish()
26 }
27}
28
29pub(crate) struct MessageFactoryImpl<M>(pub marker::PhantomData<M>);
31
32impl<M> MessageFactory for MessageFactoryImpl<M>
33where
34 M: MessageFull,
35{
36 fn new_instance(&self) -> Box<dyn MessageDyn> {
37 let m: M = Default::default();
38 Box::new(m)
39 }
40
41 fn default_instance(&self) -> &dyn MessageDyn {
42 M::default_instance() as &dyn MessageDyn
43 }
44
45 fn clone(&self, message: &dyn MessageDyn) -> Box<dyn MessageDyn> {
46 let m: &M = message.downcast_ref().expect("wrong message type");
47 Box::new(m.clone())
48 }
49
50 fn eq(&self, a: &dyn MessageDyn, b: &dyn MessageDyn) -> bool {
51 let a: &M = a.downcast_ref().expect("wrong message type");
52 let b: &M = b.downcast_ref().expect("wrong message type");
53 a == b
54 }
55}
56
57#[doc(hidden)]
58pub struct GeneratedMessageDescriptorData {
59 pub(crate) protobuf_name_to_package: &'static str,
60 pub(crate) fields: Vec<FieldAccessor>,
61 pub(crate) factory: &'static dyn MessageFactory,
62 pub(crate) oneofs: Vec<GeneratedOneofDescriptorData>,
63}
64
65impl GeneratedMessageDescriptorData {
66 #[doc(hidden)]
73 pub fn new_2<M: MessageFull>(
74 protobuf_name_to_package: &'static str,
75 fields: Vec<FieldAccessor>,
76 oneofs: Vec<GeneratedOneofDescriptorData>,
77 ) -> GeneratedMessageDescriptorData {
78 let factory = &MessageFactoryImpl(marker::PhantomData::<M>);
79 GeneratedMessageDescriptorData {
80 protobuf_name_to_package,
81 fields,
82 factory,
83 oneofs,
84 }
85 }
86}
87
88#[derive(Debug)]
89pub(crate) struct NonMapMessageDescriptor {
90 pub(crate) factory: &'static dyn MessageFactory,
91
92 pub(crate) fields: Vec<FieldAccessor>,
93}
94
95#[derive(Debug)]
96pub(crate) struct GeneratedMessageDescriptor {
97 pub(crate) non_map: Option<NonMapMessageDescriptor>,
98}
99
100impl GeneratedMessageDescriptor {
101 pub(crate) fn new_map_entry() -> GeneratedMessageDescriptor {
102 GeneratedMessageDescriptor { non_map: None }
103 }
104
105 pub(crate) fn new(
106 data: GeneratedMessageDescriptorData,
107 file_descriptor_proto: &'static FileDescriptorProto,
108 _file_index: &FileDescriptorCommon,
109 ) -> GeneratedMessageDescriptor {
110 let GeneratedMessageDescriptorData {
111 protobuf_name_to_package,
112 fields,
113 factory,
114 oneofs: _,
115 } = data;
116
117 let (_path_to_package, _proto) =
118 match find_message_or_enum(file_descriptor_proto, protobuf_name_to_package) {
119 Some((path_to_package, MessageOrEnum::Message(m))) => (path_to_package, m),
120 Some((_, MessageOrEnum::Enum(_))) => panic!("not a message"),
121 None => panic!("not found"),
122 };
123
124 GeneratedMessageDescriptor {
125 non_map: Some(NonMapMessageDescriptor { factory, fields }),
126 }
127 }
128
129 pub(crate) fn non_map(&self) -> &NonMapMessageDescriptor {
130 match &self.non_map {
131 Some(non_map) => non_map,
132 None => panic!("map message"),
133 }
134 }
135}