prost_reflect/dynamic/
unknown.rs

1use std::{fmt, slice, vec};
2
3use prost::{
4    bytes::{Buf, BufMut, Bytes},
5    encoding::{self, DecodeContext, WireType},
6    DecodeError, Message,
7};
8
9use crate::dynamic::text_format;
10
11/// An unknown field found when deserializing a protobuf message.
12///
13/// A field is unknown if the message descriptor does not contain a field with the given number. This is often the
14/// result of a new field being added to the message definition.
15///
16/// The [`Message`](prost::Message) implementation of [`DynamicMessage`](crate::DynamicMessage) will preserve any unknown
17/// fields.
18#[derive(Debug, Clone, PartialEq)]
19pub struct UnknownField {
20    number: u32,
21    value: UnknownFieldValue,
22}
23
24/// The vaalue of an unknown field in a protobuf message.
25#[derive(Debug, Clone, PartialEq)]
26pub(crate) enum UnknownFieldValue {
27    /// An unknown field with the `Varint` wire type.
28    Varint(u64),
29    /// An unknown field with the `SixtyFourBit` wire type.
30    SixtyFourBit([u8; 8]),
31    /// An unknown field with the `LengthDelimited` wire type.
32    LengthDelimited(Bytes),
33    /// An unknown field with the group wire type.
34    Group(UnknownFieldSet),
35    /// An unknown field with the `ThirtyTwoBit` wire type.
36    ThirtyTwoBit([u8; 4]),
37}
38
39#[derive(Debug, Default, Clone, PartialEq)]
40pub(crate) struct UnknownFieldSet {
41    fields: Vec<UnknownField>,
42}
43
44impl UnknownField {
45    /// The number of this field as found during decoding.
46    pub fn number(&self) -> u32 {
47        self.number
48    }
49
50    /// The wire type of this field as found during decoding.
51    pub fn wire_type(&self) -> WireType {
52        match &self.value {
53            UnknownFieldValue::Varint(_) => WireType::Varint,
54            UnknownFieldValue::SixtyFourBit(_) => WireType::SixtyFourBit,
55            UnknownFieldValue::LengthDelimited(_) => WireType::LengthDelimited,
56            UnknownFieldValue::Group(_) => WireType::StartGroup,
57            UnknownFieldValue::ThirtyTwoBit(_) => WireType::ThirtyTwoBit,
58        }
59    }
60
61    pub(crate) fn value(&self) -> &UnknownFieldValue {
62        &self.value
63    }
64
65    /// Encodes this field into its byte representation.
66    pub fn encode<B>(&self, buf: &mut B)
67    where
68        B: BufMut,
69    {
70        match &self.value {
71            UnknownFieldValue::Varint(value) => {
72                encoding::encode_key(self.number, WireType::Varint, buf);
73                encoding::encode_varint(*value, buf);
74            }
75            UnknownFieldValue::SixtyFourBit(value) => {
76                encoding::encode_key(self.number, WireType::SixtyFourBit, buf);
77                buf.put_slice(value);
78            }
79            UnknownFieldValue::LengthDelimited(value) => {
80                encoding::bytes::encode(self.number, value, buf);
81            }
82            UnknownFieldValue::Group(value) => {
83                encoding::group::encode(self.number, value, buf);
84            }
85            UnknownFieldValue::ThirtyTwoBit(value) => {
86                encoding::encode_key(self.number, WireType::ThirtyTwoBit, buf);
87                buf.put_slice(value);
88            }
89        }
90    }
91
92    /// Decodes an unknown field from the given buffer.
93    ///
94    /// This method will read the field number and wire type from the buffer. Normally, it is useful to know
95    /// the field number before deciding whether to treat a field as unknown. See [`decode_value`](UnknownField::decode_value)
96    /// if you have already read the number.
97    ///
98    /// # Examples
99    ///
100    /// ```
101    /// # use prost_reflect::{DescriptorPool, UnknownField};
102    /// # use prost::encoding::{DecodeContext, WireType};
103    /// # let pool = DescriptorPool::decode(include_bytes!("../file_descriptor_set.bin").as_ref()).unwrap();
104    /// # let message_descriptor = pool.get_message_by_name("google.protobuf.Empty").unwrap();
105    /// let unknown_field = UnknownField::decode(&mut b"\x1a\x02\x10\x42".as_ref(), DecodeContext::default()).unwrap();
106    /// assert_eq!(unknown_field.number(), 3);
107    /// assert_eq!(unknown_field.wire_type(), WireType::LengthDelimited);
108    /// ```
109    pub fn decode<B>(buf: &mut B, ctx: DecodeContext) -> Result<Self, DecodeError>
110    where
111        B: Buf,
112    {
113        let (number, wire_type) = encoding::decode_key(buf)?;
114        Self::decode_value(number, wire_type, buf, ctx)
115    }
116
117    /// Given a field number and wire type, decodes the value of an unknown field.
118    ///
119    /// This method assumes the field number and wire type have already been read from the buffer.
120    /// See also [`decode`](UnknownField::decode).
121    ///
122    /// # Examples
123    ///
124    /// ```
125    /// # use prost_reflect::{DescriptorPool, UnknownField};
126    /// # use prost::encoding::{DecodeContext, WireType};
127    /// # let pool = DescriptorPool::decode(include_bytes!("../file_descriptor_set.bin").as_ref()).unwrap();
128    /// # let message_descriptor = pool.get_message_by_name("google.protobuf.Empty").unwrap();
129    /// let unknown_field = UnknownField::decode_value(3, WireType::LengthDelimited, &mut b"\x02\x10\x42".as_ref(), DecodeContext::default()).unwrap();
130    /// assert_eq!(unknown_field.number(), 3);
131    /// assert_eq!(unknown_field.wire_type(), WireType::LengthDelimited);
132    ///
133    /// let mut buf = Vec::new();
134    /// unknown_field.encode(&mut buf);
135    /// assert_eq!(buf, b"\x1a\x02\x10\x42");
136    /// ```
137    pub fn decode_value<B>(
138        number: u32,
139        wire_type: WireType,
140        buf: &mut B,
141        ctx: DecodeContext,
142    ) -> Result<Self, DecodeError>
143    where
144        B: Buf,
145    {
146        let value = match wire_type {
147            WireType::Varint => {
148                let value = encoding::decode_varint(buf)?;
149                UnknownFieldValue::Varint(value)
150            }
151            WireType::SixtyFourBit => {
152                let mut value = 0u64;
153                encoding::fixed64::merge(wire_type, &mut value, buf, ctx)?;
154                UnknownFieldValue::SixtyFourBit(value.to_le_bytes())
155            }
156            WireType::LengthDelimited => {
157                let mut value = Bytes::default();
158                encoding::bytes::merge(wire_type, &mut value, buf, ctx)?;
159                UnknownFieldValue::LengthDelimited(value)
160            }
161            WireType::StartGroup => {
162                let mut value = UnknownFieldSet::default();
163                encoding::group::merge(number, wire_type, &mut value, buf, ctx)?;
164                UnknownFieldValue::Group(value)
165            }
166            WireType::EndGroup => {
167                encoding::check_wire_type(WireType::StartGroup, wire_type)?;
168                unreachable!()
169            }
170            WireType::ThirtyTwoBit => {
171                let mut value = 0u32;
172                encoding::fixed32::merge(wire_type, &mut value, buf, ctx)?;
173                UnknownFieldValue::ThirtyTwoBit(value.to_le_bytes())
174            }
175        };
176
177        Ok(UnknownField { number, value })
178    }
179
180    /// Gets the length of this field when encoded to its byte representation.
181    pub fn encoded_len(&self) -> usize {
182        match &self.value {
183            UnknownFieldValue::Varint(value) => {
184                encoding::key_len(self.number) + encoding::encoded_len_varint(*value)
185            }
186            UnknownFieldValue::SixtyFourBit(value) => encoding::key_len(self.number) + value.len(),
187            UnknownFieldValue::LengthDelimited(value) => {
188                encoding::bytes::encoded_len(self.number, value)
189            }
190            UnknownFieldValue::Group(value) => encoding::group::encoded_len(self.number, value),
191            UnknownFieldValue::ThirtyTwoBit(value) => encoding::key_len(self.number) + value.len(),
192        }
193    }
194}
195
196impl fmt::Display for UnknownField {
197    /// Formats this unknown field using the protobuf text format.
198    ///
199    /// The protobuf format does not include type information, so the formatter will attempt to infer types.
200    ///
201    /// # Examples
202    ///
203    /// ```
204    /// # use prost_reflect::{DescriptorPool, UnknownField};
205    /// # use prost::encoding::DecodeContext;
206    /// # let pool = DescriptorPool::decode(include_bytes!("../file_descriptor_set.bin").as_ref()).unwrap();
207    /// # let message_descriptor = pool.get_message_by_name("google.protobuf.Empty").unwrap();
208    /// let unknown_field = UnknownField::decode(&mut b"\x1a\x02\x10\x42".as_ref(), DecodeContext::default()).unwrap();
209    /// assert_eq!(format!("{}", unknown_field), "3{2:66}");
210    /// // The alternate format specifier may be used to indent the output
211    /// assert_eq!(format!("{:#}", unknown_field), "3 {\n  2: 66\n}");
212    /// ```
213    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
214        text_format::Writer::new(text_format::FormatOptions::new().pretty(f.alternate()), f)
215            .fmt_unknown_field(self)
216    }
217}
218
219impl UnknownFieldSet {
220    pub(crate) fn is_empty(&self) -> bool {
221        self.fields.is_empty()
222    }
223
224    pub(crate) fn iter(&self) -> slice::Iter<'_, UnknownField> {
225        self.fields.iter()
226    }
227
228    pub(crate) fn into_iter(self) -> vec::IntoIter<UnknownField> {
229        self.fields.into_iter()
230    }
231
232    pub(crate) fn insert(&mut self, unknown: UnknownField) {
233        self.fields.push(unknown);
234    }
235}
236
237impl Message for UnknownFieldSet {
238    fn encode_raw(&self, buf: &mut impl BufMut)
239    where
240        Self: Sized,
241    {
242        for field in &self.fields {
243            field.encode(buf)
244        }
245    }
246
247    fn merge_field(
248        &mut self,
249        number: u32,
250        wire_type: WireType,
251        buf: &mut impl Buf,
252        ctx: DecodeContext,
253    ) -> Result<(), DecodeError>
254    where
255        Self: Sized,
256    {
257        let field = UnknownField::decode_value(number, wire_type, buf, ctx)?;
258        self.fields.push(field);
259        Ok(())
260    }
261
262    fn encoded_len(&self) -> usize {
263        let mut len = 0;
264        for field in &self.fields {
265            len += field.encoded_len();
266        }
267        len
268    }
269
270    fn clear(&mut self) {
271        self.fields.clear();
272    }
273}
274
275impl FromIterator<UnknownField> for UnknownFieldSet {
276    fn from_iter<T>(iter: T) -> Self
277    where
278        T: IntoIterator<Item = UnknownField>,
279    {
280        UnknownFieldSet {
281            fields: Vec::from_iter(iter),
282        }
283    }
284}
285
286#[cfg(test)]
287mod tests {
288    use prost::{
289        bytes::Bytes,
290        encoding::{DecodeContext, WireType},
291    };
292
293    use super::{UnknownField, UnknownFieldSet, UnknownFieldValue};
294
295    fn assert_roundtrip(expected: &[u8], value: &UnknownField) {
296        assert_eq!(expected.len(), value.encoded_len());
297
298        let mut actual = Vec::with_capacity(expected.len());
299        value.encode(&mut actual);
300        assert_eq!(expected, actual.as_slice());
301    }
302
303    #[test]
304    fn sixty_four_bit() {
305        let bytes = b"\x09\x9a\x99\x99\x99\x99\x99\xf1\x3ftail";
306        let mut buf = bytes.as_ref();
307
308        let value = UnknownField::decode(&mut buf, DecodeContext::default()).unwrap();
309
310        assert_eq!(value.number(), 1);
311        assert_eq!(value.wire_type(), WireType::SixtyFourBit);
312        assert_eq!(
313            value.value(),
314            &UnknownFieldValue::SixtyFourBit(*b"\x9a\x99\x99\x99\x99\x99\xf1\x3f")
315        );
316        assert_eq!(buf, b"tail");
317
318        assert_roundtrip(bytes.strip_suffix(buf).unwrap(), &value);
319    }
320
321    #[test]
322    fn thirty_two_bit() {
323        let bytes = b"\x15\xcd\xcc\x0c\x40tail";
324        let mut buf = bytes.as_ref();
325
326        let value = UnknownField::decode(&mut buf, DecodeContext::default()).unwrap();
327
328        assert_eq!(value.number(), 2);
329        assert_eq!(value.wire_type(), WireType::ThirtyTwoBit);
330        assert_eq!(
331            value.value(),
332            &UnknownFieldValue::ThirtyTwoBit(*b"\xcd\xcc\x0c\x40")
333        );
334        assert_eq!(buf, b"tail");
335
336        assert_roundtrip(bytes.strip_suffix(buf).unwrap(), &value);
337    }
338
339    #[test]
340    fn varint() {
341        let bytes = b"\x18\x03tail";
342        let mut buf = bytes.as_ref();
343
344        let value = UnknownField::decode(&mut buf, DecodeContext::default()).unwrap();
345
346        assert_eq!(value.number(), 3);
347        assert_eq!(value.wire_type(), WireType::Varint);
348        assert_eq!(value.value(), &UnknownFieldValue::Varint(3));
349        assert_eq!(buf, b"tail");
350
351        assert_roundtrip(bytes.strip_suffix(buf).unwrap(), &value);
352    }
353
354    #[test]
355    fn length_delimited() {
356        let bytes = b"\x7a\x07\x69\xa6\xbe\x6d\xb6\xff\x58tail";
357        let mut buf = bytes.as_ref();
358
359        let value = UnknownField::decode(&mut buf, DecodeContext::default()).unwrap();
360
361        assert_eq!(value.number(), 15);
362        assert_eq!(value.wire_type(), WireType::LengthDelimited);
363        assert_eq!(
364            value.value(),
365            &UnknownFieldValue::LengthDelimited(Bytes::from_static(
366                b"\x69\xa6\xbe\x6d\xb6\xff\x58"
367            ))
368        );
369        assert_eq!(buf, b"tail");
370
371        assert_roundtrip(bytes.strip_suffix(buf).unwrap(), &value);
372    }
373
374    #[test]
375    fn group() {
376        let bytes = b"\x1b\x0a\x05\x68\x65\x6c\x6c\x6f\x10\x0a\x10\x0b\x1ctail";
377        let mut buf = bytes.as_ref();
378
379        let value = UnknownField::decode(&mut buf, DecodeContext::default()).unwrap();
380
381        assert_eq!(value.number(), 3);
382        assert_eq!(value.wire_type(), WireType::StartGroup);
383        assert_eq!(
384            value.value(),
385            &UnknownFieldValue::Group(UnknownFieldSet::from_iter([
386                UnknownField {
387                    number: 1,
388                    value: UnknownFieldValue::LengthDelimited(Bytes::from_static(b"hello"))
389                },
390                UnknownField {
391                    number: 2,
392                    value: UnknownFieldValue::Varint(10)
393                },
394                UnknownField {
395                    number: 2,
396                    value: UnknownFieldValue::Varint(11)
397                },
398            ]))
399        );
400        assert_eq!(buf, b"tail");
401
402        assert_roundtrip(bytes.strip_suffix(buf).unwrap(), &value);
403    }
404}