blob: e9d6b30ff66e9e1ce294b22f4ebced5464dc01a8 [file] [log] [blame]
Chih-Hung Hsiehcfc3a232020-06-10 20:13:05 -07001use std::any::Any;
2use std::any::TypeId;
3use std::fmt;
4use std::io::Read;
5use std::io::Write;
6
7#[cfg(feature = "bytes")]
8use bytes::Bytes;
9
Haibo Huangd32e6ee2020-08-12 13:52:04 -070010use crate::clear::Clear;
Joel Galensonfa77f002021-04-02 11:32:01 -070011use crate::coded_input_stream::CodedInputStream;
12use crate::coded_input_stream::WithCodedInputStream;
13use crate::coded_output_stream::with_coded_output_stream_to_bytes;
14use crate::coded_output_stream::CodedOutputStream;
15use crate::coded_output_stream::WithCodedOutputStream;
Haibo Huangd32e6ee2020-08-12 13:52:04 -070016use crate::error::ProtobufError;
17use crate::error::ProtobufResult;
18use crate::reflect::MessageDescriptor;
Haibo Huangd32e6ee2020-08-12 13:52:04 -070019use crate::unknown::UnknownFields;
Chih-Hung Hsiehcfc3a232020-06-10 20:13:05 -070020
21/// Trait implemented for all generated structs for protobuf messages.
22///
23/// Also, generated messages implement `Clone + Default + PartialEq`
24pub trait Message: fmt::Debug + Clear + Any + Send + Sync {
25 /// Message descriptor for this message, used for reflection.
26 fn descriptor(&self) -> &'static MessageDescriptor;
27
28 /// True iff all required fields are initialized.
29 /// Always returns `true` for protobuf 3.
30 fn is_initialized(&self) -> bool;
31
32 /// Update this message object with fields read from given stream.
33 fn merge_from(&mut self, is: &mut CodedInputStream) -> ProtobufResult<()>;
34
Haibo Huang914311b2021-01-07 18:06:15 -080035 /// Parse message from stream.
36 fn parse_from(is: &mut CodedInputStream) -> ProtobufResult<Self>
37 where
38 Self: Sized,
39 {
40 let mut r: Self = Message::new();
41 r.merge_from(is)?;
42 r.check_initialized()?;
43 Ok(r)
44 }
45
Chih-Hung Hsiehcfc3a232020-06-10 20:13:05 -070046 /// Write message to the stream.
47 ///
48 /// Sizes of this messages and nested messages must be cached
49 /// by calling `compute_size` prior to this call.
50 fn write_to_with_cached_sizes(&self, os: &mut CodedOutputStream) -> ProtobufResult<()>;
51
52 /// Compute and cache size of this message and all nested messages
53 fn compute_size(&self) -> u32;
54
55 /// Get size previously computed by `compute_size`.
56 fn get_cached_size(&self) -> u32;
57
58 /// Write the message to the stream.
59 ///
60 /// Results in error if message is not fully initialized.
61 fn write_to(&self, os: &mut CodedOutputStream) -> ProtobufResult<()> {
62 self.check_initialized()?;
63
64 // cache sizes
65 self.compute_size();
66 // TODO: reserve additional
67 self.write_to_with_cached_sizes(os)?;
68
69 Ok(())
70 }
71
72 /// Write the message to the stream prepending the message with message length
73 /// encoded as varint.
74 fn write_length_delimited_to(&self, os: &mut CodedOutputStream) -> ProtobufResult<()> {
75 let size = self.compute_size();
76 os.write_raw_varint32(size)?;
77 self.write_to_with_cached_sizes(os)?;
78
79 // TODO: assert we've written same number of bytes as computed
80
81 Ok(())
82 }
83
84 /// Write the message to the vec, prepend the message with message length
85 /// encoded as varint.
86 fn write_length_delimited_to_vec(&self, vec: &mut Vec<u8>) -> ProtobufResult<()> {
87 let mut os = CodedOutputStream::vec(vec);
88 self.write_length_delimited_to(&mut os)?;
89 os.flush()?;
90 Ok(())
91 }
92
93 /// Update this message object with fields read from given stream.
94 fn merge_from_bytes(&mut self, bytes: &[u8]) -> ProtobufResult<()> {
95 let mut is = CodedInputStream::from_bytes(bytes);
96 self.merge_from(&mut is)
97 }
98
Haibo Huang914311b2021-01-07 18:06:15 -080099 /// Parse message from reader.
100 /// Parse stops on EOF or when error encountered.
101 fn parse_from_reader(reader: &mut dyn Read) -> ProtobufResult<Self>
102 where
103 Self: Sized,
104 {
105 let mut is = CodedInputStream::new(reader);
106 let r = Message::parse_from(&mut is)?;
107 is.check_eof()?;
108 Ok(r)
109 }
110
111 /// Parse message from byte array.
112 fn parse_from_bytes(bytes: &[u8]) -> ProtobufResult<Self>
113 where
114 Self: Sized,
115 {
116 let mut is = CodedInputStream::from_bytes(bytes);
117 let r = Message::parse_from(&mut is)?;
118 is.check_eof()?;
119 Ok(r)
120 }
121
122 /// Parse message from `Bytes` object.
123 /// Resulting message may share references to the passed bytes object.
124 #[cfg(feature = "bytes")]
125 fn parse_from_carllerche_bytes(bytes: &Bytes) -> ProtobufResult<Self>
126 where
127 Self: Sized,
128 {
129 let mut is = CodedInputStream::from_carllerche_bytes(bytes);
130 let r = Self::parse_from(&mut is)?;
131 is.check_eof()?;
132 Ok(r)
133 }
134
Chih-Hung Hsiehcfc3a232020-06-10 20:13:05 -0700135 /// Check if all required fields of this object are initialized.
136 fn check_initialized(&self) -> ProtobufResult<()> {
137 if !self.is_initialized() {
138 Err(ProtobufError::message_not_initialized(
139 self.descriptor().name(),
140 ))
141 } else {
142 Ok(())
143 }
144 }
145
146 /// Write the message to the writer.
Haibo Huang4bf8b462020-11-24 20:53:50 -0800147 fn write_to_writer(&self, w: &mut dyn Write) -> ProtobufResult<()> {
Chih-Hung Hsiehcfc3a232020-06-10 20:13:05 -0700148 w.with_coded_output_stream(|os| self.write_to(os))
149 }
150
151 /// Write the message to bytes vec.
152 fn write_to_vec(&self, v: &mut Vec<u8>) -> ProtobufResult<()> {
153 v.with_coded_output_stream(|os| self.write_to(os))
154 }
155
156 /// Write the message to bytes vec.
157 fn write_to_bytes(&self) -> ProtobufResult<Vec<u8>> {
158 self.check_initialized()?;
159
160 let size = self.compute_size() as usize;
161 let mut v = Vec::with_capacity(size);
162 // skip zerofill
163 unsafe {
164 v.set_len(size);
165 }
166 {
167 let mut os = CodedOutputStream::bytes(&mut v);
168 self.write_to_with_cached_sizes(&mut os)?;
169 os.check_eof();
170 }
171 Ok(v)
172 }
173
174 /// Write the message to the writer, prepend the message with message length
175 /// encoded as varint.
Haibo Huang4bf8b462020-11-24 20:53:50 -0800176 fn write_length_delimited_to_writer(&self, w: &mut dyn Write) -> ProtobufResult<()> {
Chih-Hung Hsiehcfc3a232020-06-10 20:13:05 -0700177 w.with_coded_output_stream(|os| self.write_length_delimited_to(os))
178 }
179
180 /// Write the message to the bytes vec, prepend the message with message length
181 /// encoded as varint.
182 fn write_length_delimited_to_bytes(&self) -> ProtobufResult<Vec<u8>> {
183 with_coded_output_stream_to_bytes(|os| self.write_length_delimited_to(os))
184 }
185
186 /// Get a reference to unknown fields.
187 fn get_unknown_fields<'s>(&'s self) -> &'s UnknownFields;
188 /// Get a mutable reference to unknown fields.
189 fn mut_unknown_fields<'s>(&'s mut self) -> &'s mut UnknownFields;
190
191 /// Get type id for downcasting.
192 fn type_id(&self) -> TypeId {
193 TypeId::of::<Self>()
194 }
195
196 /// View self as `Any`.
Haibo Huang4bf8b462020-11-24 20:53:50 -0800197 fn as_any(&self) -> &dyn Any;
Chih-Hung Hsiehcfc3a232020-06-10 20:13:05 -0700198
199 /// View self as mutable `Any`.
Haibo Huang4bf8b462020-11-24 20:53:50 -0800200 fn as_any_mut(&mut self) -> &mut dyn Any {
Chih-Hung Hsiehcfc3a232020-06-10 20:13:05 -0700201 panic!()
202 }
203
204 /// Convert boxed self to boxed `Any`.
Haibo Huang4bf8b462020-11-24 20:53:50 -0800205 fn into_any(self: Box<Self>) -> Box<dyn Any> {
Chih-Hung Hsiehcfc3a232020-06-10 20:13:05 -0700206 panic!()
207 }
208
209 // Rust does not allow implementation of trait for trait:
210 // impl<M : Message> fmt::Debug for M {
211 // ...
212 // }
213
214 /// Create an empty message object.
215 ///
216 ///
217 /// ```
218 /// # use protobuf::Message;
219 /// # fn foo<MyMessage: Message>() {
220 /// let m = MyMessage::new();
221 /// # }
222 /// ```
223 fn new() -> Self
224 where
225 Self: Sized;
226
227 /// Get message descriptor for message type.
228 ///
229 /// ```
230 /// # use protobuf::Message;
231 /// # fn foo<MyMessage: Message>() {
232 /// let descriptor = MyMessage::descriptor_static();
233 /// assert_eq!("MyMessage", descriptor.name());
234 /// # }
235 /// ```
236 fn descriptor_static() -> &'static MessageDescriptor
237 where
238 Self: Sized,
239 {
240 panic!(
241 "descriptor_static is not implemented for message, \
242 LITE_RUNTIME must be used"
243 );
244 }
245
246 /// Return a pointer to default immutable message with static lifetime.
247 ///
248 /// ```
249 /// # use protobuf::Message;
250 /// # fn foo<MyMessage: Message>() {
251 /// let m: &MyMessage = MyMessage::default_instance();
252 /// # }
253 /// ```
254 fn default_instance() -> &'static Self
255 where
256 Self: Sized;
257}
258
Haibo Huang4bf8b462020-11-24 20:53:50 -0800259pub fn message_down_cast<'a, M: Message + 'a>(m: &'a dyn Message) -> &'a M {
Chih-Hung Hsiehcfc3a232020-06-10 20:13:05 -0700260 m.as_any().downcast_ref::<M>().unwrap()
261}
262
Chih-Hung Hsiehcfc3a232020-06-10 20:13:05 -0700263/// Parse message from reader.
264/// Parse stops on EOF or when error encountered.
Haibo Huang914311b2021-01-07 18:06:15 -0800265#[deprecated(since = "2.19", note = "Use Message::parse_from_reader instead")]
Haibo Huang4bf8b462020-11-24 20:53:50 -0800266pub fn parse_from_reader<M: Message>(reader: &mut dyn Read) -> ProtobufResult<M> {
Haibo Huang914311b2021-01-07 18:06:15 -0800267 M::parse_from_reader(reader)
Chih-Hung Hsiehcfc3a232020-06-10 20:13:05 -0700268}
269
270/// Parse message from byte array.
Haibo Huang914311b2021-01-07 18:06:15 -0800271#[deprecated(since = "2.19", note = "Use Message::parse_from_bytes instead")]
Chih-Hung Hsiehcfc3a232020-06-10 20:13:05 -0700272pub fn parse_from_bytes<M: Message>(bytes: &[u8]) -> ProtobufResult<M> {
Haibo Huang914311b2021-01-07 18:06:15 -0800273 M::parse_from_bytes(bytes)
Chih-Hung Hsiehcfc3a232020-06-10 20:13:05 -0700274}
275
276/// Parse message from `Bytes` object.
277/// Resulting message may share references to the passed bytes object.
278#[cfg(feature = "bytes")]
Haibo Huang914311b2021-01-07 18:06:15 -0800279#[deprecated(
280 since = "2.19",
281 note = "Use Message::parse_from_carllerche_bytes instead"
282)]
Chih-Hung Hsiehcfc3a232020-06-10 20:13:05 -0700283pub fn parse_from_carllerche_bytes<M: Message>(bytes: &Bytes) -> ProtobufResult<M> {
Haibo Huang914311b2021-01-07 18:06:15 -0800284 M::parse_from_carllerche_bytes(bytes)
Chih-Hung Hsiehcfc3a232020-06-10 20:13:05 -0700285}
286
287/// Parse length-delimited message from stream.
288///
289/// Read varint length first, and read messages of that length then.
290///
291/// This function is deprecated and will be removed in the next major release.
292#[deprecated]
293pub fn parse_length_delimited_from<M: Message>(is: &mut CodedInputStream) -> ProtobufResult<M> {
294 is.read_message::<M>()
295}
296
297/// Parse length-delimited message from `Read`.
298///
299/// This function is deprecated and will be removed in the next major release.
300#[deprecated]
Haibo Huang4bf8b462020-11-24 20:53:50 -0800301pub fn parse_length_delimited_from_reader<M: Message>(r: &mut dyn Read) -> ProtobufResult<M> {
Chih-Hung Hsiehcfc3a232020-06-10 20:13:05 -0700302 // TODO: wrong: we may read length first, and then read exact number of bytes needed
303 r.with_coded_input_stream(|is| is.read_message::<M>())
304}
305
306/// Parse length-delimited message from bytes.
307///
308/// This function is deprecated and will be removed in the next major release.
309#[deprecated]
310pub fn parse_length_delimited_from_bytes<M: Message>(bytes: &[u8]) -> ProtobufResult<M> {
311 bytes.with_coded_input_stream(|is| is.read_message::<M>())
312}