blob: 1b1f39f6254e074a8665d448ff8d9c29683dbf28 [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;
11use crate::error::ProtobufError;
12use crate::error::ProtobufResult;
13use crate::reflect::MessageDescriptor;
14use crate::stream::with_coded_output_stream_to_bytes;
15use crate::stream::CodedInputStream;
16use crate::stream::CodedOutputStream;
17use crate::stream::WithCodedInputStream;
18use crate::stream::WithCodedOutputStream;
19use 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
35 /// Write message to the stream.
36 ///
37 /// Sizes of this messages and nested messages must be cached
38 /// by calling `compute_size` prior to this call.
39 fn write_to_with_cached_sizes(&self, os: &mut CodedOutputStream) -> ProtobufResult<()>;
40
41 /// Compute and cache size of this message and all nested messages
42 fn compute_size(&self) -> u32;
43
44 /// Get size previously computed by `compute_size`.
45 fn get_cached_size(&self) -> u32;
46
47 /// Write the message to the stream.
48 ///
49 /// Results in error if message is not fully initialized.
50 fn write_to(&self, os: &mut CodedOutputStream) -> ProtobufResult<()> {
51 self.check_initialized()?;
52
53 // cache sizes
54 self.compute_size();
55 // TODO: reserve additional
56 self.write_to_with_cached_sizes(os)?;
57
58 Ok(())
59 }
60
61 /// Write the message to the stream prepending the message with message length
62 /// encoded as varint.
63 fn write_length_delimited_to(&self, os: &mut CodedOutputStream) -> ProtobufResult<()> {
64 let size = self.compute_size();
65 os.write_raw_varint32(size)?;
66 self.write_to_with_cached_sizes(os)?;
67
68 // TODO: assert we've written same number of bytes as computed
69
70 Ok(())
71 }
72
73 /// Write the message to the vec, prepend the message with message length
74 /// encoded as varint.
75 fn write_length_delimited_to_vec(&self, vec: &mut Vec<u8>) -> ProtobufResult<()> {
76 let mut os = CodedOutputStream::vec(vec);
77 self.write_length_delimited_to(&mut os)?;
78 os.flush()?;
79 Ok(())
80 }
81
82 /// Update this message object with fields read from given stream.
83 fn merge_from_bytes(&mut self, bytes: &[u8]) -> ProtobufResult<()> {
84 let mut is = CodedInputStream::from_bytes(bytes);
85 self.merge_from(&mut is)
86 }
87
88 /// Check if all required fields of this object are initialized.
89 fn check_initialized(&self) -> ProtobufResult<()> {
90 if !self.is_initialized() {
91 Err(ProtobufError::message_not_initialized(
92 self.descriptor().name(),
93 ))
94 } else {
95 Ok(())
96 }
97 }
98
99 /// Write the message to the writer.
100 fn write_to_writer(&self, w: &mut Write) -> ProtobufResult<()> {
101 w.with_coded_output_stream(|os| self.write_to(os))
102 }
103
104 /// Write the message to bytes vec.
105 fn write_to_vec(&self, v: &mut Vec<u8>) -> ProtobufResult<()> {
106 v.with_coded_output_stream(|os| self.write_to(os))
107 }
108
109 /// Write the message to bytes vec.
110 fn write_to_bytes(&self) -> ProtobufResult<Vec<u8>> {
111 self.check_initialized()?;
112
113 let size = self.compute_size() as usize;
114 let mut v = Vec::with_capacity(size);
115 // skip zerofill
116 unsafe {
117 v.set_len(size);
118 }
119 {
120 let mut os = CodedOutputStream::bytes(&mut v);
121 self.write_to_with_cached_sizes(&mut os)?;
122 os.check_eof();
123 }
124 Ok(v)
125 }
126
127 /// Write the message to the writer, prepend the message with message length
128 /// encoded as varint.
129 fn write_length_delimited_to_writer(&self, w: &mut Write) -> ProtobufResult<()> {
130 w.with_coded_output_stream(|os| self.write_length_delimited_to(os))
131 }
132
133 /// Write the message to the bytes vec, prepend the message with message length
134 /// encoded as varint.
135 fn write_length_delimited_to_bytes(&self) -> ProtobufResult<Vec<u8>> {
136 with_coded_output_stream_to_bytes(|os| self.write_length_delimited_to(os))
137 }
138
139 /// Get a reference to unknown fields.
140 fn get_unknown_fields<'s>(&'s self) -> &'s UnknownFields;
141 /// Get a mutable reference to unknown fields.
142 fn mut_unknown_fields<'s>(&'s mut self) -> &'s mut UnknownFields;
143
144 /// Get type id for downcasting.
145 fn type_id(&self) -> TypeId {
146 TypeId::of::<Self>()
147 }
148
149 /// View self as `Any`.
150 fn as_any(&self) -> &Any;
151
152 /// View self as mutable `Any`.
153 fn as_any_mut(&mut self) -> &mut Any {
154 panic!()
155 }
156
157 /// Convert boxed self to boxed `Any`.
158 fn into_any(self: Box<Self>) -> Box<Any> {
159 panic!()
160 }
161
162 // Rust does not allow implementation of trait for trait:
163 // impl<M : Message> fmt::Debug for M {
164 // ...
165 // }
166
167 /// Create an empty message object.
168 ///
169 ///
170 /// ```
171 /// # use protobuf::Message;
172 /// # fn foo<MyMessage: Message>() {
173 /// let m = MyMessage::new();
174 /// # }
175 /// ```
176 fn new() -> Self
177 where
178 Self: Sized;
179
180 /// Get message descriptor for message type.
181 ///
182 /// ```
183 /// # use protobuf::Message;
184 /// # fn foo<MyMessage: Message>() {
185 /// let descriptor = MyMessage::descriptor_static();
186 /// assert_eq!("MyMessage", descriptor.name());
187 /// # }
188 /// ```
189 fn descriptor_static() -> &'static MessageDescriptor
190 where
191 Self: Sized,
192 {
193 panic!(
194 "descriptor_static is not implemented for message, \
195 LITE_RUNTIME must be used"
196 );
197 }
198
199 /// Return a pointer to default immutable message with static lifetime.
200 ///
201 /// ```
202 /// # use protobuf::Message;
203 /// # fn foo<MyMessage: Message>() {
204 /// let m: &MyMessage = MyMessage::default_instance();
205 /// # }
206 /// ```
207 fn default_instance() -> &'static Self
208 where
209 Self: Sized;
210}
211
212pub fn message_down_cast<'a, M: Message + 'a>(m: &'a Message) -> &'a M {
213 m.as_any().downcast_ref::<M>().unwrap()
214}
215
216/// Parse message from stream.
217pub fn parse_from<M: Message>(is: &mut CodedInputStream) -> ProtobufResult<M> {
218 let mut r: M = Message::new();
219 r.merge_from(is)?;
220 r.check_initialized()?;
221 Ok(r)
222}
223
224/// Parse message from reader.
225/// Parse stops on EOF or when error encountered.
226pub fn parse_from_reader<M: Message>(reader: &mut Read) -> ProtobufResult<M> {
227 reader.with_coded_input_stream(|is| parse_from::<M>(is))
228}
229
230/// Parse message from byte array.
231pub fn parse_from_bytes<M: Message>(bytes: &[u8]) -> ProtobufResult<M> {
232 bytes.with_coded_input_stream(|is| parse_from::<M>(is))
233}
234
235/// Parse message from `Bytes` object.
236/// Resulting message may share references to the passed bytes object.
237#[cfg(feature = "bytes")]
238pub fn parse_from_carllerche_bytes<M: Message>(bytes: &Bytes) -> ProtobufResult<M> {
239 // Call trait explicitly to avoid accidental construction from `&[u8]`
240 WithCodedInputStream::with_coded_input_stream(bytes, |is| parse_from::<M>(is))
241}
242
243/// Parse length-delimited message from stream.
244///
245/// Read varint length first, and read messages of that length then.
246///
247/// This function is deprecated and will be removed in the next major release.
248#[deprecated]
249pub fn parse_length_delimited_from<M: Message>(is: &mut CodedInputStream) -> ProtobufResult<M> {
250 is.read_message::<M>()
251}
252
253/// Parse length-delimited message from `Read`.
254///
255/// This function is deprecated and will be removed in the next major release.
256#[deprecated]
257pub fn parse_length_delimited_from_reader<M: Message>(r: &mut Read) -> ProtobufResult<M> {
258 // TODO: wrong: we may read length first, and then read exact number of bytes needed
259 r.with_coded_input_stream(|is| is.read_message::<M>())
260}
261
262/// Parse length-delimited message from bytes.
263///
264/// This function is deprecated and will be removed in the next major release.
265#[deprecated]
266pub fn parse_length_delimited_from_bytes<M: Message>(bytes: &[u8]) -> ProtobufResult<M> {
267 bytes.with_coded_input_stream(|is| is.read_message::<M>())
268}