1use std::collections;
3
4use protobuf;
5use protobuf::wire_format;
6
7use crate::descriptor;
8use crate::error;
9
10#[derive(Clone, Debug)]
12pub enum Value {
13 Bool(bool),
15 I32(i32),
17 I64(i64),
19 U32(u32),
21 U64(u64),
23 F32(f32),
25 F64(f64),
27 Bytes(Vec<u8>),
29 String(String),
31 Enum(i32),
33 Message(Message),
35}
36
37#[derive(Clone, Debug)]
39pub struct Message {
40 pub fields: collections::BTreeMap<i32, Field>,
42 pub unknown: protobuf::UnknownFields,
44}
45
46#[derive(Clone, Debug)]
48pub enum Field {
49 Singular(Option<Value>),
51 Repeated(Vec<Value>),
53}
54
55impl Message {
56 #[inline]
58 pub fn new(message: &descriptor::MessageDescriptor) -> Message {
59 let mut m = Message {
60 fields: collections::BTreeMap::new(),
61 unknown: protobuf::UnknownFields::new(),
62 };
63
64 for field in message.fields() {
65 m.fields.insert(
66 field.number(),
67 if field.is_repeated() {
68 Field::Repeated(Vec::new())
69 } else {
70 Field::Singular(field.default_value().cloned())
71 },
72 );
73 }
74
75 m
76 }
77
78 #[inline]
80 pub fn merge_from(
81 &mut self,
82 descriptors: &descriptor::Descriptors,
83 message: &descriptor::MessageDescriptor,
84 input: &mut protobuf::CodedInputStream,
85 ) -> error::Result<()> {
86 while !input.eof()? {
87 let (number, wire_type) = input.read_tag_unpack()?;
88
89 if let Some(field) = message.field_by_number(number as i32) {
90 let value = self.ensure_field(field);
91 value.merge_from(descriptors, field, input, wire_type)?;
92 } else {
93 use protobuf::rt::read_unknown_or_skip_group as u;
94 u(number, wire_type, input, &mut self.unknown)?;
95 }
96 }
97 Ok(())
98 }
99
100 #[inline]
101 fn ensure_field(&mut self, field: &descriptor::FieldDescriptor) -> &mut Field {
102 self.fields
103 .entry(field.number())
104 .or_insert_with(|| Field::new(field))
105 }
106}
107
108impl Field {
109 #[inline]
111 pub fn new(field: &descriptor::FieldDescriptor) -> Field {
112 if field.is_repeated() {
113 Field::Repeated(Vec::new())
114 } else {
115 Field::Singular(None)
116 }
117 }
118
119 #[inline]
121 pub fn merge_from(
122 &mut self,
123 descriptors: &descriptor::Descriptors,
124 field: &descriptor::FieldDescriptor,
125 input: &mut protobuf::CodedInputStream,
126 wire_type: protobuf::wire_format::WireType,
127 ) -> error::Result<()> {
128 use crate::descriptor::FieldType::*;
130 use protobuf::wire_format::WireType::*;
131 use protobuf::CodedInputStream as I;
132
133 macro_rules! ss {
135 ($expected_wire_type:expr, $visit_func:expr, $reader:expr) => {
136 self.merge_scalar(input, wire_type, $expected_wire_type, $visit_func, $reader)
137 };
138 }
139
140 macro_rules! ps {
142 ($expected_wire_type:expr, $visit_func:expr, $reader:expr) => {
143 self.merge_packable_scalar(
144 input,
145 wire_type,
146 $expected_wire_type,
147 $visit_func,
148 $reader,
149 )
150 };
151 ($expected_wire_type:expr, $size:expr, $visit_func:expr, $reader:expr) => {
152 self.merge_packable_scalar(
154 input,
155 wire_type,
156 $expected_wire_type,
157 $visit_func,
158 $reader,
159 )
160 };
161 }
162
163 match field.field_type(descriptors) {
164 Bool => ps!(WireTypeVarint, Value::Bool, I::read_bool),
165 Int32 => ps!(WireTypeVarint, Value::I32, I::read_int32),
166 Int64 => ps!(WireTypeVarint, Value::I64, I::read_int64),
167 SInt32 => ps!(WireTypeVarint, Value::I32, I::read_sint32),
168 SInt64 => ps!(WireTypeVarint, Value::I64, I::read_sint64),
169 UInt32 => ps!(WireTypeVarint, Value::U32, I::read_uint32),
170 UInt64 => ps!(WireTypeVarint, Value::U64, I::read_uint64),
171 Fixed32 => ps!(WireTypeFixed32, 4, Value::U32, I::read_fixed32),
172 Fixed64 => ps!(WireTypeFixed64, 8, Value::U64, I::read_fixed64),
173 SFixed32 => ps!(WireTypeFixed32, 4, Value::I32, I::read_sfixed32),
174 SFixed64 => ps!(WireTypeFixed64, 8, Value::I64, I::read_sfixed64),
175 Float => ps!(WireTypeFixed32, 4, Value::F32, I::read_float),
176 Double => ps!(WireTypeFixed64, 8, Value::F64, I::read_double),
177 Bytes => ss!(WireTypeLengthDelimited, Value::Bytes, I::read_bytes),
178 String => ss!(WireTypeLengthDelimited, Value::String, I::read_string),
179 Enum(_) => self.merge_enum(input, wire_type),
180 Message(ref m) => self.merge_message(input, descriptors, m, wire_type),
181 Group => unimplemented!(),
182 UnresolvedEnum(e) => Err(error::Error::UnknownEnum { name: e.to_owned() }),
183 UnresolvedMessage(m) => Err(error::Error::UnknownMessage { name: m.to_owned() }),
184 }
185 }
186
187 #[inline]
188 fn merge_scalar<'a, A, V, R>(
189 &mut self,
190 input: &mut protobuf::CodedInputStream<'a>,
191 actual_wire_type: wire_format::WireType,
192 expected_wire_type: wire_format::WireType,
193 value_ctor: V,
194 reader: R,
195 ) -> error::Result<()>
196 where
197 V: Fn(A) -> Value,
198 R: Fn(&mut protobuf::CodedInputStream<'a>) -> protobuf::ProtobufResult<A>,
199 {
200 if expected_wire_type == actual_wire_type {
201 self.put(value_ctor(reader(input)?));
202 Ok(())
203 } else {
204 Err(error::Error::BadWireType {
205 wire_type: actual_wire_type,
206 })
207 }
208 }
209
210 #[inline]
211 fn merge_packable_scalar<'a, A, V, R>(
212 &mut self,
213 input: &mut protobuf::CodedInputStream<'a>,
214 actual_wire_type: wire_format::WireType,
215 expected_wire_type: wire_format::WireType,
216 value_ctor: V,
217 reader: R,
218 ) -> error::Result<()>
219 where
220 V: Fn(A) -> Value,
221 R: Fn(&mut protobuf::CodedInputStream<'a>) -> protobuf::ProtobufResult<A>,
222 {
223 if wire_format::WireType::WireTypeLengthDelimited == actual_wire_type {
224 let len = input.read_raw_varint64()?;
225
226 let old_limit = input.push_limit(len)?;
227 while !input.eof()? {
228 self.put(value_ctor(reader(input)?));
229 }
230 input.pop_limit(old_limit);
231
232 Ok(())
233 } else {
234 self.merge_scalar(
235 input,
236 actual_wire_type,
237 expected_wire_type,
238 value_ctor,
239 reader,
240 )
241 }
242 }
243
244 #[inline]
245 fn merge_enum(
246 &mut self,
247 input: &mut protobuf::CodedInputStream,
248 actual_wire_type: wire_format::WireType,
249 ) -> error::Result<()> {
250 if wire_format::WireType::WireTypeVarint == actual_wire_type {
251 let v = input.read_raw_varint32()? as i32;
252 self.put(Value::Enum(v));
253 Ok(())
254 } else {
255 Err(error::Error::BadWireType {
256 wire_type: actual_wire_type,
257 })
258 }
259 }
260
261 #[inline]
262 fn merge_message(
263 &mut self,
264 input: &mut protobuf::CodedInputStream,
265 descriptors: &descriptor::Descriptors,
266 message: &descriptor::MessageDescriptor,
267 actual_wire_type: wire_format::WireType,
268 ) -> error::Result<()> {
269 if wire_format::WireType::WireTypeLengthDelimited == actual_wire_type {
270 let len = input.read_raw_varint64()?;
271 let mut msg = match *self {
272 Field::Singular(ref mut o) => {
273 if let Some(Value::Message(m)) = o.take() {
274 m
275 } else {
276 Message::new(message)
277 }
278 }
279 _ => Message::new(message),
280 };
281
282 let old_limit = input.push_limit(len)?;
283 msg.merge_from(descriptors, message, input)?;
284 input.pop_limit(old_limit);
285
286 self.put(Value::Message(msg));
287 Ok(())
288 } else {
289 Err(error::Error::BadWireType {
290 wire_type: actual_wire_type,
291 })
292 }
293 }
294
295 #[inline]
296 fn put(&mut self, value: Value) {
297 match *self {
298 Field::Singular(ref mut s) => *s = Some(value),
299 Field::Repeated(ref mut r) => r.push(value),
300 }
301 }
302}