1 use std::any::Any;
2 use std::any::TypeId;
3 use std::fmt;
4 use std::io::Read;
5 use std::io::Write;
6
7 #[cfg(feature = "bytes")]
8 use bytes::Bytes;
9
10 use clear::Clear;
11 use error::ProtobufError;
12 use error::ProtobufResult;
13 use reflect::MessageDescriptor;
14 use stream::with_coded_output_stream_to_bytes;
15 use stream::CodedInputStream;
16 use stream::CodedOutputStream;
17 use stream::WithCodedInputStream;
18 use stream::WithCodedOutputStream;
19 use unknown::UnknownFields;
20
21 /// Trait implemented for all generated structs for protobuf messages.
22 ///
23 /// Also, generated messages implement `Clone + Default + PartialEq`
24 pub trait Message: fmt::Debug + Clear + Any + Send + Sync {
25 /// Message descriptor for this message, used for reflection.
descriptor(&self) -> &'static MessageDescriptor26 fn descriptor(&self) -> &'static MessageDescriptor;
27
28 /// True iff all required fields are initialized.
29 /// Always returns `true` for protobuf 3.
is_initialized(&self) -> bool30 fn is_initialized(&self) -> bool;
31
32 /// Update this message object with fields read from given stream.
merge_from(&mut self, is: &mut CodedInputStream) -> ProtobufResult<()>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.
write_to_with_cached_sizes(&self, os: &mut CodedOutputStream) -> ProtobufResult<()>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
compute_size(&self) -> u3242 fn compute_size(&self) -> u32;
43
44 /// Get size previously computed by `compute_size`.
get_cached_size(&self) -> u3245 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.
write_to(&self, os: &mut CodedOutputStream) -> ProtobufResult<()>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.
write_length_delimited_to(&self, os: &mut CodedOutputStream) -> ProtobufResult<()>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.
write_length_delimited_to_vec(&self, vec: &mut Vec<u8>) -> ProtobufResult<()>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.
merge_from_bytes(&mut self, bytes: &[u8]) -> ProtobufResult<()>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.
check_initialized(&self) -> ProtobufResult<()>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.
write_to_writer(&self, w: &mut Write) -> ProtobufResult<()>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.
write_to_vec(&self, v: &mut Vec<u8>) -> ProtobufResult<()>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.
write_to_bytes(&self) -> ProtobufResult<Vec<u8>>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.
write_length_delimited_to_writer(&self, w: &mut Write) -> ProtobufResult<()>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.
write_length_delimited_to_bytes(&self) -> ProtobufResult<Vec<u8>>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.
get_unknown_fields<'s>(&'s self) -> &'s UnknownFields140 fn get_unknown_fields<'s>(&'s self) -> &'s UnknownFields;
141 /// Get a mutable reference to unknown fields.
mut_unknown_fields<'s>(&'s mut self) -> &'s mut UnknownFields142 fn mut_unknown_fields<'s>(&'s mut self) -> &'s mut UnknownFields;
143
144 /// Get type id for downcasting.
type_id(&self) -> TypeId145 fn type_id(&self) -> TypeId {
146 TypeId::of::<Self>()
147 }
148
149 /// View self as `Any`.
as_any(&self) -> &Any150 fn as_any(&self) -> &Any;
151
152 /// View self as mutable `Any`.
as_any_mut(&mut self) -> &mut Any153 fn as_any_mut(&mut self) -> &mut Any {
154 panic!()
155 }
156
157 /// Convert boxed self to boxed `Any`.
into_any(self: Box<Self>) -> Box<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 /// ```
new() -> Self where Self: Sized176 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 /// ```
descriptor_static() -> &'static MessageDescriptor where Self: Sized,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 /// ```
default_instance() -> &'static Self where Self: Sized207 fn default_instance() -> &'static Self
208 where
209 Self: Sized;
210 }
211
message_down_cast<'a, M: Message + 'a>(m: &'a Message) -> &'a M212 pub 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.
parse_from<M: Message>(is: &mut CodedInputStream) -> ProtobufResult<M>217 pub 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.
parse_from_reader<M: Message>(reader: &mut Read) -> ProtobufResult<M>226 pub 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.
parse_from_bytes<M: Message>(bytes: &[u8]) -> ProtobufResult<M>231 pub 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")]
parse_from_carllerche_bytes<M: Message>(bytes: &Bytes) -> ProtobufResult<M>238 pub 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]
parse_length_delimited_from<M: Message>(is: &mut CodedInputStream) -> ProtobufResult<M>249 pub 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]
parse_length_delimited_from_reader<M: Message>(r: &mut Read) -> ProtobufResult<M>257 pub 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]
parse_length_delimited_from_bytes<M: Message>(bytes: &[u8]) -> ProtobufResult<M>266 pub fn parse_length_delimited_from_bytes<M: Message>(bytes: &[u8]) -> ProtobufResult<M> {
267 bytes.with_coded_input_stream(|is| is.read_message::<M>())
268 }
269