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 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, 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, 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 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 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 "None".to_owned()
625 } else {
626 match &self.default {
627 Some(custom_default) => {
628 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), };
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 }
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()) } 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 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 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 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 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 pub name: String,
1155 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, pub messages: Vec<Message>, pub enums: Vec<Enumerator>, pub module: String, pub path: PathBuf,
1174 pub import: PathBuf,
1175 pub index: MessageIndex,
1176 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 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 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 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 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 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 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 pub to: i32,
1944}
1945
1946impl Extensions {
1947 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 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 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)?; 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 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 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 for m in &mut self.messages {
2542 m.convert_field_types(from, to);
2543 }
2544 }
2545
2546 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 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 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 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 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 let Syntax::Proto3 = self.syntax {
2665 for m in &mut self.messages {
2666 m.set_repeated_as_packed();
2667 }
2668 }
2669 let copy = self.clone();
2672 for m in &mut self.messages {
2673 m.sanitize_defaults(©, config)?; }
2675 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 fn break_cycles(
2693 &mut self,
2694 error_cycle: bool,
2695 ) -> Result<()> {
2696 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 for scc in &sccs {
2722 for (i, v) in scc.iter().enumerate() {
2724 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 '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 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 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
3079fn tag(
3081 number: u32,
3082 typ: &FieldType,
3083 packed: bool,
3084) -> u32 {
3085 (number << 3) | typ.wire_type_num(packed)
3086}
3087
3088fn 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
3099fn 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 sanitize_keyword(&mut file_stem);
3110 Ok(file_stem)
3111}