quack_builder/
types.rs

1use crate::errors::{Error, Result};
2use crate::keywords::sanitize_keyword;
3use crate::parser::file_descriptor;
4use std::collections::HashMap;
5use std::fmt;
6use std::fs::File;
7use std::io::{BufWriter, Write};
8use std::path::{Path, PathBuf};
9
10fn sizeof_varint(v: u32) -> usize {
11    match v {
12        0x0..=0x7f => 1,
13        0x80..=0x3fff => 2,
14        0x4000..=0x1f_ffff => 3,
15        0x20_0000..=0xfff_ffff => 4,
16        _ => 5,
17    }
18}
19
20#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
21pub enum Syntax {
22    #[default]
23    Proto2,
24    Proto3,
25}
26
27#[derive(Debug, Clone, Copy, PartialEq, Eq)]
28pub enum Frequency {
29    Proto2Frequency(Proto2Frequency),
30    Proto3Frequency(Proto3Frequency),
31}
32
33#[derive(Debug, Clone, Copy, PartialEq, Eq)]
34pub enum Proto2Frequency {
35    Optional,
36    Repeated,
37    Required,
38    Map,
39}
40
41#[derive(Debug, Clone, Copy, PartialEq, Eq)]
42pub enum Proto3Frequency {
43    Optional,
44    Repeated,
45    Default,
46    Map,
47}
48
49#[derive(Debug, Clone, Copy, PartialEq, Eq)]
50pub enum GeneratedType {
51    SingularType,
52    ArrayLikeType,
53    Map,
54}
55
56impl Frequency {
57    pub fn is_map(&self) -> bool {
58        matches!(
59            self,
60            Frequency::Proto2Frequency(Proto2Frequency::Map)
61                | Frequency::Proto3Frequency(Proto3Frequency::Map)
62        )
63    }
64
65    pub fn is_optional(&self) -> bool {
66        matches!(
67            self,
68            Frequency::Proto2Frequency(Proto2Frequency::Optional)
69                | Frequency::Proto3Frequency(Proto3Frequency::Optional)
70        )
71    }
72
73    pub fn is_repeated(&self) -> bool {
74        matches!(
75            self,
76            Frequency::Proto2Frequency(Proto2Frequency::Repeated)
77                | Frequency::Proto3Frequency(Proto3Frequency::Repeated)
78        )
79    }
80}
81
82impl From<Frequency> for GeneratedType {
83    fn from(value: Frequency) -> Self {
84        if value.is_map() {
85            GeneratedType::Map
86        } else if value.is_repeated() {
87            GeneratedType::ArrayLikeType
88        } else {
89            GeneratedType::SingularType
90        }
91    }
92}
93
94#[derive(Clone, PartialEq, Eq, Hash, Default)]
95pub struct MessageIndex {
96    indexes: Vec<usize>,
97}
98
99impl fmt::Debug for MessageIndex {
100    fn fmt(
101        &self,
102        f: &mut fmt::Formatter,
103    ) -> ::std::result::Result<(), fmt::Error> {
104        f.debug_set().entries(self.indexes.iter()).finish()
105    }
106}
107
108impl MessageIndex {
109    pub fn get_message<'a>(
110        &self,
111        desc: &'a FileDescriptor,
112    ) -> &'a Message {
113        let first_message = self.indexes.first().and_then(|i| desc.messages.get(*i));
114        self.indexes
115            .iter()
116            .skip(1)
117            .fold(first_message, |cur, next| {
118                cur.and_then(|msg| msg.messages.get(*next))
119            })
120            .expect("Message index not found")
121    }
122
123    fn get_message_mut<'a>(
124        &self,
125        desc: &'a mut FileDescriptor,
126    ) -> &'a mut Message {
127        let first_message = self
128            .indexes
129            .first()
130            .and_then(move |i| desc.messages.get_mut(*i));
131        self.indexes
132            .iter()
133            .skip(1)
134            .fold(first_message, |cur, next| {
135                cur.and_then(|msg| msg.messages.get_mut(*next))
136            })
137            .expect("Message index not found")
138    }
139
140    fn push(
141        &mut self,
142        i: usize,
143    ) {
144        self.indexes.push(i);
145    }
146
147    fn pop(&mut self) {
148        self.indexes.pop();
149    }
150}
151
152#[derive(Debug, Clone, PartialEq, Eq, Hash, Default)]
153pub struct EnumIndex {
154    msg_index: MessageIndex,
155    index: usize,
156}
157
158impl EnumIndex {
159    pub fn get_enum<'a>(
160        &self,
161        desc: &'a FileDescriptor,
162    ) -> &'a Enumerator {
163        let enums = if self.msg_index.indexes.is_empty() {
164            &desc.enums
165        } else {
166            &self.msg_index.get_message(desc).enums
167        };
168        enums.get(self.index).expect("Enum index not found")
169    }
170}
171
172#[derive(Debug, Clone, PartialEq, Eq, Hash)]
173pub enum FieldType {
174    Int32,
175    Int64,
176    Uint32,
177    Uint64,
178    Sint32,
179    Sint64,
180    Bool,
181    Enum(EnumIndex),
182    Fixed64,
183    Sfixed64,
184    Double,
185    StringCow,
186    BytesCow,
187    String_,
188    Bytes_,
189    Message(MessageIndex),
190    MessageOrEnum(String),
191    Fixed32,
192    Sfixed32,
193    Float,
194    Map(Box<FieldType>, Box<FieldType>),
195}
196
197impl FieldType {
198    fn is_cow(&self) -> bool {
199        matches!(self, FieldType::StringCow | FieldType::BytesCow)
200    }
201
202    fn is_non_cow_string_or_byte(&self) -> bool {
203        matches!(self, FieldType::String_ | FieldType::Bytes_)
204    }
205
206    fn need_to_dereference(&self) -> bool {
207        matches!(
208            self,
209            FieldType::Enum(_)
210                | FieldType::Int32
211                | FieldType::Sint32
212                | FieldType::Int64
213                | FieldType::Sint64
214                | FieldType::Uint32
215                | FieldType::Uint64
216                | FieldType::Bool
217                | FieldType::Fixed64
218                | FieldType::Sfixed64
219                | FieldType::Double
220                | FieldType::Fixed32
221                | FieldType::Sfixed32
222                | FieldType::Float
223        )
224    }
225
226    pub fn is_primitive(&self) -> bool {
227        !matches!(
228            *self,
229            FieldType::Message(_)
230                | FieldType::Map(_, _)
231                | FieldType::StringCow
232                | FieldType::BytesCow
233                | FieldType::String_
234                | FieldType::Bytes_
235        )
236    }
237
238    fn has_cow(&self) -> bool {
239        match *self {
240            FieldType::BytesCow | FieldType::StringCow => true,
241            FieldType::Map(ref k, ref v) => k.has_cow() || v.has_cow(),
242            _ => false,
243        }
244    }
245
246    fn has_bytes_and_string(&self) -> bool {
247        matches!(*self, FieldType::Bytes_ | FieldType::String_)
248    }
249
250    fn is_map(&self) -> bool {
251        matches!(*self, FieldType::Map(_, _))
252    }
253
254    fn wire_type_num(
255        &self,
256        packed: bool,
257    ) -> u32 {
258        if packed {
259            2
260        } else {
261            self.wire_type_num_non_packed()
262        }
263    }
264
265    fn wire_type_num_non_packed(&self) -> u32 {
266        /*
267        0	Varint	int32, int64, uint32, uint64, sint32, sint64, bool, enum
268        1	64-bit	fixed64, sfixed64, double
269        2	Length-delimited	string, bytes, embedded messages, packed repeated fields
270        3	Start group	groups (deprecated)
271        4	End group	groups (deprecated)
272        5	32-bit	fixed32, sfixed32, float
273        */
274        match *self {
275            FieldType::Int32
276            | FieldType::Sint32
277            | FieldType::Int64
278            | FieldType::Sint64
279            | FieldType::Uint32
280            | FieldType::Uint64
281            | FieldType::Bool
282            | FieldType::Enum(_) => 0,
283            FieldType::Fixed64 | FieldType::Sfixed64 | FieldType::Double => 1,
284            FieldType::StringCow
285            | FieldType::BytesCow
286            | FieldType::String_
287            | FieldType::Bytes_
288            | FieldType::Message(_)
289            | FieldType::Map(_, _) => 2,
290            FieldType::Fixed32 | FieldType::Sfixed32 | FieldType::Float => 5,
291            FieldType::MessageOrEnum(_) => unreachable!("Message / Enum not resolved"),
292        }
293    }
294
295    fn proto_type(&self) -> &str {
296        match *self {
297            FieldType::Int32 => "int32",
298            FieldType::Sint32 => "sint32",
299            FieldType::Int64 => "int64",
300            FieldType::Sint64 => "sint64",
301            FieldType::Uint32 => "uint32",
302            FieldType::Uint64 => "uint64",
303            FieldType::Bool => "bool",
304            FieldType::Enum(_) => "enum",
305            FieldType::Fixed32 => "fixed32",
306            FieldType::Sfixed32 => "sfixed32",
307            FieldType::Float => "float",
308            FieldType::Fixed64 => "fixed64",
309            FieldType::Sfixed64 => "sfixed64",
310            FieldType::Double => "double",
311            FieldType::String_ => "string",
312            FieldType::Bytes_ => "bytes",
313            FieldType::StringCow => "string",
314            FieldType::BytesCow => "bytes",
315            FieldType::Message(_) => "message",
316            FieldType::Map(_, _) => "map",
317            FieldType::MessageOrEnum(_) => unreachable!("Message / Enum not resolved"),
318        }
319    }
320
321    fn is_fixed_size(&self) -> bool {
322        matches!(self.wire_type_num_non_packed(), 1 | 5)
323    }
324
325    fn singular_field_defaults(
326        &self,
327        desc: &FileDescriptor,
328    ) -> String {
329        match *self {
330            FieldType::Int32 => "0i32".to_owned(),
331            FieldType::Sint32 => "0i32".to_owned(),
332            FieldType::Int64 => "0i64".to_owned(),
333            FieldType::Sint64 => "0i64".to_owned(),
334            FieldType::Uint32 => "0u32".to_owned(),
335            FieldType::Uint64 => "0u64".to_owned(),
336            FieldType::Bool => "false".to_owned(),
337            FieldType::Fixed32 => "0u32".to_owned(),
338            FieldType::Sfixed32 => "0i32".to_owned(),
339            FieldType::Float => "0f32".to_owned(),
340            FieldType::Fixed64 => "0u64".to_owned(),
341            FieldType::Sfixed64 => "0i64".to_owned(),
342            FieldType::Double => "0f64".to_owned(),
343            FieldType::StringCow => "Cow::Borrowed(\"\")".to_owned(),
344            FieldType::String_ => "\"\".to_string()".to_owned(),
345            FieldType::BytesCow => "Cow::Borrowed(b\"\")".to_owned(),
346            FieldType::Bytes_ => "Vec::<u8>::new()".to_owned(),
347            FieldType::Enum(ref e) => {
348                let e = e.get_enum(desc);
349                e.fully_qualified_fields[0].0.to_owned()
350            }
351            FieldType::Message(ref m) => {
352                let m = m.get_message(desc);
353                format!("{}{}::default()", m.get_modules(desc), m.name)
354            }
355            _ => unreachable!(),
356        }
357    }
358
359    pub fn message(&self) -> Option<&MessageIndex> {
360        if let FieldType::Message(m) = self {
361            Some(m)
362        } else {
363            None
364        }
365    }
366
367    fn has_lifetime(
368        &self,
369        desc: &FileDescriptor,
370        config: &Config,
371        packed: bool,
372        ignore: &mut Vec<MessageIndex>,
373    ) -> bool {
374        match *self {
375            FieldType::StringCow | FieldType::BytesCow => true, // Cow<[u8]>
376            FieldType::Message(ref m) => m.get_message(desc).has_lifetime(desc, config, ignore),
377            FieldType::Fixed64
378            | FieldType::Sfixed64
379            | FieldType::Double
380            | FieldType::Fixed32
381            | FieldType::Sfixed32
382            | FieldType::String_
383            | FieldType::Bytes_
384            | FieldType::Float => packed, // Cow<[M]>
385            FieldType::Map(ref key, ref value) => {
386                key.has_lifetime(desc, config, false, ignore)
387                    || value.has_lifetime(desc, config, false, ignore)
388            }
389            _ => false,
390        }
391    }
392
393    fn rust_type(
394        &self,
395        desc: &FileDescriptor,
396        config: &Config,
397    ) -> Result<String> {
398        Ok(match *self {
399            FieldType::Int32 | FieldType::Sint32 | FieldType::Sfixed32 => "i32".to_string(),
400            FieldType::Int64 | FieldType::Sint64 | FieldType::Sfixed64 => "i64".to_string(),
401            FieldType::Uint32 | FieldType::Fixed32 => "u32".to_string(),
402            FieldType::Uint64 | FieldType::Fixed64 => "u64".to_string(),
403            FieldType::Double => "f64".to_string(),
404            FieldType::Float => "f32".to_string(),
405            FieldType::StringCow => "Cow<'a, str>".to_string(),
406            FieldType::BytesCow => "Cow<'a, [u8]>".to_string(),
407            FieldType::String_ => "String".to_string(),
408            FieldType::Bytes_ => "Vec<u8>".to_string(),
409            FieldType::Bool => "bool".to_string(),
410            FieldType::Enum(ref e) => {
411                let e = e.get_enum(desc);
412                format!("{}{}", e.get_modules(desc), e.name)
413            }
414            FieldType::Message(ref msg) => {
415                let m = msg.get_message(desc);
416                let lifetime = if m.has_lifetime(desc, config, &mut Vec::new()) {
417                    "<'a>"
418                } else {
419                    ""
420                };
421                format!("{}{}{}", m.get_modules(desc), m.name, lifetime)
422            }
423            FieldType::Map(ref key, ref value) => format!(
424                "KVMap<{}, {}>",
425                key.rust_type(desc, config)?,
426                value.rust_type(desc, config)?
427            ),
428            FieldType::MessageOrEnum(_) => unreachable!("Message / Enum not resolved"),
429        })
430    }
431
432    /// Returns the relevant function to read the data, both for regular and Cow wrapped
433    fn read_fn(
434        &self,
435        desc: &FileDescriptor,
436    ) -> Result<(String, String)> {
437        Ok(match *self {
438            FieldType::Message(ref msg) => {
439                let m = msg.get_message(desc);
440                let m = format!(
441                    "r.read_message::<{}{}>(bytes)?",
442                    m.get_modules(desc),
443                    m.name
444                );
445                (m.clone(), m)
446            }
447            FieldType::Map(_, _) => {
448                return Err(Error::ReadFnMap);
449            }
450            FieldType::StringCow | FieldType::BytesCow => {
451                let m = format!("r.read_{}(bytes)", self.proto_type());
452                let cow = format!("{}.map(Cow::Borrowed)?", m);
453                (m, cow)
454            }
455            FieldType::String_ => {
456                let m = format!("r.read_{}(bytes)", self.proto_type());
457                let vec = format!("{}?.to_owned()", m);
458                (m, vec)
459            }
460            FieldType::Bytes_ => {
461                let m = format!("r.read_{}(bytes)", self.proto_type());
462                let vec = format!("{}?.to_owned()", m);
463                (m, vec)
464            }
465            FieldType::MessageOrEnum(_) => unreachable!("Message / Enum not resolved"),
466            _ => {
467                let m = format!("r.read_{}(bytes)?", self.proto_type());
468                (m.clone(), m)
469            }
470        })
471    }
472
473    fn get_size(
474        &self,
475        s: &str,
476    ) -> String {
477        match *self {
478            FieldType::Int32
479            | FieldType::Int64
480            | FieldType::Uint32
481            | FieldType::Uint64
482            | FieldType::Bool
483            | FieldType::Enum(_) => format!("sizeof_varint(*(&{}) as u64)", s),
484            FieldType::Sint32 => format!("sizeof_sint32(*(&{}))", s),
485            FieldType::Sint64 => format!("sizeof_sint64(*(&{}))", s),
486
487            FieldType::Fixed64 | FieldType::Sfixed64 | FieldType::Double => "8".to_string(),
488            FieldType::Fixed32 | FieldType::Sfixed32 | FieldType::Float => "4".to_string(),
489
490            FieldType::StringCow | FieldType::BytesCow => format!("sizeof_len((&{}).len())", s),
491
492            FieldType::String_ | FieldType::Bytes_ => format!("sizeof_len({}.len())", s),
493
494            FieldType::Message(_) => format!("sizeof_len(({}).get_size())", s),
495
496            FieldType::Map(ref k, ref v) => {
497                format!("2 + {} + {}", k.get_size("k"), v.get_size("v"))
498            }
499            FieldType::MessageOrEnum(_) => unreachable!("Message / Enum not resolved"),
500        }
501    }
502
503    fn get_write(
504        &self,
505        s: &str,
506        boxed: bool,
507    ) -> String {
508        match *self {
509            FieldType::Enum(_) => format!("write_enum(*&{} as i32)", s),
510            FieldType::Int32
511            | FieldType::Sint32
512            | FieldType::Int64
513            | FieldType::Sint64
514            | FieldType::Uint32
515            | FieldType::Uint64
516            | FieldType::Bool
517            | FieldType::Fixed64
518            | FieldType::Sfixed64
519            | FieldType::Double
520            | FieldType::Fixed32
521            | FieldType::Sfixed32
522            | FieldType::Float => format!("write_{}(*&{})", self.proto_type(), s),
523            FieldType::StringCow => format!("write_string({})", s),
524            FieldType::BytesCow => format!("write_bytes({})", s),
525            FieldType::String_ => format!("write_string({})", s),
526            FieldType::Bytes_ => format!("write_bytes({})", s),
527            FieldType::Message(_) if boxed => format!("write_message(&*({}))", s),
528            FieldType::Message(_) => format!("write_message({})", s),
529            FieldType::Map(ref k, ref v) => format!(
530                "write_map({}, {}, |w| w.{}, {}, |w| w.{})",
531                self.get_size(""),
532                tag(1, k, false),
533                k.get_write("k", false),
534                tag(2, v, false),
535                v.get_write("v", false)
536            ),
537            FieldType::MessageOrEnum(_) => unreachable!("Message / Enum not resolved"),
538        }
539    }
540}
541
542#[derive(Debug, Clone)]
543pub struct Field {
544    pub name: String,
545    pub frequency: Frequency,
546    pub typ: FieldType,
547    pub number: i32,
548    pub default: Option<String>,
549    pub packed: Option<bool>,
550    pub boxed: bool,
551    pub deprecated: bool,
552}
553
554impl Field {
555    fn has_valid_visible_custom_default(
556        &self,
557        desc: &FileDescriptor,
558        config: &Config,
559    ) -> bool {
560        let is_visible = config.add_deprecated_fields || !self.deprecated;
561
562        let is_proto2 = desc.syntax == Syntax::Proto2;
563
564        let optional_or_required = matches!(
565            self.frequency,
566            Frequency::Proto2Frequency(Proto2Frequency::Optional)
567                | Frequency::Proto2Frequency(Proto2Frequency::Required)
568        );
569
570        let is_not_message = !matches!(self.typ, FieldType::Message(_));
571        let has_custom_default_tag = self.default.is_some();
572        is_visible && is_proto2 && optional_or_required && is_not_message && has_custom_default_tag
573    }
574
575    fn must_generate_impl_default(
576        &self,
577        desc: &FileDescriptor,
578        config: &Config,
579    ) -> bool {
580        // `impl Default` must be generated only for Proto2 `required` fields,
581        // because:
582        //
583        // 1. They can have custom defaults (since they're Proto2)
584        // 2. Custom default influences the field's initialization values
585        //    instead of creating a default `const`.
586        self.has_valid_visible_custom_default(desc, config)
587            && self.frequency == Frequency::Proto2Frequency(Proto2Frequency::Required)
588    }
589
590    fn write_default<W: Write>(
591        &self,
592        w: &mut W,
593        desc: &FileDescriptor,
594        config: &Config,
595    ) -> Result<()> {
596        if self.deprecated && !config.add_deprecated_fields {
597            return Ok(());
598        }
599
600        writeln!(
601            w,
602            "            {}: {},",
603            self.name,
604            self.get_field_default(desc, config)
605        )?;
606        Ok(())
607    }
608
609    fn get_field_default(
610        &self,
611        desc: &FileDescriptor,
612        config: &Config,
613    ) -> String {
614        match self.frequency.into() {
615            GeneratedType::SingularType => {
616                if self.boxed {
617                    return "None".to_owned();
618                }
619                if self.frequency.is_optional() {
620                    // No matter whether there is a custom or standard default,
621                    // the field will still be initialized to `None`, since we
622                    // rely on `is_some()` as a hazzer. User must retrieve
623                    // default themselves.
624                    "None".to_owned()
625                } else {
626                    match &self.default {
627                        Some(custom_default) => {
628                            // If the command line option `--dont_use_cow` is
629                            // set, `String` and `Vec<u8>` will be used instead
630                            // of `Cow<'a, str>` and `Cow<'a, [u8]>`
631                            // respectively. However, custom defaults are
632                            // represented using `const` variables, and neither
633                            // `String` nor `Vec<u8>` are able to be `const`.
634                            // Thus, we need to be able to generate:
635                            //
636                            //      1) for string fields, both `&str` as well as
637                            //          `String` versions
638                            //      2) for byte fields, both `[u8; N]` as well
639                            //          as `Vec<u8>` versions
640                            //
641                            // For convenience, we start with the `const`
642                            // versions, and add on methods to convert to
643                            // non-`const` versions below.
644                            if self.typ.is_non_cow_string_or_byte() {
645                                return match self.typ {
646                                    FieldType::String_ => format!("{custom_default}.to_string()"),
647                                    FieldType::Bytes_ => format!("{custom_default}.to_vec()"),
648                                    _ => unreachable!(),
649                                };
650                            }
651                            custom_default.clone()
652                        }
653                        None => self.typ.singular_field_defaults(desc),
654                    }
655                }
656            }
657            GeneratedType::ArrayLikeType => {
658                if self.packed() && self.typ.is_fixed_size() && !config.dont_use_cow {
659                    "PackedFixed::from(Vec::new())".to_owned()
660                } else {
661                    "Vec::new()".to_owned()
662                }
663            }
664            GeneratedType::Map => "HashMap::new()".to_owned(),
665        }
666    }
667
668    fn packed(&self) -> bool {
669        self.packed.unwrap_or(false)
670    }
671
672    fn sanitize_default(
673        &mut self,
674        desc: &FileDescriptor,
675        config: &Config,
676    ) -> Result<()> {
677        if let Some(ref mut d) = self.default {
678            *d = match &*self.typ.rust_type(desc, config)? {
679                "u32" => format!("{}u32", *d),
680                "u64" => format!("{}u64", *d),
681                "i32" => format!("{}i32", *d),
682                "i64" => format!("{}i64", *d),
683                "f32" => match &*d.to_lowercase() {
684                    "inf" => "::core::f32::INFINITY".to_string(),
685                    "-inf" => "::core::f32::NEG_INFINITY".to_string(),
686                    "nan" => "::core::f32::NAN".to_string(),
687                    _ => format!("{}f32", *d),
688                },
689                "f64" => match &*d.to_lowercase() {
690                    "inf" => "::core::f64::INFINITY".to_string(),
691                    "-inf" => "::core::f64::NEG_INFINITY".to_string(),
692                    "nan" => "::core::f64::NAN".to_string(),
693                    _ => format!("{}f64", *d),
694                },
695                "Cow<'a, str>" => format!("Cow::Borrowed(\"{}\")", d),
696                "Cow<'a, [u8]>" => format!("Cow::Borrowed(b\"{}\")", d),
697                "String" => format!("\"{}\"", d),
698                "Bytes" => format!("b\"{}\"", d),
699                "Vec<u8>" => format!("b\"{}\"", d),
700                "bool" => format!("{}", d.parse::<bool>().unwrap()),
701                e => format!("{}::{}", e, d), // enum, as message and map do not have defaults
702            };
703        }
704        Ok(())
705    }
706
707    fn tag(&self) -> u32 {
708        tag(self.number as u32, &self.typ, self.packed())
709    }
710
711    pub fn get_type(
712        &self,
713        desc: &FileDescriptor,
714        config: &Config,
715    ) -> String {
716        let rust_type = self.typ.rust_type(desc, config).unwrap();
717        if self.boxed {
718            return format!("Option<Box<{}>>", rust_type);
719        }
720
721        match self.frequency.into() {
722            GeneratedType::SingularType => {
723                if self.frequency.is_optional() {
724                    format!("Option<{}>", rust_type)
725                } else {
726                    rust_type
727                }
728            }
729            GeneratedType::ArrayLikeType => {
730                if self.packed() && self.typ.is_fixed_size() && !config.dont_use_cow {
731                    format!("PackedFixed<'a, {}>", rust_type)
732                } else {
733                    format!("Vec<{}>", rust_type)
734                }
735            }
736            GeneratedType::Map => {
737                rust_type // rust_type is already KVMap<{}, {}>
738            }
739        }
740    }
741
742    fn write_definition<W: Write>(
743        &self,
744        w: &mut W,
745        desc: &FileDescriptor,
746        config: &Config,
747    ) -> Result<()> {
748        if self.deprecated {
749            if config.add_deprecated_fields {
750                writeln!(w, "    #[deprecated]")?;
751            } else {
752                return Ok(());
753            }
754        }
755        writeln!(w, "    pub {}: {},", self.name, self.get_type(desc, config))?;
756
757        Ok(())
758    }
759
760    fn write_match_tag<W: Write>(
761        &self,
762        w: &mut W,
763        desc: &FileDescriptor,
764        config: &Config,
765    ) -> Result<()> {
766        if self.deprecated && !config.add_deprecated_fields {
767            return Ok(());
768        }
769
770        let (val, val_cow) = if self.frequency.is_map() {
771            ("".to_owned(), "".to_owned()) // ignore if is map
772        } else {
773            self.typ.read_fn(desc)?
774        };
775
776        let name = &self.name;
777        write!(w, "                Ok({}) => ", self.tag())?;
778
779        if self.boxed {
780            writeln!(w, "msg.{} = Some(Box::new({})),", name, val)?;
781            return Ok(());
782        }
783
784        match self.frequency.into() {
785            GeneratedType::SingularType => match &self.frequency {
786                Frequency::Proto2Frequency(freq) => match freq {
787                    Proto2Frequency::Optional => writeln!(w, "msg.{} = Some({}),", name, val_cow)?,
788                    Proto2Frequency::Required => writeln!(w, "msg.{} = {},", name, val_cow)?,
789                    _ => unreachable!(),
790                },
791                Frequency::Proto3Frequency(freq) => match freq {
792                    Proto3Frequency::Optional => writeln!(w, "msg.{} = Some({}),", name, val_cow)?,
793                    Proto3Frequency::Default => writeln!(w, "msg.{} = {},", name, val_cow)?,
794                    _ => unreachable!(),
795                },
796            },
797            GeneratedType::ArrayLikeType => {
798                if self.packed() {
799                    if self.typ.is_fixed_size() {
800                        writeln!(w, "msg.{} = r.read_packed_fixed(bytes)?,", name)?;
801                    } else {
802                        writeln!(
803                            w,
804                            "msg.{} = r.read_packed(bytes, |r, bytes| Ok({}))?,",
805                            name, val_cow
806                        )?;
807                    }
808                } else {
809                    writeln!(w, "msg.{}.push({}),", name, val_cow)?;
810                }
811            }
812            GeneratedType::Map => {
813                // TODO: Is there any way of doing this without `if let`? `let`
814                // by itself requires "irrefutable types".
815                if let FieldType::Map(ref key, ref value) = self.typ {
816                    writeln!(w, "{{")?;
817                    writeln!(
818                        w,
819                        "                    let (key, value) = \
820                        r.read_map(bytes, |r, bytes| Ok({}), |r, bytes| Ok({}))?;",
821                        key.read_fn(desc)?.1,
822                        value.read_fn(desc)?.1
823                    )?;
824                    writeln!(
825                        w,
826                        "                    msg.{}.insert(key, value);",
827                        self.name
828                    )?;
829                    writeln!(w, "                }}")?;
830                    return Ok(());
831                } else {
832                    unreachable!();
833                }
834            }
835        }
836
837        Ok(())
838    }
839
840    fn write_get_size<W: Write>(
841        &self,
842        w: &mut W,
843        desc: &FileDescriptor,
844        config: &Config,
845    ) -> Result<()> {
846        if self.deprecated && !config.add_deprecated_fields {
847            return Ok(());
848        }
849
850        write!(w, "        + ")?;
851        let tag_size = sizeof_varint(self.tag());
852
853        match self.frequency.into() {
854            GeneratedType::SingularType => {
855                fn get_size_addition(
856                    field: &Field,
857                    tag_size: usize,
858                    s: &str,
859                ) -> String {
860                    format!(
861                        "{tag_size} + {actual_size}",
862                        actual_size =
863                            field
864                                .typ
865                                .get_size(if field.typ.is_fixed_size() { "" } else { s })
866                    )
867                }
868
869                let conditions_checked = {
870                    let name = self.name.clone();
871                    let def = self.get_field_default(desc, config);
872                    let m_size_addition = get_size_addition(self, tag_size, "m");
873                    let self_name_size_addition =
874                        get_size_addition(self, tag_size, format!("self.{name}").as_str());
875                    let maybe_deref_m = if self.boxed || !self.typ.is_primitive() {
876                        "m"
877                    } else {
878                        "&m"
879                    };
880
881                    match (!self.has_presence(), self.frequency.is_optional()) {
882                        (true, true) => format!(
883                            "self.{name}.as_ref().map_or(0, |{maybe_deref_m}| if m != {def} {{ {m_size_addition} }} else {{ 0 }}"
884                        ),
885                        (true, false) => format!(
886                            "if self.{name} == {def} {{ 0 }} else {{ {self_name_size_addition} }}"
887                        ),
888                        (false, true) => format!(
889                            "self.{name}.as_ref().map_or(0, |{maybe_deref_m}| {m_size_addition})"
890                        ),
891                        (false, false) => get_size_addition(
892                            self,
893                            tag_size,
894                            format!("self.{}", self.name).as_str(),
895                        ),
896                    }
897                };
898
899                writeln!(w, "{}", conditions_checked.as_str())?;
900            }
901            GeneratedType::ArrayLikeType => {
902                if self.packed() {
903                    write!(
904                        w,
905                        "if self.{}.is_empty() {{ 0 }} else {{ {} + ",
906                        self.name, tag_size
907                    )?;
908                    match self.typ.wire_type_num_non_packed() {
909                        1 => writeln!(w, "sizeof_len(self.{}.len() * 8) }}", self.name)?,
910                        5 => writeln!(w, "sizeof_len(self.{}.len() * 4) }}", self.name)?,
911                        _ => writeln!(
912                            w,
913                            "sizeof_len(self.{}.iter().map(|&s| {}).sum::<usize>()) }}",
914                            self.name,
915                            self.typ.get_size("s")
916                        )?,
917                    }
918                } else {
919                    match self.typ.wire_type_num_non_packed() {
920                        1 => writeln!(w, "({} + 8) * self.{}.len()", tag_size, self.name)?,
921                        5 => writeln!(w, "({} + 4) * self.{}.len()", tag_size, self.name)?,
922                        _ => writeln!(
923                            w,
924                            "self.{name}.iter().map(|{maybe_ampersand}s| {tag_size} + {got_size}).sum::<usize>()",
925                            maybe_ampersand = if self.typ.need_to_dereference() {
926                                "&"
927                            } else {
928                                ""
929                            },
930                            name = self.name,
931                            got_size = self.typ.get_size("s")
932                        )?,
933                    }
934                }
935            }
936            GeneratedType::Map => {
937                if let FieldType::Map(k, v) = &self.typ {
938                    writeln!(
939                        w,
940                        "self.{name}.iter().map(|({maybe_ampersand_k}k, {maybe_ampersand_v}v)| {tag_size} + sizeof_len({got_size})).sum::<usize>()",
941                        maybe_ampersand_k = if k.need_to_dereference() { "&" } else { "" },
942                        maybe_ampersand_v = if v.need_to_dereference() { "&" } else { "" },
943                        name = self.name,
944                        got_size = self.typ.get_size("")
945                    )?;
946                } else {
947                    unreachable!();
948                }
949            }
950        }
951        Ok(())
952    }
953
954    fn has_presence(&self) -> bool {
955        match &self.frequency {
956            Frequency::Proto2Frequency(f) => {
957                if let Proto2Frequency::Repeated = f {
958                    return false;
959                }
960                if let FieldType::Map(..) = self.typ {
961                    return false;
962                }
963                true
964            }
965            Frequency::Proto3Frequency(f) => {
966                if let Proto3Frequency::Repeated = f {
967                    return false;
968                }
969                if let FieldType::Map(..) = self.typ {
970                    return false;
971                }
972                if let FieldType::Message(_) = self.typ {
973                    return true;
974                }
975                if let Proto3Frequency::Optional = f {
976                    return true;
977                }
978                false
979            }
980        }
981    }
982
983    fn write_write<W: Write>(
984        &self,
985        w: &mut W,
986        desc: &FileDescriptor,
987        config: &Config,
988    ) -> Result<()> {
989        if self.deprecated && !config.add_deprecated_fields {
990            return Ok(());
991        }
992
993        write!(w, "        ")?;
994
995        match self.frequency.into() {
996            GeneratedType::SingularType => {
997                fn apply_unwrapping_code(
998                    f: &Field,
999                    equating_cows: bool,
1000                    s: &str,
1001                ) -> String {
1002                    let mut core = s.to_owned();
1003
1004                    if f.boxed {
1005                        core = format!("*({core})");
1006                    }
1007
1008                    // Required message, map and byte_ fields
1009                    if !f.typ.need_to_dereference()
1010                        && !f.typ.is_cow()
1011                        && !f.frequency.is_optional()
1012                        && !f.typ.is_non_cow_string_or_byte()
1013                    {
1014                        core = format!("&{core}");
1015                    }
1016
1017                    /*
1018                    There's a rather annoying edge case, an example of which is
1019                    given below:
1020
1021                    if &self.f_bytes != Cow::Borrowed(b"") {...}
1022                       ^
1023
1024                    For most field types, the above ampersand is ok, but for `Cow`s,
1025                    it will trigger an error (cannot compare `&Cow` to `Cow`), so we
1026                    introduce a check for this specifically.
1027                    */
1028                    if !equating_cows {
1029                        core = if f.typ.is_cow() || f.typ.is_non_cow_string_or_byte() {
1030                            format!("&{core}")
1031                        } else {
1032                            core.clone()
1033                        };
1034                    }
1035
1036                    core
1037                }
1038
1039                fn get_write_method(
1040                    f: &Field,
1041                    s: &str,
1042                ) -> String {
1043                    format!(
1044                        "w.write_with_tag({}, |w| w.{})",
1045                        f.tag(),
1046                        f.typ.get_write(s, f.boxed)
1047                    )
1048                }
1049
1050                // Check for conditions if necessary
1051                let conditions_checked = {
1052                    let name = self.name.clone();
1053                    let def = self.get_field_default(desc, config);
1054                    let m_core = apply_unwrapping_code(self, false, "m");
1055                    let self_name_core =
1056                        apply_unwrapping_code(self, false, format!("self.{name}").as_str());
1057                    let m_write_method = get_write_method(self, m_core.as_str());
1058                    let self_name_write_method = get_write_method(self, &self_name_core);
1059                    let maybe_deref_m = if self.boxed || !self.typ.is_primitive() {
1060                        "m"
1061                    } else {
1062                        "&m"
1063                    };
1064                    let self_name_core_equating_cows =
1065                        apply_unwrapping_code(self, true, format!("self.{name}").as_str());
1066
1067                    match (!self.has_presence(), self.frequency.is_optional()) {
1068                        (true, true) => format!(
1069                            "self.{name}.as_ref().map_or(Ok(()), |{maybe_deref_m}| if {m_core} != {def} {{ {m_write_method} }} else {{ Ok(()) }})?;"
1070                        ),
1071                        (true, false) => format!(
1072                            "if {self_name_core_equating_cows} != {def} {{ {self_name_write_method}?; }}"
1073                        ),
1074                        (false, true) => format!(
1075                            "self.{name}.as_ref().map_or(Ok(()), |{maybe_deref_m}| {m_write_method})?;"
1076                        ),
1077                        (false, false) => format!("{}?;", self_name_write_method),
1078                    }
1079                };
1080
1081                writeln!(w, "{}", conditions_checked.as_str())?;
1082            }
1083            GeneratedType::ArrayLikeType => {
1084                if self.packed() {
1085                    if self.typ.is_fixed_size() {
1086                        writeln!(
1087                            w,
1088                            "w.write_packed_fixed_with_tag({}, &self.{})?;",
1089                            self.tag(),
1090                            self.name
1091                        )?;
1092                    } else {
1093                        writeln!(
1094                            w,
1095                            "w.write_packed_with_tag({}, &self.{}, |w, &m| w.{}, &|&m| {})?;",
1096                            self.tag(),
1097                            self.name,
1098                            self.typ.get_write("m", self.boxed),
1099                            self.typ.get_size("m")
1100                        )?;
1101                    }
1102                } else {
1103                    let maybe_deref_s = if self.typ.need_to_dereference() {
1104                        "*s"
1105                    } else {
1106                        "s"
1107                    };
1108                    writeln!(
1109                        w,
1110                        "for s in &self.{} {{ w.write_with_tag({}, |w| w.{})?; }}",
1111                        self.name,
1112                        self.tag(),
1113                        self.typ.get_write(maybe_deref_s, self.boxed)
1114                    )?;
1115                }
1116            }
1117            GeneratedType::Map => {
1118                if let FieldType::Map(k, v) = &self.typ {
1119                    writeln!(
1120                        w,
1121                        "for ({maybe_ampersand_k}k, {maybe_ampersand_v}v) in self.{name}.iter() {{ w.write_with_tag({tag}, |w| w.{got_write})?; }}",
1122                        maybe_ampersand_k = if k.need_to_dereference() { "&" } else { "" },
1123                        maybe_ampersand_v = if v.need_to_dereference() { "&" } else { "" },
1124                        name = self.name,
1125                        tag = self.tag(),
1126                        got_write = self.typ.get_write("", false)
1127                    )?;
1128                } else {
1129                    unreachable!();
1130                }
1131            }
1132        }
1133        Ok(())
1134    }
1135}
1136
1137fn get_modules(
1138    module: &str,
1139    imported: bool,
1140    desc: &FileDescriptor,
1141) -> String {
1142    let skip = usize::from(desc.package.is_empty() && !imported);
1143    module
1144        .split('.')
1145        .filter(|p| !p.is_empty())
1146        .skip(skip)
1147        .map(|p| format!("{}::", p))
1148        .collect()
1149}
1150
1151#[derive(Debug, Clone, Default)]
1152pub struct Extend {
1153    /// The message being extended.
1154    pub name: String,
1155    /// All fields that are being added to the extended message.
1156    pub fields: Vec<Field>,
1157}
1158
1159impl Extend {}
1160
1161#[derive(Debug, Clone, Default)]
1162pub struct Message {
1163    pub name: String,
1164    pub fields: Vec<Field>,
1165    pub oneofs: Vec<OneOf>,
1166    pub reserved_nums: Option<Vec<i32>>,
1167    pub reserved_names: Option<Vec<String>>,
1168    pub imported: bool,
1169    pub package: String,        // package from imports + nested items
1170    pub messages: Vec<Message>, // nested messages
1171    pub enums: Vec<Enumerator>, // nested enums
1172    pub module: String,         // 'package' corresponding to actual generated Rust module
1173    pub path: PathBuf,
1174    pub import: PathBuf,
1175    pub index: MessageIndex,
1176    /// Allowed extensions for this message, None if no extensions.
1177    pub extensions: Option<Extensions>,
1178}
1179
1180impl Message {
1181    fn convert_field_types(
1182        &mut self,
1183        from: &FieldType,
1184        to: &FieldType,
1185    ) {
1186        for f in self.all_fields_mut().filter(|f| f.typ == *from) {
1187            f.typ = to.clone();
1188        }
1189
1190        // If that type is a map with the fieldtype, it must also be converted.
1191        for f in self.all_fields_mut() {
1192            let new_type: FieldType = match f.typ {
1193                FieldType::Map(ref mut key, ref mut value)
1194                    if **key == *from && **value == *from =>
1195                {
1196                    FieldType::Map(Box::new(to.clone()), Box::new(to.clone()))
1197                }
1198                FieldType::Map(ref mut key, ref mut value) if **key == *from => {
1199                    FieldType::Map(Box::new(to.clone()), value.clone())
1200                }
1201                FieldType::Map(ref mut key, ref mut value) if **value == *from => {
1202                    FieldType::Map(key.clone(), Box::new(to.clone()))
1203                }
1204                ref other => other.clone(),
1205            };
1206            f.typ = new_type;
1207        }
1208
1209        for message in &mut self.messages {
1210            message.convert_field_types(from, to);
1211        }
1212    }
1213
1214    fn has_lifetime(
1215        &self,
1216        desc: &FileDescriptor,
1217        config: &Config,
1218        ignore: &mut Vec<MessageIndex>,
1219    ) -> bool {
1220        if ignore.contains(&self.index) {
1221            return false;
1222        }
1223        ignore.push(self.index.clone());
1224        let res = self.all_fields().any(|f| {
1225            f.typ.has_lifetime(desc, config, f.packed(), ignore)
1226                && (!f.deprecated || config.add_deprecated_fields)
1227        });
1228        ignore.pop();
1229        res
1230    }
1231
1232    fn set_imported(&mut self) {
1233        self.imported = true;
1234        for o in self.oneofs.iter_mut() {
1235            o.imported = true;
1236        }
1237        for m in self.messages.iter_mut() {
1238            m.set_imported();
1239        }
1240        for e in self.enums.iter_mut() {
1241            e.imported = true;
1242        }
1243    }
1244
1245    fn get_modules(
1246        &self,
1247        desc: &FileDescriptor,
1248    ) -> String {
1249        get_modules(&self.module, self.imported, desc)
1250    }
1251
1252    fn is_unit(&self) -> bool {
1253        self.fields.is_empty()
1254            && self.oneofs.is_empty()
1255            && self.messages.iter().all(|m| m.is_unit())
1256    }
1257
1258    fn write_common_uses<W: Write>(
1259        w: &mut W,
1260        messages: &[Message],
1261        desc: &FileDescriptor,
1262        config: &Config,
1263    ) -> Result<()> {
1264        if config.nostd {
1265            writeln!(w, "use alloc::vec::Vec;")?;
1266        }
1267
1268        if !config.dont_use_cow {
1269            if messages.iter().any(|m| {
1270                m.all_fields()
1271                    .any(|f| (f.typ.has_cow() || (f.packed() && f.typ.is_fixed_size())))
1272            }) {
1273                if config.nostd {
1274                    writeln!(w, "use alloc::borrow::Cow;")?;
1275                } else {
1276                    writeln!(w, "use std::borrow::Cow;")?;
1277                }
1278            }
1279        } else if config.nostd
1280            && messages
1281                .iter()
1282                .any(|m| m.all_fields().any(|f| f.typ.has_bytes_and_string()))
1283        {
1284            writeln!(w, "use alloc::borrow::ToOwned;")?;
1285        }
1286
1287        if config.nostd
1288            && messages.iter().any(|m| {
1289                (desc.owned && m.has_lifetime(desc, config, &mut Vec::new()))
1290                    || m.all_fields().any(|f| f.boxed)
1291            })
1292        {
1293            writeln!(w)?;
1294            writeln!(w, "use alloc::boxed::Box;")?;
1295        }
1296
1297        if messages
1298            .iter()
1299            .filter(|m| !m.imported)
1300            .any(|m| m.all_fields().any(|f| f.typ.is_map()))
1301        {
1302            if config.hashbrown {
1303                writeln!(w, "use hashbrown::HashMap;")?;
1304                writeln!(w, "type KVMap<K, V> = HashMap<K, V>;")?;
1305            } else if config.nostd {
1306                writeln!(w, "use alloc::collections::BTreeMap;")?;
1307                writeln!(w, "type KVMap<K, V> = BTreeMap<K, V>;")?;
1308            } else {
1309                writeln!(w, "use std::collections::HashMap;")?;
1310                writeln!(w, "type KVMap<K, V> = HashMap<K, V>;")?;
1311            }
1312        }
1313
1314        Ok(())
1315    }
1316
1317    fn must_generate_impl_default(
1318        &self,
1319        desc: &FileDescriptor,
1320        config: &Config,
1321    ) -> bool {
1322        self.fields
1323            .iter()
1324            .any(|f| f.must_generate_impl_default(desc, config))
1325    }
1326
1327    fn write<W: Write>(
1328        &self,
1329        w: &mut W,
1330        desc: &FileDescriptor,
1331        config: &Config,
1332    ) -> Result<()> {
1333        println!("Writing message {}{}", self.get_modules(desc), self.name);
1334        writeln!(w)?;
1335
1336        self.write_definition(w, desc, config)?;
1337        writeln!(w)?;
1338
1339        if self.must_generate_impl_default(desc, config) {
1340            self.write_impl_default(w, desc, config)?;
1341            writeln!(w)?;
1342        }
1343
1344        self.write_impl_message_read(w, desc, config)?;
1345        writeln!(w)?;
1346        self.write_impl_message_write(w, desc, config)?;
1347
1348        if config.gen_info {
1349            self.write_impl_message_info(w, desc, config)?;
1350            writeln!(w)?;
1351        }
1352
1353        if desc.owned {
1354            writeln!(w)?;
1355
1356            if self.has_lifetime(desc, config, &mut Vec::new()) {
1357                self.write_impl_owned(w, config)?;
1358            } else {
1359                self.write_impl_try_from(w)?;
1360            }
1361        }
1362
1363        if !(self.messages.is_empty() && self.enums.is_empty() && self.oneofs.is_empty()) {
1364            writeln!(w)?;
1365            writeln!(w, "pub mod mod_{} {{", self.name)?;
1366            writeln!(w)?;
1367
1368            Self::write_common_uses(w, &self.messages, desc, config)?;
1369
1370            if !self.messages.is_empty() || !self.oneofs.is_empty() {
1371                writeln!(w, "use super::*;")?;
1372            }
1373            for m in &self.messages {
1374                m.write(w, desc, config)?;
1375            }
1376            for e in &self.enums {
1377                e.write(w)?;
1378            }
1379            for o in &self.oneofs {
1380                o.write(w, desc, config)?;
1381            }
1382
1383            writeln!(w)?;
1384            writeln!(w, "}}")?;
1385        }
1386
1387        Ok(())
1388    }
1389
1390    fn write_definition<W: Write>(
1391        &self,
1392        w: &mut W,
1393        desc: &FileDescriptor,
1394        config: &Config,
1395    ) -> Result<()> {
1396        let mut custom_struct_derive = config.custom_struct_derive.join(", ");
1397
1398        if !self.must_generate_impl_default(desc, config) {
1399            custom_struct_derive += "Default";
1400        }
1401
1402        if !custom_struct_derive.is_empty() {
1403            custom_struct_derive += ", ";
1404        }
1405
1406        writeln!(w, "#[allow(clippy::derive_partial_eq_without_eq)]")?;
1407
1408        writeln!(
1409            w,
1410            "#[derive({}Debug, PartialEq, Clone)]",
1411            custom_struct_derive
1412        )?;
1413
1414        if let Some(repr) = &config.custom_repr {
1415            writeln!(w, "#[repr({})]", repr)?;
1416        }
1417
1418        if self.is_unit() {
1419            writeln!(w, "pub struct {} {{ }}", self.name)?;
1420            return Ok(());
1421        }
1422
1423        let mut ignore = Vec::new();
1424        if config.dont_use_cow {
1425            ignore.push(self.index.clone());
1426        }
1427        if self.has_lifetime(desc, config, &mut ignore) {
1428            writeln!(w, "pub struct {}<'a> {{", self.name)?;
1429        } else {
1430            writeln!(w, "pub struct {} {{", self.name)?;
1431        }
1432        for f in &self.fields {
1433            f.write_definition(w, desc, config)?;
1434        }
1435        for o in &self.oneofs {
1436            o.write_message_definition(w, desc, config)?;
1437        }
1438        writeln!(w, "}}")?;
1439        Ok(())
1440    }
1441
1442    fn write_impl_default<W: Write>(
1443        &self,
1444        w: &mut W,
1445        desc: &FileDescriptor,
1446        config: &Config,
1447    ) -> Result<()> {
1448        if self.is_unit() {
1449            writeln!(w, "impl Default for {} {{", self.name)?;
1450            writeln!(w, "    fn default() -> Self {{")?;
1451            writeln!(w, "        Self {{}}")?;
1452            writeln!(w, "    }}")?;
1453            writeln!(w, "}}")?;
1454            return Ok(());
1455        }
1456
1457        let mut ignore = Vec::new();
1458        if config.dont_use_cow {
1459            ignore.push(self.index.clone());
1460        }
1461        if self.has_lifetime(desc, config, &mut ignore) {
1462            writeln!(w, "impl<'a> Default for {}<'a> {{", self.name)?;
1463        } else {
1464            writeln!(w, "impl Default for {} {{", self.name)?;
1465        }
1466        writeln!(w, "    fn default() -> Self {{")?;
1467        writeln!(w, "        Self {{")?;
1468        for f in &self.fields {
1469            f.write_default(w, desc, config)?;
1470        }
1471        for o in &self.oneofs {
1472            o.write_default(w, desc)?;
1473        }
1474        writeln!(w, "        }}")?;
1475        writeln!(w, "    }}")?;
1476        writeln!(w, "}}")?;
1477        Ok(())
1478    }
1479
1480    fn write_impl_message_info<W: Write>(
1481        &self,
1482        w: &mut W,
1483        desc: &FileDescriptor,
1484        config: &Config,
1485    ) -> Result<()> {
1486        let mut ignore = Vec::new();
1487        if config.dont_use_cow {
1488            ignore.push(self.index.clone());
1489        }
1490        if self.has_lifetime(desc, config, &mut ignore) {
1491            writeln!(w, "impl<'a> MessageInfo for {}<'a> {{", self.name)?;
1492        } else {
1493            writeln!(w, "impl MessageInfo for {} {{", self.name)?;
1494        }
1495        writeln!(
1496            w,
1497            "    const PATH : &'static str = \"{}.{}\";",
1498            self.module, self.name
1499        )?;
1500        writeln!(w, "}}")?;
1501        Ok(())
1502    }
1503
1504    fn write_impl_message_read<W: Write>(
1505        &self,
1506        w: &mut W,
1507        desc: &FileDescriptor,
1508        config: &Config,
1509    ) -> Result<()> {
1510        if self.is_unit() {
1511            writeln!(w, "impl<'a> MessageRead<'a> for {} {{", self.name)?;
1512            writeln!(
1513                w,
1514                "    fn from_reader(r: &mut BytesReader, _: &[u8]) -> Result<Self> {{"
1515            )?;
1516            writeln!(w, "        r.read_to_end();")?;
1517            writeln!(w, "        Ok(Self::default())")?;
1518            writeln!(w, "    }}")?;
1519            writeln!(w, "}}")?;
1520            return Ok(());
1521        }
1522
1523        let mut ignore = Vec::new();
1524        if config.dont_use_cow {
1525            ignore.push(self.index.clone());
1526        }
1527        if self.has_lifetime(desc, config, &mut ignore) {
1528            writeln!(w, "impl<'a> MessageRead<'a> for {}<'a> {{", self.name)?;
1529            writeln!(
1530                w,
1531                "    fn from_reader(r: &mut BytesReader, bytes: &'a [u8]) -> Result<Self> {{"
1532            )?;
1533        } else {
1534            writeln!(w, "impl<'a> MessageRead<'a> for {} {{", self.name)?;
1535            writeln!(
1536                w,
1537                "    fn from_reader(r: &mut BytesReader, bytes: &'a [u8]) -> Result<Self> {{"
1538            )?;
1539        }
1540
1541        writeln!(w, "        let mut msg = Self::default();")?;
1542        writeln!(w, "        while !r.is_eof() {{")?;
1543        writeln!(w, "            match r.next_tag(bytes) {{")?;
1544        for f in &self.fields {
1545            f.write_match_tag(w, desc, config)?;
1546        }
1547        for o in &self.oneofs {
1548            o.write_match_tag(w, desc, config)?;
1549        }
1550        writeln!(
1551            w,
1552            "                Ok(t) => {{ r.read_unknown(bytes, t)?; }}"
1553        )?;
1554        writeln!(w, "                Err(e) => return Err(e),")?;
1555        writeln!(w, "            }}")?;
1556        writeln!(w, "        }}")?;
1557        writeln!(w, "        Ok(msg)")?;
1558        writeln!(w, "    }}")?;
1559        writeln!(w, "}}")?;
1560
1561        Ok(())
1562    }
1563
1564    fn write_impl_message_write<W: Write>(
1565        &self,
1566        w: &mut W,
1567        desc: &FileDescriptor,
1568        config: &Config,
1569    ) -> Result<()> {
1570        if self.is_unit() {
1571            writeln!(w, "impl MessageWrite for {} {{ }}", self.name)?;
1572            return Ok(());
1573        }
1574
1575        let mut ignore = Vec::new();
1576        if config.dont_use_cow {
1577            ignore.push(self.index.clone());
1578        }
1579        if self.has_lifetime(desc, config, &mut ignore) {
1580            writeln!(w, "impl<'a> MessageWrite for {}<'a> {{", self.name)?;
1581        } else {
1582            writeln!(w, "impl MessageWrite for {} {{", self.name)?;
1583        }
1584        self.write_get_size(w, desc, config)?;
1585        writeln!(w)?;
1586        self.write_write_message(w, desc, config)?;
1587        writeln!(w, "}}")?;
1588        Ok(())
1589    }
1590
1591    fn write_impl_owned<W: Write>(
1592        &self,
1593        w: &mut W,
1594        config: &Config,
1595    ) -> Result<()> {
1596        write!(
1597            w,
1598            r#"
1599            // IMPORTANT: For any future changes, note that the lifetime parameter
1600            // of the `proto` field is set to 'static!!!
1601            //
1602            // This means that the internals of `proto` should at no point create a
1603            // mutable reference to something using that lifetime parameter, on pain
1604            // of UB. This applies even though it may be transmuted to a smaller
1605            // lifetime later (through `proto()` or `proto_mut()`).
1606            //
1607            // At the time of writing, the only possible thing that uses the
1608            // lifetime parameter is `Cow<'a, T>`, which never does this, so it's
1609            // not UB.
1610            //
1611            #[derive(Debug)]
1612            struct {name}OwnedInner {{
1613                buf: Vec<u8>,
1614                proto: Option<{name}<'static>>,
1615                _pin: core::marker::PhantomPinned,
1616            }}
1617
1618            impl {name}OwnedInner {{
1619                fn new(buf: Vec<u8>) -> Result<core::pin::Pin<Box<Self>>> {{
1620                    let inner = Self {{
1621                        buf,
1622                        proto: None,
1623                        _pin: core::marker::PhantomPinned,
1624                    }};
1625                    let mut pinned = Box::pin(inner);
1626
1627                    let mut reader = BytesReader::from_bytes(&pinned.buf);
1628                    let proto = {name}::from_reader(&mut reader, &pinned.buf)?;
1629
1630                    unsafe {{
1631                        let proto = core::mem::transmute::<_, {name}<'_>>(proto);
1632                        pinned.as_mut().get_unchecked_mut().proto = Some(proto);
1633                    }}
1634                    Ok(pinned)
1635                }}
1636            }}
1637
1638            pub struct {name}Owned {{
1639                inner: core::pin::Pin<Box<{name}OwnedInner>>,
1640            }}
1641
1642            #[allow(dead_code)]
1643            impl {name}Owned {{
1644                pub fn buf(&self) -> &[u8] {{
1645                    &self.inner.buf
1646                }}
1647
1648                pub fn proto<'a>(&'a self) -> &'a {name}<'a> {{
1649                    let proto = self.inner.proto.as_ref().unwrap();
1650                    unsafe {{ core::mem::transmute::<&{name}<'static>, &{name}<'a>>(proto) }}
1651                }}
1652
1653                pub fn proto_mut<'a>(&'a mut self) -> &'a mut {name}<'a> {{
1654                    let inner = self.inner.as_mut();
1655                    let inner = unsafe {{ inner.get_unchecked_mut() }};
1656                    let proto = inner.proto.as_mut().unwrap();
1657                    unsafe {{ core::mem::transmute::<_, &mut {name}<'a>>(proto) }}
1658                }}
1659            }}
1660
1661            impl core::fmt::Debug for {name}Owned {{
1662                fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {{
1663                    self.inner.proto.as_ref().unwrap().fmt(f)
1664                }}
1665            }}
1666
1667            impl TryFrom<Vec<u8>> for {name}Owned {{
1668                type Error=quick_protobuf::Error;
1669
1670                fn try_from(buf: Vec<u8>) -> Result<Self> {{
1671                    Ok(Self {{ inner: {name}OwnedInner::new(buf)? }})
1672                }}
1673            }}
1674
1675            impl TryInto<Vec<u8>> for {name}Owned {{
1676                type Error=quick_protobuf::Error;
1677
1678                fn try_into(self) -> Result<Vec<u8>> {{
1679                    let mut buf = Vec::new();
1680                    let mut writer = Writer::new(&mut buf);
1681                    self.inner.proto.as_ref().unwrap().write_message(&mut writer)?;
1682                    Ok(buf)
1683                }}
1684            }}
1685
1686            impl From<{name}<'static>> for {name}Owned {{
1687                fn from(proto: {name}<'static>) -> Self {{
1688                    Self {{
1689                        inner: Box::pin({name}OwnedInner {{
1690                            buf: Vec::new(),
1691                            proto: Some(proto),
1692                            _pin: core::marker::PhantomPinned,
1693                        }})
1694                    }}
1695                }}
1696            }}
1697            "#,
1698            name = self.name
1699        )?;
1700
1701        if config.gen_info {
1702            write!(
1703                w,
1704                r#"
1705            impl MessageInfo for {name}Owned {{
1706                const PATH: &'static str = "{module}.{name}";
1707            }}
1708            "#,
1709                name = self.name,
1710                module = self.module
1711            )?;
1712        }
1713        Ok(())
1714    }
1715
1716    fn write_get_size<W: Write>(
1717        &self,
1718        w: &mut W,
1719        desc: &FileDescriptor,
1720        config: &Config,
1721    ) -> Result<()> {
1722        writeln!(w, "    fn get_size(&self) -> usize {{")?;
1723        writeln!(w, "        0")?;
1724        for f in &self.fields {
1725            f.write_get_size(w, desc, config)?;
1726        }
1727        for o in self.oneofs.iter() {
1728            o.write_get_size(w, desc, config)?;
1729        }
1730        writeln!(w, "    }}")?;
1731        Ok(())
1732    }
1733
1734    fn write_impl_try_from<W: Write>(
1735        &self,
1736        w: &mut W,
1737    ) -> Result<()> {
1738        write!(
1739            w,
1740            r#"
1741            impl TryFrom<&[u8]> for {name} {{
1742                type Error=quick_protobuf::Error;
1743
1744                fn try_from(buf: &[u8]) -> Result<Self> {{
1745                    let mut reader = BytesReader::from_bytes(&buf);
1746                    Ok({name}::from_reader(&mut reader, &buf)?)
1747                }}
1748            }}
1749            "#,
1750            name = self.name
1751        )?;
1752        Ok(())
1753    }
1754
1755    fn write_write_message<W: Write>(
1756        &self,
1757        w: &mut W,
1758        desc: &FileDescriptor,
1759        config: &Config,
1760    ) -> Result<()> {
1761        writeln!(
1762            w,
1763            "    fn write_message<W: WriterBackend>(&self, w: &mut Writer<W>) -> Result<()> {{"
1764        )?;
1765        for f in &self.fields {
1766            f.write_write(w, desc, config)?;
1767        }
1768        for o in &self.oneofs {
1769            o.write_write(w, desc, config)?;
1770        }
1771        writeln!(w, "        Ok(())")?;
1772        writeln!(w, "    }}")?;
1773        Ok(())
1774    }
1775
1776    fn sanity_checks(
1777        &self,
1778        desc: &FileDescriptor,
1779    ) -> Result<()> {
1780        for f in self.all_fields() {
1781            // check reserved
1782            if self
1783                .reserved_names
1784                .as_ref()
1785                .as_ref()
1786                .is_some_and(|names| names.contains(&f.name))
1787                || self
1788                    .reserved_nums
1789                    .as_ref()
1790                    .is_some_and(|nums| nums.contains(&f.number))
1791            {
1792                return Err(Error::InvalidMessage(format!(
1793                    "Error in message {}\n\
1794                     Field {:?} conflict with reserved fields",
1795                    self.name, f
1796                )));
1797            }
1798
1799            // check default enums
1800            if let Some(var) = f.default.as_ref() {
1801                if let FieldType::Enum(ref e) = f.typ {
1802                    let e = e.get_enum(desc);
1803                    e.fields.iter().find(|(name, _)| name == var).ok_or_else(|| {
1804                        Error::InvalidDefaultEnum(format!(
1805                            "Error in message {}\n\
1806                                Enum field {:?} has a default value '{}' which is not valid for enum index {:?}",
1807                            self.name, f, var, e
1808                        ))
1809                    })?;
1810                }
1811            }
1812        }
1813        Ok(())
1814    }
1815
1816    fn set_package(
1817        &mut self,
1818        package: &str,
1819        module: &str,
1820    ) {
1821        // The complication here is that the _package_ (as declared in the proto file) does
1822        // not directly map to the _module_. For example, the package 'a.A' where A is a
1823        // message will be the module 'a.mod_A', since we can't reuse the message name A as
1824        // the submodule containing nested items. Also, protos with empty packages always
1825        // have a module corresponding to the file name.
1826        let (child_package, child_module) = if package.is_empty() {
1827            self.module = module.to_string();
1828            (self.name.clone(), format!("{}.mod_{}", module, self.name))
1829        } else {
1830            self.package = package.to_string();
1831            self.module = module.to_string();
1832            (
1833                format!("{}.{}", package, self.name),
1834                format!("{}.mod_{}", module, self.name),
1835            )
1836        };
1837
1838        for m in &mut self.messages {
1839            m.set_package(&child_package, &child_module);
1840        }
1841        for m in &mut self.enums {
1842            m.set_package(&child_package, &child_module);
1843        }
1844        for m in &mut self.oneofs {
1845            m.set_package(&child_package, &child_module);
1846        }
1847    }
1848
1849    fn set_repeated_as_packed(&mut self) {
1850        for f in self.all_fields_mut() {
1851            if f.packed.is_none() && f.frequency.is_repeated() {
1852                f.packed = Some(true);
1853            }
1854        }
1855    }
1856
1857    fn unset_packed_non_primitives(&mut self) {
1858        for f in self.all_fields_mut() {
1859            if !f.typ.is_primitive() && f.packed.is_some() {
1860                f.packed = None;
1861            }
1862        }
1863    }
1864
1865    fn sanitize_defaults(
1866        &mut self,
1867        desc: &FileDescriptor,
1868        config: &Config,
1869    ) -> Result<()> {
1870        for f in self.all_fields_mut() {
1871            f.sanitize_default(desc, config)?;
1872        }
1873        for m in &mut self.messages {
1874            m.sanitize_defaults(desc, config)?;
1875        }
1876        Ok(())
1877    }
1878
1879    fn sanitize_names(&mut self) {
1880        sanitize_keyword(&mut self.name);
1881        sanitize_keyword(&mut self.package);
1882        for f in self.fields.iter_mut() {
1883            sanitize_keyword(&mut f.name);
1884        }
1885        for m in &mut self.messages {
1886            m.sanitize_names();
1887        }
1888        for e in &mut self.enums {
1889            e.sanitize_names();
1890        }
1891        for o in &mut self.oneofs {
1892            o.sanitize_names();
1893        }
1894    }
1895
1896    /// Return an iterator producing references to all the `Field`s of `self`,
1897    /// including both direct and `oneof` fields.
1898    pub fn all_fields(&self) -> impl Iterator<Item = &Field> {
1899        self.fields
1900            .iter()
1901            .chain(self.oneofs.iter().flat_map(|o| o.fields.iter()))
1902    }
1903
1904    /// Return an iterator producing mutable references to all the `Field`s of
1905    /// `self`, including both direct and `oneof` fields.
1906    fn all_fields_mut(&mut self) -> impl Iterator<Item = &mut Field> {
1907        self.fields
1908            .iter_mut()
1909            .chain(self.oneofs.iter_mut().flat_map(|o| o.fields.iter_mut()))
1910    }
1911}
1912
1913#[derive(Debug, Clone, Default)]
1914pub struct RpcFunctionDeclaration {
1915    pub name: String,
1916    pub arg: String,
1917    pub ret: String,
1918}
1919
1920#[derive(Debug, Clone, Default)]
1921pub struct RpcService {
1922    pub service_name: String,
1923    pub functions: Vec<RpcFunctionDeclaration>,
1924}
1925
1926impl RpcService {
1927    fn write_definition<W: Write>(
1928        &self,
1929        w: &mut W,
1930        config: &Config,
1931    ) -> Result<()> {
1932        (config.custom_rpc_generator)(self, w)
1933    }
1934}
1935
1936pub type RpcGeneratorFunction = Box<dyn Fn(&RpcService, &mut dyn Write) -> Result<()>>;
1937
1938#[derive(Debug, Clone, Default)]
1939pub struct Extensions {
1940    pub from: i32,
1941    /// Max number is 536,870,911 (2^29 - 1), as defined in the
1942    /// protobuf docs
1943    pub to: i32,
1944}
1945
1946impl Extensions {
1947    /// The max field number that can be used as an extension.
1948    pub fn max() -> i32 {
1949        536870911
1950    }
1951}
1952
1953#[derive(Debug, Clone, Default)]
1954pub struct Enumerator {
1955    pub name: String,
1956    pub fields: Vec<(String, i32)>,
1957    pub fully_qualified_fields: Vec<(String, i32)>,
1958    pub partially_qualified_fields: Vec<(String, i32)>,
1959    pub imported: bool,
1960    pub package: String,
1961    pub module: String,
1962    pub path: PathBuf,
1963    pub import: PathBuf,
1964    pub index: EnumIndex,
1965}
1966
1967impl Enumerator {
1968    fn set_package(
1969        &mut self,
1970        package: &str,
1971        module: &str,
1972    ) {
1973        self.package = package.to_string();
1974        self.module = module.to_string();
1975        self.partially_qualified_fields = self
1976            .fields
1977            .iter()
1978            .map(|f| (format!("{}::{}", &self.name, f.0), f.1))
1979            .collect();
1980        self.fully_qualified_fields = self
1981            .partially_qualified_fields
1982            .iter()
1983            .map(|pqf| {
1984                let fqf = if self.module.is_empty() {
1985                    pqf.0.clone()
1986                } else {
1987                    format!("{}::{}", self.module.replace('.', "::"), pqf.0)
1988                };
1989                (fqf, pqf.1)
1990            })
1991            .collect();
1992    }
1993
1994    fn sanitize_names(&mut self) {
1995        sanitize_keyword(&mut self.name);
1996        sanitize_keyword(&mut self.package);
1997        for f in self.fields.iter_mut() {
1998            sanitize_keyword(&mut f.0);
1999        }
2000    }
2001
2002    fn get_modules(
2003        &self,
2004        desc: &FileDescriptor,
2005    ) -> String {
2006        get_modules(&self.module, self.imported, desc)
2007    }
2008
2009    fn write<W: Write>(
2010        &self,
2011        w: &mut W,
2012    ) -> Result<()> {
2013        println!("Writing enum {}", self.name);
2014        writeln!(w)?;
2015        self.write_definition(w)?;
2016        writeln!(w)?;
2017        if self.fields.is_empty() {
2018            Ok(())
2019        } else {
2020            self.write_impl_default(w)?;
2021            writeln!(w)?;
2022            self.write_from_i32(w)?;
2023            writeln!(w)?;
2024            self.write_from_str(w)
2025        }
2026    }
2027
2028    fn write_definition<W: Write>(
2029        &self,
2030        w: &mut W,
2031    ) -> Result<()> {
2032        writeln!(w, "#[derive(Debug, PartialEq, Eq, Clone, Copy)]")?;
2033        writeln!(w, "pub enum {} {{", self.name)?;
2034        for (f, number) in &self.fields {
2035            writeln!(w, "    {} = {},", f, number)?;
2036        }
2037        writeln!(w, "}}")?;
2038        Ok(())
2039    }
2040
2041    fn write_impl_default<W: Write>(
2042        &self,
2043        w: &mut W,
2044    ) -> Result<()> {
2045        writeln!(w, "impl Default for {} {{", self.name)?;
2046        writeln!(w, "    fn default() -> Self {{")?;
2047        // TODO: check with default field and return error if there is no field
2048        writeln!(w, "        {}", self.partially_qualified_fields[0].0)?;
2049        writeln!(w, "    }}")?;
2050        writeln!(w, "}}")?;
2051        Ok(())
2052    }
2053
2054    fn write_from_i32<W: Write>(
2055        &self,
2056        w: &mut W,
2057    ) -> Result<()> {
2058        writeln!(w, "impl From<i32> for {} {{", self.name)?;
2059        writeln!(w, "    fn from(i: i32) -> Self {{")?;
2060        writeln!(w, "        match i {{")?;
2061        for (f, number) in &self.fields {
2062            writeln!(w, "            {} => Self::{},", number, f)?;
2063        }
2064        writeln!(w, "            _ => Self::default(),")?;
2065        writeln!(w, "        }}")?;
2066        writeln!(w, "    }}")?;
2067        writeln!(w, "}}")?;
2068        Ok(())
2069    }
2070
2071    fn write_from_str<W: Write>(
2072        &self,
2073        w: &mut W,
2074    ) -> Result<()> {
2075        writeln!(w, "impl<'a> From<&'a str> for {} {{", self.name)?;
2076        writeln!(w, "    fn from(s: &'a str) -> Self {{")?;
2077        writeln!(w, "        match s {{")?;
2078        for (f, _) in &self.fields {
2079            writeln!(w, "            {:?} => Self::{},", f, f)?;
2080        }
2081        writeln!(w, "            _ => Self::default(),")?;
2082        writeln!(w, "        }}")?;
2083        writeln!(w, "    }}")?;
2084        writeln!(w, "}}")?;
2085        Ok(())
2086    }
2087}
2088
2089#[derive(Debug, Clone, Default)]
2090pub struct OneOf {
2091    pub name: String,
2092    pub fields: Vec<Field>,
2093    pub package: String,
2094    pub module: String,
2095    pub imported: bool,
2096}
2097
2098impl OneOf {
2099    pub fn write_default<W: Write>(
2100        &self,
2101        w: &mut W,
2102        desc: &FileDescriptor,
2103    ) -> Result<()> {
2104        writeln!(
2105            w,
2106            "            {}: {},",
2107            self.name,
2108            self.write_impl_default_field(desc)
2109        )?;
2110        Ok(())
2111    }
2112
2113    fn write_impl_default_field(
2114        &self,
2115        desc: &FileDescriptor,
2116    ) -> String {
2117        format!("{}OneOf{}::None", self.get_modules(desc), self.name)
2118    }
2119
2120    fn has_lifetime(
2121        &self,
2122        desc: &FileDescriptor,
2123        config: &Config,
2124    ) -> bool {
2125        self.fields.iter().any(|f| {
2126            f.typ
2127                .has_lifetime(desc, config, f.packed(), &mut Vec::new())
2128                && (!f.deprecated || config.add_deprecated_fields)
2129        })
2130    }
2131
2132    fn set_package(
2133        &mut self,
2134        package: &str,
2135        module: &str,
2136    ) {
2137        self.package = package.to_string();
2138        self.module = module.to_string();
2139    }
2140
2141    fn sanitize_names(&mut self) {
2142        sanitize_keyword(&mut self.name);
2143        sanitize_keyword(&mut self.package);
2144        for f in self.fields.iter_mut() {
2145            sanitize_keyword(&mut f.name);
2146        }
2147    }
2148
2149    fn get_modules(
2150        &self,
2151        desc: &FileDescriptor,
2152    ) -> String {
2153        get_modules(&self.module, self.imported, desc)
2154    }
2155
2156    fn write<W: Write>(
2157        &self,
2158        w: &mut W,
2159        desc: &FileDescriptor,
2160        config: &Config,
2161    ) -> Result<()> {
2162        writeln!(w)?;
2163        self.write_definition(w, desc, config)?;
2164        writeln!(w)?;
2165        self.write_impl_default(w, desc, config)?;
2166        Ok(())
2167    }
2168
2169    fn write_definition<W: Write>(
2170        &self,
2171        w: &mut W,
2172        desc: &FileDescriptor,
2173        config: &Config,
2174    ) -> Result<()> {
2175        writeln!(w, "#[derive(Debug, PartialEq, Clone)]")?;
2176        if self.has_lifetime(desc, config) {
2177            writeln!(w, "pub enum OneOf{}<'a> {{", self.name)?;
2178        } else {
2179            writeln!(w, "pub enum OneOf{} {{", self.name)?;
2180        }
2181        for f in &self.fields {
2182            if f.deprecated {
2183                if config.add_deprecated_fields {
2184                    writeln!(w, "    #[deprecated]")?;
2185                } else {
2186                    continue;
2187                }
2188            }
2189
2190            let rust_type = f.typ.rust_type(desc, config)?;
2191            if f.boxed {
2192                writeln!(w, "    {}(Box<{}>),", f.name, rust_type)?;
2193            } else {
2194                writeln!(w, "    {}({}),", f.name, rust_type)?;
2195            }
2196        }
2197        writeln!(w, "    None,")?;
2198        writeln!(w, "}}")?;
2199
2200        self.generate_impl_from_for_enums(w, desc, config)
2201    }
2202
2203    fn generate_impl_from_for_enums<W: Write>(
2204        &self,
2205        w: &mut W,
2206        desc: &FileDescriptor,
2207        config: &Config,
2208    ) -> Result<()> {
2209        // For the first of each enumeration type, generate an impl From<> for it.
2210        let mut handled_fields = Vec::new();
2211        for f in self
2212            .fields
2213            .iter()
2214            .filter(|f| (!f.deprecated || config.add_deprecated_fields))
2215        {
2216            let rust_type = f.typ.rust_type(desc, config)?;
2217            if handled_fields.contains(&rust_type) {
2218                continue;
2219            }
2220            writeln!(w, "impl From<{}> for OneOf{} {{", rust_type, self.name)?; // TODO: lifetime.
2221            writeln!(w, "   fn from(f: {}) -> OneOf{} {{", rust_type, self.name)?;
2222            writeln!(w, "      OneOf{}::{}(f)", self.name, f.name)?;
2223            writeln!(w, "   }}")?;
2224            writeln!(w, "}}")?;
2225
2226            handled_fields.push(rust_type);
2227        }
2228
2229        Ok(())
2230    }
2231
2232    fn write_impl_default<W: Write>(
2233        &self,
2234        w: &mut W,
2235        desc: &FileDescriptor,
2236        config: &Config,
2237    ) -> Result<()> {
2238        if self.has_lifetime(desc, config) {
2239            writeln!(w, "impl<'a> Default for OneOf{}<'a> {{", self.name)?;
2240        } else {
2241            writeln!(w, "impl Default for OneOf{} {{", self.name)?;
2242        }
2243        writeln!(w, "    fn default() -> Self {{")?;
2244        writeln!(w, "        OneOf{}::None", self.name)?;
2245        writeln!(w, "    }}")?;
2246        writeln!(w, "}}")?;
2247        Ok(())
2248    }
2249
2250    fn write_message_definition<W: Write>(
2251        &self,
2252        w: &mut W,
2253        desc: &FileDescriptor,
2254        config: &Config,
2255    ) -> Result<()> {
2256        if self.has_lifetime(desc, config) {
2257            writeln!(
2258                w,
2259                "    pub {}: {}OneOf{}<'a>,",
2260                self.name,
2261                self.get_modules(desc),
2262                self.name
2263            )?;
2264        } else {
2265            writeln!(
2266                w,
2267                "    pub {}: {}OneOf{},",
2268                self.name,
2269                self.get_modules(desc),
2270                self.name
2271            )?;
2272        }
2273        Ok(())
2274    }
2275
2276    fn write_match_tag<W: Write>(
2277        &self,
2278        w: &mut W,
2279        desc: &FileDescriptor,
2280        config: &Config,
2281    ) -> Result<()> {
2282        for f in self
2283            .fields
2284            .iter()
2285            .filter(|f| (!f.deprecated || config.add_deprecated_fields))
2286        {
2287            let (val, val_cow) = f.typ.read_fn(desc)?;
2288            if f.boxed {
2289                writeln!(
2290                    w,
2291                    "                Ok({}) => msg.{} = {}OneOf{}::{}(Box::new({})),",
2292                    f.tag(),
2293                    self.name,
2294                    self.get_modules(desc),
2295                    self.name,
2296                    f.name,
2297                    val
2298                )?;
2299            } else {
2300                writeln!(
2301                    w,
2302                    "                Ok({}) => msg.{} = {}OneOf{}::{}({}),",
2303                    f.tag(),
2304                    self.name,
2305                    self.get_modules(desc),
2306                    self.name,
2307                    f.name,
2308                    val_cow
2309                )?;
2310            }
2311        }
2312        Ok(())
2313    }
2314
2315    fn write_get_size<W: Write>(
2316        &self,
2317        w: &mut W,
2318        desc: &FileDescriptor,
2319        config: &Config,
2320    ) -> Result<()> {
2321        writeln!(w, "        + match &self.{} {{", self.name)?;
2322        for f in self
2323            .fields
2324            .iter()
2325            .filter(|f| (!f.deprecated || config.add_deprecated_fields))
2326        {
2327            let tag_size = sizeof_varint(f.tag());
2328            if f.typ.is_fixed_size() {
2329                writeln!(
2330                    w,
2331                    "            {}OneOf{}::{}(_) => {} + {},",
2332                    self.get_modules(desc),
2333                    self.name,
2334                    f.name,
2335                    tag_size,
2336                    f.typ.get_size("")
2337                )?;
2338            } else if f.typ.need_to_dereference() {
2339                writeln!(
2340                    w,
2341                    "            {}OneOf{}::{}(m) => {} + {},",
2342                    self.get_modules(desc),
2343                    self.name,
2344                    f.name,
2345                    tag_size,
2346                    f.typ.get_size("*m")
2347                )?;
2348            } else {
2349                writeln!(
2350                    w,
2351                    "            {}OneOf{}::{}(ref m) => {} + {},",
2352                    self.get_modules(desc),
2353                    self.name,
2354                    f.name,
2355                    tag_size,
2356                    f.typ.get_size("m")
2357                )?;
2358            }
2359        }
2360        writeln!(
2361            w,
2362            "            {}OneOf{}::None => 0,",
2363            self.get_modules(desc),
2364            self.name
2365        )?;
2366        writeln!(w, "        }}")?;
2367        Ok(())
2368    }
2369
2370    fn write_write<W: Write>(
2371        &self,
2372        w: &mut W,
2373        desc: &FileDescriptor,
2374        config: &Config,
2375    ) -> Result<()> {
2376        writeln!(w, "        match &self.{} {{", self.name)?;
2377        for f in self
2378            .fields
2379            .iter()
2380            .filter(|f| (!f.deprecated || config.add_deprecated_fields))
2381        {
2382            if f.typ.need_to_dereference() || f.boxed {
2383                writeln!(
2384                    w,
2385                    "            {}OneOf{}::{}(m) => {{ w.write_with_tag({}, |w| w.{})? }},",
2386                    self.get_modules(desc),
2387                    self.name,
2388                    f.name,
2389                    f.tag(),
2390                    f.typ.get_write("*m", f.boxed)
2391                )?;
2392            } else {
2393                writeln!(
2394                    w,
2395                    "            {}OneOf{}::{}(m) => {{ w.write_with_tag({}, |w| w.{})? }},",
2396                    self.get_modules(desc),
2397                    self.name,
2398                    f.name,
2399                    f.tag(),
2400                    f.typ.get_write("m", f.boxed)
2401                )?;
2402            }
2403        }
2404        writeln!(
2405            w,
2406            "            {}OneOf{}::None => {{}},",
2407            self.get_modules(desc),
2408            self.name
2409        )?;
2410        writeln!(w, "        }}")?;
2411        Ok(())
2412    }
2413}
2414
2415pub struct Config {
2416    pub in_file: PathBuf,
2417    pub out_file: PathBuf,
2418    pub single_module: bool,
2419    pub import_search_path: Vec<PathBuf>,
2420    pub no_output: bool,
2421    pub error_cycle: bool,
2422    pub headers: bool,
2423    pub dont_use_cow: bool,
2424    pub custom_struct_derive: Vec<String>,
2425    pub custom_repr: Option<String>,
2426    pub custom_rpc_generator: RpcGeneratorFunction,
2427    pub custom_includes: Vec<String>,
2428    pub owned: bool,
2429    pub nostd: bool,
2430    pub hashbrown: bool,
2431    pub gen_info: bool,
2432    pub add_deprecated_fields: bool,
2433    pub generate_getters: bool,
2434}
2435
2436#[derive(Debug, Default, Clone)]
2437pub struct FileDescriptor {
2438    pub import_paths: Vec<PathBuf>,
2439    pub package: String,
2440    pub syntax: Syntax,
2441    pub messages: Vec<Message>,
2442    pub message_extends: Vec<Extend>,
2443    pub enums: Vec<Enumerator>,
2444    pub module: String,
2445    pub rpc_services: Vec<RpcService>,
2446    pub owned: bool,
2447}
2448
2449impl FileDescriptor {
2450    pub fn run(configs: &[Config]) -> Result<()> {
2451        for config in configs {
2452            Self::write_proto(config)?;
2453        }
2454        Ok(())
2455    }
2456
2457    pub fn write_proto(config: &Config) -> Result<()> {
2458        let mut desc = FileDescriptor::read_proto(&config.in_file, &config.import_search_path)?;
2459        desc.owned = config.owned;
2460
2461        if desc.messages.is_empty() && desc.enums.is_empty() {
2462            // There could had been unsupported structures, so bail early
2463            return Err(Error::EmptyRead);
2464        }
2465
2466        desc.resolve_types()?;
2467        desc.break_cycles(config.error_cycle)?;
2468        desc.sanity_checks()?;
2469        if config.dont_use_cow {
2470            desc.convert_field_types(&FieldType::StringCow, &FieldType::String_);
2471            desc.convert_field_types(&FieldType::BytesCow, &FieldType::Bytes_);
2472        }
2473        desc.set_defaults(config)?;
2474        desc.sanitize_names();
2475
2476        if config.single_module {
2477            desc.package = "".to_string();
2478        }
2479
2480        let (prefix, file_package) = split_package(&desc.package);
2481
2482        let mut file_stem = if file_package.is_empty() {
2483            get_file_stem(&config.out_file)?
2484        } else {
2485            file_package.to_string()
2486        };
2487
2488        if !file_package.is_empty() {
2489            sanitize_keyword(&mut file_stem);
2490        }
2491        let mut out_file = config.out_file.with_file_name(format!("{}.rs", file_stem));
2492
2493        if !prefix.is_empty() {
2494            use std::fs::create_dir_all;
2495            // e.g. package is a.b; we need to create directory 'a' and insert it into the path
2496            let file = PathBuf::from(out_file.file_name().unwrap());
2497            out_file.pop();
2498            for p in prefix.split('.') {
2499                out_file.push(p);
2500
2501                if !out_file.exists() {
2502                    create_dir_all(&out_file)?;
2503                }
2504            }
2505            out_file.push(file);
2506        }
2507        if config.no_output {
2508            let imported = |b| if b { " imported" } else { "" };
2509            println!("source will be written to {}\n", out_file.display());
2510            for m in &desc.messages {
2511                println!(
2512                    "message {} module {}{}",
2513                    m.name,
2514                    m.module,
2515                    imported(m.imported)
2516                );
2517            }
2518            for e in &desc.enums {
2519                println!(
2520                    "enum {} module {}{}",
2521                    e.name,
2522                    e.module,
2523                    imported(e.imported)
2524                );
2525            }
2526            return Ok(());
2527        }
2528
2529        let name = config.in_file.file_name().and_then(|e| e.to_str()).unwrap();
2530        let mut w = BufWriter::new(File::create(&out_file)?);
2531        desc.write(&mut w, name, config)?;
2532        Ok(())
2533    }
2534
2535    pub fn convert_field_types(
2536        &mut self,
2537        from: &FieldType,
2538        to: &FieldType,
2539    ) {
2540        // Messages and enums are the only structures with types
2541        for m in &mut self.messages {
2542            m.convert_field_types(from, to);
2543        }
2544    }
2545
2546    /// Opens a proto file, reads it and returns raw parsed data
2547    pub fn read_proto(
2548        in_file: &Path,
2549        import_search_path: &[PathBuf],
2550    ) -> Result<FileDescriptor> {
2551        let file = std::fs::read_to_string(in_file)?;
2552        let (rem, mut desc) = file_descriptor(&file).map_err(Error::Nom)?;
2553        let rem = rem.trim();
2554        if !rem.is_empty() {
2555            return Err(Error::TrailingGarbage(rem.chars().take(50).collect()));
2556        }
2557        for m in &mut desc.messages {
2558            if m.path.as_os_str().is_empty() {
2559                m.path = in_file.to_path_buf();
2560                if !import_search_path.is_empty() {
2561                    if let Ok(p) = m.path.clone().strip_prefix(&import_search_path[0]) {
2562                        m.import = p.to_path_buf();
2563                    }
2564                }
2565            }
2566        }
2567        // proto files with no packages are given an implicit module,
2568        // since every generated Rust source file represents a module
2569        desc.module = if desc.package.is_empty() {
2570            get_file_stem(in_file)?
2571        } else {
2572            desc.package.clone()
2573        };
2574
2575        desc.fetch_imports(in_file, import_search_path)?;
2576        Ok(desc)
2577    }
2578
2579    fn sanity_checks(&self) -> Result<()> {
2580        for m in &self.messages {
2581            m.sanity_checks(self)?;
2582        }
2583        Ok(())
2584    }
2585
2586    /// Get messages and enums from imports
2587    fn fetch_imports(
2588        &mut self,
2589        in_file: &Path,
2590        import_search_path: &[PathBuf],
2591    ) -> Result<()> {
2592        for m in &mut self.messages {
2593            m.set_package(&self.package, &self.module);
2594        }
2595        for m in &mut self.enums {
2596            m.set_package(&self.package, &self.module);
2597        }
2598
2599        for import in &self.import_paths {
2600            // this is the same logic as the C preprocessor;
2601            // if the include path item is absolute, then append the filename,
2602            // otherwise it is always relative to the file.
2603            let mut matching_file = None;
2604            for path in import_search_path {
2605                let candidate = if path.is_absolute() {
2606                    path.join(import)
2607                } else {
2608                    in_file
2609                        .parent()
2610                        .map_or_else(|| path.join(import), |p| p.join(path).join(import))
2611                };
2612                if candidate.exists() {
2613                    matching_file = Some(candidate);
2614                    break;
2615                }
2616            }
2617            if matching_file.is_none() {
2618                return Err(Error::InvalidImport(format!(
2619                    "file {} not found on import path",
2620                    import.display()
2621                )));
2622            }
2623            let proto_file = matching_file.unwrap();
2624            let mut f = FileDescriptor::read_proto(&proto_file, import_search_path)?;
2625
2626            // if the proto has a packge then the names will be prefixed
2627            let package = f.package.clone();
2628            let module = f.module.clone();
2629            self.messages.extend(f.messages.drain(..).map(|mut m| {
2630                if m.package.is_empty() {
2631                    m.set_package(&package, &module);
2632                }
2633                if m.path.as_os_str().is_empty() {
2634                    m.path = proto_file.clone();
2635                }
2636                if m.import.as_os_str().is_empty() {
2637                    m.import = import.clone();
2638                }
2639                m.set_imported();
2640                m
2641            }));
2642            self.enums.extend(f.enums.drain(..).map(|mut e| {
2643                if e.package.is_empty() {
2644                    e.set_package(&package, &module);
2645                }
2646                if e.path.as_os_str().is_empty() {
2647                    e.path = proto_file.clone();
2648                }
2649                if e.import.as_os_str().is_empty() {
2650                    e.import = import.clone();
2651                }
2652                e.imported = true;
2653                e
2654            }));
2655        }
2656        Ok(())
2657    }
2658
2659    fn set_defaults(
2660        &mut self,
2661        config: &Config,
2662    ) -> Result<()> {
2663        // if proto3, then changes several defaults
2664        if let Syntax::Proto3 = self.syntax {
2665            for m in &mut self.messages {
2666                m.set_repeated_as_packed();
2667            }
2668        }
2669        // this is very inefficient but we don't care ...
2670        //let msgs = self.messages.clone();
2671        let copy = self.clone();
2672        for m in &mut self.messages {
2673            m.sanitize_defaults(&copy, config)?; //&msgs, &self.enums)?; ???
2674        }
2675        // force packed only on primitives
2676        for m in &mut self.messages {
2677            m.unset_packed_non_primitives();
2678        }
2679        Ok(())
2680    }
2681
2682    fn sanitize_names(&mut self) {
2683        for m in &mut self.messages {
2684            m.sanitize_names();
2685        }
2686        for e in &mut self.enums {
2687            e.sanitize_names();
2688        }
2689    }
2690
2691    /// Breaks cycles by adding boxes when necessary
2692    fn break_cycles(
2693        &mut self,
2694        error_cycle: bool,
2695    ) -> Result<()> {
2696        // get strongly connected components
2697        let sccs = self.sccs();
2698
2699        fn is_cycle(
2700            scc: &[MessageIndex],
2701            desc: &FileDescriptor,
2702        ) -> bool {
2703            scc.iter()
2704                .map(|m| m.get_message(desc))
2705                .flat_map(|m| m.all_fields())
2706                .filter(|f| !f.boxed)
2707                .filter_map(|f| f.typ.message())
2708                .any(|m| scc.contains(m))
2709        }
2710
2711        // sccs are sub DFS trees so if there is a edge connecting a node to
2712        // another node higher in the scc list, then this is a cycle. (Note that
2713        // we may have several cycles per scc).
2714        //
2715        // Technically we only need to box one edge (optional field) per cycle to
2716        // have Sized structs. Unfortunately, scc root depend on the order we
2717        // traverse the graph so such a field is not guaranteed to always be the same.
2718        //
2719        // For now, we decide (see discussion in #121) to box all optional fields
2720        // within a scc. We favor generated code stability over performance.
2721        for scc in &sccs {
2722            // println!("scc: {:?}", scc);
2723            for (i, v) in scc.iter().enumerate() {
2724                // cycles with v as root
2725                let cycles = v
2726                    .get_message(self)
2727                    .all_fields()
2728                    .filter_map(|f| f.typ.message())
2729                    .filter_map(|m| scc[i..].iter().position(|n| n == m))
2730                    .collect::<Vec<_>>();
2731                for cycle in cycles {
2732                    let cycle = &scc[i..i + cycle + 1];
2733                    println!("cycle: {:?}", &cycle);
2734                    for v in cycle {
2735                        for f in v
2736                            .get_message_mut(self)
2737                            .all_fields_mut()
2738                            .filter(|f| f.frequency.is_optional())
2739                            .filter(|f| f.typ.message().is_some_and(|m| cycle.contains(m)))
2740                        {
2741                            f.boxed = true;
2742                        }
2743                    }
2744                    if is_cycle(cycle, self) {
2745                        if error_cycle {
2746                            return Err(Error::Cycle(
2747                                cycle
2748                                    .iter()
2749                                    .map(|m| m.get_message(self).name.clone())
2750                                    .collect(),
2751                            ));
2752                        } else {
2753                            for v in cycle {
2754                                println!(
2755                                    "Unsound proto file would result in infinite size Messages.\n\
2756                                     Cycle detected in messages {:?}.\n\
2757                                     Modifying required fields into optional fields",
2758                                    cycle
2759                                        .iter()
2760                                        .map(|m| &m.get_message(self).name)
2761                                        .collect::<Vec<_>>()
2762                                );
2763                                for f in v
2764                                    .get_message_mut(self)
2765                                    .all_fields_mut()
2766                                    .filter(|f| {
2767                                        !(f.frequency.is_optional() || f.frequency.is_repeated())
2768                                    })
2769                                    .filter(|f| f.typ.message().is_some_and(|m| cycle.contains(m)))
2770                                {
2771                                    f.boxed = true;
2772                                    f.frequency = match f.frequency {
2773                                        Frequency::Proto2Frequency(_) => {
2774                                            Frequency::Proto2Frequency(Proto2Frequency::Optional)
2775                                        }
2776                                        Frequency::Proto3Frequency(_) => {
2777                                            Frequency::Proto3Frequency(Proto3Frequency::Optional)
2778                                        }
2779                                    };
2780                                }
2781                            }
2782                        }
2783                    }
2784                }
2785            }
2786        }
2787        Ok(())
2788    }
2789
2790    fn get_full_names(&mut self) -> (HashMap<String, MessageIndex>, HashMap<String, EnumIndex>) {
2791        fn rec_full_names(
2792            m: &mut Message,
2793            index: &mut MessageIndex,
2794            full_msgs: &mut HashMap<String, MessageIndex>,
2795            full_enums: &mut HashMap<String, EnumIndex>,
2796        ) {
2797            m.index = index.clone();
2798            if m.package.is_empty() {
2799                full_msgs
2800                    .entry(m.name.clone())
2801                    .or_insert_with(|| index.clone());
2802            } else {
2803                full_msgs
2804                    .entry(format!("{}.{}", m.package, m.name))
2805                    .or_insert_with(|| index.clone());
2806            }
2807            for (i, e) in m.enums.iter_mut().enumerate() {
2808                let index = EnumIndex {
2809                    msg_index: index.clone(),
2810                    index: i,
2811                };
2812                e.index = index.clone();
2813                full_enums
2814                    .entry(format!("{}.{}", e.package, e.name))
2815                    .or_insert(index);
2816            }
2817            for (i, m) in m.messages.iter_mut().enumerate() {
2818                index.push(i);
2819                rec_full_names(m, index, full_msgs, full_enums);
2820                index.pop();
2821            }
2822        }
2823
2824        let mut full_msgs = HashMap::new();
2825        let mut full_enums = HashMap::new();
2826        let mut index = MessageIndex { indexes: vec![] };
2827        for (i, m) in self.messages.iter_mut().enumerate() {
2828            index.push(i);
2829            rec_full_names(m, &mut index, &mut full_msgs, &mut full_enums);
2830            index.pop();
2831        }
2832        for (i, e) in self.enums.iter_mut().enumerate() {
2833            let index = EnumIndex {
2834                msg_index: index.clone(),
2835                index: i,
2836            };
2837            e.index = index.clone();
2838            if e.package.is_empty() {
2839                full_enums
2840                    .entry(e.name.clone())
2841                    .or_insert_with(|| index.clone());
2842            } else {
2843                full_enums
2844                    .entry(format!("{}.{}", e.package, e.name))
2845                    .or_insert_with(|| index.clone());
2846            }
2847        }
2848        (full_msgs, full_enums)
2849    }
2850
2851    fn resolve_types(&mut self) -> Result<()> {
2852        let (full_msgs, full_enums) = self.get_full_names();
2853
2854        fn rec_resolve_types(
2855            m: &mut Message,
2856            full_msgs: &HashMap<String, MessageIndex>,
2857            full_enums: &HashMap<String, EnumIndex>,
2858        ) -> Result<()> {
2859            // Interestingly, we can't call all_fields_mut to iterate over the
2860            // fields here: writing out the field traversal as below lets Rust
2861            // split m's mutable borrow, permitting the loop body to use fields
2862            // of `m` other than `fields` and `oneofs`.
2863            'types: for typ in m
2864                .fields
2865                .iter_mut()
2866                .chain(m.oneofs.iter_mut().flat_map(|o| o.fields.iter_mut()))
2867                .map(|f| &mut f.typ)
2868                .flat_map(|typ| match *typ {
2869                    FieldType::Map(ref mut key, ref mut value) => {
2870                        vec![&mut **key, &mut **value].into_iter()
2871                    }
2872                    _ => vec![typ].into_iter(),
2873                })
2874            {
2875                if let FieldType::MessageOrEnum(name) = typ.clone() {
2876                    let test_names: Vec<String> = if name.starts_with('.') {
2877                        vec![name.clone().split_off(1)]
2878                    } else if m.package.is_empty() {
2879                        vec![format!("{}.{}", m.name, name), name.clone()]
2880                    } else {
2881                        let mut v = vec![
2882                            format!("{}.{}.{}", m.package, m.name, name),
2883                            format!("{}.{}", m.package, name),
2884                        ];
2885                        for (index, _) in m.package.match_indices('.').rev() {
2886                            v.push(format!("{}.{}", &m.package[..index], name));
2887                        }
2888                        v.push(name.clone());
2889                        v
2890                    };
2891                    for name in &test_names {
2892                        if let Some(msg) = full_msgs.get(name) {
2893                            *typ = FieldType::Message(msg.clone());
2894                            continue 'types;
2895                        } else if let Some(e) = full_enums.get(name) {
2896                            *typ = FieldType::Enum(e.clone());
2897                            continue 'types;
2898                        }
2899                    }
2900                    return Err(Error::MessageOrEnumNotFound(name));
2901                }
2902            }
2903            for m in m.messages.iter_mut() {
2904                rec_resolve_types(m, full_msgs, full_enums)?;
2905            }
2906            Ok(())
2907        }
2908
2909        for m in self.messages.iter_mut() {
2910            rec_resolve_types(m, &full_msgs, &full_enums)?;
2911        }
2912        Ok(())
2913    }
2914
2915    fn write<W: Write>(
2916        &self,
2917        w: &mut W,
2918        filename: &str,
2919        config: &Config,
2920    ) -> Result<()> {
2921        println!(
2922            "Found {} messages, and {} enums",
2923            self.messages.len(),
2924            self.enums.len()
2925        );
2926        if config.headers {
2927            self.write_headers(w, filename, config)?;
2928        }
2929        self.write_package_start(w)?;
2930        self.write_uses(w, config)?;
2931        self.write_imports(w)?;
2932        self.write_enums(w)?;
2933        self.write_messages(w, config)?;
2934        self.write_rpc_services(w, config)?;
2935        self.write_package_end(w)?;
2936        Ok(())
2937    }
2938
2939    fn write_headers<W: Write>(
2940        &self,
2941        w: &mut W,
2942        filename: &str,
2943        config: &Config,
2944    ) -> Result<()> {
2945        writeln!(
2946            w,
2947            "// Automatically generated rust module for '{}' file",
2948            filename
2949        )?;
2950        writeln!(w)?;
2951        writeln!(w, "#![allow(non_snake_case)]")?;
2952        writeln!(w, "#![allow(non_upper_case_globals)]")?;
2953        writeln!(w, "#![allow(non_camel_case_types)]")?;
2954        writeln!(w, "#![allow(unused_imports)]")?;
2955        writeln!(w, "#![allow(unknown_lints)]")?;
2956        writeln!(w, "#![allow(clippy::all)]")?;
2957
2958        if config.add_deprecated_fields {
2959            writeln!(w, "#![allow(deprecated)]")?;
2960        }
2961
2962        // writeln!(w, "#![cfg_attr(rustfmt, rustfmt_skip)]")?;
2963        // writeln!(w)?;
2964        Ok(())
2965    }
2966
2967    fn write_package_start<W: Write>(
2968        &self,
2969        w: &mut W,
2970    ) -> Result<()> {
2971        writeln!(w)?;
2972        Ok(())
2973    }
2974
2975    fn write_uses<W: Write>(
2976        &self,
2977        w: &mut W,
2978        config: &Config,
2979    ) -> Result<()> {
2980        if self.messages.iter().all(|m| m.is_unit()) {
2981            writeln!(
2982                w,
2983                "use quack_protobuf::{{BytesReader, Result, MessageInfo, MessageRead, MessageWrite}};"
2984            )?;
2985            if self.owned {
2986                writeln!(w, "use core::convert::{{TryFrom, TryInto}};")?;
2987            }
2988            return Ok(());
2989        }
2990
2991        Message::write_common_uses(w, &self.messages, self, config)?;
2992
2993        writeln!(
2994            w,
2995            "use quack_protobuf::{{MessageInfo, MessageRead, MessageWrite, BytesReader, Writer, WriterBackend, Result, PackedFixed, PackedFixedIntoIter, PackedFixedRefIter}};"
2996        )?;
2997
2998        if self.owned {
2999            writeln!(w, "use core::convert::{{TryFrom, TryInto}};")?;
3000        }
3001
3002        writeln!(w, "use quack_protobuf::sizeofs::*;")?;
3003        for include in &config.custom_includes {
3004            writeln!(w, "{}", include)?;
3005        }
3006        Ok(())
3007    }
3008
3009    fn write_imports<W: Write>(
3010        &self,
3011        w: &mut W,
3012    ) -> Result<()> {
3013        // even if we don't have an explicit package, there is an implicit Rust module
3014        // This `use` allows us to refer to the package root.
3015        // NOTE! I'm suppressing not-needed 'use super::*' errors currently!
3016        let mut depth = self.package.split('.').count();
3017        if depth == 0 {
3018            depth = 1;
3019        }
3020        write!(w, "use ")?;
3021        for _ in 0..depth {
3022            write!(w, "super::")?;
3023        }
3024        writeln!(w, "*;")?;
3025        Ok(())
3026    }
3027
3028    fn write_package_end<W: Write>(
3029        &self,
3030        w: &mut W,
3031    ) -> Result<()> {
3032        writeln!(w)?;
3033        Ok(())
3034    }
3035
3036    fn write_enums<W: Write>(
3037        &self,
3038        w: &mut W,
3039    ) -> Result<()> {
3040        for m in self.enums.iter().filter(|e| !e.imported) {
3041            println!("Writing enum {}", m.name);
3042            writeln!(w)?;
3043            m.write_definition(w)?;
3044            writeln!(w)?;
3045            m.write_impl_default(w)?;
3046            writeln!(w)?;
3047            m.write_from_i32(w)?;
3048            writeln!(w)?;
3049            m.write_from_str(w)?;
3050        }
3051        Ok(())
3052    }
3053
3054    fn write_rpc_services<W: Write>(
3055        &self,
3056        w: &mut W,
3057        config: &Config,
3058    ) -> Result<()> {
3059        for m in self.rpc_services.iter() {
3060            println!("Writing Rpc {}", m.service_name);
3061            writeln!(w)?;
3062            m.write_definition(w, config)?;
3063        }
3064        Ok(())
3065    }
3066
3067    fn write_messages<W: Write>(
3068        &self,
3069        w: &mut W,
3070        config: &Config,
3071    ) -> Result<()> {
3072        for m in self.messages.iter().filter(|m| !m.imported) {
3073            m.write(w, self, config)?;
3074        }
3075        Ok(())
3076    }
3077}
3078
3079/// Calculates the tag value
3080fn tag(
3081    number: u32,
3082    typ: &FieldType,
3083    packed: bool,
3084) -> u32 {
3085    (number << 3) | typ.wire_type_num(packed)
3086}
3087
3088/// "" is ("",""), "a" is ("","a"), "a.b" is ("a"."b"), and so forth.
3089fn split_package(package: &str) -> (&str, &str) {
3090    if package.is_empty() {
3091        ("", "")
3092    } else if let Some(i) = package.rfind('.') {
3093        (&package[0..i], &package[i + 1..])
3094    } else {
3095        ("", package)
3096    }
3097}
3098
3099/// get the proper sanitized file stem from an input file path
3100fn get_file_stem(path: &Path) -> Result<String> {
3101    let mut file_stem = path
3102        .file_stem()
3103        .and_then(|f| f.to_str())
3104        .map(|s| s.to_string())
3105        .ok_or_else(|| Error::OutputFile(format!("{}", path.display())))?;
3106
3107    file_stem = file_stem.replace(|c: char| !c.is_alphanumeric(), "_");
3108    // will now be properly alphanumeric, but may be a keyword!
3109    sanitize_keyword(&mut file_stem);
3110    Ok(file_stem)
3111}